diff --git a/.gitattributes b/.gitattributes index 7eeeb3298dab38c2fd5a3e17e529335e846d686b..dde1b55f80106acbcd31967827b9fb809b4a9b79 100644 --- a/.gitattributes +++ b/.gitattributes @@ -44,3 +44,9 @@ .venv/lib/python3.13/site-packages/gradio/templates/node/build/client/_app/immutable/chunks/vega-tooltip.module.DSC9NprE.js.br filter=lfs diff=lfs merge=lfs -text .venv/lib/python3.13/site-packages/gradio/templates/node/build/client/_app/immutable/chunks/vega-tooltip.module.DSC9NprE.js.gz filter=lfs diff=lfs merge=lfs -text .venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/PlotlyPlot-D4ZO-WDo.js.map filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/hf_xet/hf_xet.abi3.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/images/tqdm.gif filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/jiter/jiter.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/numpy/_core/_multiarray_tests.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/numpy/_core/_multiarray_umath.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/numpy/_core/_simd.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text diff --git a/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/INSTALLER b/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/METADATA b/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..0bdc04c93d37189a586959ca66dbbebed0b8e264 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/METADATA @@ -0,0 +1,271 @@ +Metadata-Version: 2.4 +Name: gradio +Version: 5.50.0 +Summary: Python library for easily interacting with trained machine learning models +Project-URL: Homepage, https://github.com/gradio-app/gradio +Author-email: Abubakar Abid , Ali Abid , Ali Abdalla , Dawood Khan , Ahsen Khaliq , Pete Allen , Ömer Faruk Özdemir , Freddy A Boulton , Hannah Blair +License-Expression: Apache-2.0 +License-File: LICENSE +Keywords: machine learning,reproducibility,visualization +Classifier: Development Status :: 5 - Production/Stable +Classifier: Operating System :: OS Independent +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: Topic :: Scientific/Engineering +Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence +Classifier: Topic :: Scientific/Engineering :: Visualization +Requires-Python: >=3.10 +Requires-Dist: aiofiles<25.0,>=22.0 +Requires-Dist: anyio<5.0,>=3.0 +Requires-Dist: audioop-lts<1.0; python_version >= '3.13' +Requires-Dist: brotli>=1.1.0 +Requires-Dist: fastapi<1.0,>=0.115.2 +Requires-Dist: ffmpy +Requires-Dist: gradio-client==1.14.0 +Requires-Dist: groovy~=0.1 +Requires-Dist: httpx<1.0,>=0.24.1 +Requires-Dist: huggingface-hub<2.0,>=0.33.5 +Requires-Dist: jinja2<4.0 +Requires-Dist: markupsafe<4.0,>=2.0 +Requires-Dist: numpy<3.0,>=1.0 +Requires-Dist: orjson~=3.0 +Requires-Dist: packaging +Requires-Dist: pandas<3.0,>=1.0 +Requires-Dist: pillow<12.0,>=8.0 +Requires-Dist: pydantic<=2.12.3,>=2.0 +Requires-Dist: pydub +Requires-Dist: python-multipart>=0.0.18 +Requires-Dist: pyyaml<7.0,>=5.0 +Requires-Dist: ruff>=0.9.3 +Requires-Dist: safehttpx<0.2.0,>=0.1.6 +Requires-Dist: semantic-version~=2.0 +Requires-Dist: starlette<1.0,>=0.40.0 +Requires-Dist: tomlkit<0.14.0,>=0.12.0 +Requires-Dist: typer<1.0,>=0.12 +Requires-Dist: typing-extensions~=4.0 +Requires-Dist: uvicorn>=0.14.0 +Provides-Extra: mcp +Requires-Dist: mcp==1.10.1; extra == 'mcp' +Requires-Dist: pydantic>=2.11; extra == 'mcp' +Provides-Extra: oauth +Requires-Dist: authlib; extra == 'oauth' +Requires-Dist: itsdangerous; extra == 'oauth' +Description-Content-Type: text/markdown + + + +
+ +gradio + +
+ +
+ +Gradio 5.0 - the easiest way to build AI web apps | Product Hunt +gradio-app%2Fgradio | Trendshift + + +[![gradio-backend](https://github.com/gradio-app/gradio/actions/workflows/test-python.yml/badge.svg)](https://github.com/gradio-app/gradio/actions/workflows/test-python.yml) +[![gradio-ui](https://github.com/gradio-app/gradio/actions/workflows/tests-js.yml/badge.svg)](https://github.com/gradio-app/gradio/actions/workflows/tests-js.yml) +[![PyPI](https://img.shields.io/pypi/v/gradio)](https://pypi.org/project/gradio/) +[![PyPI downloads](https://img.shields.io/pypi/dm/gradio)](https://pypi.org/project/gradio/) +![Python version](https://img.shields.io/badge/python-3.10+-important) +[![Twitter follow](https://img.shields.io/twitter/follow/gradio?style=social&label=follow)](https://twitter.com/gradio) + +[Website](https://gradio.app) +| [Documentation](https://gradio.app/docs/) +| [Guides](https://gradio.app/guides/) +| [Getting Started](https://gradio.app/getting_started/) +| [Examples](demo/) + +
+ +
+ +English | [中文](https://raw.githubusercontent.com/gradio-app/gradio/main/readme_files/zh-cn#readme) + +
+ +# Gradio: Build Machine Learning Web Apps — in Python + + + +Gradio is an open-source Python package that allows you to quickly **build** a demo or web application for your machine learning model, API, or any arbitrary Python function. You can then **share** a link to your demo or web application in just a few seconds using Gradio's built-in sharing features. *No JavaScript, CSS, or web hosting experience needed!* + + + +It just takes a few lines of Python to create your own demo, so let's get started 💫 + + +### Installation + +**Prerequisite**: Gradio requires [Python 3.10 or higher](https://www.python.org/downloads/). + + +We recommend installing Gradio using `pip`, which is included by default in Python. Run this in your terminal or command prompt: + +```bash +pip install --upgrade gradio +``` + + +> [!TIP] + > It is best to install Gradio in a virtual environment. Detailed installation instructions for all common operating systems are provided here. + +### Building Your First Demo + +You can run Gradio in your favorite code editor, Jupyter notebook, Google Colab, or anywhere else you write Python. Let's write your first Gradio app: + + +```python +import gradio as gr + +def greet(name, intensity): + return "Hello, " + name + "!" * int(intensity) + +demo = gr.Interface( + fn=greet, + inputs=["text", "slider"], + outputs=["text"], +) + +demo.launch() +``` + + + +> [!TIP] + > We shorten the imported name from gradio to gr. This is a widely adopted convention for better readability of code. + +Now, run your code. If you've written the Python code in a file named `app.py`, then you would run `python app.py` from the terminal. + +The demo below will open in a browser on [http://localhost:7860](http://localhost:7860) if running from a file. If you are running within a notebook, the demo will appear embedded within the notebook. + +![`hello_world_4` demo](https://raw.githubusercontent.com/gradio-app/gradio/main/demo/hello_world_4/screenshot.gif) + +Type your name in the textbox on the left, drag the slider, and then press the Submit button. You should see a friendly greeting on the right. + +> [!TIP] + > When developing locally, you can run your Gradio app in hot reload mode, which automatically reloads the Gradio app whenever you make changes to the file. To do this, simply type in gradio before the name of the file instead of python. In the example above, you would type: `gradio app.py` in your terminal. You can also enable vibe mode by using the --vibe flag, e.g. gradio --vibe app.py, which provides an in-browser chat that can be used to write or edit your Gradio app using natural language. Learn more in the Hot Reloading Guide. + + +**Understanding the `Interface` Class** + +You'll notice that in order to make your first demo, you created an instance of the `gr.Interface` class. The `Interface` class is designed to create demos for machine learning models which accept one or more inputs, and return one or more outputs. + +The `Interface` class has three core arguments: + +- `fn`: the function to wrap a user interface (UI) around +- `inputs`: the Gradio component(s) to use for the input. The number of components should match the number of arguments in your function. +- `outputs`: the Gradio component(s) to use for the output. The number of components should match the number of return values from your function. + +The `fn` argument is very flexible -- you can pass *any* Python function that you want to wrap with a UI. In the example above, we saw a relatively simple function, but the function could be anything from a music generator to a tax calculator to the prediction function of a pretrained machine learning model. + +The `inputs` and `outputs` arguments take one or more Gradio components. As we'll see, Gradio includes more than [30 built-in components](https://www.gradio.app/docs/gradio/introduction) (such as the `gr.Textbox()`, `gr.Image()`, and `gr.HTML()` components) that are designed for machine learning applications. + +> [!TIP] + > For the `inputs` and `outputs` arguments, you can pass in the name of these components as a string (`"textbox"`) or an instance of the class (`gr.Textbox()`). + +If your function accepts more than one argument, as is the case above, pass a list of input components to `inputs`, with each input component corresponding to one of the arguments of the function, in order. The same holds true if your function returns more than one value: simply pass in a list of components to `outputs`. This flexibility makes the `Interface` class a very powerful way to create demos. + +We'll dive deeper into the `gr.Interface` on our series on [building Interfaces](https://www.gradio.app/main/guides/the-interface-class). + +### Sharing Your Demo + +What good is a beautiful demo if you can't share it? Gradio lets you easily share a machine learning demo without having to worry about the hassle of hosting on a web server. Simply set `share=True` in `launch()`, and a publicly accessible URL will be created for your demo. Let's revisit our example demo, but change the last line as follows: + +```python +import gradio as gr + +def greet(name): + return "Hello " + name + "!" + +demo = gr.Interface(fn=greet, inputs="textbox", outputs="textbox") + +demo.launch(share=True) # Share your demo with just 1 extra parameter 🚀 +``` + +When you run this code, a public URL will be generated for your demo in a matter of seconds, something like: + +👉   `https://a23dsf231adb.gradio.live` + +Now, anyone around the world can try your Gradio demo from their browser, while the machine learning model and all computation continues to run locally on your computer. + +To learn more about sharing your demo, read our dedicated guide on [sharing your Gradio application](https://www.gradio.app/guides/sharing-your-app). + + +### An Overview of Gradio + +So far, we've been discussing the `Interface` class, which is a high-level class that lets you build demos quickly with Gradio. But what else does Gradio include? + +#### Custom Demos with `gr.Blocks` + +Gradio offers a low-level approach for designing web apps with more customizable layouts and data flows with the `gr.Blocks` class. Blocks supports things like controlling where components appear on the page, handling multiple data flows and more complex interactions (e.g. outputs can serve as inputs to other functions), and updating properties/visibility of components based on user interaction — still all in Python. + +You can build very custom and complex applications using `gr.Blocks()`. For example, the popular image generation [Automatic1111 Web UI](https://github.com/AUTOMATIC1111/stable-diffusion-webui) is built using Gradio Blocks. We dive deeper into the `gr.Blocks` on our series on [building with Blocks](https://www.gradio.app/guides/blocks-and-event-listeners). + +#### Chatbots with `gr.ChatInterface` + +Gradio includes another high-level class, `gr.ChatInterface`, which is specifically designed to create Chatbot UIs. Similar to `Interface`, you supply a function and Gradio creates a fully working Chatbot UI. If you're interested in creating a chatbot, you can jump straight to [our dedicated guide on `gr.ChatInterface`](https://www.gradio.app/guides/creating-a-chatbot-fast). + +#### The Gradio Python & JavaScript Ecosystem + +That's the gist of the core `gradio` Python library, but Gradio is actually so much more! It's an entire ecosystem of Python and JavaScript libraries that let you build machine learning applications, or query them programmatically, in Python or JavaScript. Here are other related parts of the Gradio ecosystem: + +* [Gradio Python Client](https://www.gradio.app/guides/getting-started-with-the-python-client) (`gradio_client`): query any Gradio app programmatically in Python. +* [Gradio JavaScript Client](https://www.gradio.app/guides/getting-started-with-the-js-client) (`@gradio/client`): query any Gradio app programmatically in JavaScript. +* [Hugging Face Spaces](https://huggingface.co/spaces): the most popular place to host Gradio applications — for free! + +### What's Next? + +Keep learning about Gradio sequentially using the Gradio Guides, which include explanations as well as example code and embedded interactive demos. Next up: [let's dive deeper into the Interface class](https://www.gradio.app/guides/the-interface-class). + +Or, if you already know the basics and are looking for something specific, you can search the more [technical API documentation](https://www.gradio.app/docs/). + + +### Gradio Sketch + +You can also build Gradio applications without writing any code. Simply type `gradio sketch` into your terminal to open up an editor that lets you define and modify Gradio components, adjust their layouts, add events, all through a web editor. Or [use this hosted version of Gradio Sketch, running on Hugging Face Spaces](https://huggingface.co/spaces/aliabid94/Sketch). + +## Questions? + +If you'd like to report a bug or have a feature request, please create an [issue on GitHub](https://github.com/gradio-app/gradio/issues/new/choose). For general questions about usage, we are available on [our Discord server](https://discord.com/invite/feTf9x3ZSB) and happy to help. + +If you like Gradio, please leave us a ⭐ on GitHub! + +## Open Source Stack + +Gradio is built on top of many wonderful open-source libraries! + +[huggingface](https://huggingface.co) +[python](https://www.python.org) +[fastapi](https://fastapi.tiangolo.com) +[encode](https://www.encode.io) +[svelte](https://svelte.dev) +[vite](https://vitejs.dev) +[pnpm](https://pnpm.io) +[tailwind](https://tailwindcss.com) +[storybook](https://storybook.js.org/) +[chromatic](https://www.chromatic.com/) + +## License + +Gradio is licensed under the Apache License 2.0 found in the [LICENSE](LICENSE) file in the root directory of this repository. + +## Citation + +Also check out the paper _[Gradio: Hassle-Free Sharing and Testing of ML Models in the Wild](https://arxiv.org/abs/1906.02569), ICML HILL 2019_, and please cite it if you use Gradio in your work. + +``` +@article{abid2019gradio, + title = {Gradio: Hassle-Free Sharing and Testing of ML Models in the Wild}, + author = {Abid, Abubakar and Abdalla, Ali and Abid, Ali and Khan, Dawood and Alfozan, Abdulrahman and Zou, James}, + journal = {arXiv preprint arXiv:1906.02569}, + year = {2019}, +} +``` diff --git a/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/RECORD b/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..9a3233a21493a85011ac62be659af0760d32d1e5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/RECORD @@ -0,0 +1,4644 @@ +../../../bin/gradio,sha256=Tw7HmLIyc0jmJLWD0knFO97SsoN_OwXxXzfBC01BKzA,186 +../../../bin/upload_theme,sha256=uspeyby7enVoM_DjxEr7KQqRyaQYQ8xoziVzDTLPQfo,204 +gradio-5.50.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +gradio-5.50.0.dist-info/METADATA,sha256=6nBOYvglhW52QMAgSsiO8PWsKY043bKhDa9PfBX_wsQ,16452 +gradio-5.50.0.dist-info/RECORD,, +gradio-5.50.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87 +gradio-5.50.0.dist-info/entry_points.txt,sha256=1XW1nK_lUq93N9mkj5E6Z_YXfouT_l7v-25wf6HzkFE,89 +gradio-5.50.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357 +gradio/.dockerignore,sha256=yqqbJvPhtVNTTvla3dhpqUgRO5OFeneITtoSg70NFdY,43 +gradio/CHANGELOG.md,sha256=32y0jXtMEZt2192RV-hEaApWA6cASbnkqMeUtskPbSU,721087 +gradio/__init__.py,sha256=VFRuUk-rlg_R6qcnUClMmQ33xsoAkWo2LuI-7rqEK_8,5180 +gradio/__main__.py,sha256=uWOD_InlMpggpGv4R2ayVvQ7bPZjGkONwMSYOddxBfU,65 +gradio/__pycache__/__init__.cpython-313.pyc,, +gradio/__pycache__/__main__.cpython-313.pyc,, +gradio/__pycache__/analytics.cpython-313.pyc,, +gradio/__pycache__/block_function.cpython-313.pyc,, +gradio/__pycache__/blocks.cpython-313.pyc,, +gradio/__pycache__/blocks_events.cpython-313.pyc,, +gradio/__pycache__/brotli_middleware.cpython-313.pyc,, +gradio/__pycache__/chat_interface.cpython-313.pyc,, +gradio/__pycache__/component_meta.cpython-313.pyc,, +gradio/__pycache__/context.cpython-313.pyc,, +gradio/__pycache__/data_classes.cpython-313.pyc,, +gradio/__pycache__/events.cpython-313.pyc,, +gradio/__pycache__/exceptions.cpython-313.pyc,, +gradio/__pycache__/external.cpython-313.pyc,, +gradio/__pycache__/external_utils.cpython-313.pyc,, +gradio/__pycache__/flagging.cpython-313.pyc,, +gradio/__pycache__/helpers.cpython-313.pyc,, +gradio/__pycache__/http_server.cpython-313.pyc,, +gradio/__pycache__/i18n.cpython-313.pyc,, +gradio/__pycache__/image_utils.cpython-313.pyc,, +gradio/__pycache__/interface.cpython-313.pyc,, +gradio/__pycache__/ipython_ext.cpython-313.pyc,, +gradio/__pycache__/mcp.cpython-313.pyc,, +gradio/__pycache__/media.cpython-313.pyc,, +gradio/__pycache__/monitoring_dashboard.cpython-313.pyc,, +gradio/__pycache__/networking.cpython-313.pyc,, +gradio/__pycache__/node_server.cpython-313.pyc,, +gradio/__pycache__/oauth.cpython-313.pyc,, +gradio/__pycache__/pipelines.cpython-313.pyc,, +gradio/__pycache__/pipelines_utils.cpython-313.pyc,, +gradio/__pycache__/processing_utils.cpython-313.pyc,, +gradio/__pycache__/queueing.cpython-313.pyc,, +gradio/__pycache__/ranged_response.cpython-313.pyc,, +gradio/__pycache__/renderable.cpython-313.pyc,, +gradio/__pycache__/route_utils.cpython-313.pyc,, +gradio/__pycache__/routes.cpython-313.pyc,, +gradio/__pycache__/screen_recording_utils.cpython-313.pyc,, +gradio/__pycache__/server_messages.cpython-313.pyc,, +gradio/__pycache__/state_holder.cpython-313.pyc,, +gradio/__pycache__/templates.cpython-313.pyc,, +gradio/__pycache__/tunneling.cpython-313.pyc,, +gradio/__pycache__/utils.cpython-313.pyc,, +gradio/_frontend_code/accordion/Index.svelte,sha256=FBoEeqdQJ1VaAj9cMRgBvgTQBT3GQpO7qZKQlfN_j74,934 +gradio/_frontend_code/accordion/package.json,sha256=bvAOsWj2k6a0yItlcuJy3gzUbR4PLWudko7BuR91uzM,747 +gradio/_frontend_code/accordion/shared/Accordion.svelte,sha256=dU3wmO2J3y7PChvp7YfDSzliek-DrhEt0tjx1cQIKts,923 +gradio/_frontend_code/annotatedimage/Index.svelte,sha256=Br3AnwT5j5LPzIVGskCWDLxPxzcb3XauYnwvSoibUKE,5660 +gradio/_frontend_code/annotatedimage/package.json,sha256=KSarhDa-2D0F0gM4S00RqXiRhRLWCg3jC_ugbvzrRnE,845 +gradio/_frontend_code/atoms/package.json,sha256=hhF373Wa27YvAsqtMypR-kyytFJfd604wPPj6IPCy_M,743 +gradio/_frontend_code/atoms/src/Block.svelte,sha256=EOe9hVdZKXmMeqdHDBPbMvxuPfCY1-mtkgjx2U5gR0M,6322 +gradio/_frontend_code/atoms/src/BlockLabel.svelte,sha256=QRWu9YzFVGhSzY8sMSBqt_36yfaMOMCU385WcZXtr4M,1988 +gradio/_frontend_code/atoms/src/BlockTitle.svelte,sha256=a-ZRa6HU_I9PwkaTyvOVTDWFziOuDcPbLGFtbpvGb78,1064 +gradio/_frontend_code/atoms/src/DownloadLink.svelte,sha256=90b9Q-XpiJDrIrIqZGCEQh9RbJkFr4thcyAEmc_BuGs,825 +gradio/_frontend_code/atoms/src/Empty.svelte,sha256=XCjs7Ym8_pbSsCFsO2MUim7LZxRKKZR5QWOnh2XXD7U,1171 +gradio/_frontend_code/atoms/src/FullscreenButton.svelte,sha256=awYrqgyAtSeIkTl_PuRelekHLyqclufll4p0Gcwy7Zc,525 +gradio/_frontend_code/atoms/src/IconButton.svelte,sha256=brekcWmkbgOAZY37Ow7ruh8Io4Mie63eJ-LcSaU4s3s,2470 +gradio/_frontend_code/atoms/src/IconButtonWrapper.svelte,sha256=7X8C7gNmQBV2dwhEwbsjWYwhFoaTjjflGn7FzvxSudI,1798 +gradio/_frontend_code/atoms/src/Info.svelte,sha256=czD3rEsAPxJS2BM9P7TWK18A6wKFnfhnL1p5LZsOB-k,472 +gradio/_frontend_code/atoms/src/SelectSource.svelte,sha256=aCcTzVMhBYSKzsO6EaWJtmUJ--NsabBlR8_Bn80andU,2247 +gradio/_frontend_code/atoms/src/ShareButton.svelte,sha256=E66qjmVVM4h5a4tD-GblbQS2fZzXmO30mbMMtyH8ams,949 +gradio/_frontend_code/atoms/src/Toolbar.svelte,sha256=Cwmp3m31iWB3IQDeBzcrLcf8emMXR7g-dwiPDeM75hE,520 +gradio/_frontend_code/atoms/src/UploadText.svelte,sha256=8TuE97yEqQm4ZtvT3iRWguNrGr3KjgPV7eCPKGBVYt8,2027 +gradio/_frontend_code/atoms/src/icons/clear.svg,sha256=vwpFiqfMn3jDAFS1a72C1q4BEHLTaJZKurG0RIpX9j4,1920 +gradio/_frontend_code/atoms/src/icons/edit.svg,sha256=gvIbS-99UVGmYE5a38K1AcsPD_KmwwBe3hKdYzrzbHc,1427 +gradio/_frontend_code/atoms/src/icons/file.svg,sha256=Q8iW_49fybLNZLVxX77wSLPqTs-lq-eaJgKro0CvYJ4,339 +gradio/_frontend_code/atoms/src/index.ts,sha256=gCsjywG6jeL-nUIHp0_A8a1xmA1j-29mpp0W8iZ1UeI,821 +gradio/_frontend_code/atoms/src/utils/parse_placeholder.ts,sha256=hRMFwas7SebebcTRw35Cwkdyml3v8eD8-DnSuB27NC0,707 +gradio/_frontend_code/audio/Example.svelte,sha256=wjQJfKYjolyV2oOdtVyYPm5jbdMif-6K33dsBtVZn0Q,326 +gradio/_frontend_code/audio/Index.svelte,sha256=gQQdOCbkaNQmrl5COGZ14z6sqw6JgT5wUW3NKwIeH2s,7327 +gradio/_frontend_code/audio/index.ts,sha256=4eH1xCy-j7M033ZSChp-k9zBXdPx1tVcNobj_iQlECs,419 +gradio/_frontend_code/audio/interactive/InteractiveAudio.svelte,sha256=fk3HosSjUWBwzcYQ6feW3kKJmUWA1J1KoVc3eF8Cd2k,9416 +gradio/_frontend_code/audio/package.json,sha256=jlIAR-KZOhyLa2HSoIXwHPK4fRVZLC1eh2ROuHVDDig,1563 +gradio/_frontend_code/audio/player/AudioPlayer.svelte,sha256=hYN9yykANxP5n_0e6YkTZxUkXaBWiiGLtBZk6TXJC2o,11084 +gradio/_frontend_code/audio/recorder/AudioRecorder.svelte,sha256=G8InbnOS5G0WFfr250sdYUpyUGODqMrcTWoGqouVoz0,7252 +gradio/_frontend_code/audio/shared/Audio.svelte,sha256=MWvC-OEbZyTvVXmSCBYAoOxSywa8kiJlTNTn2ay02k0,497 +gradio/_frontend_code/audio/shared/DeviceSelect.svelte,sha256=5mkC8K6j9y1zXGfnDaf_po6JAjKcevHqgxNagF8rlJ8,1629 +gradio/_frontend_code/audio/shared/VolumeControl.svelte,sha256=haG-SVacPiVxqO5ppXWx6OvLXR9LC5hM__-q3oYyNvc,1628 +gradio/_frontend_code/audio/shared/VolumeLevels.svelte,sha256=1BVyw_q_ujotzkkamos2_USUiZTheS065qUL7zxBAXk,276 +gradio/_frontend_code/audio/shared/WaveformControls.svelte,sha256=bo6zun7KOHDSLEvYBGmjKzYuIOOTRPj4mSAp_AKR7NA,9843 +gradio/_frontend_code/audio/shared/WaveformRecordControls.svelte,sha256=UHVDH9vgyDXBZoAPbsM3ovu5GBw6yntLSTIdrGcULQ8,6478 +gradio/_frontend_code/audio/shared/audioBufferToWav.ts,sha256=vWXsNsrc_fH26tA_sFCihbgLJyy8RS48-d8805fWqgU,1631 +gradio/_frontend_code/audio/shared/index.ts,sha256=9t7vDzgssG1r4FxA36PHPDI5V-xScjIwj8o7haWw3ZQ,51 +gradio/_frontend_code/audio/shared/types.ts,sha256=sdplzl5YRC_aOnB8I_A6ZhlMIrV_pZA2GKsSVWIIBJ4,313 +gradio/_frontend_code/audio/shared/utils.ts,sha256=kxJRvsQwhkDW7x5UQ8aV7ZwxoUWp3wpS7PPQphVIB3o,2033 +gradio/_frontend_code/audio/static/StaticAudio.svelte,sha256=E-qdjK4n5xouCKtks0SlIr4MO7Jw-CXaqSDv-uw-_3Q,2378 +gradio/_frontend_code/audio/streaming/StreamAudio.svelte,sha256=fZ-ox5sfl3pE7b5E9ZXwJM_AuhgyJFmztazsMU6rMxc,4616 +gradio/_frontend_code/audio/streaming/media_recorder.ts,sha256=kSvzFavwRjuVl0MPhru0ErnopjSMPYUHaGG5LAa_yes,500 +gradio/_frontend_code/box/Index.svelte,sha256=8BI8qRBiKbwibcDZ4lSCpr_bY_ppvG7DM27vTDqNW9c,259 +gradio/_frontend_code/box/package.json,sha256=3ImuTpXe3p4dPTh8LcLA01VsQfhA1fqGvrL7PA0oOiQ,582 +gradio/_frontend_code/browserstate/Index.svelte,sha256=bD-B0pi3Lg03bJZgjMR0Q6znPiL06xOVorjzz_bv5rk,1348 +gradio/_frontend_code/browserstate/crypto.ts,sha256=3Bxgf846Jnr790I9K9wRsjvfR9mpjWnDXAo0tOr_Fp4,886 +gradio/_frontend_code/browserstate/package.json,sha256=Fy3ALZAd9ogCj-S-thdaJF8VMkoqW1JwpNpkcetb2qg,696 +gradio/_frontend_code/build/out/component_loader.js,sha256=_sZGvUBBTLiCfeD0TgNn3e_NXZD0x6DjrsVcKBtEAfM,2501 +gradio/_frontend_code/build/out/index.js,sha256=vhuKi7pkgvPuIT6xt8-lKr5_4KbZQV4giuzjY3un3B8,10518 +gradio/_frontend_code/build/package.json,sha256=n1qWoHmO87C2SF7HvHxkL9iBMJoVd-jZCoi0BQ_tU60,668 +gradio/_frontend_code/build/src/component_loader.js,sha256=Oapgpy7g84fZ6M85nQxRzARc8u0DghUl3dZ3MhFiJPo,2497 +gradio/_frontend_code/build/src/index.ts,sha256=jAGRUnMeIAsRfv9_9JsGEVRG17Zlkfa-Z5fe2G0XXNM,9955 +gradio/_frontend_code/button/Index.svelte,sha256=o9zfKA_e7LzaSTHlRV4jGnqjckAbOjLlJK38VVZUB_o,1010 +gradio/_frontend_code/button/main.ts,sha256=IjoRmj_pOECIz_MIUcevZkEQEBHoNu_-KWRWIx8HCRA,117 +gradio/_frontend_code/button/package.json,sha256=8zn9fZfhyu3ZmYuM-PcYYItINpE0d-uU9ag3M1BIV7o,780 +gradio/_frontend_code/button/shared/Button.svelte,sha256=Y803gbMZYV4xy9eQvsT9RgrHDCJQSiDVhq_pOP8ErAc,5049 +gradio/_frontend_code/chatbot/Index.svelte,sha256=n0qDjTBnOB50td6l3ZPPZEGTCbLNe0bcHiIYCbYuw-U,5901 +gradio/_frontend_code/chatbot/package.json,sha256=Udjt4fwS_BW-Jn6nGikrf41BgUPNYMAUajN3xRKEWt0,1186 +gradio/_frontend_code/chatbot/shared/ButtonPanel.svelte,sha256=3Z1YfZ1gRUHR72YtOm7cwzj7GwMSKbmV6lyJv2xAuww,3288 +gradio/_frontend_code/chatbot/shared/ChatBot.svelte,sha256=NLqk-2AV3LGfGSHUts2fMktF_Rm-eGRortvMSOGF-po,14113 +gradio/_frontend_code/chatbot/shared/Component.svelte,sha256=eMR4chcjlT3f9_RIEvkQvycAYGokUlRn_NhwKEHKEAw,3179 +gradio/_frontend_code/chatbot/shared/Copy.svelte,sha256=KKg3viiXiqvogHg6nBpfbHHjNwMVWzObIspCC1v2Hyk,1535 +gradio/_frontend_code/chatbot/shared/CopyAll.svelte,sha256=H5cMER9PgA6AqWjyy48BfErlO106__3CTLDhYu-fL7s,1380 +gradio/_frontend_code/chatbot/shared/Download.svelte,sha256=fLsrxH7NJEvVzFVrD5KobWsfANTHDRoCKT7zjcghS4E,2127 +gradio/_frontend_code/chatbot/shared/Examples.svelte,sha256=PUEisg5wvTKZMaqYbSgzRsFlIfUxqGxc0Rska4exhJg,7987 +gradio/_frontend_code/chatbot/shared/Flag.svelte,sha256=KiFEGNKtaugxY9r7twcYoj0Oz3bUFwvAFF4E59I8rtM,191 +gradio/_frontend_code/chatbot/shared/FlagActive.svelte,sha256=MlGpqBQjEOr8EVLXLuwKSqSBJiAp_sO4Ws1pPVRK0dc,159 +gradio/_frontend_code/chatbot/shared/LikeDislike.svelte,sha256=jmJQipExlF7kwOPlfh9iw8Bq9RfTFj-boVamQbT3hOA,2990 +gradio/_frontend_code/chatbot/shared/Message.svelte,sha256=P_q49Nk7aNIw78LDV7ore6Xk8-Zlur4RrCx0YrLzmDc,14384 +gradio/_frontend_code/chatbot/shared/MessageContent.svelte,sha256=mKp8s4scTgX6BQkENYLmJehIZNEg9FDopXkOyY9OQ1o,3520 +gradio/_frontend_code/chatbot/shared/Pending.svelte,sha256=Qxtae_XQ6Zq5T0burdMQ1_aLp4bV5aR8d6fz0ChHLJ8,2860 +gradio/_frontend_code/chatbot/shared/Remove.svelte,sha256=iTwlhWW5oFKANBZCaRzidcDcIyUuWuy7KwxDTB70lio,386 +gradio/_frontend_code/chatbot/shared/Thought.svelte,sha256=PpWw4hGGXzzfeT0BZTj2tuy7yUUcaUL_mcPsZGWKyKw,6702 +gradio/_frontend_code/chatbot/shared/ThumbDownActive.svelte,sha256=KZIeQwS0L7P5yLkKPvjq6fQN7E53owrg1UQdItCEsqQ,661 +gradio/_frontend_code/chatbot/shared/ThumbDownDefault.svelte,sha256=ErjaT7boEAZRH5H2AwPld_qq7HYh2ILkJQrhuBcQgZM,1013 +gradio/_frontend_code/chatbot/shared/ThumbUpActive.svelte,sha256=D5LhDmu4jUjVH_A1ebBUNkRKLGyzoi3poZK5HTnC4Rs,655 +gradio/_frontend_code/chatbot/shared/ThumbUpDefault.svelte,sha256=QWO9UKaxjkYVPQ6GjtEGbAb0LYZtKFKWsVWWDqv00QE,1009 +gradio/_frontend_code/chatbot/shared/autorender.d.ts,sha256=U7gulwhgaWHTTyRQgyF07_7Z2KGEBz_DAYZFlvOfXiA,52 +gradio/_frontend_code/chatbot/shared/utils.ts,sha256=sB34KOQvYMDDu1dDw29LuWI5dlta2KPPI2sBP3AKxok,11267 +gradio/_frontend_code/chatbot/types.ts,sha256=sCtTsB5JYd2HvlBPbGL29-BvIKGgqJMdmPbpUSIynSY,1350 +gradio/_frontend_code/checkbox/Example.svelte,sha256=7Gk1X9iLLI7FCVkxZPIuF_asc-S7ycxRagRuHqxizPc,353 +gradio/_frontend_code/checkbox/Index.svelte,sha256=F3uZvb6_ITRgsxZyjqT_P2940VpZFjRmhUaessayOQc,1892 +gradio/_frontend_code/checkbox/package.json,sha256=j0LpYEsCAVtqB-OlcH0nCMkTsrPDMgl4QomFcO3fzrA,890 +gradio/_frontend_code/checkbox/shared/Checkbox.svelte,sha256=J9RBHhP70oCe5B0V9LGLjF2-D-uykjo08uuflTbnNmg,3523 +gradio/_frontend_code/checkboxgroup/Example.svelte,sha256=tfQqc1qPapXrj0Fw8H_CR6rtwfKtd_xshkLeMw6prTU,605 +gradio/_frontend_code/checkboxgroup/Index.svelte,sha256=p9rfJlRfpN8y9uqlYSe2WWnwv5Gom7j5HUn7FNRucmw,7495 +gradio/_frontend_code/checkboxgroup/package.json,sha256=g7AL00O_7vX196MVCX55xt0XEZriVyTIyd0Sy_zeUbQ,899 +gradio/_frontend_code/client/CHANGELOG.md,sha256=J5SgecUoff4unPsc0dxmHJd148kBvy8nFL415ArKgDQ,52700 +gradio/_frontend_code/client/README.md,sha256=0NpBLwbpDKmi99gVPMcWtz_hcrbNKBtfmTknPsT7uDs,14249 +gradio/_frontend_code/client/index.html,sha256=-6msucAUmgJhIkge9hb0eIxVSrraOCLmMUtyrEk5ZCY,809 +gradio/_frontend_code/client/package.json,sha256=LFDBhDqitnHLlY45EDxitTnPHJVqivSHEn6Kp3pOBXQ,1390 +gradio/_frontend_code/client/src/client.ts,sha256=ESXu4n_rq-Bfdn-4ZKnUA5DmUus2PxFiPAlIzWkl9Ks,15643 +gradio/_frontend_code/client/src/constants.ts,sha256=uWrNYsGghYtrf3eERZsvd9TNAZBoPVz67dHZfTtQRYo,1870 +gradio/_frontend_code/client/src/globals.d.ts,sha256=2nHZ4PTOxpS2S_7PIsRIJhC3rynByPiMa00IgFYwUlE,321 +gradio/_frontend_code/client/src/helpers/api_info.ts,sha256=saBuOsd6rz6GmjxqEjkLnemuh9h-FoxBUA1Lsgvd1Lk,12361 +gradio/_frontend_code/client/src/helpers/data.ts,sha256=rz7apvSx0MHP9c-zwRUGQ4PnYZNjnD4MubkwtMvpSdo,5797 +gradio/_frontend_code/client/src/helpers/init_helpers.ts,sha256=skJSeomyIHbkphYC-jyfJnQXLlhb75L1fCt_XYHz24s,6686 +gradio/_frontend_code/client/src/helpers/spaces.ts,sha256=SxudP6az9NzWdoRDnvpEzmygDL4eLapOCZqyGNZQH8M,5578 +gradio/_frontend_code/client/src/index.ts,sha256=kdg0T6Ss4YCFvLFFkzCUqMRWfcNICA7-fnnXkjsbs8s,619 +gradio/_frontend_code/client/src/types.ts,sha256=rkxw4bZp5L9DhrtstOlMeqEQJZpdq4TzYLoCZoevSCk,8921 +gradio/_frontend_code/client/src/upload.ts,sha256=m9ogxoGMDL7s2kKbnnAUvzhXSJ5En-dZLE5twZJHaXY,2141 +gradio/_frontend_code/client/src/utils/duplicate.ts,sha256=I8T8DgODTAQ7f9JcQvxrwDACQXaySJ9DcFGfp9hTpGI,2869 +gradio/_frontend_code/client/src/utils/handle_blob.ts,sha256=V_ga-_PvvKHF14ekIljbZcqRrx1tehQUI2VJLbOYfB4,3216 +gradio/_frontend_code/client/src/utils/post_data.ts,sha256=LIQ3G-DSz79oq2_62Quts4_iL2d3RgZ_nhu0HzGbv4o,983 +gradio/_frontend_code/client/src/utils/predict.ts,sha256=1Ru5VeYdA8Uw0PkAKB6IXOXeVQ9uhml_9ArCNnfKuEw,1340 +gradio/_frontend_code/client/src/utils/stream.ts,sha256=GEXI1tokxFE15SJo6-WRhJ6GzoOCOhGQOsh9c3FeXH8,5589 +gradio/_frontend_code/client/src/utils/submit.ts,sha256=5lHZSmsE2kNfU7A4-b2XKUVKYJtlFQLiM-xD8zkpL9w,21799 +gradio/_frontend_code/client/src/utils/upload_files.ts,sha256=rpQ1CvDnJr3faUmIXzG84XCkvJMkiG7ZeJIY3WLHosY,1410 +gradio/_frontend_code/client/src/utils/view_api.ts,sha256=PFssixeMPevyiwy51U8nmOtJwG6kIMq7EBG7sZ83jxI,1860 +gradio/_frontend_code/client/src/vite-env.d.ts,sha256=FyVrvSPulqgLiZSTLYwObz6J5qH_XzjpnAdFwDfcULk,77 +gradio/_frontend_code/client/tsconfig.json,sha256=b2-YQEDxB6HP8IPqF5JUxGCnguo-rqFkdz0-rNfQ23o,616 +gradio/_frontend_code/client/vite.config.js,sha256=5P37aEWknyTP7mIkJk0dPrzX0ZKzosNB70YBTlNYjc0,1003 +gradio/_frontend_code/code/Example.svelte,sha256=KwYmYFH-upudovz6jV2KDNRX61Y6mfH2PStTURtxWFQ,569 +gradio/_frontend_code/code/Index.svelte,sha256=lVlXPbXFXB2s063kxBg5sY99617vkPEq0SWNh0MAd-M,2646 +gradio/_frontend_code/code/package.json,sha256=wT5XmWWXegmrIxRmYy4HubL6t2q2XxPe2qAZnSho_xw,1738 +gradio/_frontend_code/code/shared/Code.svelte,sha256=DOC0ZJaWA6TVg87EhtSGYLp2FclBJG6emJwF1TC9UPE,6864 +gradio/_frontend_code/code/shared/Copy.svelte,sha256=0ObHe4neYmHoZyzvi0YJuRJl4ERGhRb6gWBMFcnt4hQ,666 +gradio/_frontend_code/code/shared/Download.svelte,sha256=J3tAZ7MLii8d8jqF7p9ygiFH1PM6yaZOy57iwxRSBrI,1233 +gradio/_frontend_code/code/shared/Widgets.svelte,sha256=oET-vAx1UwOURzBi4Y8tg3cypd6-A5qMdZJqvt6jcxk,310 +gradio/_frontend_code/code/shared/extensions.ts,sha256=-s-8jBjUlKZF6R23YWM8qHtgSiQ563H0VZtAO8xKVug,1121 +gradio/_frontend_code/code/shared/frontmatter.ts,sha256=LHLBVc_jbZsJdIi5vXgADiuYWlfNO9zOcL2dpHlHw9A,1626 +gradio/_frontend_code/code/shared/language.ts,sha256=jLPwFEE5oB1T-6N6ujipvBdzKLLWtxNg7wNqwJkuFWc,2662 +gradio/_frontend_code/colorpicker/Example.svelte,sha256=-PaUBG-x07K6b6zJ6ffXhrIaKq2cE37Ylkbaeavoquo,388 +gradio/_frontend_code/colorpicker/Index.svelte,sha256=1PXyhiKTKFkDeViwHqRmpIlQDEJbu8PqZDjLJ2UlTqw,1788 +gradio/_frontend_code/colorpicker/package.json,sha256=Q_3jkc5zGT5s4x_TLsCqrf-gM9Nub0cGcr8vzksPGco,989 +gradio/_frontend_code/colorpicker/shared/Colorpicker.svelte,sha256=IudO9Z3gMTF5d6XYj_4f3ucxrFtVM4CMs7IVcPBxD_Y,9444 +gradio/_frontend_code/colorpicker/shared/events.ts,sha256=-cbo-YglrhUnEm0JaUyiS1JCm-Im8lYqrfdu11TIAHU,699 +gradio/_frontend_code/colorpicker/shared/utils.ts,sha256=606zayBGlEk44m4xngp4dmMs5vS4F08zbIABk75AbwI,908 +gradio/_frontend_code/column/Index.svelte,sha256=BTpfCnZimqVHn2ePlsYc24nNVV9IteUFz1-nPc-UzH8,1644 +gradio/_frontend_code/column/package.json,sha256=S-wF4UD9p6fB4yhk35h-3RnKu-JCJyBm4nx58E6EUfQ,695 +gradio/_frontend_code/dataframe/Example.svelte,sha256=PP2aNmX8ja0WPha01qxVrT0oz1JnmsPdBoflx5TU30c,2183 +gradio/_frontend_code/dataframe/Index.svelte,sha256=dpjW9-Q2dP8g2D0WRZ8iz1gJoM4D5ohb0Sni-veysuo,3407 +gradio/_frontend_code/dataframe/package.json,sha256=IdvPc5wgewBfI9uwm6dipGwtEyDRtXkdygg3bgEx7sQ,1242 +gradio/_frontend_code/dataframe/shared/BooleanCell.svelte,sha256=xpuBRGnUt8QuNTFJvkNgvfmbBUGkyejIdJNX2OWlVwk,868 +gradio/_frontend_code/dataframe/shared/CellMenu.svelte,sha256=uUsP_dr73f6JVh0hnbOkBRpoEM6qAn_mlXzYmtWnEIs,6436 +gradio/_frontend_code/dataframe/shared/CellMenuButton.svelte,sha256=E3q8slgcEDDOT4KozFCZP0d51327pNVlmM99qytRAMY,980 +gradio/_frontend_code/dataframe/shared/CellMenuIcons.svelte,sha256=R8V1R65IZNpRr6tHa4L0RxfGJMnDK__y7_DcTTenehw,4396 +gradio/_frontend_code/dataframe/shared/EditableCell.svelte,sha256=_r7JLCK_b7uoU1ma1_M2mLxtHDbdPNkNHyfh77ZPlT8,5671 +gradio/_frontend_code/dataframe/shared/EmptyRowButton.svelte,sha256=wVfksmIdiGZ4xnvOo_gcFSvLI0adZXLA3h5GUE7NY2k,610 +gradio/_frontend_code/dataframe/shared/Example.svelte,sha256=mzHr-TWR3yT0ENVcJXlyCqUFPg-DMKZuDv7PcIyRrWo,516 +gradio/_frontend_code/dataframe/shared/FilterMenu.svelte,sha256=1cFAaf7gLmEmdzr8iCyc4tAWe8WDVoVmpwNGkgXKKuw,5529 +gradio/_frontend_code/dataframe/shared/RowNumber.svelte,sha256=kPcd2oq1QK2a2pTqDMONL826b9J4HviCJXMiNQbJYwc,714 +gradio/_frontend_code/dataframe/shared/Table.svelte,sha256=MelWMS8fgTypFJAyd-10wkUqtJME4aHiAkFJndRUuxk,32937 +gradio/_frontend_code/dataframe/shared/TableCell.svelte,sha256=4NtFcBlks08pMZpXwlp7EpD-3rO-H4fuaBsz17pTXGY,7951 +gradio/_frontend_code/dataframe/shared/TableHeader.svelte,sha256=5wmX9qWlmJi8JlHG8Pq8NXdgemb58AS-XsIBMzicU4I,8490 +gradio/_frontend_code/dataframe/shared/Toolbar.svelte,sha256=9Ehe-XEIapvIsNZhsJkbGlcfdWC2mgVJ104YS7xjB24,4782 +gradio/_frontend_code/dataframe/shared/VirtualTable.svelte,sha256=eexi5xN9IF5r04MVrXSYiMvre2tr_Xf0fnGRssVGA1c,8868 +gradio/_frontend_code/dataframe/shared/context/dataframe_context.ts,sha256=_IA1QRnK6GjQGp2dwNSsbNzufRmBrq9MKU5LEwyB6bg,19949 +gradio/_frontend_code/dataframe/shared/icons/FilterIcon.svelte,sha256=FINweGUGs_T5C5dFBzrvUG8oEsdJE_PmxV4hof7SVQI,279 +gradio/_frontend_code/dataframe/shared/icons/Padlock.svelte,sha256=AiQ7-TkQriRv_Q6I3pwzffFzdcJlmOLjecD8jpo2dzw,478 +gradio/_frontend_code/dataframe/shared/icons/SelectionButtons.svelte,sha256=cpsya8EwpD4cqZs9Dzly0jMtKiXRSPgU5i4p9tHymnE,1794 +gradio/_frontend_code/dataframe/shared/icons/SortArrowDown.svelte,sha256=XUNv_ZaOV9T8xQQXK1SAP66Nd9pE3LrYkDy8Zl6I8TY,389 +gradio/_frontend_code/dataframe/shared/icons/SortArrowUp.svelte,sha256=3FAbheTo9FpEQqge8NjDlWE0qmyL708ZVcfY0pXJPUs,388 +gradio/_frontend_code/dataframe/shared/icons/SortButtonDown.svelte,sha256=PGGMFCA5xCwjp3UOAdFN90k_HcAkfbtVT8UZ1XYESF0,228 +gradio/_frontend_code/dataframe/shared/icons/SortButtonUp.svelte,sha256=JouwTdna_EQqf3UV0YbHYmoJ0LhuX9YFYCtAy4kGdco,248 +gradio/_frontend_code/dataframe/shared/icons/SortIcon.svelte,sha256=INyPmUXEGpas5jk37G27nLJzzRWF20nz9mf7krimqiA,1895 +gradio/_frontend_code/dataframe/shared/types.ts,sha256=zzHzL-964bn5HQA0SvTVu7UCI-i8XmOjJVSZnZyG8o0,605 +gradio/_frontend_code/dataframe/shared/utils/data_processing.ts,sha256=9zWaI88sDevoVud0GpKRymG6hcz91vFcBarcnh4eQwU,1870 +gradio/_frontend_code/dataframe/shared/utils/drag_utils.ts,sha256=dC342bY66vU7opuXeRQ6uTTmfzB4OmogBDVKJ9tmwKU,2956 +gradio/_frontend_code/dataframe/shared/utils/filter_utils.ts,sha256=IrB97rVNfyeEP-h6C89rtL5kWiw3NZwJqdtfRjJ0DUs,5427 +gradio/_frontend_code/dataframe/shared/utils/keyboard_utils.ts,sha256=yO8BeQccfDlcu2hVFk5a0898bXy43TGO6f8SeJc9OsA,7846 +gradio/_frontend_code/dataframe/shared/utils/menu_utils.ts,sha256=9jQzrL1bxjo8HbAUe-wQZle6Kv8hrHCHsP_A1qzWTHI,2813 +gradio/_frontend_code/dataframe/shared/utils/selection_utils.ts,sha256=UdHjPZG6ap4vu4AWz8sj8TCahQnRa6IkK08rNnUlzyg,6087 +gradio/_frontend_code/dataframe/shared/utils/sort_utils.ts,sha256=N0UR_M2noAgAKHXy_-7ieGMrQswlZ4iRZB8xt6flFOA,2382 +gradio/_frontend_code/dataframe/shared/utils/table_utils.ts,sha256=PwGmdKb_RMFkOZ5rmuMXRDW9ZnNVOjVOm1-A2cz4KSs,5446 +gradio/_frontend_code/dataframe/shared/utils/utils.ts,sha256=7MU2lElmi7HitrVzCw1PrURhzc1rrRpZuCuptnU8BZA,1196 +gradio/_frontend_code/dataframe/standalone/Index.svelte,sha256=s45kQzCmfhIxeTefNp_qLsas66unUPPT8Qaxk8Dt97o,21699 +gradio/_frontend_code/dataframe/standalone/default_i18n.ts,sha256=1cywd-trqC2mS0M1BOtnsWwGMaRFr_FYJf_9KIDABJQ,1154 +gradio/_frontend_code/dataframe/standalone/stubs/Upload.svelte,sha256=N7ZyJ_tsLENjRoWPXs9ZzU2IWsGNRERUIDH2aQVequs,335 +gradio/_frontend_code/dataframe/standalone/stubs/upload.ts,sha256=s4NES5P4zSoI-w-hYKQmla7XS4sqP9VYGBw5vnlz8Qo,53 +gradio/_frontend_code/dataset/Index.svelte,sha256=qinbQqu54-320niJlqTx-c2gBm6Cqeho1mmsoyRqrac,8886 +gradio/_frontend_code/dataset/package.json,sha256=_S0sD4V60fLk-2L8j8RgyPY6VvAd8f2fludi5q9GWQU,791 +gradio/_frontend_code/datetime/DateTimePicker.svelte,sha256=rw45-P9pnP6LpDCbiALdyuTI5B-zfV_Fa-5rKUSiCQg,9717 +gradio/_frontend_code/datetime/Example.svelte,sha256=SO7MGqaOaq-_-HzCSZzwLn8rFavTV2kpunPF56LpAm4,78 +gradio/_frontend_code/datetime/Index.svelte,sha256=7Iuvq2Cvitq9BbKgfSiSAWeHowLRZOFVrjlDWg5kWqo,7424 +gradio/_frontend_code/datetime/package.json,sha256=H8Ryq_jDQEOOcoOMAl1WTFBoiC-7EzrqTQBPa2GEtQ0,922 +gradio/_frontend_code/datetime/utils.ts,sha256=hIH0N1MEtC0JkRKTaDMZX0zrC0zOqvMm6zmqsNn_3PU,4398 +gradio/_frontend_code/dialogue/Dialogue.svelte,sha256=7sj5e0rp_rNmyc_3DpJL-U1I_QyIEA7vONReRvwdOJ4,25419 +gradio/_frontend_code/dialogue/Example.svelte,sha256=Mjl0zFOVTmgdFkDshYl6E-OhXekoiPVVbef3aTnxinc,306 +gradio/_frontend_code/dialogue/Index.svelte,sha256=9Um7dpjmuv6e-KPERFLkuIcD-pSmt4LIsNJtoyEY8vg,2663 +gradio/_frontend_code/dialogue/Switch.svelte,sha256=Jenzb3ecdzqbtImB0oP5iAAE3v9X3NnIi6MT52AKa6k,1735 +gradio/_frontend_code/dialogue/main.ts,sha256=wzLUIMACGbXHmDWh8BvZ0J6RBk-ED8baloQrMvMmWRQ,73 +gradio/_frontend_code/dialogue/package.json,sha256=g6e7oxIRw6tibGD9wA-Jlqqh9Gepgvt0Te3pSfiymSs,982 +gradio/_frontend_code/dialogue/utils.ts,sha256=vnS4z7eowg1bQVXCCKYa5DnLCNv6coHbiyD0Qjaz2LI,67 +gradio/_frontend_code/downloadbutton/Index.svelte,sha256=mOEQoZasb2zkgfCFWVquZuztsiEpMWNcQfQ-6tlness,1045 +gradio/_frontend_code/downloadbutton/package.json,sha256=0xxi4-c_zVpS6Rr_-MmQ1nv67VcUlycbmgjmpVTs03U,762 +gradio/_frontend_code/downloadbutton/shared/DownloadButton.svelte,sha256=skNNMd45cCjqdVDmKOe89LU9BWc7QiMJ8mBC9t5z0F8,1515 +gradio/_frontend_code/draggable/Index.svelte,sha256=But-ceDkjUAvcvaylB7jlnKrc4MJIyU0Rp1muGbzvSE,10073 +gradio/_frontend_code/draggable/package.json,sha256=78fxEKr0brgWBzhXi2HSD9G3lyjv4XcfhqWv_19_QHI,689 +gradio/_frontend_code/dropdown/Example.svelte,sha256=l97rvppejvS2CIsb-D6cP4H1gKGLsU-G8naeXgMyNsc,701 +gradio/_frontend_code/dropdown/Index.svelte,sha256=rMbvYAqizxngv6bT0AUbuF0tQBRxCB28J7FAIkh_2Nw,2965 +gradio/_frontend_code/dropdown/package.json,sha256=M-ZYIIEShqcTN1cHC3BPCQOxN5qxvHeJ7ZJDVi_K2C4,897 +gradio/_frontend_code/dropdown/shared/Dropdown.svelte,sha256=ktc2pS0pyI0MNCaxf7DQKGBC19YKVFN7PJaPiD1uH3U,7864 +gradio/_frontend_code/dropdown/shared/DropdownOptions.svelte,sha256=yD7AANV5bFEbnmECCIeixPNHdi746g712y_JDjPYkZk,4233 +gradio/_frontend_code/dropdown/shared/Multiselect.svelte,sha256=MlZWMd5DTVY346HNNP48h6WjPzHyy7TNGiguwJl9_gw,10360 +gradio/_frontend_code/dropdown/shared/utils.ts,sha256=mCPyqrNKlABBtWqxf4l0bG3yIfEQe6H0HPT0sfw9A14,1404 +gradio/_frontend_code/fallback/Example.svelte,sha256=Mjl0zFOVTmgdFkDshYl6E-OhXekoiPVVbef3aTnxinc,306 +gradio/_frontend_code/fallback/Index.svelte,sha256=KC1GLosogFCkJ1bQ0Fvz_Mk-6Gr0AwjSZNDPXjZkWAY,1095 +gradio/_frontend_code/fallback/package.json,sha256=ZoI43IrXfs_KGIOY_8i1k_3QDd-ffbdjMbbbzO1sWPo,905 +gradio/_frontend_code/file/Example.svelte,sha256=_2lmWwrAt0aP_oiyQku3bkVr7m75XljDCIw1Vtkgc8g,581 +gradio/_frontend_code/file/Index.svelte,sha256=4nZyq3QZXJMmTlNxu8_-TPwjzvTslgV0K-PJvBAhy9I,3586 +gradio/_frontend_code/file/package.json,sha256=oWXwjcy7GXaQvd4Xj91Db29xKUK2_MX-rIafIlV_vys,986 +gradio/_frontend_code/file/shared/File.svelte,sha256=Mkb_YtIBbO23OmYQhwditYUWdZIUdGXw1dqAdIE76Yc,808 +gradio/_frontend_code/file/shared/FilePreview.svelte,sha256=fFvxAri_HY0QcM5ITQXnPmYxWTmj47aX_4KcP4jtLeU,7604 +gradio/_frontend_code/file/shared/FileUpload.svelte,sha256=v3oV1O0Tl9xnh9s50M6d8-ljOtlJWIXbhutZlxqPPE8,2916 +gradio/_frontend_code/file/shared/utils.ts,sha256=BlSispgFtq_cFdBb54p4vOoqd6n4nNA6Kl8PF2ycMNs,281 +gradio/_frontend_code/fileexplorer/Example.svelte,sha256=TT6IbqkrWeZ2ompstGgdqqOmmJ14BLKEdJ0Foo5K_gc,732 +gradio/_frontend_code/fileexplorer/Index.svelte,sha256=Vuy569GEPQcAwcJpXGsEfo8oUAZhGw_VQJKP49R36vs,2205 +gradio/_frontend_code/fileexplorer/icons/light-file.svg,sha256=DnLB4W7QsTL43t0xzNEWa2DiR5dtd34ADZukbgAtg0g,211 +gradio/_frontend_code/fileexplorer/icons/light-folder.svg,sha256=TpdWxAhFCE515yCcjz-6a9BNPiGqC5R7EcgoK0B-cEI,3787 +gradio/_frontend_code/fileexplorer/package.json,sha256=IxWlJ7Z6ELmxNxwgwHeISwkKPBsxiC8L4RouKPKb_Fk,1048 +gradio/_frontend_code/fileexplorer/shared/ArrowIcon.svelte,sha256=qRXNXURfgfkdXAYFXsozrin87Y2WWLFKRu2TMudQ438,580 +gradio/_frontend_code/fileexplorer/shared/Checkbox.svelte,sha256=Kb_LiYyWc3n0tuKfZDq0A1rfVTmkxIuPG62EXx-WZMo,1239 +gradio/_frontend_code/fileexplorer/shared/DirectoryExplorer.svelte,sha256=g_D4eIwB2Un6n_Cb2dyeQXyivaOcEM4uX8tcovKl05w,1847 +gradio/_frontend_code/fileexplorer/shared/FileTree.svelte,sha256=5I0PQbXTpz1gMZLSehlkSnzTAGpFJlMK2J-LTKAs5hE,4750 +gradio/_frontend_code/fileexplorer/shared/types.ts,sha256=rHqZoaKf9nufjrO8P_d6Ruf6F_nZ1Bnv_6yDjKUJD0Q,89 +gradio/_frontend_code/form/Index.svelte,sha256=JQAIMyjoKWvOcxKlPqE3FFwcFxoSLgSw_ZLQuLZXsTg,867 +gradio/_frontend_code/form/package.json,sha256=Eh-LQElYlfNtV3xvda_R6K8d-40H0eIWHU0QqdegmrI,740 +gradio/_frontend_code/gallery/Example.svelte,sha256=qucv6IVtDwuPM4jjiuvk2zdEEHrs8HmfQocoaeyEjq8,2963 +gradio/_frontend_code/gallery/Index.svelte,sha256=_D5J37LeV095A63h0U6goZ4FwB1CKFkvVq25CwpRNUw,5565 +gradio/_frontend_code/gallery/package.json,sha256=GSh-09eUQHjma9I-cCp0sod9SPRNcmcI9HTffTpHjaM,1268 +gradio/_frontend_code/gallery/shared/Gallery.svelte,sha256=rssbQ0T9kyuLvPhxCVbpIrJ2SgcCbnnfm46S3HFKSZw,20240 +gradio/_frontend_code/gallery/shared/utils.ts,sha256=K8W_f-C4REsxmQzq5hY-r-iXDuV8WUNfGFRQIfZ7tn4,576 +gradio/_frontend_code/gallery/types.ts,sha256=wyH6i5Fg0NnvOjKyUPUjF0yEwg4s9NHSmb67VxnRFzQ,204 +gradio/_frontend_code/group/Index.svelte,sha256=F1Fv6IAAJ9cpnGL6kzZeXmsswG4QPstyW-te1dIaffk,888 +gradio/_frontend_code/group/package.json,sha256=v5AAUtyXXglmilwcDLaS1253zQn8C648ZkHL1xYOUMk,590 +gradio/_frontend_code/highlightedtext/Index.svelte,sha256=_RDSy5ibJix_2YPBdEFzGPrPxQcw4fGs6NRgr2N0498,3569 +gradio/_frontend_code/highlightedtext/package.json,sha256=HkU17zMiu5XroThKb-Mz5ilVlpMe0XA3pnh8wFIVK5c,838 +gradio/_frontend_code/highlightedtext/shared/InteractiveHighlightedtext.svelte,sha256=eKRCzHkQNtlWaYevLcKREIH-1ATraMqVX91w2xQI-U4,13258 +gradio/_frontend_code/highlightedtext/shared/LabelInput.svelte,sha256=WioQIMFbL8Fka2agLYQhku_dV6o1pltc8S_gdPE0WDY,2908 +gradio/_frontend_code/highlightedtext/shared/StaticHighlightedtext.svelte,sha256=MnBoZ4rmz8suNPcDfqlllgkmY4mY8grHm4pxnfu_JVo,6601 +gradio/_frontend_code/highlightedtext/shared/utils.ts,sha256=aMm_o9bZFOvayoo1gXnYzPmCw0zW-W0UyFXGPcHrP4A,1870 +gradio/_frontend_code/html/Example.svelte,sha256=yjmZLkkliYyAaZbx3PsmHksGrmWuk5PM38dRq-YJaKI,313 +gradio/_frontend_code/html/Index.svelte,sha256=pxhqs4uA13_NKfH0qOyZ3Z9d5koJE3yBIYfwJiPmwmM,1877 +gradio/_frontend_code/html/package.json,sha256=nEOkzEemUASzTpKqZGDLsj1KyFvpeKCeFkHEKIqMp2c,1013 +gradio/_frontend_code/html/shared/HTML.svelte,sha256=rJU-R8phy5tcXNRWzso73-xeumIl3eTVh5Pi8LHnG4I,2155 +gradio/_frontend_code/icons/package.json,sha256=kqffHQ6Nr1QUf02A_E5MY2etsykEbPv5yUG31SzGEyM,552 +gradio/_frontend_code/icons/src/ArrowDown.svelte,sha256=ZHRIN7CO9BCJj42Bpg01eWhzcetmANE7RVwStbyKgxY,299 +gradio/_frontend_code/icons/src/ArrowUp.svelte,sha256=rG2QyeTW5TkTI8HvQkepWr5O0703uf3hBqBmyyF9Pcc,298 +gradio/_frontend_code/icons/src/Back.svelte,sha256=9eAzciUHH2ML7niHWf0AUTB7-occFWLxu3uUln4ubRE,281 +gradio/_frontend_code/icons/src/Backward.svelte,sha256=GTK5efz8L1oLI9I_UW7Y7R8GmJc-ux0UGVVqiD_n7Ws,483 +gradio/_frontend_code/icons/src/Brush.svelte,sha256=V-xgKN6R-YAl0qxUb_H0I8Z6l8lx4vA8FGbDNsQE7qs,842 +gradio/_frontend_code/icons/src/BrushSize.svelte,sha256=vCp9xx2ukH9UYh7hJCLZuAr-s7ZShpcDT5mX1QgkDvc,1567 +gradio/_frontend_code/icons/src/Calendar.svelte,sha256=csjQmo4VNHZ2uFXrveUqIrlj-A4xENTvKWbx87a0R6s,730 +gradio/_frontend_code/icons/src/Camera.svelte,sha256=_gfhQWsQXPe-h7s_0FUz6OF4kQBRMYm4VvICUewANSk,370 +gradio/_frontend_code/icons/src/Chart.svelte,sha256=TQEqjqAATJa0zbmZ5YrAqYbGHxYFtBwxArpa1EpsHp0,815 +gradio/_frontend_code/icons/src/Chat.svelte,sha256=_KHLvJAmhpxZ7hoQ6FE0m0YOrV33bHiQ1GJ8lVCi1gc,507 +gradio/_frontend_code/icons/src/Check.svelte,sha256=MW_HLuukJV-HQgPXQ5sXDdUw-gd4Bl-SuGoVHkokQk8,289 +gradio/_frontend_code/icons/src/Circle.svelte,sha256=J4viOiEcesOP7z4xCscjHu-dmDrDhhQA9LgPnoFQPQc,236 +gradio/_frontend_code/icons/src/Clear.svelte,sha256=6wC5jacKstmSJ_ur40tVRanLY2i8BLgCO2Ssqbx3sg8,581 +gradio/_frontend_code/icons/src/ClosedCaption.svelte,sha256=DeDDWfjmNSFRo7oT0u5uBROrn90xCbvw9TbHxoDeHsk,461 +gradio/_frontend_code/icons/src/Code.svelte,sha256=eNHHR0k6azlL8a5jjrKWdCyegu0ZKR8eNqJsw2cn7fg,241 +gradio/_frontend_code/icons/src/Color.svelte,sha256=i543j2nWhHRQXiK8YBO-Z92rf7e25owj9THA7OuHsis,712 +gradio/_frontend_code/icons/src/ColorPickerSolid.svelte,sha256=Wh5_04tJs6TaeQkmzAyD5wLlwkMC9VuRRwi903P_sLE,723 +gradio/_frontend_code/icons/src/Community.svelte,sha256=VvCUfxnmZnxNXCmyczwKzRosryCvQ7yKzfKLHGiN2n4,440 +gradio/_frontend_code/icons/src/Copy.svelte,sha256=-BXJ7Vz6QxCWANSxXVQJmwWdUJp4DIcWr_que_DvU1A,336 +gradio/_frontend_code/icons/src/Crop.svelte,sha256=_3dX6OZdzAawmFaNfvVPKQ0vexwl5h_Uv4oJwzFHE60,332 +gradio/_frontend_code/icons/src/Download.svelte,sha256=P8ik8snlrchAp_XVqE-TqzG3aANxuGw_Pi7VGxRcaeg,256 +gradio/_frontend_code/icons/src/DropdownArrow.svelte,sha256=q6J3lnSEhrVze5QBvRtDKDPnyhPpF3kI4AunJAvymvo,281 +gradio/_frontend_code/icons/src/DropdownCircularArrow.svelte,sha256=TUwtXEONg10p6ChXcURvHSbNpOH9fFVY-3MGe--FM_M,314 +gradio/_frontend_code/icons/src/Edit.svelte,sha256=JTTDlnflEVTJGec9Xen5FPCxQusx6H-lNRa7cpr-y-M,307 +gradio/_frontend_code/icons/src/Erase.svelte,sha256=nbl7F5i8f5DJIXFZ1IteRhI3U4WKXSeTYX48UVZKd58,1776 +gradio/_frontend_code/icons/src/Error.svelte,sha256=_YMH3x5zOJRr7XKWj0JjmGoFLaIP23F-zeiI0GxTuEI,364 +gradio/_frontend_code/icons/src/Eyedropper.svelte,sha256=UEKY5i8Ig--iWMhG4j08Q2TLsWnRlE_m3ra_xGCeZYo,771 +gradio/_frontend_code/icons/src/File.svelte,sha256=7gg0qUJ5XVNQfzlisedgg7FYjaNFur3usB8a_UGX4uU,346 +gradio/_frontend_code/icons/src/Forward.svelte,sha256=MiYQ35EVDUf6MzsvejVqnIZjpL-xeZEOt81IkNDhdwU,480 +gradio/_frontend_code/icons/src/Image.svelte,sha256=ZnW4KHlXwJTwwg-tDeqSCEJfEM_7FqUsSTrIouj0ZaY,373 +gradio/_frontend_code/icons/src/ImagePaste.svelte,sha256=4PWVs3isV0j1esF_F7AjscjWbwV6gjJcTKDYfjBvy6E,418 +gradio/_frontend_code/icons/src/ImageResize.svelte,sha256=SKFlHZQNmPGWo7JpB6xEdVareyUXZj7a-jA6g9Ff9JU,1050 +gradio/_frontend_code/icons/src/Info.svelte,sha256=en09dED0sPo6-pqb7KUeGjLn0L43yhV9TRhMeHj1lqs,438 +gradio/_frontend_code/icons/src/JSON.svelte,sha256=97R2-cZthwEhQtaW4yLVk4S6NYCZRLMSnj0fDk_MR6Y,708 +gradio/_frontend_code/icons/src/Layers.svelte,sha256=zeZWCKlIUwvP1qjmdEsBq1Cp4WONyTAT5dFCxvWsMwI,1148 +gradio/_frontend_code/icons/src/LineChart.svelte,sha256=j7yHex_G_LDNvVsNR53ys7K1XKaaFMz8i8PzYtnyHcU,365 +gradio/_frontend_code/icons/src/Maximize.svelte,sha256=_8gYmpFIiWaqsB9w6zU6nx2PChqperHC98-GHLjAIY8,356 +gradio/_frontend_code/icons/src/Microphone.svelte,sha256=Mf8zDxfmT1ZZHPiQrfBOyEJKMtzIZNxTLfmSU_1j1T4,428 +gradio/_frontend_code/icons/src/Minimize.svelte,sha256=89ge7duSKcJWc8eN-c-QwQYDU5gNztE3bKENIzM92PU,353 +gradio/_frontend_code/icons/src/Music.svelte,sha256=DYXCRT6v6wxsFMJOcK-0ZRwraycZnrR1N0SKUu4RN64,333 +gradio/_frontend_code/icons/src/Palette.svelte,sha256=FYOFPmAMSgbP34nQOmnj7KW0MRZOXmtJ55J5CA-iCpk,584 +gradio/_frontend_code/icons/src/Pan.svelte,sha256=tAeEmyL03Krmf25amABBKXQq00RevhDJC8CUNkJN6Zk,639 +gradio/_frontend_code/icons/src/Paperclip.svelte,sha256=PYS_R8WzozrFnFOMUTXwEdjk8wBfT_0a5q6J0yP4MqU,1006 +gradio/_frontend_code/icons/src/Pause.svelte,sha256=Ulz7d3ZJMjAzX5t53ccvD6d5Bjc6pnXFz3VoAOz_Wac,302 +gradio/_frontend_code/icons/src/Play.svelte,sha256=ClBhdzgbe6k2WnIgkWAP2FSnW4bbSOvIOOlVkP-mGv4,254 +gradio/_frontend_code/icons/src/Plot.svelte,sha256=WTLO3CPko35wZLXHpCGUZY7KJi-7ZHn16iVH_yHO1PA,614 +gradio/_frontend_code/icons/src/Plus.svelte,sha256=DUfrvFCEcm_-aMZpALU2_9IdzgfWMJFh3IwvkBNQt1w,266 +gradio/_frontend_code/icons/src/Prompt.svelte,sha256=jfl8Keuca66LGuR2ow7dAZ4sOWf8egCsAtLmZHEjR38,426 +gradio/_frontend_code/icons/src/Redo.svelte,sha256=Bam1xz8c4hPbn1CyDBUMbJD0NYDzj7U0kIbUmskoqz0,361 +gradio/_frontend_code/icons/src/Remove.svelte,sha256=BaPpuDf5iD5rvACzbSG7Gfq5Dj-KkKH37mURgrmyw68,219 +gradio/_frontend_code/icons/src/Resize.svelte,sha256=VDjORbMvnXHpjLqWE68EDSoAz4p_coRLOSNU_QjDHcY,543 +gradio/_frontend_code/icons/src/Resource.svelte,sha256=L7-2BI1Tp_q52jx3shBK_C8EOP8XfzXpvzIbEBwexq4,390 +gradio/_frontend_code/icons/src/Retry.svelte,sha256=FWAM6_ox2Gfo__ucsLjyuAyIu9HxDL0Hz8pzEs5tltw,916 +gradio/_frontend_code/icons/src/Rotate.svelte,sha256=69ym46KjFuNHnfwGGsBH49YVWMKCF5ZqYzU3yyg5vC4,661 +gradio/_frontend_code/icons/src/ScrollDownArrow.svelte,sha256=v_g6VVHlGaa0fdeD-gyC6GbYYXl2-N60QMETD4dI9mg,259 +gradio/_frontend_code/icons/src/Send.svelte,sha256=gt7YrxuKxLkFYOGvLLX08ND_wZ7DJpWDqnA7yfu-7qk,2461 +gradio/_frontend_code/icons/src/Settings.svelte,sha256=mjFM_h_WqdmgcP6pEgbY3Hs-10mXEBfxH0Fzhc23yks,523 +gradio/_frontend_code/icons/src/Sketch.svelte,sha256=JTTDlnflEVTJGec9Xen5FPCxQusx6H-lNRa7cpr-y-M,307 +gradio/_frontend_code/icons/src/Spinner.svelte,sha256=lU6ycntw1x14zbWAO1m8x9cqOrnnK7s2Nbm-Y7cTBGo,599 +gradio/_frontend_code/icons/src/Square.svelte,sha256=cRvzqKYAW4I2u1aYn1eRt-pqL2PL7k8ICUGlGkrXGE0,392 +gradio/_frontend_code/icons/src/Success.svelte,sha256=diSgSj7eknZHUx17SNxuW_h93rSLfvex8gDYvq5e788,351 +gradio/_frontend_code/icons/src/Table.svelte,sha256=y2hZwERoTw8Edtcnpcs2JnAkIFNGBTg4WoaYt3CB-J8,359 +gradio/_frontend_code/icons/src/TextHighlight.svelte,sha256=SLwCPSwJ5Nl-b7FWJgUF1Gfnn5844BLTLbds9n0mUWE,580 +gradio/_frontend_code/icons/src/Tool.svelte,sha256=LySEX7eCKH_yb8Etjg1xLyS3RpZyq4WfTJDBxIWnDwQ,783 +gradio/_frontend_code/icons/src/Trash.svelte,sha256=76arxogTPQ-4eZuaOlnwHM-ajc5MJLLdws01HYt3oW4,546 +gradio/_frontend_code/icons/src/Tree.svelte,sha256=DMs6hUHJn27ionaxWojntYVWEJxsq2bDMgM7XLyt2Eo,669 +gradio/_frontend_code/icons/src/Trim.svelte,sha256=LBmHMIbFJ2ILkVi8w7WJbCXCRJE0Qc_ft8JPUW92yXU,451 +gradio/_frontend_code/icons/src/Undo.svelte,sha256=RlTtkRqtkPTg2Wjn3M3TaF4UXLIvFZioGxM2Scy7Ig8,345 +gradio/_frontend_code/icons/src/Upload.svelte,sha256=LWTY0kf_EsjIcUjqY1gvN0wKPh403o65QP6TuUa5LS4,365 +gradio/_frontend_code/icons/src/Video.svelte,sha256=RLBzSyIztHlW4_7pf_SnVGjNKIu8oLQE_9NCzwUIOmo,339 +gradio/_frontend_code/icons/src/Visibility.svelte,sha256=M8f3iK9Nna7aWr1DA-e3uD0v7y3x-n3Z6_ipf6Q77ts,433 +gradio/_frontend_code/icons/src/VisibilityOff.svelte,sha256=5dVLgl-WdGEZ3sXfmGHjtM6geAbag9PPzQNZ9QXB6Jc,618 +gradio/_frontend_code/icons/src/VolumeHigh.svelte,sha256=Na5bdlfvzKJd0d4PUr2i5HEYz95ZcpXCPvrjhAOlE-A,844 +gradio/_frontend_code/icons/src/VolumeLow.svelte,sha256=vI9T-UsN29Wjjlzv_YDXaxWYAmCS4hNCIkxtbL0A8Qo,698 +gradio/_frontend_code/icons/src/VolumeMuted.svelte,sha256=-NofGV-yiWpEjKm6TtBgM88-L8RVw6Y6sIHS0L9d5fg,878 +gradio/_frontend_code/icons/src/Warning.svelte,sha256=v80YMskig6ccDSX1liJSqkWdI_Sq9ZxI3leVS7W0QEU,468 +gradio/_frontend_code/icons/src/Webcam.svelte,sha256=wMsrVxNZe49hzwXjojcgzavShVhqbiwTlPH07K4hNK4,552 +gradio/_frontend_code/icons/src/ZoomIn.svelte,sha256=XiOv-JMA1h1YIWKrn_P5U48z89OZXApvYpA4XNDeuAk,308 +gradio/_frontend_code/icons/src/ZoomOut.svelte,sha256=aoPbMGx43I0GL9jl94aXMGF-9koyNQ184wcSSUbqxf4,301 +gradio/_frontend_code/icons/src/index.ts,sha256=Ruadx6qGiPiYSmOhmbD9NDhUYb290N_3yuRNSn5ERus,4280 +gradio/_frontend_code/image/Example.svelte,sha256=NZblDzR4CS8ZG3w1QZRkFhXlJo32WPCwVWxG_uzbewM,912 +gradio/_frontend_code/image/Index.svelte,sha256=Q8frn9lFYNQ3iA2uYrSs7vhkwoNpa8ZdzZfZ6mRiOiw,6850 +gradio/_frontend_code/image/package.json,sha256=-EVVk9e4CqyVdZxL9mHcfZWwP7hg17C79XK9lj00gzc,1380 +gradio/_frontend_code/image/shared/Image.svelte,sha256=FJdMKj4nx9UwCuR80nlo4aXGeEXccgtS6lepWpmfNNQ,377 +gradio/_frontend_code/image/shared/ImagePreview.svelte,sha256=vz-NHVLwtJhIELcLjWxup4a953Ot6lh1uVTuS4Yt5co,3375 +gradio/_frontend_code/image/shared/ImageUploader.svelte,sha256=mfMXHrEkoYlF77QYsSt1bX9vRVPfOkrDAcod-wNYGkM,7465 +gradio/_frontend_code/image/shared/Webcam.svelte,sha256=K5RQwE92A4I76FyEiX_6kBKgkXtNscxrFe5-89hn0xM,12316 +gradio/_frontend_code/image/shared/WebcamPermissions.svelte,sha256=eAf9fzN_YircqysiGQ1S5hHdTjYUnbheCeGSXUvXhy4,812 +gradio/_frontend_code/image/shared/index.ts,sha256=gsSGgzhfF-l468itWDucsShFUa83J3R-q8lsXKc5J_E,115 +gradio/_frontend_code/image/shared/stream_utils.ts,sha256=ohSjbiAyHL5coN81yWWdqbYWKbOXgt4TzlmULp74p9g,1325 +gradio/_frontend_code/image/shared/types.ts,sha256=__2tV86_1VPgGAqMl1aS_kLrHdehmqU82chWNTLNGJE,157 +gradio/_frontend_code/image/shared/utils.ts,sha256=xNGqGs8jtH21911m1POAnTNMbva4MSFZE608oR_11YU,1079 +gradio/_frontend_code/imageeditor/Example.svelte,sha256=oAq8JMeDWE8j4OyYU1bswKci9Nur2zf8SpxsWQk2nQA,939 +gradio/_frontend_code/imageeditor/IMAGE_EDITOR_OVERVIEW.md,sha256=cZGdtkVJ6cuFmlwAvSC7JXG72l1JiUHMhoiGIw72t3g,8651 +gradio/_frontend_code/imageeditor/Index.svelte,sha256=xX6VGwo0zwTVy1rGg4O1hTBPerhTEoy9mFK4unftN-k,6586 +gradio/_frontend_code/imageeditor/InteractiveImageEditor.svelte,sha256=PxrviMzxvb6rKgAD1TyAXOOJlGjktCl1ftAVkQAHK6k,6955 +gradio/_frontend_code/imageeditor/package.json,sha256=6j1bAjj2FAOKrT_iPC5lRfCism2J5nSb9UJdOkGVfq0,1144 +gradio/_frontend_code/imageeditor/shared/Anchor.svelte,sha256=b5-DNzyXswHq84DWH-qXKx9vH_IBNc6z1m_g9wTfrDA,7902 +gradio/_frontend_code/imageeditor/shared/Controls.svelte,sha256=QS4751SRxP-9agq0eB3RtG1J7C_KHhfO_IVkvraovZc,4836 +gradio/_frontend_code/imageeditor/shared/IconButton.svelte,sha256=r0LqTg9sixAW6YLq_oAWPDPhhFR0Ly99cERcFEXKwVg,2973 +gradio/_frontend_code/imageeditor/shared/ImageEditor.svelte,sha256=WHXu-YT3vluVuRKpnSnnS9VrUkdf_UC_yp33-eGm8jI,21769 +gradio/_frontend_code/imageeditor/shared/Layers.svelte,sha256=zpEEgTmx-V-Z-Ql4xkZXSB0nlBnQdDDoJ3uwq7R5Uqc,6151 +gradio/_frontend_code/imageeditor/shared/Resize.svelte,sha256=2j6NpV3hv5OPL6W8hfgfJkQA-02Vfp7TY4PBg_4xwVw,4932 +gradio/_frontend_code/imageeditor/shared/SecondaryToolbar.svelte,sha256=AeOD1NSk-E0Fnb3YCMM1xvUc6OYdNV2jOmDxC9nRScY,1305 +gradio/_frontend_code/imageeditor/shared/Toolbar.svelte,sha256=ZGa5W-_NwvgCqA42K5sfK2vpEZ7GicASwYbNg6yQ9wk,8692 +gradio/_frontend_code/imageeditor/shared/brush/BRUSH_TOOL.md,sha256=Hmd1mHe9W7UgxMvry00tBr-HnLnlzZBl4ZYKD3Ddz1o,5938 +gradio/_frontend_code/imageeditor/shared/brush/BrushOptions.svelte,sha256=bRP-MQ2pxGJCQ6Y_9KEow9XiOWrB6OlWtrxno-UwB-U,4595 +gradio/_frontend_code/imageeditor/shared/brush/BrushSize.svelte,sha256=8N_jX6BrQfWC2EeqhevVtGS_fFPRMDJaA8K_sG6yEJs,814 +gradio/_frontend_code/imageeditor/shared/brush/ColorField.svelte,sha256=hHpRgdkrjbrx7dDtdljW9D_gCOrrX0iJT3fL_-CwLtg,3744 +gradio/_frontend_code/imageeditor/shared/brush/ColorPicker.svelte,sha256=CdvPbu3Bqqr1lzAJ6sjFkQNZK72zQWsJ6nH7WGcvShM,6908 +gradio/_frontend_code/imageeditor/shared/brush/ColorSwatch.svelte,sha256=oReHJKKDNkEr_4V-JMg1hBjKBrv9rTQX1O4gsViBy8M,5571 +gradio/_frontend_code/imageeditor/shared/brush/brush-cursor.ts,sha256=pshCefAxvNJCbSb0C94SnGvaZPji-Q8rD-yDStiWwXE,9702 +gradio/_frontend_code/imageeditor/shared/brush/brush-textures.ts,sha256=3Rq0PLdUOGJ_3kDqthvdBFaboXlrZStDmq8jd1CaJdc,19376 +gradio/_frontend_code/imageeditor/shared/brush/brush-utils.ts,sha256=a1CfTpyFkGXJ6ygHdYa5R0r6X3Wn5RY2VY08sm0odbs,1884 +gradio/_frontend_code/imageeditor/shared/brush/brush.ts,sha256=Gh6H1RaHCFJe05ONlDqFEy4qWwAoErUag0ElM535fBI,10959 +gradio/_frontend_code/imageeditor/shared/brush/types.ts,sha256=40MRt2GXwWaJKKka1P9ffp9bun1kx8kIRFsjjfc6ICs,1146 +gradio/_frontend_code/imageeditor/shared/core/EDITOR.md,sha256=XDcZYjemAGD7fvjEDUxB09C-o3pxLoijlv1mameoI3w,7614 +gradio/_frontend_code/imageeditor/shared/core/commands.ts,sha256=zM7C4LDnZJ_9CoZFPcm3qKAM-pyvtHSEKfHpN4DdUw4,3459 +gradio/_frontend_code/imageeditor/shared/core/editor.ts,sha256=32XJmbCgpQXeC-NvH1q_P0a50ujSbtTBzEAv7y42fNc,22543 +gradio/_frontend_code/imageeditor/shared/core/layers.ts,sha256=RkLTX6HyXGDQ8WVTSoqxb-iLA8ZtqDXnTqW-TCNcZIw,27857 +gradio/_frontend_code/imageeditor/shared/crop/CROP.md,sha256=WhTl1XCoYtn2JpyIne1WrVCdj4AgKB0G9wp6RP2IJZY,5239 +gradio/_frontend_code/imageeditor/shared/crop/crop.ts,sha256=aSnnTGv4C2EjW_Q3GM4jTwvpuXSSJ-FnPSKf3_Ro234,29545 +gradio/_frontend_code/imageeditor/shared/image/IMAGE.md,sha256=4Zihiajk5lWqGBusYFD9iDNcmqwo-S4m1cy1IYgMIpM,5884 +gradio/_frontend_code/imageeditor/shared/image/image.ts,sha256=H7Wu3YIocnhy8l8p8XGeerwf9MzrG7PGL6XLoRap1r8,10412 +gradio/_frontend_code/imageeditor/shared/resize/resize.ts,sha256=b2QwNXcL1d3id8IDjVP94ry4KXloWYAol_0q6yuzfF4,47531 +gradio/_frontend_code/imageeditor/shared/types.ts,sha256=N5quPcmQw4kRPdYEzzCE_Foe1uQfYdoxoJ1wiOvpeAc,581 +gradio/_frontend_code/imageeditor/shared/utils/events.ts,sha256=0j45nAq4ZMvk26uQ77nm_0tOvpZ8nJ29T1ip_59uYXI,731 +gradio/_frontend_code/imageeditor/shared/utils/parse_placeholder.ts,sha256=hRMFwas7SebebcTRw35Cwkdyml3v8eD8-DnSuB27NC0,707 +gradio/_frontend_code/imageeditor/shared/utils/pixi.ts,sha256=7TQ40JVgK-vbrwyG2cwRpTBZXY0XkeyJSIjYUlbtkKo,1786 +gradio/_frontend_code/imageeditor/shared/zoom/zoom.ts,sha256=y3fnZnrbFgW8IE1Vq_Vzw6DPBnQwau0ENhANFzK7tcw,19838 +gradio/_frontend_code/imageslider/Example.svelte,sha256=7Zz2HS8EMLHxyLEFSKtleE2gUxkGfwLnpqlks1RZG14,1342 +gradio/_frontend_code/imageslider/Index.svelte,sha256=fNaYsKKVKQASaCUC17SO_G1QsHcIJeCVuFZbgulik_Q,5643 +gradio/_frontend_code/imageslider/img_01.png,sha256=0VOETqNvFZC_JyEvbDRK78AqaaAkgAR2gE5ixQ_Ku5s,730883 +gradio/_frontend_code/imageslider/img_02.png,sha256=C55wvvkjLXVPzFJhjcRJG3nMuUVpZNdvB4uDnFnOEmE,2637662 +gradio/_frontend_code/imageslider/img_03.png,sha256=H2WX6Gox4TvxB8wWRH30bgfO9DTvBwe5HUrQi0iBlaI,3639532 +gradio/_frontend_code/imageslider/package.json,sha256=RZkET_QEeU91ZCsBFU6IVtsXbbjDF11IyIRIBl-XVew,1089 +gradio/_frontend_code/imageslider/shared/ClearImage.svelte,sha256=iZZ7-bQ4nEqXzoVDU2LVQ2stn29uIlNsZ3gziOxWkqs,558 +gradio/_frontend_code/imageslider/shared/Image.svelte,sha256=o4DTGiqtds8T2ldTN3LtS18U24nHvTE3bV1MIWH5RWs,5021 +gradio/_frontend_code/imageslider/shared/ImageEl.svelte,sha256=81-vLiW4EjyPii1p3Is-CNKKHSIzqxyX386Id38cXmk,2977 +gradio/_frontend_code/imageslider/shared/Slider.svelte,sha256=-ztoGCFpxwXIcht4DW4A3WyImqo5YWhusYc4Qt_yOxk,4090 +gradio/_frontend_code/imageslider/shared/SliderPreview.svelte,sha256=hclY62d_RhVN_2Dxp13VA0PXM_iuH7RRYNRcBgTMukg,5803 +gradio/_frontend_code/imageslider/shared/SliderUpload.svelte,sha256=oOyB0iAvX-JgnSSury-7dOhfwjMzi06-DvQ0wbsp8eY,1008 +gradio/_frontend_code/imageslider/shared/zoom.ts,sha256=fKDlSSlTIpDB0VI92s7EXveMCILs294GkmEWEltNqRg,12744 +gradio/_frontend_code/json/Example.svelte,sha256=nvo-EZxUVTxfEX42B3iXTqXKyGpxWR-R2zYJmpvZSIU,1168 +gradio/_frontend_code/json/Index.svelte,sha256=KTYe5NFerVycYdQAk2zGuCAk2faKQQxqOtpPznJpKG8,1950 +gradio/_frontend_code/json/package.json,sha256=ERrJzsSiMNeDPX2G9ht-hsZnWnrrXu2NasonVP7-tCo,916 +gradio/_frontend_code/json/shared/JSON.svelte,sha256=OGUfiIXIH9N8QzUYOWfA0PVUmwVa6LP6a8vP72489oI,2127 +gradio/_frontend_code/json/shared/JSONNode.svelte,sha256=N4wVuPOcWI6wIREBmmvc4LOvfxIa3QG4h2MXp8s5P0Y,6338 +gradio/_frontend_code/label/Index.svelte,sha256=kYzTlEHvoQ22Cw3VXsI9pZ9HZFM4jA6jSlf3Q2RPKg0,2060 +gradio/_frontend_code/label/package.json,sha256=eCKokaeGggYeTvtKv7FOXdEluZ16kDgrXCIYXYBmBsM,784 +gradio/_frontend_code/label/shared/Label.svelte,sha256=kwhnG2JWrZdTGPLVfgestFzdBf43daFMWWxVkbwbw_g,4257 +gradio/_frontend_code/markdown-code/MarkdownCode.svelte,sha256=Bc4OWt66HqsT0dcmzlCFphFy9hN-IWQK84hf7qXMNNM,5991 +gradio/_frontend_code/markdown-code/html-tags.ts,sha256=-dhy3DzVsyh2ibYxUCPm-CfRiuCkxOsvnP5bf2b-quc,2381 +gradio/_frontend_code/markdown-code/index.ts,sha256=sFTJQFK0kEZ55kP6caj1BHOnc-tVaROLOrG5HCBfyhw,65 +gradio/_frontend_code/markdown-code/package.json,sha256=7ER-y1-DDtMcfiDZjpERQRhCvgsXRxUs3exjA7g6s5U,923 +gradio/_frontend_code/markdown-code/prism-dark.css,sha256=vZrRS7y-q5FBMthHmqVe5IHexRIbWMGemPPOpyk14ZY,1194 +gradio/_frontend_code/markdown-code/prism.css,sha256=IROZ_kvh0SIgjI_MRKiSWxo0MZTvEpBK1jGl-NFs4x0,3869 +gradio/_frontend_code/markdown-code/utils.ts,sha256=exDPk6AvIiQd9mp-S-mrogoGA1hywn8-t7MH7dPYP0E,8745 +gradio/_frontend_code/markdown/Example.svelte,sha256=geR2cssR8m6jp-59CrZ21_reQhEdbsSBgmg8BbIB-n8,876 +gradio/_frontend_code/markdown/Index.svelte,sha256=XmIxyTFYXXlNtlj-7gu8YMOdFuZGHI1iOoRnzLo54YI,2166 +gradio/_frontend_code/markdown/package.json,sha256=BqrUxX7TNajjikw4ljJDoO5kWkd7WuQNEq_UVyFXHhg,965 +gradio/_frontend_code/markdown/shared/Markdown.svelte,sha256=1hPkLSB6AJXT3i6xR-KfnKunbG4E5Lz34TWjV2_fmt0,2625 +gradio/_frontend_code/model3D/Example.svelte,sha256=wjQJfKYjolyV2oOdtVyYPm5jbdMif-6K33dsBtVZn0Q,326 +gradio/_frontend_code/model3D/Index.svelte,sha256=YMRZeWLcjBeJugZVBT5c-NOoZB8jfw5kAlZy0JTd62g,3969 +gradio/_frontend_code/model3D/package.json,sha256=iNOn8WtrVKAI6wGkCIDfWLNHyQmBgAnryPRaK-CWPPA,1165 +gradio/_frontend_code/model3D/shared/Canvas3D.svelte,sha256=MoY-nw5d7CeVYrqOnJqGiBd-vyzLEHL_M57hEJWJI50,2902 +gradio/_frontend_code/model3D/shared/Canvas3DGS.svelte,sha256=dLgWdlaL-r00Tw9obUPLT9ko7PXOHQ7LodWjqx69KSw,2045 +gradio/_frontend_code/model3D/shared/Model3D.svelte,sha256=Ci7dyKfSqMdIOX9Ouk7r0D1MTKrhoki2hXQsy6zpTtE,3398 +gradio/_frontend_code/model3D/shared/Model3DUpload.svelte,sha256=ptLFLhP8SbOnPdv1Ej-gdrWMuTVOGwNNQb4gW-N8otA,3625 +gradio/_frontend_code/multimodaltextbox/Example.svelte,sha256=jcDWo6bpdRUabCbaBdt7abk3MbzzG7GcE6uie48zvYc,2105 +gradio/_frontend_code/multimodaltextbox/Index.svelte,sha256=1JvonCIVHQcC4cTiC8xrCSPBRmUstjmSmazE1xLizo0,5870 +gradio/_frontend_code/multimodaltextbox/package.json,sha256=9rd-qwwXPSsOIA3k_HWw1i1thCfPBb0D9Fuj2KUOCwI,1079 +gradio/_frontend_code/multimodaltextbox/shared/MultimodalTextbox.svelte,sha256=3sv_4FddRjCs-Zfe86Y4NlhQUd7wMJlnefx-5ayxvWQ,17491 +gradio/_frontend_code/multimodaltextbox/shared/types.ts,sha256=Ar3YGIDmPyprgr3PG8MiU5iLFJNaHb740HVETgwQR3c,71 +gradio/_frontend_code/multimodaltextbox/shared/utils.ts,sha256=1TDeOPxvXaexAonQYmA6jKSlOWbt8wLrW_GY3lBt_ss,1502 +gradio/_frontend_code/nativeplot/Example.svelte,sha256=Gu-5sl1zjpuv11iO_JwiTHueoRi-UATPGGtv2auxjdM,156 +gradio/_frontend_code/nativeplot/Index.svelte,sha256=-ahsB8zXedUStlwP4pb9he1KzyjnF3HJFxV7IlOR6fc,21537 +gradio/_frontend_code/nativeplot/package.json,sha256=2JN2UtPEXeC8NGwpBEVjz_OBg9Jsx11p4cUyLJdHYE4,1008 +gradio/_frontend_code/navbar/Example.svelte,sha256=QjLBUH3_c-C-be0CGaYGKwHpm9KY-4fNQ4ogfuVM2yA,295 +gradio/_frontend_code/navbar/Index.svelte,sha256=hbpNKamw1rwBzknOf_G44Dicm3gE2zRjmind40vooDo,797 +gradio/_frontend_code/navbar/package.json,sha256=DvWi_M8N2I2HZnR-IEo1XajcQ1Szi1TpbcJGUmC3u5E,1016 +gradio/_frontend_code/number/Example.svelte,sha256=lm0bOjYxIGNvM6I4taZoUMxnCdHohd6x8iiFX0XWdzo,335 +gradio/_frontend_code/number/Index.svelte,sha256=wu7suU_ntKZUfbRf3mbRjdFdVBnVwPRMZx1KIvWtybI,3883 +gradio/_frontend_code/number/package.json,sha256=ppBHc2Q9_Vq1scRpr-PU3xtmDI2T7Z1Xsv56wgEwQVk,858 +gradio/_frontend_code/paramviewer/Example.svelte,sha256=-77ewJAsgv82w4GL7xmHgG5LmMeWitZbLUK2ZAQhNE8,342 +gradio/_frontend_code/paramviewer/Index.svelte,sha256=FVqJB0WeWTO_SZydcH870sL_UQ68BDYktzPgTM-mCpM,444 +gradio/_frontend_code/paramviewer/ParamViewer.svelte,sha256=RA-JiyO5opDJJbPZQ1uYTN13-WwBmX1OVHec3c-otec,7726 +gradio/_frontend_code/paramviewer/package.json,sha256=1TI0jVCSqyVqqeKeCzrsNUheWYsrWbNZWA0S33sypkI,923 +gradio/_frontend_code/paramviewer/prism.css,sha256=pAe2KsTAaLnB56dgTbAkyz-05f2eMUEffKjtChcuTfo,3794 +gradio/_frontend_code/plot/Index.svelte,sha256=tx5fXzqMJsZ3g3eEaZtd7ouMfIP8Tnhk_4L9whxLmBc,2198 +gradio/_frontend_code/plot/package.json,sha256=NprY3LJERCTfUNIWYabfeeqvXb3qieEpxmk5GtDkVng,1102 +gradio/_frontend_code/plot/shared/Plot.svelte,sha256=7X8G01xQvbaQA95ttN3wrrPgkmt87H7QEQPlaLT8PxE,2085 +gradio/_frontend_code/plot/shared/plot_types/AltairPlot.svelte,sha256=gkj7hnse98KSxqE0g6YRjvWGrz7KBrzaA-8k4nN2vaU,3966 +gradio/_frontend_code/plot/shared/plot_types/BokehPlot.svelte,sha256=EuBqy6F3RnnCCiq6ZiOF2O81m7Uss1fcfxo676W0IoQ,2455 +gradio/_frontend_code/plot/shared/plot_types/MatplotlibPlot.svelte,sha256=f3xTCUAQtRIvtfpRAMCMQ4kUFNxxpXSNeFGWULFwhkw,487 +gradio/_frontend_code/plot/shared/plot_types/PlotlyPlot.svelte,sha256=ZLyJU2J85W-6-g7Wl9cVqQrk4_2qvqMmjleQVLvrWGU,1572 +gradio/_frontend_code/plot/shared/plot_types/altair_utils.ts,sha256=Mpu8beU9e3MJHgzAqqbimxri2gNstCZ0Ayh1dl47gj4,3426 +gradio/_frontend_code/plot/testplot.js,sha256=vQuBO46edgqcCuC9OenS4ywXpo8h63eKlS4BMFsBaEo,401245 +gradio/_frontend_code/preview/dist/__pycache__/examine.cpython-313.pyc,, +gradio/_frontend_code/preview/dist/examine.py,sha256=12KT78oknnY_T1T9brsyXPHLPIPf6TUCj9ua0RN_75U,2762 +gradio/_frontend_code/preview/dist/index.js,sha256=68Gb2oob631_olYxO-OxmmjcSvoSMKHk800SSDD1zCs,19057 +gradio/_frontend_code/preview/package.json,sha256=CIFSi-2Ygfebn0lfo97VpNDqoNoC8hjxSRujwiqK6ng,1349 +gradio/_frontend_code/preview/rollup.config.js,sha256=KSUxBuA_Qo_xZQ2e8LIFLO6PDUOGLHNwCdRc472uC5o,1156 +gradio/_frontend_code/preview/src/__pycache__/examine.cpython-313.pyc,, +gradio/_frontend_code/preview/src/_deepmerge_internal.ts,sha256=xS7DZQqOaux4CzaS6MWrbBm7L_WrnZODmg0Vo_vp_TA,3853 +gradio/_frontend_code/preview/src/build.ts,sha256=js6S7s4GmcZWLCCxMRLXveIkl8zPpeQnPz_pXsWMQ5E,2658 +gradio/_frontend_code/preview/src/compiler.ts,sha256=1youKuwUgwjYdGjjIEO9Mp1zBCkzfb7aKKUGpq6sNwc,77 +gradio/_frontend_code/preview/src/dev.ts,sha256=xX30RXu8-rSe-KDKbkHDJnmGkm3Z3BKx-hAUvC1UlIE,5022 +gradio/_frontend_code/preview/src/examine.py,sha256=12KT78oknnY_T1T9brsyXPHLPIPf6TUCj9ua0RN_75U,2762 +gradio/_frontend_code/preview/src/hooks.mjs,sha256=qSu36ayhEE5FZuhHtwufI_u6_o24a_zvkjSQ2tDHgY0,619 +gradio/_frontend_code/preview/src/index.ts,sha256=6m-mYaq1mkkuzLXqOYMn4FR-D5kX0cKLhoHD3VFETyk,5116 +gradio/_frontend_code/preview/src/placeholder.ts,sha256=RQ8K9PTB7MTHGA8uNkyKWb_tad01D7a0e86GQcKjd4Y,19 +gradio/_frontend_code/preview/src/plugins.ts,sha256=gBiqIULsW3tB5MHhUTFH0Nw-_4Bcdl1OQLpcEHRToaw,3490 +gradio/_frontend_code/preview/src/register.mjs,sha256=KGuBPFzyHGapIVZqUYuOnuWrWO3YS9jhb66jwr-oChc,83 +gradio/_frontend_code/preview/src/svelte-disclose.ts,sha256=4bzMWCf_qvoPa2Z_MLP6hxqH6i30X1yEUFo3S3pya_Q,64 +gradio/_frontend_code/preview/src/svelte-internal.ts,sha256=8kGRPgGcFDBSTQvbWzMXQzy51M0EiJfyW1sO2sdg0qs,46 +gradio/_frontend_code/preview/src/svelte-submodules.ts,sha256=06Tk_rtL9WF1yCcS-NfZLu_Co1psfWdnT_xOLb6hc4w,177 +gradio/_frontend_code/preview/src/svelte.ts,sha256=h0ivehpKJ8RpjiX3aoo8y5u26JtfMoC81s6QAkg_h6w,411 +gradio/_frontend_code/preview/test/test/.gitignore,sha256=lUCqIsnru6MyCYcyVNxrHNgGau-VOdtVPBJj6znCJYA,79 +gradio/_frontend_code/preview/test/test/backend/gradio_test/__init__.py,sha256=NUV_4fFy_iUQdtJRYaJYQc1hbvuLFZIEUs7m3TOfiOU,44 +gradio/_frontend_code/preview/test/test/backend/gradio_test/__pycache__/__init__.cpython-313.pyc,, +gradio/_frontend_code/preview/test/test/backend/gradio_test/__pycache__/test.cpython-313.pyc,, +gradio/_frontend_code/preview/test/test/backend/gradio_test/test.py,sha256=VibvmnbBR7Zh3zkQI-wdDOGdflg11wRMomjtQ0_OLdg,311 +gradio/_frontend_code/preview/test/test/demo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +gradio/_frontend_code/preview/test/test/demo/__pycache__/__init__.cpython-313.pyc,, +gradio/_frontend_code/preview/test/test/demo/__pycache__/app.cpython-313.pyc,, +gradio/_frontend_code/preview/test/test/demo/app.py,sha256=6pOjUQuHUkwqa0Xf2KhBrKQmIBptb6prYgbwdVzt2n8,214 +gradio/_frontend_code/preview/test/test/frontend/Example.svelte,sha256=Mjl0zFOVTmgdFkDshYl6E-OhXekoiPVVbef3aTnxinc,306 +gradio/_frontend_code/preview/test/test/frontend/Index.svelte,sha256=_Pv482yHKuND6QoRJIwMlyfbiC_eT6fegD3AERD9La4,3515 +gradio/_frontend_code/preview/test/test/frontend/gradio.config.js,sha256=avwvyTVoGw3KcO-HAH4Vfks25n_HYXlqXnUOPZODHYw,152 +gradio/_frontend_code/preview/test/test/frontend/main.css,sha256=QgcOC0W7IBsrg4pSqqpull-WTgtULZfx_lF_5ZxLdag,23 +gradio/_frontend_code/preview/test/test/frontend/package.json,sha256=DXWp0gmSZWbk5UbCGLLImH5xPQMR4FXywUsdWVRrFNc,484 +gradio/_frontend_code/preview/test/test/pyproject.toml,sha256=K2eulO3KEHaQMLIX7uxEgYY3lNHFcRl9CXGXHcM-w6s,1409 +gradio/_frontend_code/preview/vite.config.ts,sha256=hBZPwyiMY5bxXqrVMGKkgrvBCkZBaCnBirptfyDxvBs,994 +gradio/_frontend_code/radio/Example.svelte,sha256=Pk3i8KkqxvA4cE9c4QyJNgrSdGZ32_9WfkQ1qdykDmY,546 +gradio/_frontend_code/radio/Index.svelte,sha256=udxt1iFNcLz1VboYnMift5gw9ROoj83s_mFxiPPXtxE,2415 +gradio/_frontend_code/radio/package.json,sha256=I-dOzI_LQYIb2KGznwnmN_tTw_hAkfNjEHnn2ZbgNfE,884 +gradio/_frontend_code/radio/shared/Radio.svelte,sha256=LP6HXPTijaWocSMjgz6Ka7j_qbcmwE8yBBgUEQ-OfxI,3218 +gradio/_frontend_code/row/Index.svelte,sha256=p4i2HNR8b3fpPQOwywwA0hUR1Dpfcc2mjDhICD6idls,2592 +gradio/_frontend_code/row/package.json,sha256=T12oAt3Yf3OuF4EYrFrQlMv50Ji3pytpT-hWz82QWc4,662 +gradio/_frontend_code/sanitize/browser.ts,sha256=3RcbeOHPDDB-LGnEijCtk7oBySiVUMbr4GBe5A9-xSU,1178 +gradio/_frontend_code/sanitize/index.d.ts,sha256=C9XeUho_av3ZpP41tEOeZfaox69q5pHUnU2ra1lw5fY,58 +gradio/_frontend_code/sanitize/package.json,sha256=YZySkVoZcZ6N1sNnhCylpZqZHfL8KJJU4fzb06rUtbA,810 +gradio/_frontend_code/sanitize/server.ts,sha256=O6qw9Zk9I7urIGcEfmyWQbw6TpMSu9LseMGR6opvVXI,145 +gradio/_frontend_code/sidebar/Index.svelte,sha256=iicNwHgZOLrCM9u_WYXFzw5Ee9fRZhlnmGIuXlxJgi8,952 +gradio/_frontend_code/sidebar/package.json,sha256=C47mjZ_aMs_uiF2WObNZ5HSKyEuVTOooPqxDplct1K8,743 +gradio/_frontend_code/sidebar/shared/Sidebar.svelte,sha256=QP35Tn-WdFxz3OemCgHr1pRpEvn_wSDJDi4Y3iA_XmQ,5989 +gradio/_frontend_code/simpledropdown/Example.svelte,sha256=wjQJfKYjolyV2oOdtVyYPm5jbdMif-6K33dsBtVZn0Q,326 +gradio/_frontend_code/simpledropdown/Index.svelte,sha256=f8LY0ed_erUU6D68aMfw0AhQcisl0xbjuqW3tRjNS1c,2748 +gradio/_frontend_code/simpledropdown/package.json,sha256=jSsplmpEAbboPTpQi7iB7lLO0HU-9cLyIGXHp_oAiYg,909 +gradio/_frontend_code/simpleimage/Example.svelte,sha256=HlLcnCBkaLx8htqFFZgLvmg5z0l2rBEnTTdyzsxBSpw,873 +gradio/_frontend_code/simpleimage/Index.svelte,sha256=Rfr7AlVJwDdnrCg3IqVfgpg0aLbNNJx0IT6Kf4cQwgE,2789 +gradio/_frontend_code/simpleimage/package.json,sha256=9FCmriR_C2OBAxg-1dqTnIJdPXy1tgxKzptsKhs_ouo,1258 +gradio/_frontend_code/simpleimage/shared/ClearImage.svelte,sha256=Qv_wGNH6x5QqcWnIx3nyt1kGsNYdcaVTE4OG_IM3_0s,410 +gradio/_frontend_code/simpleimage/shared/ImagePreview.svelte,sha256=NVZi1INVM175UtVPq4buUBqMrwLcOBZQATi9eug5F2E,1404 +gradio/_frontend_code/simpleimage/shared/ImageUploader.svelte,sha256=8SzVAjT_rbI2hzXi7MfhCpdEkyZSyzP_9hjN2oyx_kk,2020 +gradio/_frontend_code/simpletextbox/Example.svelte,sha256=3eA1yghgue3384wHJbrQ-bTAfxkG7hOfrrnUfz7UdPg,1029 +gradio/_frontend_code/simpletextbox/Index.svelte,sha256=n2ilCEhvCUBsxyz9qU8sFwNJYLPPp7pJtZs0ClsQLUQ,3072 +gradio/_frontend_code/simpletextbox/package.json,sha256=DbNoqYHPM_i6E8AZu1kl1H31KoBmTwsmf14l-IwR8pM,907 +gradio/_frontend_code/sketchbox/Index.svelte,sha256=g-khPoc9-2FdiDpKg34Y7J3nZxGh4Jw3HvVEFVPjrHs,5224 +gradio/_frontend_code/sketchbox/package.json,sha256=noHP0iMZWMSDamzpZAFoU1tf-VDYa4svgK4k2oUK8-g,747 +gradio/_frontend_code/slider/Example.svelte,sha256=Mjl0zFOVTmgdFkDshYl6E-OhXekoiPVVbef3aTnxinc,306 +gradio/_frontend_code/slider/Index.svelte,sha256=n3-VHzRn1zELxFBW9QbeUTZG8dRZ42NKAGu3Fy-xjVo,8693 +gradio/_frontend_code/slider/package.json,sha256=1xsNJ-_hJ7rGnFLQkqV2ePSiCLfPBQl0pLprftMJy4U,859 +gradio/_frontend_code/state/Index.svelte,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +gradio/_frontend_code/state/package.json,sha256=THPKpvOqzelDRUT5vqPAUOoYiLZ5c8ZoKazrKxgI_40,529 +gradio/_frontend_code/statustracker/index.ts,sha256=Wfy2U5C39-P0SCQgUbLJMLI4Pi5F1NROjFTOiSre08E,342 +gradio/_frontend_code/statustracker/package.json,sha256=Bnp9LNPQlQUUkynr1sTCWfoO9p5v1HWS8ULDTntgoZU,752 +gradio/_frontend_code/statustracker/static/Loader.svelte,sha256=aFtAjnZyjNbBoVuA1d5VK4lALPEODpNGh9xxyx2pvms,2256 +gradio/_frontend_code/statustracker/static/StreamingBar.svelte,sha256=bXyPhnHvDeTrXfAfALOMNgrkvekOEMq5mLmPRO0P5Eg,489 +gradio/_frontend_code/statustracker/static/Toast.svelte,sha256=Du-U7_yFjmbVXI1q6nrUktL8xKcQb4vNGJi3D8CkYwQ,1421 +gradio/_frontend_code/statustracker/static/ToastContent.svelte,sha256=S1wWXYDjoT84WB32qtbuby3rdYYGobNCUdz1YurqXQE,6872 +gradio/_frontend_code/statustracker/static/index.svelte,sha256=R3W8PvVb1Uuc8_2BsHS_kOfab4m1b1BJiVAu7QeLyAs,11814 +gradio/_frontend_code/statustracker/static/index.ts,sha256=MLKfN6PI9VJz5T7BRa_1iRtXfWspUMbmkf2oPPaSja4,300 +gradio/_frontend_code/statustracker/static/types.ts,sha256=RCfrgfr2QLjYWjXQ_ZvQZsiAMJk2-N70yY0V-Ey-ZZg,681 +gradio/_frontend_code/statustracker/static/utils.ts,sha256=rTTvXnIG_uZoUoGkiTSmpxAOwY8AUqNc1JGvLbKWqbQ,273 +gradio/_frontend_code/tabitem/Index.svelte,sha256=dfhizbh1VaAcz6TSrO9jLP_6MbgxSrCFncqtXPEs7Rw,773 +gradio/_frontend_code/tabitem/package.json,sha256=jTQOqIDuhyL2sQicUY1wtEGPOl7-8btB6iT3VAZmW6Q,718 +gradio/_frontend_code/tabitem/shared/TabItem.svelte,sha256=OX37UhpYgBTDMsY4JWLz2nvlJ3qjMcofWxSd62U_vjk,1548 +gradio/_frontend_code/tabs/Index.svelte,sha256=FYwNJiDh_sXAOuemVJYu-CjF9ayTWMdwHZxMoZEt4Xg,1278 +gradio/_frontend_code/tabs/package.json,sha256=HbUJ9X-7HH3S4MVREIEbFx8wWvLtM1Dkg10BdY6pnZI,669 +gradio/_frontend_code/tabs/shared/OverflowIcon.svelte,sha256=vRKP_ejunMnZ1AVZ_ONSR87I4SghcYHDhOzKaZIdwIA,276 +gradio/_frontend_code/tabs/shared/Tabs.svelte,sha256=GZwC24ePTRZ5Bo8xuqEQ7Biy-Mg1rtqEno6FHJTee4I,9368 +gradio/_frontend_code/tabs/shared/Walkthrough.svelte,sha256=2G012bqXHNspNyEYekF3hTva-bjC0UnmDPa_yMBh_Xs,10050 +gradio/_frontend_code/textbox/Example.svelte,sha256=XHhHQWn6NqLV-OQ9BL5beJVPvgjLwDbERLwIdk7nZ40,990 +gradio/_frontend_code/textbox/Index.svelte,sha256=K4o3qN7iXOfe68VsKUk5MCP7LtbS2i3qfGdbDt-haes,3180 +gradio/_frontend_code/textbox/package.json,sha256=PJij5ypmP0CVGrOIznbv0AW6QdEzg1ONpZjqvf-pWwI,920 +gradio/_frontend_code/textbox/shared/Textbox.svelte,sha256=qkXwBRYG2MIl6luH_1Ogp81lIKd9Javyvgm9MG5Odx0,13470 +gradio/_frontend_code/textbox/shared/types.ts,sha256=X-PAu_LCsn2G2FLgoVWkTyBHOIW3D1GrGKF7ki-eu4U,399 +gradio/_frontend_code/theme/.gitignore,sha256=c0VSOMl92CCoW7YjoHLS_SNrpP3-iGq4BCQlSHOXzn0,24 +gradio/_frontend_code/theme/dist/src/colors.d.ts,sha256=jQczbOwOIISiIsTaQyaLpaR5HhJKQWRQP_IB3PmmjGs,1429 +gradio/_frontend_code/theme/dist/src/colors.js,sha256=zS6XUAre5fJkVnRxrbP7HV5smvHneSggOBy3_e7Q3N8,7384 +gradio/_frontend_code/theme/dist/src/global.css,sha256=y0bqFU4BnOp5qkkE1rmkjIZpA4L0DUc4wqi3PyW7_dU,5138 +gradio/_frontend_code/theme/dist/src/index.d.ts,sha256=PTu1SKUzyjw7fiR6EOtqzZiybRmL9V97vmg_iLeX8_U,29 +gradio/_frontend_code/theme/dist/src/index.js,sha256=5XUGDsapOhDOkRMNP9Hq8yumihw3Kqr6VzoK6wq9oTA,244 +gradio/_frontend_code/theme/dist/src/pollen.config.cjs,sha256=GhtCa4wuQSS7vjSDvjy3m-_gj6l9brJ0pIdzWj3Ho_Y,3047 +gradio/_frontend_code/theme/dist/src/pollen.config.d.cts,sha256=cR393jeEfwWNFohVtWopLwpUhAjiOSQqTF7OdOqNux0,5179 +gradio/_frontend_code/theme/dist/src/pollen.css,sha256=nrN8FCl0vQfkU-E8zV6CV2DpTzaeI6g-UpDFUtBC_UQ,9511 +gradio/_frontend_code/theme/dist/src/reset.css,sha256=B0Giqg3ZMW1h3vgEcGqob3NAzwVpfBuR1aX1xJ7uQAY,4358 +gradio/_frontend_code/theme/dist/src/tokens.css,sha256=iUDEzlkPEdZcKH-Cajla4xIWPIdvTGnV2k1DFz22a58,283 +gradio/_frontend_code/theme/dist/src/typography.css,sha256=vl4gf42qjJPQbd2Fp50b3ZUtvHkaEdOFGA3wZJODGUs,3345 +gradio/_frontend_code/theme/package.json,sha256=Ul9PeHzJMyM7LuhUuOWCG8opsLwDQWICICkPdt2oywI,1157 +gradio/_frontend_code/theme/src/colors.ts,sha256=EXcBXwPiNLhluRaadWLt7_BddPkRdFpfFjXzMYm4roM,6016 +gradio/_frontend_code/theme/src/global.css,sha256=y0bqFU4BnOp5qkkE1rmkjIZpA4L0DUc4wqi3PyW7_dU,5138 +gradio/_frontend_code/theme/src/index.ts,sha256=3G5ACUThUJr8kviPrQMDDGG_YSSbGxKOFeWQ6Nen_Jw,245 +gradio/_frontend_code/theme/src/pollen.config.cjs,sha256=GhtCa4wuQSS7vjSDvjy3m-_gj6l9brJ0pIdzWj3Ho_Y,3047 +gradio/_frontend_code/theme/src/pollen.css,sha256=nrN8FCl0vQfkU-E8zV6CV2DpTzaeI6g-UpDFUtBC_UQ,9511 +gradio/_frontend_code/theme/src/reset.css,sha256=B0Giqg3ZMW1h3vgEcGqob3NAzwVpfBuR1aX1xJ7uQAY,4358 +gradio/_frontend_code/theme/src/tokens.css,sha256=iUDEzlkPEdZcKH-Cajla4xIWPIdvTGnV2k1DFz22a58,283 +gradio/_frontend_code/theme/src/typography.css,sha256=vl4gf42qjJPQbd2Fp50b3ZUtvHkaEdOFGA3wZJODGUs,3345 +gradio/_frontend_code/timer/Index.svelte,sha256=fpkq0PaKnwqAwTunQFqqRROhfFv8kTH8uUo0cp97alE,651 +gradio/_frontend_code/timer/package.json,sha256=7BSZY_q-9Nlbgz2tHZ12lJ6t-AtMNg1fGJA8GFdD64g,646 +gradio/_frontend_code/tooltip/package.json,sha256=ByL-HVjWUFoSQa34niIWvA0TjTrAjhDP3Lc0NAr1REw,536 +gradio/_frontend_code/tooltip/src/Tooltip.svelte,sha256=XyPZX013BQRSi40hAHyywPuOT0fZH0ch0ezypo_NyBI,744 +gradio/_frontend_code/tooltip/src/index.ts,sha256=MeVSTP6c6rQ7Y63xIlhIkuA58HdJLszkJmrUSSC6y0w,37 +gradio/_frontend_code/tooltip/src/tooltip.ts,sha256=91aSYE8be1E6y6dfMwRpqhk1ou5g0nXh-O64ycojj2Y,1001 +gradio/_frontend_code/tootils/package.json,sha256=5unqILDtH8rZX7l69JEoV1NhzBqGOufX6Qpv-mX49Zg,489 +gradio/_frontend_code/tootils/src/index.ts,sha256=J70ISSG1sFVXyi8urbIrPdE415T8XJ95c1zcgICapAg,3130 +gradio/_frontend_code/tootils/src/render.ts,sha256=ZjQ18HW1OkLlhC702JCBcTQMm-6SH7QGJ2rwuKRN4nA,4575 +gradio/_frontend_code/upload/package.json,sha256=9JgQAHErM3Zc_C3kqkx75x8_RF_v8r8hjZzAGnHFnmA,656 +gradio/_frontend_code/upload/src/ModifyUpload.svelte,sha256=0KmbSTYeY4RHrshZxns0-4YAjLqBAGQHQrblljvV604,1140 +gradio/_frontend_code/upload/src/Upload.svelte,sha256=vcnchw6TeCSofPk0KpgL4xq1fh12gxoD-5CGG7ola-s,8690 +gradio/_frontend_code/upload/src/UploadProgress.svelte,sha256=MPTRJqR6g3hzPB3_IN77SukAETb1_J8W06oiDbEzle4,4483 +gradio/_frontend_code/upload/src/index.ts,sha256=ljt0pZMIyQKvFhmgH4PaisyJ6t1cKp6TFOz3b9ChcVg,226 +gradio/_frontend_code/upload/src/utils.ts,sha256=To-B4wTAH_DvfNi3ASBEUBMpxrs-olWjCSFLNhCPA0w,4146 +gradio/_frontend_code/uploadbutton/Index.svelte,sha256=tUMSoXbt-oQsXXqut5MzoWvIoMRmus7iTkCT4SXmbG8,1713 +gradio/_frontend_code/uploadbutton/package.json,sha256=kJp_KmZl86EBOFlUf6XRSrbFo-TuCJ_yB1NZ-QbpS74,793 +gradio/_frontend_code/uploadbutton/shared/UploadButton.svelte,sha256=_GAOZTMgohsjE2DOeHUi_2gV4egh1IVdjGMOcoCj6yk,3015 +gradio/_frontend_code/utils/dist/src/color.d.ts,sha256=PtN4fKm9o5nZU9gfPbgG_jcWo-tAYqjxNUE6RTjJd74,117 +gradio/_frontend_code/utils/dist/src/color.js,sha256=K3wptCQXL7q1HKCxjty3LcQTlnfbcXGyc4P6SwLtDTc,160 +gradio/_frontend_code/utils/dist/src/index.d.ts,sha256=TemKs2Whqo7i4Ro4ZF3ybGN00Ec_xZfa0yjcGIjelyA,56 +gradio/_frontend_code/utils/dist/src/index.js,sha256=TemKs2Whqo7i4Ro4ZF3ybGN00Ec_xZfa0yjcGIjelyA,56 +gradio/_frontend_code/utils/dist/src/utils.d.ts,sha256=VfXXIJ6P9aPBoON3Fsh6DuCWdujLb0MRJ_G2vi0EHN8,2245 +gradio/_frontend_code/utils/dist/src/utils.js,sha256=gcXReVDG0Iy_FqMG4Wx4b-_kuHUItRF6OOXJTE0chD0,5949 +gradio/_frontend_code/utils/package.json,sha256=2y9dsCLrzuiXEWbMlGO7ZVu00T32cutqLKdxwBbPdSo,622 +gradio/_frontend_code/utils/src/color.ts,sha256=szs0PWQ_4BkJVpVv_xUFbj1OWehK4D5MrK6hhlefswY,187 +gradio/_frontend_code/utils/src/index.ts,sha256=TemKs2Whqo7i4Ro4ZF3ybGN00Ec_xZfa0yjcGIjelyA,56 +gradio/_frontend_code/utils/src/utils.ts,sha256=a_EcsKreb8L354bbm1eSiG2OomLcbEPqA0nkBooE_zs,6814 +gradio/_frontend_code/vibeeditor/Index.svelte,sha256=kHYob7esgU9jg1JDRdE2vB2MRuwVu1ef9BPkmWLmvP0,18622 +gradio/_frontend_code/vibeeditor/package.json,sha256=UqodWnxMMZgKvIhF-OPg95IZE_0XB-Eesl6Rnq88XRw,838 +gradio/_frontend_code/video/Example.svelte,sha256=lLdOItXcu91QWPIjDS7cU2PRBG_JJzXjble7FfwT75M,1587 +gradio/_frontend_code/video/Index.svelte,sha256=cYUOkfoXZo8pAfm4-CBO4WFhpsrTo73nKFNHD6sPmbE,5757 +gradio/_frontend_code/video/index.ts,sha256=z8qzgqYKynBOk6Ri4ezpk_kLZ6sgAYA_p948Xl0KEtk,419 +gradio/_frontend_code/video/package.json,sha256=7sozfEdvewB_8j9PboBtUCBCMlmqS5v9h46EMTUki6o,1406 +gradio/_frontend_code/video/shared/InteractiveVideo.svelte,sha256=QdZw0qh9Gs5I_cEQoORhTT9rWvuz9N0sPpMRbyHb9WY,4202 +gradio/_frontend_code/video/shared/Player.svelte,sha256=h0lSpc680dSvxRio6omYVNO8bab8eVuRL-6ZthLmPc4,6223 +gradio/_frontend_code/video/shared/Video.svelte,sha256=jLZ6DVI1P3fD2Fhhkr0UA-CLRym1cLViUrlR6ao2Sb0,4718 +gradio/_frontend_code/video/shared/VideoControls.svelte,sha256=Do1vcIHJbDg0B6sUvxXSaG6VW08_zRtnbJ5bceehFU8,4265 +gradio/_frontend_code/video/shared/VideoPreview.svelte,sha256=elNKpHLsjZhwUDXHXZlrXcUv2tbqezFw864WbuTBhXs,2983 +gradio/_frontend_code/video/shared/VideoTimeline.svelte,sha256=kAZKek_soHplXYrjMu3K50nt2ywnm0iRRbMo7G_Um18,6851 +gradio/_frontend_code/video/shared/index.ts,sha256=y2Ysps8mncaAIp1T4uvUfOasvkoIJtAISBNwpWDF6XQ,51 +gradio/_frontend_code/video/shared/utils.ts,sha256=8_S5DteGo22jYXHQ8r7MkXZyxyR53MNuH6PkGmTRqFA,3821 +gradio/_simple_templates/__init__.py,sha256=Gch9wDUHBu3eMMRKYdGrkLTJuqckvLSMT6tbsNs8Z2M,183 +gradio/_simple_templates/__pycache__/__init__.cpython-313.pyc,, +gradio/_simple_templates/__pycache__/simpledropdown.cpython-313.pyc,, +gradio/_simple_templates/__pycache__/simpleimage.cpython-313.pyc,, +gradio/_simple_templates/__pycache__/simpletextbox.cpython-313.pyc,, +gradio/_simple_templates/simpledropdown.py,sha256=Y_UTEs-2m35vUMhWB40HLt9MMtHN00-8jOHJRotv9uQ,7032 +gradio/_simple_templates/simpledropdown.pyi,sha256=csyuLi-JwqX4rzE0j5bq1lmazx6Uvc9yhI7p9HfVTjk,27196 +gradio/_simple_templates/simpleimage.py,sha256=xv_3NcT67VT_tndGLLKRvQ0vDB-lei1r-goNx3k74lY,6331 +gradio/_simple_templates/simpleimage.pyi,sha256=_i107U-eEyYTwtMhbxi8GYKOuBzAc47GuqprnCT58MU,26495 +gradio/_simple_templates/simpletextbox.py,sha256=UEljR3RinDiNDOlNBg0MKQG9c_1GGVptIi55uaQ5C_I,5855 +gradio/_simple_templates/simpletextbox.pyi,sha256=qWBsXnIz5Kr6QyzL-COqaNB9aw9E7-vTQV_3E7QBVWc,26019 +gradio/analytics.py,sha256=usmseQS8fq9f0IAmgnoU-japGaPkTUW5w4x-H0f-jL4,8000 +gradio/block_function.py,sha256=TUNTNECEjXzKh7lpssid-bWTo8ISPykR0eO3Aw4exGk,6689 +gradio/blocks.py,sha256=Cr51TblircQqANSt-a73WRhNlhfu4zrwV-pOGO4u4HM,146720 +gradio/blocks_events.py,sha256=K7qyl6qji8_e4eV5PbbOUmOWNlBWnPLaZIx45bFZP5E,911 +gradio/blocks_events.pyi,sha256=hg_FKLZMd0RYgCfXbLiMO6z75pssc5FOyA14L-q-gL0,7806 +gradio/brotli_middleware.py,sha256=cwpp_kX_oye4bWqUfuIG557sC8ogy7vVn0A22k-4H5Y,8782 +gradio/chat_interface.py,sha256=42yOAETePVRA18Da4L5nqlycp0fc8xwMuHDUb90UGgE,54565 +gradio/cli/__init__.py,sha256=LCZZt6fpSgLtZAfmLowkyuIdEEWEeTBgZOCaAYeWDwI,135 +gradio/cli/__pycache__/__init__.cpython-313.pyc,, +gradio/cli/__pycache__/cli.cpython-313.pyc,, +gradio/cli/cli.py,sha256=7Qdccxpd-SSp2n2GBjdky7VOw9-vvNJ8tDVsadaXskQ,2418 +gradio/cli/commands/__init__.py,sha256=EjKVyXEq3YmESYELtm2KFkenWvfGA3kT7ou9RCMxlzE,464 +gradio/cli/commands/__pycache__/__init__.cpython-313.pyc,, +gradio/cli/commands/__pycache__/cli_env_info.cpython-313.pyc,, +gradio/cli/commands/__pycache__/deploy_space.cpython-313.pyc,, +gradio/cli/commands/__pycache__/display.cpython-313.pyc,, +gradio/cli/commands/__pycache__/hf_login.cpython-313.pyc,, +gradio/cli/commands/__pycache__/load.cpython-313.pyc,, +gradio/cli/commands/__pycache__/load_chat.cpython-313.pyc,, +gradio/cli/commands/__pycache__/reload.cpython-313.pyc,, +gradio/cli/commands/__pycache__/sketch.cpython-313.pyc,, +gradio/cli/commands/__pycache__/upload_mcp.cpython-313.pyc,, +gradio/cli/commands/__pycache__/utils.cpython-313.pyc,, +gradio/cli/commands/cli_env_info.py,sha256=9FPHcCAP07BUSztYnR6KTqeVZ5qkJ6v3yKadUDZusy0,1544 +gradio/cli/commands/components/__init__.py,sha256=jArxVms_ZS6eug_h3jSt4pbNpU0XFAAkZ_qbrA9Xrk8,40 +gradio/cli/commands/components/__pycache__/__init__.cpython-313.pyc,, +gradio/cli/commands/components/__pycache__/_create_utils.cpython-313.pyc,, +gradio/cli/commands/components/__pycache__/_docs_assets.cpython-313.pyc,, +gradio/cli/commands/components/__pycache__/_docs_utils.cpython-313.pyc,, +gradio/cli/commands/components/__pycache__/app.cpython-313.pyc,, +gradio/cli/commands/components/__pycache__/build.cpython-313.pyc,, +gradio/cli/commands/components/__pycache__/create.cpython-313.pyc,, +gradio/cli/commands/components/__pycache__/dev.cpython-313.pyc,, +gradio/cli/commands/components/__pycache__/docs.cpython-313.pyc,, +gradio/cli/commands/components/__pycache__/install_component.cpython-313.pyc,, +gradio/cli/commands/components/__pycache__/publish.cpython-313.pyc,, +gradio/cli/commands/components/__pycache__/show.cpython-313.pyc,, +gradio/cli/commands/components/_create_utils.py,sha256=HwEeZNd9ewz9YWisld9xNGhIorjxHnzbsEsqg-BkTbE,13813 +gradio/cli/commands/components/_docs_assets.py,sha256=Kp3uZ5KPczZAykGilW-KSomI5ltXFWWsfvSOahF-kXY,2556 +gradio/cli/commands/components/_docs_utils.py,sha256=CmykZXJPwmUbGdU3OtH0zgNe_z_UwvNS4c_kgwOYUlY,27774 +gradio/cli/commands/components/app.py,sha256=EPduChTv9dnpzi0Ru7K-CdRFME7TnFBjT0T2NhwGWps,910 +gradio/cli/commands/components/build.py,sha256=8SFlhs06Vfqb5MkKavbNb4h-FBqxGlq9_Xe_cEpBxIM,6701 +gradio/cli/commands/components/create.py,sha256=ydMoe1A6yBpyK3xLM5VRtEP2zlz9T9ygeM-YdT8Hy4Y,7377 +gradio/cli/commands/components/dev.py,sha256=367STeAoq8Alk1F9srPA_GepgVtjgsnVG3Ub491ePeQ,3982 +gradio/cli/commands/components/docs.py,sha256=JgHKfCsYKYt83xmBFIWC96Og0Xo4jynAEeRL_Ss-T6U,6884 +gradio/cli/commands/components/files/README.md,sha256=H2sQSrGi_n65JlmkMsz2KYWJT4Wyn2EwEQOSvyFZzeM,352 +gradio/cli/commands/components/files/gitignore,sha256=PpQhmvGKrGI5Mt5YbNvGKjVW0LD6SoiTDXQ59dOOhI4,124 +gradio/cli/commands/components/files/gradio.config.js,sha256=a2pxGcUNNaW5sWifOFr9tTpVQaY1Ecbdm0_7S7RUiw0,110 +gradio/cli/commands/components/files/pyproject_.toml,sha256=b-ygjFrbbXycPRqJOryfvHofOT_z7aAeOBHxVpxZzns,1727 +gradio/cli/commands/components/files/tsconfig.json,sha256=DtuyCD1JyJMtsjU7bf7KVc3-Es2sjKrvHVxBoRBCNUw,321 +gradio/cli/commands/components/install_component.py,sha256=88qlVYTGMV6NV4xbIXXJZu4kJLt2RWroAHxOnT4c9Ys,4001 +gradio/cli/commands/components/publish.py,sha256=xpE90sDWbDZrWvdKTVDgGQq96uIYFIUXUW-i3TBJTW4,11718 +gradio/cli/commands/components/show.py,sha256=MKx04ZPuwxMzKo8H26ZjvIFy8R2G-dceAwuH0Ms0uCs,2241 +gradio/cli/commands/deploy_space.py,sha256=iRVbWMGNvNWZTorkhc8639YHNjZsxqvwsg_l2PWCIQY,11012 +gradio/cli/commands/deploy_space_action.yaml,sha256=H8fTuoaAsRaGwjBgM_q81NgW8NTHCNdXw4nhOVYNifg,541 +gradio/cli/commands/display.py,sha256=Qjj3q_6Hxvo_NEIYYvWMgxOY8xaq5dkAtB7mQp202Xs,845 +gradio/cli/commands/hf_login.py,sha256=imuqi-EKcKdERGA9zzU3GDzFPW7Ivl77p2lBa5eaJKo,1693 +gradio/cli/commands/load.py,sha256=VsbB23fndVWu3OFITdaTpB46uqwlcCgVTCkjkreR1JQ,260 +gradio/cli/commands/load_chat.py,sha256=e08iIu6qpL7uAstHeIufxS-DCyTNjPb00MfJlhlZ66k,1798 +gradio/cli/commands/reload.py,sha256=7fhnnwmnstNfMON_2mcgaJSfZgqAJfsxzh6DULCyE7U,4598 +gradio/cli/commands/sketch.py,sha256=nG8Yv6pcNSGSI4vvxJ8BV1M9pBXfA8AK-YNzzERLKUI,796 +gradio/cli/commands/upload_mcp.py,sha256=3pd6nKXa5TIEF91bi-ZR35YeygvxyQBrMlrxHTH1XdY,1395 +gradio/cli/commands/utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +gradio/component_meta.py,sha256=3i5-TjfpJTAyxj0G_9zuddrkYV6Vwbw8JFn7RuVnfPU,12669 +gradio/components/__init__.py,sha256=SlsU4qVaAAsYJRXWamnSf9o8ZfML2iYpXSxUzSevs3g,3871 +gradio/components/__pycache__/__init__.cpython-313.pyc,, +gradio/components/__pycache__/annotated_image.cpython-313.pyc,, +gradio/components/__pycache__/api_component.cpython-313.pyc,, +gradio/components/__pycache__/audio.cpython-313.pyc,, +gradio/components/__pycache__/base.cpython-313.pyc,, +gradio/components/__pycache__/browser_state.cpython-313.pyc,, +gradio/components/__pycache__/button.cpython-313.pyc,, +gradio/components/__pycache__/chatbot.cpython-313.pyc,, +gradio/components/__pycache__/checkbox.cpython-313.pyc,, +gradio/components/__pycache__/checkboxgroup.cpython-313.pyc,, +gradio/components/__pycache__/clear_button.cpython-313.pyc,, +gradio/components/__pycache__/code.cpython-313.pyc,, +gradio/components/__pycache__/color_picker.cpython-313.pyc,, +gradio/components/__pycache__/dataframe.cpython-313.pyc,, +gradio/components/__pycache__/dataset.cpython-313.pyc,, +gradio/components/__pycache__/datetime.cpython-313.pyc,, +gradio/components/__pycache__/deep_link_button.cpython-313.pyc,, +gradio/components/__pycache__/dialogue.cpython-313.pyc,, +gradio/components/__pycache__/download_button.cpython-313.pyc,, +gradio/components/__pycache__/dropdown.cpython-313.pyc,, +gradio/components/__pycache__/duplicate_button.cpython-313.pyc,, +gradio/components/__pycache__/fallback.cpython-313.pyc,, +gradio/components/__pycache__/file.cpython-313.pyc,, +gradio/components/__pycache__/file_explorer.cpython-313.pyc,, +gradio/components/__pycache__/gallery.cpython-313.pyc,, +gradio/components/__pycache__/highlighted_text.cpython-313.pyc,, +gradio/components/__pycache__/html.cpython-313.pyc,, +gradio/components/__pycache__/image.cpython-313.pyc,, +gradio/components/__pycache__/image_editor.cpython-313.pyc,, +gradio/components/__pycache__/imageslider.cpython-313.pyc,, +gradio/components/__pycache__/json_component.cpython-313.pyc,, +gradio/components/__pycache__/label.cpython-313.pyc,, +gradio/components/__pycache__/login_button.cpython-313.pyc,, +gradio/components/__pycache__/logout_button.cpython-313.pyc,, +gradio/components/__pycache__/markdown.cpython-313.pyc,, +gradio/components/__pycache__/model3d.cpython-313.pyc,, +gradio/components/__pycache__/multimodal_textbox.cpython-313.pyc,, +gradio/components/__pycache__/native_plot.cpython-313.pyc,, +gradio/components/__pycache__/navbar.cpython-313.pyc,, +gradio/components/__pycache__/number.cpython-313.pyc,, +gradio/components/__pycache__/paramviewer.cpython-313.pyc,, +gradio/components/__pycache__/plot.cpython-313.pyc,, +gradio/components/__pycache__/radio.cpython-313.pyc,, +gradio/components/__pycache__/scatter_plot.cpython-313.pyc,, +gradio/components/__pycache__/slider.cpython-313.pyc,, +gradio/components/__pycache__/state.cpython-313.pyc,, +gradio/components/__pycache__/textbox.cpython-313.pyc,, +gradio/components/__pycache__/timer.cpython-313.pyc,, +gradio/components/__pycache__/upload_button.cpython-313.pyc,, +gradio/components/__pycache__/video.cpython-313.pyc,, +gradio/components/annotated_image.py,sha256=QKNlaHJB7BOZh3gWvp5ZuG35ldVOCevUyKDvkTX5ekw,12247 +gradio/components/annotated_image.pyi,sha256=5sDEhWZuS5-GCbblhHtKGv3V7GN_u78znEFnCdhsnYk,19144 +gradio/components/api_component.py,sha256=hJjDwzRTo-UTXPmiDT17XqkTLpLC1vca0GDwbEJnK8c,1124 +gradio/components/audio.py,sha256=v9Xh5jKJ6BljmTJbUK6tYxTLNN-GAQSGDV7DwMhXt40,25961 +gradio/components/audio.pyi,sha256=4AVjak2G7JtN9DYR368pr3BP_Fi0q741kEbLKx2bOhw,106238 +gradio/components/base.py,sha256=zKapqmUVkjqwEMu3IlILKEBQYu61lDP4b6d8VLFprF8,17476 +gradio/components/base.pyi,sha256=wkqIGiL3UayRryKW_9dTHmjlFA-jialX_AF0sHIDAgU,18190 +gradio/components/browser_state.py,sha256=n_9C81_msV4Ck6JMVDtw2Poy9dFSLcw8kDs_f-vKjsA,2430 +gradio/components/browser_state.pyi,sha256=Dn32-e9YvW4AV7WVqfqGwN79ciIVcUih4bEja3F0FMg,9327 +gradio/components/button.py,sha256=-CLqnmU_MbtmMfRngS4JYnTI0IjWC-DnF-pI5heGP0o,5809 +gradio/components/button.pyi,sha256=pqpm8nmziJOVgp_Ev8T89vNdsvyHbVUAt8-TpfKyP14,12705 +gradio/components/chatbot.py,sha256=seo1uzA_5BKAaIMaizUxJMjOJvlH50YlFpTgPAzMxRk,37042 +gradio/components/chatbot.pyi,sha256=Wu1au6z_Pe_rZaV3REdQORs6IFASxVAbo4SKjnWICEw,103807 +gradio/components/checkbox.py,sha256=PdZS0BamyvE0t2kPP1eOnHGT-qwmZV2ZfY48UzT1-Y4,5957 +gradio/components/checkbox.pyi,sha256=Q8Q6wfsL9mj9Om8y_EWgdnIqexRwEW2pytLFyEE872w,26121 +gradio/components/checkboxgroup.py,sha256=JzTjb3czxCaIEtFhG6h_uV-s9R2Jc_jT5jR7zw6qQHI,8815 +gradio/components/checkboxgroup.pyi,sha256=kJip_tIYv-f5qiwO3jtUhgUsQ7A4y87W65QDqtJ1amU,28979 +gradio/components/clear_button.py,sha256=SMZObxMnUNvA08SJ-mvfsMEXc-ehi-XlUhPD2Gct-T4,5048 +gradio/components/clear_button.pyi,sha256=4G0dY1PEGsa3dBKxU6vIo3DGXnf5keseK2yODLNmlKM,5310 +gradio/components/code.py,sha256=RSs205WLban0QJ56-g_-7vClvCsfoFt3FLZ_KYYTass,8483 +gradio/components/code.pyi,sha256=CuDWWWLrkj0fdtUVfTU_gaJJlmNQv_rWKatm4CkbHg0,35278 +gradio/components/color_picker.py,sha256=Lov3tMvhmZRE55swkpH2alkT7zBbEca1J0miWspPNQw,6150 +gradio/components/color_picker.pyi,sha256=RhBeYIuYbNM4vPXN8yvP-sYokrsIvG7EpWHlDtKQ6ZE,39579 +gradio/components/dataframe.py,sha256=uejOA1RdmBTVlmrNTSsIeHqGwS_3mrPyHq8FjZXPWRQ,29653 +gradio/components/dataframe.pyi,sha256=8TUBnrXI-rJ8Oijrn_xlZSZ0_j61MnuQdj_OzJXG_mQ,56449 +gradio/components/dataset.py,sha256=BkAW0w3u04_xxlocvAFBvlkGjavCe4jOeH6Pl5UE5xo,10535 +gradio/components/dataset.pyi,sha256=NTuG7LMRKx8ESofQO7YaCJMb-IhZIepfdoDIbUyhJg0,24065 +gradio/components/datetime.py,sha256=A4UzTNjPvQb7TER_7NQN15-T3LakFKeMtE10JQNcdTE,7907 +gradio/components/datetime.pyi,sha256=PPSmZxA_a06VPQIqfu6nvh_vlqPv7RJtSJrKPC9VhJ0,21438 +gradio/components/deep_link_button.py,sha256=_rbcvI1rPk7pbAkKOUtei6TFW_UWKMFd5vR71bOEFgk,4511 +gradio/components/deep_link_button.pyi,sha256=r3ZRv3YIUFaAZDuFi4Iyb4QN0BkHpSUR1XSbPQlbuf8,4773 +gradio/components/dialogue.py,sha256=xirgqqPHCZaOxb_GOUfhmCXdad4OTlhgSp3BzLFy1H0,12689 +gradio/components/dialogue.pyi,sha256=ii73-OmbIXzfoyGid6vdwEQ44JpHJXbUEzO90uCxZl8,32853 +gradio/components/download_button.py,sha256=K1gGVd2_Nz2wlEDMFMpDA8AMs8qsQWSjzc8TFRwO8aE,6109 +gradio/components/download_button.pyi,sha256=Um55zzoc8IBWvfpKvZ2DxqgNjnUk8dAeg9NI8fP81ZY,13005 +gradio/components/dropdown.py,sha256=nHvgwk-vCJkUvZJKcuZ1NkNprlixqXoGclttr_diaXA,12055 +gradio/components/dropdown.pyi,sha256=oIa1Vi9j4XyIg2Ne-3sFVkl4svwPZkKw4Sj32i_40PY,52118 +gradio/components/duplicate_button.py,sha256=JMWjQEMOyIetsnn-i8s2XaqLmdQMa7Py-Nc3aI6Y0dA,5341 +gradio/components/duplicate_button.pyi,sha256=gEC1vz0uy2XrDQCxHDjgPQNRUUkYXF0zBpXY-DCmkU0,5603 +gradio/components/fallback.py,sha256=V45NWD4dds0na0EJk2dSy1qB14RSBrU4OamGHib8GSI,994 +gradio/components/fallback.pyi,sha256=2rgYjSB73azsQZr1CJjqPz-9ENehgWsGK4Nt9Z_oJTE,1256 +gradio/components/file.py,sha256=U7C7Su5NUqNeh8C5wuY4zmuydV3pHj1eGWpRJkrE1sY,12675 +gradio/components/file.pyi,sha256=7O9SOxFDGe0LEaMqBo2GSiJbYxhxwH6RMfKaWTAbILM,52743 +gradio/components/file_explorer.py,sha256=KLcU3sYedsvRW9KjeISDRklGCvvmsZshSXpy9gShwAk,11555 +gradio/components/file_explorer.pyi,sha256=wXOcrGhIz6sS4qvgWWFpfy135_bItVE5LeSaN9jzkUQ,18452 +gradio/components/gallery.py,sha256=DDjJzdpmKUylPwFmVoK7lSN2DiYfEsz5ZB4jnDYHDIU,16796 +gradio/components/gallery.pyi,sha256=EpnaxDKtT-10ZfSBjmieIpZ6_kIaUvOGFQSDebmvTk8,56876 +gradio/components/highlighted_text.py,sha256=muBxTnFLILOA8Y0B6-e700iRhugGfRnbz5DwYsAe7y0,10431 +gradio/components/highlighted_text.pyi,sha256=O-9UadlLmuCaXAdfl-hrG1ZYBuW0TUk2vVebk34IUA4,23962 +gradio/components/html.py,sha256=IzuK05zlZoAL4H1FwOxeHBAyjp6PYBxOY6_ZFXJGE3I,6263 +gradio/components/html.pyi,sha256=iubSpFXQrzia6I1DspivrQQvIDMfrOPRxZ5cPderJRQ,19793 +gradio/components/image.py,sha256=qKSukybGBFj7m4ZubSBdkX1BgM8J9jJskHOTZYuTyAk,16671 +gradio/components/image.pyi,sha256=pLYSYhTwLYY3EKkFSUdakZvUe4tqT4fBs2kod5Tvn4s,57124 +gradio/components/image_editor.py,sha256=yqfaialhQPVRi6sM8eovQV8HoD4GyHvqR_W8xuLQ5HA,27234 +gradio/components/image_editor.pyi,sha256=NDZYD99SnokKx1rwQ1FN6PD24oUHbAZhcKJ99eHz3z4,67298 +gradio/components/imageslider.py,sha256=YBK2FJROa5QKhJd43P2EsnIYgt3QB4txi2XtJXTHgCI,12067 +gradio/components/imageslider.pyi,sha256=8KGB9Exb5aAzIPMM5YzLXjshTJWiTW1I7ACmRxdxFBc,52520 +gradio/components/json_component.py,sha256=KY6DCEnUqy-MgO4QfXiB1cnDVHqeXqR9e8GvkwXN8fo,8158 +gradio/components/json_component.pyi,sha256=g_IS835IXu7EnucQDHHJsLBOU97B5uTtYqruhvURvFg,15055 +gradio/components/label.py,sha256=rWVLvSclOJi_VEjdEwhNZBzuHDnpDyY_9TVwxM7jDUU,9045 +gradio/components/label.pyi,sha256=bLDNAI9fxxot8vtCFKcZoL41gc7Xyn0czQHctgMT9rI,22576 +gradio/components/login_button.py,sha256=hxpEgZYHHOrv6zg_dE7UcNNHIqS_Vu71IcNsPbUHXQo,5090 +gradio/components/login_button.pyi,sha256=FoBdch3PQyTdUr3QbjwGZIpqrv2UfZ4xpHlPR8yXg2s,5352 +gradio/components/logout_button.py,sha256=1FvgNoTj3RtsiukXZghbBzB7YDbCyBseYyHnxE2axLg,2397 +gradio/components/markdown.py,sha256=pE10O2G2KcOLY2AUFdS-w1Zgrq4k2zKuwNMx2Ul6GEU,8730 +gradio/components/markdown.pyi,sha256=DcrCgikCxKVv7i4A3-u1Dxmc8pMumwaxx-LY5bIYqE4,22259 +gradio/components/model3d.py,sha256=N5mkCgvy3pAsq_wf8fqv3j8IjY1-JG5IsYWbReBdyhQ,8610 +gradio/components/model3d.pyi,sha256=BT8HwmtwbUZSxe77fYNFIMxGLDwg7FP5HL5MLXh_oqQ,35406 +gradio/components/multimodal_textbox.py,sha256=SiHEPPLJ32WAKMh6CrglNGgM1rwxFI7Gk8y0Lit8qqo,13899 +gradio/components/multimodal_textbox.pyi,sha256=hfchZlJHi2VM5tdmXbUj6EbrrD_Q0FG-6KLNEbfc-r8,60594 +gradio/components/native_plot.py,sha256=adNEqOfczSW1NPrBbaxsEPAgU_uVjSHwjakLgNKRIBg,12762 +gradio/components/native_plot.pyi,sha256=UTxNtJ1bRLZlQBFqWG7AdTnOAzfWe6d0wx3j--FrLWo,26977 +gradio/components/navbar.py,sha256=qDx6DUyiwLdBvpi_CGiNS4cXmZx0YRr1h55fqqoEb4I,3844 +gradio/components/navbar.pyi,sha256=-nue8bRUYSlyWRl2BI9UirVHVQ7i90SVvc871gLJx4U,10741 +gradio/components/number.py,sha256=SgK1xQR_UD0_Jo6F1LcWRO0gHLa8Ni9UyfJJzfYkrvs,9044 +gradio/components/number.pyi,sha256=KnT-jU7Lm2LJjBuJT_s8hTVSd0zyyXEJyBUT8U7S7PI,42473 +gradio/components/paramviewer.py,sha256=avgPWfNEiLOCk-C5SghORyrr7JMSK-x-G0oOIzAkON0,5977 +gradio/components/paramviewer.pyi,sha256=gttT-y_W8OCP7HoY8PdCh_uaQeHbAJ-w8e3snRXNsOg,19508 +gradio/components/plot.py,sha256=TAK3wbvmBO6TuyuIAQ9j2DNcOgNCqg5FeD7NB98_wyY,7874 +gradio/components/plot.pyi,sha256=ZTal2VNTMBjLhOA7DZ6PP7cUIKOGEmAPBhywN2WC1lI,14771 +gradio/components/radio.py,sha256=wwqyXLG5xCF8heEDR4l9FBQHM5fmCCUdFJfmsnnklb4,8251 +gradio/components/radio.pyi,sha256=myZ0q6i3B5xMYUgzn09h2oSZGCXsSMUO0NTqRtxNdMI,28415 +gradio/components/scatter_plot.py,sha256=X6DigTQsIj8DPQAhsNWxLeXuvn4lr01iME6erKjoaQM,17033 +gradio/components/slider.py,sha256=4pst3UqrMlCOOmpvjkEJCsGdAqQi9cVnOgHtallhnzo,8786 +gradio/components/slider.pyi,sha256=uMhC5-yHVGvJSLe8HbOR3L1djcG4cjD5LSWkZz82Q7c,28951 +gradio/components/state.py,sha256=rIsrbHUMUFEGRQ6x4dDGQOAod9MzmEu0eEtD_N3OveA,3447 +gradio/components/state.pyi,sha256=Y3cbdE3ZxkyOF56cz3Q__Vv1Trmc3cNOltO4Z5C-sbg,10344 +gradio/components/textbox.py,sha256=XUYzDmKwrKM-5r_3hcXI-WRGZJQBrlc1yH4gzNN2ox8,12402 +gradio/components/textbox.pyi,sha256=Wu7tN9ZLJ4EmnGCLuL3SKskL5EYnEktrU5mX52k7rRw,65729 +gradio/components/timer.py,sha256=ffFh4pQTmLdEbqzILRWeQUCfr_c-o6NA7hDHG3IZTuU,1909 +gradio/components/timer.pyi,sha256=uXOQBUmRR41ajCtSl_SCE6xlpRRNHOm0zeh6QbvPY9M,8804 +gradio/components/upload_button.py,sha256=F29fyZXRPFzrOBPV5QJB7f0GQjna6pqiW_OXcB7Ig5I,11477 +gradio/components/upload_button.pyi,sha256=UaU66qnzjPnf6YgeR8F4BKBMYy77Sya3LB8vm6Buars,25007 +gradio/components/video.py,sha256=eYkSxMv1q2VG5jm3UHH-8qS18SEJ0hCcJo57IdayAqM,30179 +gradio/components/video.pyi,sha256=mP9see65lFallySBB20nyyA9vi7IeBZt0dcIcO9Jiw0,90156 +gradio/context.py,sha256=mFJ4PLGYaMGkZSAFaLTayrEd9HRVeBMgpEMIG3S2sR0,2121 +gradio/data_classes.py,sha256=bYh-a_DU3wd2ig_VHhfHKtQ7oHE8-LLSLfEroVzLP7I,12773 +gradio/events.py,sha256=tKhCUBeWJ9uRDJT2VoMbFWqcLIEhgNYr8zxrik4pF2w,59758 +gradio/exceptions.py,sha256=XmDDxrprFoTVeJHRR3s54f9EyQqaN2pV8PKIFYCs93Q,3275 +gradio/external.py,sha256=YWvE_kmp747hwgYshwmLe6_luDdcYSwSOZNJYEUooSs,42912 +gradio/external_utils.py,sha256=MpAl88J_XH4Nd1L8T69HlGh9UPuGcpRgjqE4tp1sCs0,20589 +gradio/flagging.py,sha256=LszwWr1mRrGLv48swkCA1pv2p2MElsUwivh2ZahCsdw,15361 +gradio/helpers.py,sha256=kepdMlX72CEYYEWCiCFBg0XRhUg2fDwibp2fVO3VVLI,54788 +gradio/http_server.py,sha256=SvaaN8WXcrQhsbIJeXEUVx0QNnkZ4LiEpo1kpaHEMXw,7060 +gradio/i18n.py,sha256=aFRvfQ8kb0WuQsEEybOnp5ngNHs8E10cHuM20AWr6y0,4610 +gradio/icons/README.md,sha256=p_N7_BGQNMOL8ZhLKU0v2aTd6JKx9TudGNGWTVJGAbE,152 +gradio/icons/huggingface-logo.svg,sha256=NhPHPwfMrhkRi_5tL4zRJxg9CM-ZRopwjgkJU-EW7Qo,4634 +gradio/icons/link.svg,sha256=w71tQzhRqCwDSE94VWknZgVjxtBcBz2dcK2X5NPCTlA,354 +gradio/icons/plus.svg,sha256=PbxK2HJRfQKyuP_57u68w_pq7v60u4AgN7FDssfz23E,480 +gradio/image_utils.py,sha256=z0Syk0lyQbq7qXTQt3AAvc3pd3ak3m9bUsXVBQHnZlg,11984 +gradio/interface.py,sha256=peAbgWqsKHNeTuEen40rMBfILzCfESa5d3JILbM81V8,51979 +gradio/ipython_ext.py,sha256=8lO2nFDRMR4lzOXbqSjad4HfYyrhhT8qZEOSHnDl1TU,2525 +gradio/layouts/__init__.py,sha256=_7_khsko333vDRdphsGfMFMvBP_nFFxGOh_1RWPzZ78,454 +gradio/layouts/__pycache__/__init__.cpython-313.pyc,, +gradio/layouts/__pycache__/accordion.cpython-313.pyc,, +gradio/layouts/__pycache__/column.cpython-313.pyc,, +gradio/layouts/__pycache__/draggable.cpython-313.pyc,, +gradio/layouts/__pycache__/form.cpython-313.pyc,, +gradio/layouts/__pycache__/group.cpython-313.pyc,, +gradio/layouts/__pycache__/row.cpython-313.pyc,, +gradio/layouts/__pycache__/sidebar.cpython-313.pyc,, +gradio/layouts/__pycache__/tabs.cpython-313.pyc,, +gradio/layouts/__pycache__/walkthrough.cpython-313.pyc,, +gradio/layouts/accordion.py,sha256=veEaaKerf30wePhYlCZAKCv77APxpNvDVuUukyHwa6A,2547 +gradio/layouts/accordion.pyi,sha256=CTSc54KdGnkOAZsq_PACD8MO3Bp6yKp1FkjediOUq-Y,16080 +gradio/layouts/column.py,sha256=Z61ji3NizKjmG6o9vPJXM5RmMkZlhWe7O68EWXVwQ8k,3884 +gradio/layouts/column.pyi,sha256=iqzrjlSebJXt4-lcNXoVvUoYCgUhN4dxuL5JLqGMpk0,4146 +gradio/layouts/draggable.py,sha256=dsfALua21NqfCpp-DTgq0MexxWfWP-Zb2R8NgeH3axo,2615 +gradio/layouts/draggable.pyi,sha256=AO8HBjYNHFighoQGax3eGaYdJfUhYftNwwsJFFSEsU4,2877 +gradio/layouts/form.py,sha256=puQdkXTLdff-KRaejjg0DffehxM4i7i_sBbV8omfPJ4,2775 +gradio/layouts/form.pyi,sha256=PSd2CnvFTTIzoIIS5dEo7dduq7goBg1-5KbsALjDL7c,3037 +gradio/layouts/group.py,sha256=h6p2_TPFCaLSouoIFF0r_lwQC4BS9_GXyyVgm3dU3Mg,2298 +gradio/layouts/group.pyi,sha256=E_Zsxxa11s3-MJz2l7LjJhTk5I6mJ9-xrC-GxQBebtE,2560 +gradio/layouts/row.py,sha256=BLjeGTrAMc3ppux1DnHgGhaNJVXantaSZJO-oyJlaYs,4723 +gradio/layouts/row.pyi,sha256=lHqRgAesd-FsDrVyLybyvVrs1bGn9hvEyBunkrsxx58,4985 +gradio/layouts/sidebar.py,sha256=leY0S2XzLBvWGv_rLal2Sss-cYU4V9q2ovT__chTJxQ,3005 +gradio/layouts/sidebar.pyi,sha256=PG2k4gQB5FhveCzxKmfVHDk1d6CaZvGINfk2fvDUlBA,16538 +gradio/layouts/tabs.py,sha256=FHG1KYqh8pS9lMPZjRjq3fnQGcZs8AalPHP33vLK9uA,5378 +gradio/layouts/tabs.pyi,sha256=nyWw0Pqsjb_bIG2wBb3II0te-cL6s-YEm_2Jld79YWA,25770 +gradio/layouts/walkthrough.py,sha256=WLP_5r_wDaBcVSSIis34StBpuoW2CTzZdw6FJ7eHhhc,5136 +gradio/layouts/walkthrough.pyi,sha256=I2k2gm4B2jhYapca_owwjVoKjhcy2yaMS6VAI_8f4EY,25528 +gradio/mcp.py,sha256=m2I8GVqEON3ky54zrRxsZmp0ud3OdQKMJzbii8qg-Eg,46068 +gradio/media.py,sha256=vrc7_TaspZa-8uwS_jUxH7z3O5nw_p26xl9w8xiG5Iw,4040 +gradio/media_assets/audio/audio_sample.wav,sha256=rvN2KgIRr8t2EBOn4lPdocYAotgSEz0qszPvxaOllm0,16136 +gradio/media_assets/audio/cantina.wav,sha256=Ll9zABsyTkE73PZY_KVIUFfDM_QZjlHn6Guy53LNCXM,132344 +gradio/media_assets/audio/cate_blanch.mp3,sha256=hOEpmwFc3WgNolJI6uIBu_L-oGbTcTxesJtGNMXw_tQ,67208 +gradio/media_assets/audio/cate_blanch_2.mp3,sha256=6tfpQLMKv-LlPOfteG8_E0xdRBMlVM58dxWApBYWFnA,35816 +gradio/media_assets/audio/heath_ledger.mp3,sha256=NgpdNpIKte9Wkfwi7v-x35G81JjZzc2_n974GHR78r4,28416 +gradio/media_assets/audio/recording1.wav,sha256=HQh4dnlf8ryLbhqHLrmpssykTbGGbpyfoA31olVpGf8,639020 +gradio/media_assets/data/imagenet_labels.json,sha256=cOFcINl7o961nUZBlzi-JtKuPDnVVTk7LRrlhcnePf8,18188 +gradio/media_assets/data/sample.txt,sha256=WKRKFUkC_A25UV3JpbWG4zgWZvlRVIDIfSIfzi2Rwtg,13 +gradio/media_assets/data/time.csv,sha256=bCMY7foyHO-RdPsvhKVELqYFb6MC5cIZQUc497JLbIg,67 +gradio/media_assets/data/titanic.csv,sha256=fRGP74tsz3-BERh3vDiFNvex5JimVePWSdGaqgEOn28,61194 +gradio/media_assets/images/avatar.png,sha256=kro78PrtWrWR7FrT0G-olAnupN5pSyts6jzJieCOzHk,5328 +gradio/media_assets/images/bus.png,sha256=OWx7U1hp5EGP2dlldjXlE0xrpiaBkFnwsm6bj7yCp2E,1951 +gradio/media_assets/images/cheetah.jpg,sha256=KbAJD17EcdrQJkq8IOzDyAoBM6Y6A9Ed-SDjmgk_5sg,53144 +gradio/media_assets/images/cheetah1.jpg,sha256=NVUL-7qZblnCQq8A9qFKnA0FXfvFKtBpoaTowcOcoJU,20552 +gradio/media_assets/images/groot.jpeg,sha256=__TQXTAIjaDwc65Ksh0i0Ry9Vs-rcR88NZ-qu_hXcHY,349746 +gradio/media_assets/images/hf-logo_transpng.png,sha256=Wn-fc0uvof_B0Z_6ocCr6mP9EEX14Liyie8UM4JDsNU,43650 +gradio/media_assets/images/lion.jpg,sha256=TEXs4AB18VLLLmz9Xx39fcjoMEImRoW09HACYkDv8-8,18489 +gradio/media_assets/images/logo.png,sha256=kro78PrtWrWR7FrT0G-olAnupN5pSyts6jzJieCOzHk,5328 +gradio/media_assets/images/screenshot.gif,sha256=Ld9RNndSl_J0yvebvSvrjPFypdiUFZfMgu20NYjFTGU,92391 +gradio/media_assets/images/tower.jpg,sha256=9X-W96cfiXOdJ66P_An3PNLxdBXRbJTULcsNVx9OsO4,112385 +gradio/media_assets/models3d/Bunny.obj,sha256=yT5Kb8ZCMZT_iyTeNy0KBjImQpAwKhHTkfgyMToNVe8,198443 +gradio/media_assets/models3d/Duck.glb,sha256=Zb-Tj1TWBz5hnnbgB4ILv5gM3D3A2uwNlIMP_ErlSrU,120484 +gradio/media_assets/models3d/Fox.gltf,sha256=lyHEdMOTXaK-G4lQs2QM3HOVG89CfQ1bMW6h08GAT8M,240667 +gradio/media_assets/models3d/face.obj,sha256=NA7l8ZNCTnQSncuSnWwdViLM7U0-oljReId_d7etJV4,72476 +gradio/media_assets/models3d/sofia.stl,sha256=ucdk2zM-72RfhQDAvepDKnmQ6_NMONUFY11vVix87HA,675084 +gradio/media_assets/videos/a.mp4,sha256=pvluE9_WlCPRxsyIPW0Ihv2K5cafWodmHFaYzov5kbU,130399 +gradio/media_assets/videos/b.mp4,sha256=_H4F7YAslNdOkAXjvFPVq_02q0tjvhYC9s_ml7eJxBg,261179 +gradio/media_assets/videos/world.mp4,sha256=cZRNdDDEYfDNbn_RDO5-tyeGNSo2ePx7wK49QQ9yrs4,1570024 +gradio/monitoring_dashboard.py,sha256=BQtEPaVvg-ho_FDkO8Dc_bFmGn11F7Kz5Ww7gpDiae0,3258 +gradio/networking.py,sha256=dYJ7-RUyTjAEwKJQdMVcVFg5z5stWKamzeHbmzlkxWY,2370 +gradio/node_server.py,sha256=43kj_gCl1adVdTVc5UFebPdqJAW4n_xGK67taBcv2KM,6593 +gradio/oauth.py,sha256=v4s4xWIceU3xwrAG1z69Ajto23-MKemm_4MNwNqcfPQ,14256 +gradio/package.json,sha256=IR1sqa968kJtizI5iWByegA09n6O1574rSGFkYeOvy4,82 +gradio/pipelines.py,sha256=TkQXsTC087Xu9viwQ3swmFSq-AjnfbEG8WsvaEHBj5A,4765 +gradio/pipelines_utils.py,sha256=xG-ff3iOJfhy5wBPuF-aqq7yR8_JhgCb5KKLnj89YWg,32989 +gradio/processing_utils.py,sha256=mpww78y1ypBOYHxlWrOnO5eqd-EzKKc3A7EH1QZ7dEQ,39418 +gradio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +gradio/queueing.py,sha256=VWfiSFWDYOAAhwnG75QAC-oZT4W2Vb5CGf29QFX7dso,38672 +gradio/ranged_response.py,sha256=jct3o6ZgXAcMf3Vc9s6S1BsBN67tKzyF0ZNA6Ccd3og,6336 +gradio/renderable.py,sha256=OYhGGKWOXqkDZ2wq3wQQXB6G8JW7d1A6Jjc3tPFnrGE,7970 +gradio/route_utils.py,sha256=40fmK-xEVr39FvN0mUCcCQE-1DOthbNVlVK8vsvQFE4,39368 +gradio/routes.py,sha256=I2LbG-ir-oi6uCdkEzA8BH3it-4xSmmKrBARx7bVslE,104881 +gradio/screen_recording_utils.py,sha256=DZ4_V_yiEkOEwFugWBjKZSfeOachxD9OzHotZ8_8xOc,11966 +gradio/server_messages.py,sha256=zf4XHVw1biLgL3uIk1PZJWSxOc2F5QM-bO15O_AvAXU,2383 +gradio/sketch/__init__.py,sha256=hS9C4SDytCoX32KdeFw4ZpLs-gy1d-9YvXy80VPCYGs,59 +gradio/sketch/__pycache__/__init__.cpython-313.pyc,, +gradio/sketch/__pycache__/run.cpython-313.pyc,, +gradio/sketch/__pycache__/sketchbox.cpython-313.pyc,, +gradio/sketch/__pycache__/utils.cpython-313.pyc,, +gradio/sketch/run.py,sha256=DhKg3Wum2PYRsR57uSsmvZ4cmAEpJ4twEag2ZltLTlE,33504 +gradio/sketch/sketchbox.py,sha256=Kjmvj8GGNYyFrLidBYjtBVFKiEVt53-qmRtGD42xS5k,1346 +gradio/sketch/sketchbox.pyi,sha256=iMsud7LpiiJSNNLw97rCrmSAYspDXPD2MfwmJxhd2yg,8243 +gradio/sketch/utils.py,sha256=s7fVRNKzvxnESGINCVv2C7F7koP0bqc6GsoMTDY3PQo,5339 +gradio/state_holder.py,sha256=9geJ7Itk0hfxwcW8hqNfD2ePdtWQo3u5k86rKMrGb_A,5767 +gradio/stubs/anyio.pyi,sha256=k4CN3iohlNh4fObD8EQt1j4E5TGV6ywsncBOA2J62x4,2313 +gradio/templates.py,sha256=IVopthadBRou_St5RTRkYw7UdD1Ax9I9fVJUy4tileI,29071 +gradio/templates.pyi,sha256=fnVN3Axi-vdFVqdZzEUkd10bLHXFV84ktSXL1bUUdUA,31367 +gradio/templates/frontend/assets/AltairPlot-CjD3Y0Tt.js,sha256=Gl3j4g3Wth5mgQIfn5zw4S46CmHs66hMniKwxwsb8t0,291827 +gradio/templates/frontend/assets/AltairPlot-CjD3Y0Tt.js.map,sha256=vw86_cf1rsiJBD2sU6PbATB3zBf917YFpYwOgV1thZs,1427498 +gradio/templates/frontend/assets/AltairPlot-CwUOFQzi.css,sha256=GstHlQBXaihn5CFTKFkdxUgn4uNaWtSPYIrvFYe0EqY,880 +gradio/templates/frontend/assets/ApiDocs-B7xG8uq0.js,sha256=0BJso0jMM4FK1-fwcEduTEzlBX0Y-VGOhjqQNrm-b-Y,89655 +gradio/templates/frontend/assets/ApiDocs-B7xG8uq0.js.map,sha256=0ZvuWLxOD3cvjlppzzIm4NTJmwvqa7U9Y850XqM7Ix8,114905 +gradio/templates/frontend/assets/ApiDocs-MshfCJX-.css,sha256=HbrGjh0FPGyyjoAXYKTOpPN9CO8tiKWpIjLCc5PnbaQ,14830 +gradio/templates/frontend/assets/ApiRecorder-B689T6cM.js,sha256=PMWz1EbTNOy6ybfa4xHWIrf6OubDV8WpruFOEkTcXV4,2362 +gradio/templates/frontend/assets/ApiRecorder-B689T6cM.js.map,sha256=ooCo6-DMI_DhCnoYA5EjTw9BkeQioVTT_16RlndeEdY,2752 +gradio/templates/frontend/assets/ApiRecorder-N1NZAe7o.css,sha256=Crd8s3gL70HPXPudZ10AYeGvJEwBzGdUYmP8xfdhmLE,781 +gradio/templates/frontend/assets/AudioPlayer-Bioz4LGv.css,sha256=YPVn0NiTdyg8D6Se2AmZ_x8Yz5xYCflCb2XpLLoc7B8,4245 +gradio/templates/frontend/assets/AudioPlayer-Ct6ZSLxK.js,sha256=5jFVUy36c6tgIpi4ULi5rlsa0Vg4iBslRf158CEWgnU,59273 +gradio/templates/frontend/assets/AudioPlayer-Ct6ZSLxK.js.map,sha256=Nae3NIqeFVe326bzuJdAB0vYjPal-7nTehYw_yNPixU,147403 +gradio/templates/frontend/assets/Blocks-BEaKnzuj.js,sha256=gh_XcWU9x279WZO7Nlk82o-7MCpDcMWgXaIftcUSRMc,51263 +gradio/templates/frontend/assets/Blocks-BEaKnzuj.js.map,sha256=TwdvLmlZ3jGP3vTnwVP4oSZPO78nPyDe-BfCvdtLToI,93769 +gradio/templates/frontend/assets/Blocks-D0rbzfnq.css,sha256=EWtHSWcBWDVBCEx_ovdaJgueAtF8sQupva4LImNuGzk,2431 +gradio/templates/frontend/assets/BokehPlot-BYdRHwLQ.js,sha256=qDl71zN2pIBSwZrAYa0hC_Xq0vuXxMZRyqhqQz_FGzg,2047 +gradio/templates/frontend/assets/BokehPlot-BYdRHwLQ.js.map,sha256=YWr2RE1BSe7lQMhCsrCqWxjbKO7n7irqv13J0ntL1d4,4417 +gradio/templates/frontend/assets/BokehPlot-DxLBXYml.css,sha256=8PW6X7eeBzZ1_ZxGXEwdzDbUWjWYq_XAa23_UZ7mtwM,66 +gradio/templates/frontend/assets/Canvas3D-CBJJFssf.js,sha256=qBp-YDNf8ZU2OTsEyiYW7ySkW_A6HexL_ENllY1FM_4,2801 +gradio/templates/frontend/assets/Canvas3D-CBJJFssf.js.map,sha256=sb8vx0LoEqVHidU2WnDzehCeFQp89LJoVJNwyyf5Ohg,5070 +gradio/templates/frontend/assets/Canvas3DGS-jE2bOsN7.js,sha256=JMREw1VBe5ICwkZMqFWORRaSKjNk0YXaTFdLY8u60Hs,115974 +gradio/templates/frontend/assets/Canvas3DGS-jE2bOsN7.js.map,sha256=vmMWGDkO8VHCtM01TzuaCPIbwFjLuYcXGuUG1z0rY6A,234463 +gradio/templates/frontend/assets/EXT_lights_ies-C9PYUbWZ.js,sha256=-FMo582w1rwxmeckg4YzpnwUX_Emgkie5oeOHUhKzg8,1856 +gradio/templates/frontend/assets/EXT_lights_ies-C9PYUbWZ.js.map,sha256=EEQdbhJ0l1NykGFGsp3Q7VOeV6k1nWFfTsuSPmbgXf0,6238 +gradio/templates/frontend/assets/EXT_lights_image_based-9yYf2nbr.js,sha256=_70jJaC70tk6JHwMJfBAfaWGpthN9lUWibkxlYI3tH4,3252 +gradio/templates/frontend/assets/EXT_lights_image_based-9yYf2nbr.js.map,sha256=jpPm6mkhgG4eERjlMJO5V_pKLrsEUuPpevcPB2n1Zt4,13408 +gradio/templates/frontend/assets/EXT_mesh_gpu_instancing-DhwxVQZs.js,sha256=9AGi45oosmRr4T0BPbQHO5AIIyte7dkNSb0nLjjLCk0,1868 +gradio/templates/frontend/assets/EXT_mesh_gpu_instancing-DhwxVQZs.js.map,sha256=veqWD30BHgaq7D8UlkaBnwKI5DWo0VnvfNAvDiU0ITg,6560 +gradio/templates/frontend/assets/EXT_meshopt_compression-COS4Murt.js,sha256=JKsOzHYGrWRrrZ7GaQ29zt78LYcwDr3FtWXQq6RJDx0,1631 +gradio/templates/frontend/assets/EXT_meshopt_compression-COS4Murt.js.map,sha256=_Qy_nN6WCSQiMQWymviCYwxLLGEjkZ9vaSPe-VztGZI,7561 +gradio/templates/frontend/assets/EXT_texture_avif-CDhoPDCq.js,sha256=DJDBeQ5JB4A72B7I7nRtK6DnAn6gmvRDQMw6T6kIjUo,888 +gradio/templates/frontend/assets/EXT_texture_avif-CDhoPDCq.js.map,sha256=dqnKDCn9KAcwHS1wi7b02CI-WRVy_ur5OJsMWnvUWp0,2803 +gradio/templates/frontend/assets/EXT_texture_webp-DCt8Pny1.js,sha256=fEAuld0cp0EceUgHWj727QyRv5wYcu2SAZ-pMU5bZrQ,888 +gradio/templates/frontend/assets/EXT_texture_webp-DCt8Pny1.js.map,sha256=yhUczMsXDEM3A1VupXb3iCdrCpErGgcL_vQ_3eq7wh0,2741 +gradio/templates/frontend/assets/Example-2_XpXLIx.css,sha256=mPwrLCP67zJxLaJpIH8hlELYAgSh0qoFQxeeXxfnqKw,61 +gradio/templates/frontend/assets/Example-BBLMS951.js,sha256=oZBn_LC7U3NNNQ6I-8bpvO3moiJggorRlU_5KirElV0,567 +gradio/templates/frontend/assets/Example-BBLMS951.js.map,sha256=q7E_WvJZGaZ-4TbNS8aY-86-yn_oPUXI6CO7h_A17II,409 +gradio/templates/frontend/assets/Example-BFRraYb6.js,sha256=paZ5xSYpsZXDKPHLlHWZW2HoPPXDQbjxsBIRrKbWohc,3673 +gradio/templates/frontend/assets/Example-BFRraYb6.js.map,sha256=o4JyHX6y7fFGmb95-d7cT_7zXewhLVV-TjafoXase5o,5385 +gradio/templates/frontend/assets/Example-BK3gyXL2.css,sha256=nO_TtzchGr2yRJh7skxXU6VN08V1Oczg5wXeqXRxV7k,46 +gradio/templates/frontend/assets/Example-BU7VN3ij.js,sha256=tnLZM1EuO9oPeNcXPNZOiqOHJW6ZJhwdfp7yFOQQ4VU,1657 +gradio/templates/frontend/assets/Example-BU7VN3ij.js.map,sha256=rMt5A87l_jmy0W15STx9EShOKRXSk9phggH7DctdZLE,1723 +gradio/templates/frontend/assets/Example-BUnh5COx.js,sha256=fIgfAnm1HlkV2fSWAvsJEb93VyRBUSw6oJiuxlYdLcI,3883 +gradio/templates/frontend/assets/Example-BUnh5COx.js.map,sha256=5Oyp2ITsyfC3XK_ZtT28RHT7CAy9HpdJ66o_cYNnfa0,4600 +gradio/templates/frontend/assets/Example-Bdcw8sPw.js,sha256=sIGPBfDXScljyR48tV5Q-2tBMX4t0vmVThuA9bS2SPU,1594 +gradio/templates/frontend/assets/Example-Bdcw8sPw.js.map,sha256=qR-m9TEa9wHjmpsBxH0zY_UHxoaA6vY1Pq2x5CXSq8o,2215 +gradio/templates/frontend/assets/Example-BjJvNKVN.css,sha256=HNpkFYu7Ir2Kjx_inXdII02VD6diCu7jjfTA2NRaiso,199 +gradio/templates/frontend/assets/Example-Bx762nxc.js,sha256=85jluGdlGn9XcMxZfAnhI8YA0AtNCiA_a0u4oZWYoMI,1065 +gradio/templates/frontend/assets/Example-Bx762nxc.js.map,sha256=3bBbTt72OpubVeR52FXq5BGZMuj53on_sG2hMfVTzhE,872 +gradio/templates/frontend/assets/Example-C0AteSIo.css,sha256=JqFvmFuRC1-pV3fs6HX0BXI8f6oZtseyLe3x-LzU-Bo,526 +gradio/templates/frontend/assets/Example-C1b-Ajeo.css,sha256=pn4qPfiZbAGQPDCNIVuD2kcOJjFJtfhNaaRJ5cHWu1o,234 +gradio/templates/frontend/assets/Example-C8iE-5-4.css,sha256=O4i35uwKBSekWp-_qNvjDMEJMcuHrm83nszbiAwO9dw,746 +gradio/templates/frontend/assets/Example-CIE90Dgc.js,sha256=pyXEoj_WaJDzo3D9IsitjD-ledkpFQxIVztuUU914U8,2234 +gradio/templates/frontend/assets/Example-CIE90Dgc.js.map,sha256=s0pOt1CPwUboECyxEO7itsf7anbiXcH68YCyDHVFRno,1928 +gradio/templates/frontend/assets/Example-CTIV4tuG.js,sha256=X96xdLqReh0XyFcW1C7JAolxi4y4E9dtt6XXfJqtmH4,2249 +gradio/templates/frontend/assets/Example-CTIV4tuG.js.map,sha256=JmKqhksUY6Ol5fsleh2DiNzm7DQmECnd9jarmj79rLo,1902 +gradio/templates/frontend/assets/Example-CXIB7Ya_.js,sha256=uaDcXpSmooNujmtaWKFMMsDKu6FIMekDTzPNxbdqv4s,1104 +gradio/templates/frontend/assets/Example-CXIB7Ya_.js.map,sha256=gIemZ6dPUSkZwGrgUk5sQoHxZLvwifKtlUL6rA2aCiY,1014 +gradio/templates/frontend/assets/Example-CXKuTmQ6.js,sha256=IelcR5COxEMMBdoQJG9AjSIe-h7-5Mx7s2mJ-2RWAqY,1265 +gradio/templates/frontend/assets/Example-CXKuTmQ6.js.map,sha256=qEW_Eys61NVfR1tiPoQzYeL_zCLA0aD-ta1TfUVD8Dk,1544 +gradio/templates/frontend/assets/Example-CYFTcOx-.js,sha256=Eej3-CpMJXdTElfKwCcEYY-lMa9arjkyp_cG5GN2A28,1556 +gradio/templates/frontend/assets/Example-CYFTcOx-.js.map,sha256=HGB4eP-u2B99SS_Lic56l6ymhEx0FKpjS3OHmW-AYZo,2425 +gradio/templates/frontend/assets/Example-C_JLPM_G.js,sha256=PrJZDbjtVy9CQUMBliZ39yt9w5Bf5h9dk8VGaH4isxM,1065 +gradio/templates/frontend/assets/Example-C_JLPM_G.js.map,sha256=avSsjtwXfbYpCuW3x7TvnzECKxPTldeLeE9nkZR-nlg,870 +gradio/templates/frontend/assets/Example-Ch2O2d18.js,sha256=Mc5AIqP4Od5lIlDl6Kc094G9mEPKml3593tCxYpjf3c,1266 +gradio/templates/frontend/assets/Example-Ch2O2d18.js.map,sha256=X5jkc0GmYjocyZVSwz3-KhZYwWmAhU13FgrRKiu3aeo,1318 +gradio/templates/frontend/assets/Example-Cl1JGlzw.css,sha256=7pNbDDioQpVq4Nh24s0dCGLMWTgb3WzdVwWUU9jdIIA,97 +gradio/templates/frontend/assets/Example-Creifpe8.js,sha256=hIXfWDnvrlmJ5tp-JLicSX0pyFJY892rpDln2F_xo-E,1121 +gradio/templates/frontend/assets/Example-Creifpe8.js.map,sha256=wOID0_ZXrC-5VjJtId3MfBw_0plgN4_eZJxycLATS2U,616 +gradio/templates/frontend/assets/Example-CvSfqFaB.js,sha256=aGNe3BCtvfMbRnwY-WDYVFWddOlqCvPTplKrPQPd13E,1065 +gradio/templates/frontend/assets/Example-CvSfqFaB.js.map,sha256=MriRLZ9TR1Qxhaz46izWsb5s55QWOFjslL2sq9uj0Sg,872 +gradio/templates/frontend/assets/Example-D1sBsWPM.css,sha256=vPvlZ9Le6qqi_YSNzHqTgBqwq47qHTDBgXUAqEaFfb8,448 +gradio/templates/frontend/assets/Example-D4Z-QWNz.js,sha256=NLc800lmwpzYvE3gJMdDAOD0LDcObQmeWsYf-qkZxLs,4226 +gradio/templates/frontend/assets/Example-D4Z-QWNz.js.map,sha256=wsczSYS0E0MRkxKHFJM4Bs3zAFldRVMTTNA2FnPFiI4,4305 +gradio/templates/frontend/assets/Example-D4vuQ8w9.css,sha256=91y6EEN27aDOpSwJS62qQSdZg5SrLEGcnsisPD-YYCM,94 +gradio/templates/frontend/assets/Example-D5YxIsQj.js,sha256=iv1Cn5APXuD7wtZkPkmOJZSa_fY2f07VNKqlq7p_g-8,1154 +gradio/templates/frontend/assets/Example-D5YxIsQj.js.map,sha256=6puEQ0wG7lBuNcmFKi74qpPWQc_ZfoVRTfWMnzklW9k,1040 +gradio/templates/frontend/assets/Example-D5podvjf.js,sha256=p6pv40Xs7UDZIeusmMiqDi0xxp-VBgkK-qL4h7H88x0,1152 +gradio/templates/frontend/assets/Example-D5podvjf.js.map,sha256=TqtH6BLdxE9RNw93R5PFZCAjUivSi6MQzzYDNkUrClE,1088 +gradio/templates/frontend/assets/Example-DIQgnXqL.css,sha256=Zau5ysRzUrXEyr2GQ2woKTyVyRqBSu8CKo5ax2WJzmg,880 +gradio/templates/frontend/assets/Example-DNToQOMy.css,sha256=j14fOWIu8-l1EzzGdtTB6XztpF6XrM6snh8XGg7-yW8,451 +gradio/templates/frontend/assets/Example-DRnq2kzJ.css,sha256=jw3zti8Eo0HA958JHF7xMjIo4jQrxRRLQGmUn0hfPMM,115 +gradio/templates/frontend/assets/Example-DW8ARmNI.js,sha256=jUiyO7QlW4YVaN-uuSOnSyVeisw3pWDCQ8mTCeoZUP4,1106 +gradio/templates/frontend/assets/Example-DW8ARmNI.js.map,sha256=vde4w7vb3mEDPwdzpCK4UBHpiC6U5BzetD3C7ixPM9Y,981 +gradio/templates/frontend/assets/Example-DgXchnDW.js,sha256=IgGnvE81RLZssWU0hkGR123BllpZFDPT4DtYJqevvk0,2892 +gradio/templates/frontend/assets/Example-DgXchnDW.js.map,sha256=yZZGJrTYHkhwQ-DPYa-L7IoBOLaE_bp8EXcZzlXF1a0,3137 +gradio/templates/frontend/assets/Example-DiimdKNC.js,sha256=6v-ekZZ4hELy25Q8BH-Etf3Px2wMmPKhkXtykvflU9M,1120 +gradio/templates/frontend/assets/Example-DiimdKNC.js.map,sha256=QMHtsSdlJE_xTwftM75rFxtZyypyVurjXpDv1I9r3ZI,1018 +gradio/templates/frontend/assets/Example-DmPzKeqe.css,sha256=ieU1iBlq2LM5elVQSPyeu2l1gZk3OJLZ6gDU1bkytpc,2026 +gradio/templates/frontend/assets/Example-Do2HGpgf.js,sha256=HOKwpQT2mceUXrprMPALdJW0IoT-aQkPQKYmNios2I4,1183 +gradio/templates/frontend/assets/Example-Do2HGpgf.js.map,sha256=K1wi8GmfGofwBpN9X-NgzIqIkk6-7lHNAU2qk9miRqw,1453 +gradio/templates/frontend/assets/Example-DrWPR_f5.js,sha256=eKBnHCrcLQ6abyyf6wRY8-g--bKsozYCL-n_EtSUryo,2130 +gradio/templates/frontend/assets/Example-DrWPR_f5.js.map,sha256=p-5oihEt23bHtN84gIos0jzS9Vsj_X-HMAR4UOOCyWg,2047 +gradio/templates/frontend/assets/Example-DsiMUgiT.css,sha256=lCmly42A6cBMsZedc_U9JlAUqyE6L0U522Sj5VQxmx0,552 +gradio/templates/frontend/assets/Example-DzV-zr8S.js,sha256=wYwcGBfdYCcIVClkw1HG4xIegdioRk5FiAWpdAE7z8s,861 +gradio/templates/frontend/assets/Example-DzV-zr8S.js.map,sha256=U8Wj4HzRGDpXj_Awd8U4mGIg9q7BHnGAFemiTQ8CAxo,869 +gradio/templates/frontend/assets/Example-Hjv0Coey.js,sha256=i5TEEJHIJ7qY2eGWVQWxl_BwW7ovtCDy5LeVyah0gx8,1757 +gradio/templates/frontend/assets/Example-Hjv0Coey.js.map,sha256=GBoR-0lVIux6gqPQ_JmbV--cyr_fe5zqzOz2wuIp118,1640 +gradio/templates/frontend/assets/Example-Plzo0itC.js,sha256=hXl7BKtaw-YoKe9H250o5tU8WWXkx14tQVMfyQdU_-U,1106 +gradio/templates/frontend/assets/Example-Plzo0itC.js.map,sha256=0pu4umefYHN_4Wf-X-9UW8nyelP8fBG0RCRSn7z4gyk,983 +gradio/templates/frontend/assets/Example-cR3xzyOo.js,sha256=3C4hbGlSGvyjOqZqATSS5GqjKhmMa70Erqy186L2Y68,1177 +gradio/templates/frontend/assets/Example-cR3xzyOo.js.map,sha256=_6fotCMntITy5v_mfU4jeDWXu9g8z--Ha9Gu2YJJmLg,1393 +gradio/templates/frontend/assets/Example-mHz6_3U2.js,sha256=vkNkLVzOJxEQzJmo4tifGc2EDOK5Lpe6RDm8fQU8Nog,1237 +gradio/templates/frontend/assets/Example-mHz6_3U2.js.map,sha256=lKY3K7NAkUSSKdmpcGp_8JgMUd816nm6cDKO1E4Owbw,1402 +gradio/templates/frontend/assets/Example-qYVyHUA1.css,sha256=X_nt4sEVM_OMmDSB02l4924ZHAlyFWsCTO_jU_Q_NcA,1097 +gradio/templates/frontend/assets/Example-vUEPA0tM.js,sha256=MPpCWXI8NRAv_lRJe1QnpAtv3bexPLBvZfikqPcEJeA,1050 +gradio/templates/frontend/assets/Example-vUEPA0tM.js.map,sha256=Qfg1_Qrr-5bOMO_iTp5AwiB-vJgmMgf9nwr0btDfM28,868 +gradio/templates/frontend/assets/ExtrasAsMetadata-wb6lwaw-.js,sha256=RMR_e7vqw9zK-5NyRFPeELFUTm17GhnJVl_zof6DO40,763 +gradio/templates/frontend/assets/ExtrasAsMetadata-wb6lwaw-.js.map,sha256=i_lw1Ib_eXfz3ng-PvfnS9OaBio_si9kNWhEVDDzROc,3353 +gradio/templates/frontend/assets/FullscreenButton-BYduS5IX.css,sha256=2duHxWsN9Om0s1CG7EtEUolUYXQCpeNHF2Y8WG2kKhw,8884 +gradio/templates/frontend/assets/FullscreenButton-D7DmzQQ9.js,sha256=Wh-NOyjeS5hPJ2-IFsaNc5e0ooF2VbPKnMkEshc1KCE,104526 +gradio/templates/frontend/assets/FullscreenButton-D7DmzQQ9.js.map,sha256=HCJpcSqFFMeg28CCUUTWT1s1eUFfBitO989BEq5nJBI,101182 +gradio/templates/frontend/assets/Gallery-1Y3LlKu1.css,sha256=dzIMF1zLQQl4EXJETCrzfRHz8sHdCYSyo3HwiNaMthA,5097 +gradio/templates/frontend/assets/Gallery-BF-Vt8uf.js,sha256=E6lSvo72JmYAIPP8lqYa_6Y3UpMrYGBrBX5ALSrg-tg,23761 +gradio/templates/frontend/assets/Gallery-BF-Vt8uf.js.map,sha256=TJpdS_H4QZyFIjHsd2Hn9MSbF9230hgqBo6Af-L_RBs,35131 +gradio/templates/frontend/assets/Image-0bVIZe-w.js,sha256=k8Flmns3cWivTfvcQr_qwEAWA-L9E9v8NcqLfFPx37Y,954 +gradio/templates/frontend/assets/Image-0bVIZe-w.js.map,sha256=GXW63kYTOX5vjSPjp6gA_xTGzzg8_lRIs2gQ2eTMbZY,711 +gradio/templates/frontend/assets/Image-Ds1uFAjO.css,sha256=wvliu0UpszhKHZH7tOsAnOAVD6KZ_xCAlY9B6v77Ww4,37 +gradio/templates/frontend/assets/ImagePreview-BiSVoKtP.js,sha256=PCp9h1kofFytO2tvk5oXI-q9b9Bynn_uZbLMR49I4qc,7514 +gradio/templates/frontend/assets/ImagePreview-BiSVoKtP.js.map,sha256=JBDApHFgXQIxL0MT2QcBunQLDzIclm_UrmUzxPhp3ao,7765 +gradio/templates/frontend/assets/ImagePreview-D5bl4ZzZ.css,sha256=9W79xtNHpowNVqS07hGBrdCwuGvUAUzVKiNR4Avjwf8,801 +gradio/templates/frontend/assets/Index-19hQstid.js,sha256=YI7GXuh9GETI1D8u9-uy-2wdER9ZznA5t4D-Y6ZGPF8,29451 +gradio/templates/frontend/assets/Index-19hQstid.js.map,sha256=ZxpGJnTpK-M0caER6A9mFCfsLdX01XwO3Y3aOj_RRgM,51307 +gradio/templates/frontend/assets/Index-3q62CqrC.css,sha256=QiNazTWepRM3wUQhukmSoakSYtrKs7tlLMuwnFXfF20,3180 +gradio/templates/frontend/assets/Index-5Uu_FBwt.js,sha256=SMrKuy6iKXFbPk64iL0xKntFSkAjK1d9HC6BYsqokhw,9973 +gradio/templates/frontend/assets/Index-5Uu_FBwt.js.map,sha256=xWHu9EldH-LWWkmo1sZx5p4-p0tY2LFtU7ko3n_foQk,9016 +gradio/templates/frontend/assets/Index-AS9ilRzv.js,sha256=Et6ugKMZBJtDtdcb3_LC3t8tiS8L-9tzV2fEbLOu7FY,119552 +gradio/templates/frontend/assets/Index-AS9ilRzv.js.map,sha256=97s5ppZqvqiGF2m6IqkdvUlbgUBxHTfomsPvJIQ9B7o,142064 +gradio/templates/frontend/assets/Index-B-cWiLsJ.js,sha256=BJEA9MpbrCI9y0mx1Z0AkJQ80VQG1mF19Bmhk1kJkgs,72220 +gradio/templates/frontend/assets/Index-B-cWiLsJ.js.map,sha256=Su__ZSHP3LKH9n9OizVOCVusxJrYmZgjhH9J-MBKnl8,354401 +gradio/templates/frontend/assets/Index-B3uxtn26.css,sha256=oRXTZzGFFbyS6o3zuZ8WpUZdKmp8Cd5QDIv0j6vGUHg,1094 +gradio/templates/frontend/assets/Index-B60oSkOX.js,sha256=ZDUO18spPFWR-PGeMBfR0envPI_GY-PK5klUG5VttFY,6626 +gradio/templates/frontend/assets/Index-B60oSkOX.js.map,sha256=mXETOn9k_VV19EwnV_YyFvlLfEzpZ9ttloVuqwVBxf4,3961 +gradio/templates/frontend/assets/Index-B7RqhG-W.css,sha256=TTqlWTZp2McJvdfVfkJHzfqHn1NyaBDwCSi2yLpnn5U,20351 +gradio/templates/frontend/assets/Index-B8k0osbz.css,sha256=t9EkwoJJ_9u6urZPj2GBR82jq7rtysRIRPL-wcdvqiI,5092 +gradio/templates/frontend/assets/Index-BGmaqQju.css,sha256=U5AzLUjsep4FwWQYXrap8tReQyFZNSI6ryCDLOZDGkk,3072 +gradio/templates/frontend/assets/Index-BMLc4VxK.js,sha256=5JEgQZLJBn3xRDEXTckM8vC65pvM5NSTIs-NxhhmkCM,920 +gradio/templates/frontend/assets/Index-BMLc4VxK.js.map,sha256=5p9q3I2CWqxXV5VBTprEGZe2dU4QWg3o-MvAOLFoWFQ,1260 +gradio/templates/frontend/assets/Index-BRLQ5ruI.js,sha256=ifnGUPdff4Q2Sjkks72HBQZQn7zpjDtFrpt2Aype_ng,6627 +gradio/templates/frontend/assets/Index-BRLQ5ruI.js.map,sha256=6lOKZgxL2A5w4YnRcxcTL1tiJyB5ybBj3QcyH06wkeI,6638 +gradio/templates/frontend/assets/Index-BS59nC2I.js,sha256=y3RZJ7640umieM4Kk3e9C3NpHrBajx09b3SIhOpx960,8422 +gradio/templates/frontend/assets/Index-BS59nC2I.js.map,sha256=aw2UD55-MJbKddMEcK3l0D1YZHO62YnX6CNbUvmU884,8872 +gradio/templates/frontend/assets/Index-BUpWl19q.js,sha256=j1mAh3ZZQ_k30fhvZAZSx0P0kPIIyXDGNpIDKYR-Kx8,5627 +gradio/templates/frontend/assets/Index-BUpWl19q.js.map,sha256=cAhB10d2BkYvIiCAayB6l8kZeyZjOIEZ8KiLw-qCTVA,3560 +gradio/templates/frontend/assets/Index-BV1vZ3md.css,sha256=pZspzer_pU1TojkwfMWOWJf1S6BPNoAb5ObAOcOVHWU,811 +gradio/templates/frontend/assets/Index-BXw1GUZ1.css,sha256=fmgA5VGsmr-CAe18yjQ-9EatoAggPK5uy_09s3Q5BhQ,6341 +gradio/templates/frontend/assets/Index-BbAGodqB.js,sha256=sFpzY3xENEwvP2yDeeXrlFbNzwEtBEQSPfZc2P-JeLU,9730 +gradio/templates/frontend/assets/Index-BbAGodqB.js.map,sha256=LxZvM-N33hB528eFiFWUl9uYsjZyi1hzTviAcnlFE4s,8941 +gradio/templates/frontend/assets/Index-BdohJ9Zy.js,sha256=Gv4_2kfVUm74A6CketkBGyy7tqBr9JD-BahamVgYG6E,1742 +gradio/templates/frontend/assets/Index-BdohJ9Zy.js.map,sha256=bA_OxMg_f59jeiuUap8HQ2KpTcFognD_sw4cgtWgcak,1559 +gradio/templates/frontend/assets/Index-BdvHG3t0.css,sha256=tXf77rI-isPCMvtSVO-bDXHtWq1FCIPDAy2EGBVcvts,4921 +gradio/templates/frontend/assets/Index-BiNBEl32.js,sha256=R27FfQdEfliLL8-e9Dc-fkS-0vlDB-4z8XmyBPWFTxw,1788 +gradio/templates/frontend/assets/Index-BiNBEl32.js.map,sha256=6kpkHcJ7R9nieFZ50zsFyEaHGiR0c0w1J3cayGfA4gQ,540 +gradio/templates/frontend/assets/Index-BkyjjaNE.css,sha256=bgnm4JzL5xaoJb90NyA7ZMqA1u3d5_fuTL8p3PYKHhs,476 +gradio/templates/frontend/assets/Index-Bp6-wsMo.css,sha256=XaVZtv6-28M11Lh6lGDmrtnyrJ2mBjQLhsYygcMEDTY,478 +gradio/templates/frontend/assets/Index-BujyaVC_.js,sha256=473QPl1xwQOot5b5joU8QgKPn4yQWGRIXjf-Ho33VJM,6042 +gradio/templates/frontend/assets/Index-BujyaVC_.js.map,sha256=bd0sSfu-y75GhqRMAICKYueaDoZXNMrRLbPvQOAIyEw,4638 +gradio/templates/frontend/assets/Index-BvfIbfoO.css,sha256=jkqpox6Kna5iZGYU3hrNVVhFksRDCRi5lPUkm3UlBW0,2126 +gradio/templates/frontend/assets/Index-Bw0J9UWH.js,sha256=Vpa91Yuhq18863nlbv6pBvTH1tIn35JDRTqZV3RYL-c,12972 +gradio/templates/frontend/assets/Index-Bw0J9UWH.js.map,sha256=t7Je8RS2Cx6IBMeFKAAMPI7_VdDTcb6v6kCMr230nDI,21588 +gradio/templates/frontend/assets/Index-Bx0cemiQ.js,sha256=ATcANjTe7lL6w3m5BoZOaLbT9fYpRYuV4Z5GTBCuedM,10010 +gradio/templates/frontend/assets/Index-Bx0cemiQ.js.map,sha256=PbtGP2VA-m6NN109cUJCBd-l50dVs75wXR7IhtW-sMg,11211 +gradio/templates/frontend/assets/Index-ByCYYE22.css,sha256=UOBFVvPtUXo-8yMQphFt03bUw0sbZOYNGm2rTk7DFvU,4438 +gradio/templates/frontend/assets/Index-C-vZ3ifd.css,sha256=Uh2BV4YMBxUssMDuli6g_c-KZmf-xUnkFHREqMlsHUs,2100 +gradio/templates/frontend/assets/Index-C0P5OBZ1.css,sha256=YjzCYrHvR8gPcUHH1K3YY31qL0Q3R1a1JLbx8xpuTzk,13670 +gradio/templates/frontend/assets/Index-C4baFzFZ.css,sha256=Eg2HtrcTKCu7aXKFSmql5BsIBVTlQXH9W5LU8kIz6Y4,3250 +gradio/templates/frontend/assets/Index-C51KCnnj.js,sha256=Mrb5HVP4-2D7yW6fnuaormWnvjMYQRVZIofs3gD72xI,6738 +gradio/templates/frontend/assets/Index-C51KCnnj.js.map,sha256=OVsLmWKF1VpcUdbjV7WNqvDLKqP4_v50Gn_TtLzAuYY,4899 +gradio/templates/frontend/assets/Index-C8GNV2pm.css,sha256=Q_5znBEgZSHAvOg5QMTwOKpS5pKDT9FMSZkpmegfXsg,205 +gradio/templates/frontend/assets/Index-C9J3GN6_.css,sha256=4k_GdSNcjt-z9RlBJR2LIe-xT0c57ue2oLk_JcDqD50,5297 +gradio/templates/frontend/assets/Index-CAyDzuve.js,sha256=uo6aSQLi8fDimJiLQQFOk_ItlqA_N5w_xs8AsEJAPbw,32178 +gradio/templates/frontend/assets/Index-CAyDzuve.js.map,sha256=ewPXHvG2nuStx479DAk2apyWcQiuSNjoaaBWTVNLHE0,42429 +gradio/templates/frontend/assets/Index-CBOTzXyy.css,sha256=pKkAd8hkQ3IRliuD-GDIRU3G4XDfbcLKbpaMBMBWM0o,579 +gradio/templates/frontend/assets/Index-CDBfCghh.js,sha256=zqT6o_dT8m6hnOucD9g7L-tIZKro_mG1KLiUuDZAMOM,25084 +gradio/templates/frontend/assets/Index-CDBfCghh.js.map,sha256=YdsmLN2kjn6qj-u3u2TK30LkKhMJfnOQuJTlBqrQwbQ,48425 +gradio/templates/frontend/assets/Index-CFtPgl3E.js,sha256=wL8EEkD0tI1Ozu9u3FceXntW7ce6mKC2tdyf1K6F-5s,395772 +gradio/templates/frontend/assets/Index-CFtPgl3E.js.map,sha256=OTPQgj6tziAYlGS2Xj_goc_Wr1MNhZBpinkNrln0NlY,1669236 +gradio/templates/frontend/assets/Index-CG0-ctDl.js,sha256=HkO-vBzj311x9JzRMybJGtvCa8vRcWDoPMuKvpF9gmo,22458 +gradio/templates/frontend/assets/Index-CG0-ctDl.js.map,sha256=0J8GPX2jEYdQgcG2X8x_9ayBdQ-lrBIdEwRlcRS4YEc,37101 +gradio/templates/frontend/assets/Index-CHBVi5hu.js,sha256=XPit-FYW1aVP6k9vuTSds8MITS-vRHoB8rm85nHOWTo,25475 +gradio/templates/frontend/assets/Index-CHBVi5hu.js.map,sha256=rcZBzjRlktDgjm9MTbY4OXk0ggW-EzaGYD4zyZWyOB0,30013 +gradio/templates/frontend/assets/Index-CIdRvN_d.js,sha256=bJJD679qFQAg2YpMgeINX3k-TAQwWzil4JcaLKjS0Jg,26396 +gradio/templates/frontend/assets/Index-CIdRvN_d.js.map,sha256=SBIsyiXNLkk_uV5i0qj8nr8dO0vdKqUnUbPTle3EC1Y,27788 +gradio/templates/frontend/assets/Index-CJMF8twY.js,sha256=ZEcJzNg6qyTTfcRRsQ7m82lctlugCu_RG5qFhvvb7u4,6447 +gradio/templates/frontend/assets/Index-CJMF8twY.js.map,sha256=bWwjpbmaON7eGCkR07DlD1s5q87xS-hVcXvKDHofgfs,8721 +gradio/templates/frontend/assets/Index-CKu1GnBa.js,sha256=oODEIJ-rbhF6p8mrCpFyQIh53raXURX_NSJ3lbLBB38,13598 +gradio/templates/frontend/assets/Index-CKu1GnBa.js.map,sha256=H-Wz24aBwvwdXcma13C9i7W4LwcJT0_Rwo1QzozNSsY,28944 +gradio/templates/frontend/assets/Index-CM5ifdvZ.js,sha256=rXLOupu2JwH6yvA2JyES42pY42LBrvx-rKIfgSfLQDI,142993 +gradio/templates/frontend/assets/Index-CM5ifdvZ.js.map,sha256=tD80EcY4K-Xs5w9gk9CUfuDu77PziD6-4-SYQWvgfnY,260115 +gradio/templates/frontend/assets/Index-CRDZOrHF.css,sha256=mXrkgPXih5Lar82kaFDSLBRYh5yQefURMzdf4wsqgWU,445 +gradio/templates/frontend/assets/Index-CRfssLQd.css,sha256=Ampi7bie1ouN_MmhWt4PoloMK26NwRWnkF24aEjlsCc,427 +gradio/templates/frontend/assets/Index-CTWglnWq.js,sha256=PvVaE3jQqKAzSHjWFf0dhGo8Aa0dAnQ9Ezj0m3kCvsg,18835 +gradio/templates/frontend/assets/Index-CTWglnWq.js.map,sha256=Y4VMEWsVvzA3BhkEKczPEqW0lVP1bMsRMmooRMAVSAY,37712 +gradio/templates/frontend/assets/Index-CYOl-zJ8.js,sha256=Hvi2-muvh742hQOjpeCfdNoG3p-PHRzXRvlZNmKLMZ0,11170 +gradio/templates/frontend/assets/Index-CYOl-zJ8.js.map,sha256=-neU4jMQReDXq8wIyQ2SL6pttapFMcP3ccg49SEISVg,10212 +gradio/templates/frontend/assets/Index-CZxO08Kq.css,sha256=ID8wXpsM930AywKzV6bE4jK5FdgQA4Ye2K2FB1vxzuo,2674 +gradio/templates/frontend/assets/Index-CaNpT1A3.css,sha256=9q_mQteovaWIyJXFeCHtS4YvHmLd7zb0nm3plt3gtiY,6844 +gradio/templates/frontend/assets/Index-Cb-VzZbl.js,sha256=sptkSzzkE2d4Cv_aRebK9L6bzVZJdj-5FioU9d_LFxI,7112 +gradio/templates/frontend/assets/Index-Cb-VzZbl.js.map,sha256=cT7wSquE-WvV5N3j6YGas_PtyQ6EY5GBgd04Z0BW1bQ,7407 +gradio/templates/frontend/assets/Index-Ci4eVLjY.css,sha256=YcvJYAw-514UKSvE4LUH_zfMHScPwiJRjIm5F_awPw4,722 +gradio/templates/frontend/assets/Index-Cj521F3D.css,sha256=tx8966KfHHKGOLkOzoWW3WmlsMf1slWterMY5i8YBjc,4924 +gradio/templates/frontend/assets/Index-CoChn8_I.js,sha256=wkein3jS92yf6LdBTGmjfL7CLu2Zj-W5grr1opPo0GE,30002 +gradio/templates/frontend/assets/Index-CoChn8_I.js.map,sha256=fL4GLjCbVOVDfD_m8Us5OGVwPs6jCxP8sW8zpv6IiAw,46697 +gradio/templates/frontend/assets/Index-Cup2yvT8.css,sha256=ZX69e6dnM9x_-wKMLTHPLfmBspH4JDEKVmm8TpKOZVw,154 +gradio/templates/frontend/assets/Index-CyB_R4gK.js,sha256=RN04Giw3z7aAryqnwlS-jRXf-JsUI6Q01ouHdugAwzY,1592 +gradio/templates/frontend/assets/Index-CyB_R4gK.js.map,sha256=DAxCqSrKqeBcbpMcCSfklXURcQYCWf2KDkJZ2D1DN7Q,1633 +gradio/templates/frontend/assets/Index-Cz3L5lEP.css,sha256=oBdSLbYXJC8D-NUJdX1dmSS5SWVsT7UszqKHts8fdaY,3235 +gradio/templates/frontend/assets/Index-CzTqaf_5.js,sha256=DNRNpyfgsKtOp5ygddBS_HZDrpjYKh9-xkt2HM0onE4,4691 +gradio/templates/frontend/assets/Index-CzTqaf_5.js.map,sha256=VTPH3LO5Immg8qSyKsr_jaq01GUnMW8n2LEuGLhQSoU,5049 +gradio/templates/frontend/assets/Index-D-fiIdl6.css,sha256=SP462B9o-aomtH7_LJKNZT4A5Joe-JwQdG8htM0Cy34,1428 +gradio/templates/frontend/assets/Index-D01C4iWk.css,sha256=GQfdOKaAlfjO4mncDK6nCiB-i2fJOeL_lzXSxpFceZg,7202 +gradio/templates/frontend/assets/Index-D2wzIuuw.js,sha256=9Uv8Sqpj60Brh6tnv8b3xWhKzOBHNXbvpOc-wQjDHQQ,10698 +gradio/templates/frontend/assets/Index-D2wzIuuw.js.map,sha256=amwf4Ln682Ar746XM-rE20Zb-EoSoE4cHbRcWI-2d-M,8405 +gradio/templates/frontend/assets/Index-D2z_OZgJ.js,sha256=9BOQhbjuLJRZNeV-tOZI2TUbkbJGeQEtekK52Z7Bzjk,18295 +gradio/templates/frontend/assets/Index-D2z_OZgJ.js.map,sha256=P2Dp156WQJWFlQfkCP4V4wNtJ9okWAM-nGhZk7I3PUE,35706 +gradio/templates/frontend/assets/Index-D5xjOoMv.js,sha256=UEXRij4KyHHUEyRFLWMjCouBXmm5fzdXCzyQbZrYwp0,10520 +gradio/templates/frontend/assets/Index-D5xjOoMv.js.map,sha256=Iv7ur0c_LfLrGq6tJ0U6_EZxo_ZY_sk2nNO4VTvHSOo,10878 +gradio/templates/frontend/assets/Index-D7XIGp9S.css,sha256=5uFk-X-o87lqKh6JrVVX3qF_2ihOD6iAPa-_OJMOEUE,7365 +gradio/templates/frontend/assets/Index-D80jikzp.js,sha256=ircnH--S2ppJ_LnUr4FddahLS6Zzs59hMFPbckbLDG4,6884 +gradio/templates/frontend/assets/Index-D80jikzp.js.map,sha256=0TSmhM5zY9fcJFPBvIhQA2YJEke5QBRCX6dq2A1Wvbo,8166 +gradio/templates/frontend/assets/Index-D812IjdW.css,sha256=YOuUd4-geKXWUDqcoa1HKdWxlR9WObxN6fmamqXSn1k,3342 +gradio/templates/frontend/assets/Index-D93tjYm5.js,sha256=oUb8Sp4CxgvEnner36asUnFAv7zl-LRC1_E8nCCPwlI,20837 +gradio/templates/frontend/assets/Index-D93tjYm5.js.map,sha256=5LLvFqOIBNdgv4WGFmNHBvheXm7gCdgw8o1VoWNvlmA,23057 +gradio/templates/frontend/assets/Index-DFtgEU7U.js,sha256=eifXUgeKzHSvEwPbUDDIjhYYunPBtn_Wf1ZmJIIVqxk,41620 +gradio/templates/frontend/assets/Index-DFtgEU7U.js.map,sha256=nelw7ZyhUzKNb88LLrq_Ax-1KTe5DfZQ8P0sh7KLJmo,50444 +gradio/templates/frontend/assets/Index-DI509U_e.js,sha256=qmJJyM0RzOELX8Anw7s_GK0tuKXANxKreq25x-T1Qvw,462033 +gradio/templates/frontend/assets/Index-DI509U_e.js.map,sha256=HHvQqE6W3u6FVzj9afHUr0sMJPfRhtx7VfybNeR-2ZM,1700552 +gradio/templates/frontend/assets/Index-DKVik73_.js,sha256=1r71RKYYDe4428QLDTs9Ea9ji-7gEUUfZHQ63BfHHHg,37750 +gradio/templates/frontend/assets/Index-DKVik73_.js.map,sha256=S1EB6i5HNHCT3KiDR4cxAL-oTP-4X4aN4rJnoR6AvNY,51634 +gradio/templates/frontend/assets/Index-DMXFGchm.css,sha256=6Fw0_PzkhcgQHYJzVnTd4QZj9bNJ7SSIJ1lEgjhdVeU,475 +gradio/templates/frontend/assets/Index-DRmgII2F.js,sha256=12E-jqbKiNk6rBVLgL1W1GC_yX6GSl-G9rjy5vvu4pI,5423 +gradio/templates/frontend/assets/Index-DRmgII2F.js.map,sha256=PPpXVQ97qXuL2qPDPUVUz8HwaQIzBWEJIH6ia0zF8po,3342 +gradio/templates/frontend/assets/Index-DTopiiMh.css,sha256=xAdFpslGVCdsVpMohnFcgOc9JbbDoYz9GDKfh74PYEk,102 +gradio/templates/frontend/assets/Index-D_8bvB3d.css,sha256=XpQdJaOWWIq1wCytnVsaaJI4Ae3ukmlIfAWeD9R1SGk,278 +gradio/templates/frontend/assets/Index-Db-S_rhj.css,sha256=mNM5gk_u6OoGvwQ510GU6lg-ZiF75eTtnntgZubQnvw,2492 +gradio/templates/frontend/assets/Index-DcuC0IYx.js,sha256=IbMKrh1_GKXwq-cb1WxfKSHWRSn5jcjq-8-rIJBDL3M,3813 +gradio/templates/frontend/assets/Index-DcuC0IYx.js.map,sha256=uipxucpDf-1hGQ6c4YhfnajZVELMvfGiTsbChu6WMpI,3309 +gradio/templates/frontend/assets/Index-Dko6XNbv.css,sha256=czy7Mi0EFZpNxEtN0UVQ71cS8IUVWo5puXWaehp81vk,3340 +gradio/templates/frontend/assets/Index-DnPJ43ZZ.js,sha256=gcQY4baN2jRr-w3zBjNjkpom24Wcy3GTZujlmk9imGs,58335 +gradio/templates/frontend/assets/Index-DnPJ43ZZ.js.map,sha256=v9qQh1RiDW6nDhGAyEOFZuenIyoD7gFU2LW4DrTjVj4,88559 +gradio/templates/frontend/assets/Index-DqCgYdoJ.css,sha256=l284XOHKOh3i74lUdyFY3gC8TNFHbexybWeytG9utUc,6849 +gradio/templates/frontend/assets/Index-Dwn46RCV.js,sha256=QXM0femMXeEP7Rq6yxlDZXOzChfpeeADgrRdF9jqVrw,8873 +gradio/templates/frontend/assets/Index-Dwn46RCV.js.map,sha256=2VUQ8sk3pIEJjHvFg9DZX3MTvoeBN2zhKuFQLSn1IPA,9985 +gradio/templates/frontend/assets/Index-DyBEaHjs.js,sha256=LLUXZfi_JK1k2KFK_4YLEnm3KghIq6umgky0-RhhFJE,9115 +gradio/templates/frontend/assets/Index-DyBEaHjs.js.map,sha256=zECQX9E6O_dMTGmfC40TVgzzezZblAybtaY93R0HMIU,16816 +gradio/templates/frontend/assets/Index-LbNTTE3T.css,sha256=aY6rE2rH3hzdfL00CgTGEO85BYSf8DtFas4_N_CZpyg,18309 +gradio/templates/frontend/assets/Index-LsyOdqMY.js,sha256=HRqnfT1oC-nJCm7epE6AoSOHaDAGs6PIcutQMNtYz_s,7945 +gradio/templates/frontend/assets/Index-LsyOdqMY.js.map,sha256=ogIfCYUtl-maqShDl6MQi0e8ZTawgYABAVd1RcrF0g8,12056 +gradio/templates/frontend/assets/Index-ML6PhJec.css,sha256=MQGDwfJzNreLqC7K5OVItReEEUAB_D2f3cYBos-HijI,1863 +gradio/templates/frontend/assets/Index-NxvmjJPq.css,sha256=79HrJ2F1fVdICe4oUHMKYre6r9UY2rrHdEveKN75M7s,137 +gradio/templates/frontend/assets/Index-VLJFaMM1.css,sha256=6_VXDDi98fNi772a-_GavH2QyY0H6oVt5UvgVCHJCN0,3268 +gradio/templates/frontend/assets/Index-YcGCkygm.css,sha256=BYw8aNj37nBAYjxQJFSnuZ7VffSpwuzp4ll-SBXtHZQ,348 +gradio/templates/frontend/assets/Index-a-pQRFMj.css,sha256=ZHuNEhnBhOjn0Z2_OjmAQ4SodoDLqUQLhszF4KgMYPQ,2507 +gradio/templates/frontend/assets/Index-cwl6r4yK.js,sha256=Yzy4F6qW5wAs4aj-H4iqC6dBj1s3YkwWRuqpCf8G9BI,1508 +gradio/templates/frontend/assets/Index-cwl6r4yK.js.map,sha256=2nVlcYvyDbZ6bm4g4jo6Q03VMo09FzQ34JKGVtSVm58,1540 +gradio/templates/frontend/assets/Index-iJ9qCsik.js,sha256=6BSE3t8X2i5SlfnAcUu4y_UTfDUtqiQ8fxp4Y3mrwIA,8205 +gradio/templates/frontend/assets/Index-iJ9qCsik.js.map,sha256=WFzc0YHkb04UsIqqGM61s8IMUjM8FghDGy0v-E-_Dl4,13133 +gradio/templates/frontend/assets/Index-mSlsptTy.css,sha256=DMbaY8lCSKTCov7OjbUaB7a1jm1HTXiwuEV9UE_r-Ok,333 +gradio/templates/frontend/assets/Index-mr0iIpbh.css,sha256=zjCpyXzLvJTOghtqMv4NmzBALzxVotpu6pImfLOnaAA,2680 +gradio/templates/frontend/assets/Index-pH7dzLsN.js,sha256=cH99gy--D4cFFiAv0IOaTEHrKRBHDtaxMqrP1LctZDg,15238 +gradio/templates/frontend/assets/Index-pH7dzLsN.js.map,sha256=L4SljugsiSjw5rXJvsKIEOW23-mF0Jd8fYN8H10BE0I,16761 +gradio/templates/frontend/assets/Index-tCOkHk2O.js,sha256=-6XcwaArG5PnBv2NS0tIB02BOM7EEda7Om8nm2BdthE,24714 +gradio/templates/frontend/assets/Index-tCOkHk2O.js.map,sha256=6wVFTrOpt8YNKFjlxWqDCtwzDvlNqxHTf9lXa25-UeA,18494 +gradio/templates/frontend/assets/Index-uRgjJb4U.js,sha256=V8ssur9VfcLaZcjllUox1HpN37fQDPoUqWG7aCwlEhw,215 +gradio/templates/frontend/assets/Index-uRgjJb4U.js.map,sha256=ocfZXZ-eRfFWEcqI3eUizQQvPyTtQ4jI-skRYYy81zQ,98 +gradio/templates/frontend/assets/Index-xY6e4O2k.js,sha256=gwaqPqbRcIfWocU0sKxg1D35Tg6WOL5DtYi6hxqoavo,6568 +gradio/templates/frontend/assets/Index-xY6e4O2k.js.map,sha256=xqqR4jtSedHQDkLCOBFlqDrpnvwkce07L6W5SyVbSH8,16458 +gradio/templates/frontend/assets/Index-y7Nikn1a.js,sha256=0upMbj3Mz5yaU4PcO_uBHurNlcmgpkwyS2BJo06L878,7380 +gradio/templates/frontend/assets/Index-y7Nikn1a.js.map,sha256=QYFLbnAhn-KIyP_OdlcCdv4V-Oez_X7yhnw9C4fOAZw,10512 +gradio/templates/frontend/assets/InteractiveAudio-DVY93Upe.js,sha256=fgGB94fyjeqg0xur2D_8MoKRaajV6AhpO3_iimVt-QE,38504 +gradio/templates/frontend/assets/InteractiveAudio-DVY93Upe.js.map,sha256=vOkcHSdjDyZ-rBP0i_y5v66waezNkiGv4ySVVZCiMOA,55916 +gradio/templates/frontend/assets/InteractiveAudio-DkbXm_Wx.css,sha256=jeVtIM1654vbhMm-DNUPSu19LzGDXET6X2VnDavk1-o,6505 +gradio/templates/frontend/assets/JSON-DtX0YR2l.js,sha256=Ou_nSpf5D_0obgeO-eHoDw926h_8phupO75jimc4uf4,13630 +gradio/templates/frontend/assets/JSON-DtX0YR2l.js.map,sha256=PRMtVMu2kMvRGNMK_oCX3YjsFrwGfFQ1DOZaoVqoUZs,16287 +gradio/templates/frontend/assets/JSON-oocacrvV.css,sha256=53DymkTNZs-ATZ8D8AJGkkipL-43I1KO10TN_x9GKpk,2301 +gradio/templates/frontend/assets/KHR_animation_pointer-BeHq9L-5.js,sha256=P-Ns5nApgmbTL0tFbqlK_rPnLrpy4z7OrRETrMN20bU,14913 +gradio/templates/frontend/assets/KHR_animation_pointer-BeHq9L-5.js.map,sha256=KRUj9lARIZhDKawT_e2vv7b8MxPL0Wm-4S9sF-Kep88,37117 +gradio/templates/frontend/assets/KHR_draco_mesh_compression-B_A30f4F.js,sha256=mIB3ZjkZnuYTkkqYFUG46nEYvBncNIi-D3ZfQoRrbqA,9218 +gradio/templates/frontend/assets/KHR_draco_mesh_compression-B_A30f4F.js.map,sha256=onplhuIrn70PKkdROpmA0TNLhGBgC41Upa6coGDu9Uk,47654 +gradio/templates/frontend/assets/KHR_interactivity-BU9clz1F.js,sha256=G-_WSzjv8tty3kbCwH3Mi93Bw03-ibGxtZNiBIr0SyQ,76551 +gradio/templates/frontend/assets/KHR_interactivity-BU9clz1F.js.map,sha256=T_tBOeIpBgfn8F2MYB0ZUR2LKMADyHHVr0QjOaFSSKU,207043 +gradio/templates/frontend/assets/KHR_lights_punctual-Cj86u7xc.js,sha256=m1KbgdU-IgRGAURaF8Q87eXm4D6F-2q14WqPJFZiPO4,8759 +gradio/templates/frontend/assets/KHR_lights_punctual-Cj86u7xc.js.map,sha256=BgxGYvAG-JZcgWl15LibezvHpcnYXo1-MBKnQfR62AA,36154 +gradio/templates/frontend/assets/KHR_materials_anisotropy-CznKZrxW.js,sha256=d4WyKubBHmC-w8ybEjcb_WUNJRAacaf3Ro2dG7olhaA,1351 +gradio/templates/frontend/assets/KHR_materials_anisotropy-CznKZrxW.js.map,sha256=282ARfuEh9bHze2Oe6SRO9ZzAHXJf3F9CLX28hQBF5g,4219 +gradio/templates/frontend/assets/KHR_materials_clearcoat-tH1_e5WM.js,sha256=yCikUMDqxYAH-bZ_neD102ccopl0wnRW6PkiIIjvBH4,2177 +gradio/templates/frontend/assets/KHR_materials_clearcoat-tH1_e5WM.js.map,sha256=FumGkqLtrtfbD3o7cmiAAoh-Zut652CBb_c98Ah4Xf8,6561 +gradio/templates/frontend/assets/KHR_materials_diffuse_transmission-D6VWpVZG.js,sha256=x1IuyQp-tQGz7pVTCKbrlnA42CjweZuCEf1YfGU-8e8,2240 +gradio/templates/frontend/assets/KHR_materials_diffuse_transmission-D6VWpVZG.js.map,sha256=FSExVa2KV76ZuzxJbv-COC4qqgZA8nGd5GkcFxhJE0U,6649 +gradio/templates/frontend/assets/KHR_materials_dispersion-CX8Ra3EX.js,sha256=v25UyAIN_1g3_XQ-20enBecu1_rbvKNCv8OzxqOiXnI,1116 +gradio/templates/frontend/assets/KHR_materials_dispersion-CX8Ra3EX.js.map,sha256=3pMaCEXBXUC04Tqb84f9ZdjQBtUQk2xaZo2O0NpdKEA,3839 +gradio/templates/frontend/assets/KHR_materials_emissive_strength-DHm-TyZx.js,sha256=cc6JFHpx4Pe-dGywz22Q_pUN_POGoO9a8dFzqgaYZw8,981 +gradio/templates/frontend/assets/KHR_materials_emissive_strength-DHm-TyZx.js.map,sha256=74ADiGiq6LiphxAKpdf35S-mkBrbF3CZMRv_YMWf-vY,3176 +gradio/templates/frontend/assets/KHR_materials_ior-Bv67dCzu.js,sha256=H8J_CNqk_3uuqOz-dXIZYRr2ou7LYer6xEj-843ilS4,1048 +gradio/templates/frontend/assets/KHR_materials_ior-Bv67dCzu.js.map,sha256=_DlVG8XTIwisuoqBb1S6XwlBUolSK9PPloXrCdRSGps,3524 +gradio/templates/frontend/assets/KHR_materials_iridescence-DM26kewg.js,sha256=PPMOgGthpSdkuHcpktU_JfsaXri4Z53Fsfr7vpS-BZE,1693 +gradio/templates/frontend/assets/KHR_materials_iridescence-DM26kewg.js.map,sha256=hFDjspFT-8PFrlEoAOnp0Fi5bRFAlVi846nnLWTuPE8,5040 +gradio/templates/frontend/assets/KHR_materials_pbrSpecularGlossiness-Dsydq26k.js,sha256=Tw1zcPjzs_8FQQeRehiAf4cSuNAO55tE6sIdu3Oaefc,1843 +gradio/templates/frontend/assets/KHR_materials_pbrSpecularGlossiness-Dsydq26k.js.map,sha256=afH14hzywDLJzAAkR4uSEB47FBpqqcrqlXNI8Wkxek8,5731 +gradio/templates/frontend/assets/KHR_materials_sheen-vROdrnsq.js,sha256=dGdYpfuJVdP-QGlSsqsCgTeViyMrig0k558x1i90KM0,1688 +gradio/templates/frontend/assets/KHR_materials_sheen-vROdrnsq.js.map,sha256=uWyusT2icQWSRmZ6tdMMK9SSd7n0ZSIOLsd9VPTXyTg,5494 +gradio/templates/frontend/assets/KHR_materials_specular-DqywsOvo.js,sha256=Ls0Q6Pc9Z2SGQPoX7EoArVPzWd4gcUP9uZ0KiLRUdGs,1612 +gradio/templates/frontend/assets/KHR_materials_specular-DqywsOvo.js.map,sha256=990JAfxtd7atJguO-QvoMF5ZAGDKbUXpSRdbPhBNRDo,5002 +gradio/templates/frontend/assets/KHR_materials_transmission-D1xAsnWs.js,sha256=MPUcaW7SngccdYvpnn6UnPpxLKBqIe1Rz37Kiv8vymM,6262 +gradio/templates/frontend/assets/KHR_materials_transmission-D1xAsnWs.js.map,sha256=Sj5HitCRHym8-vlLIARvSTNkJd-R4Ln0rt66uRfPzRk,18819 +gradio/templates/frontend/assets/KHR_materials_unlit-SL93Xz8E.js,sha256=pGa25yAJ6L0AO3QnweHSiwKvHY0GgxeB6kFYckcSNrk,1310 +gradio/templates/frontend/assets/KHR_materials_unlit-SL93Xz8E.js.map,sha256=N2dMTbUvgUHbJMz9jPwALLIQckLuy_RfK-xysvOcaWU,4358 +gradio/templates/frontend/assets/KHR_materials_variants-BTAYdyKX.js,sha256=e7nPi680BW5ZUd8vfBYGasSrd6lhIXENdYeSNJVcJDc,4039 +gradio/templates/frontend/assets/KHR_materials_variants-BTAYdyKX.js.map,sha256=feSrGuh8rEoWXfUQeEiKBIibkh5daxOgvEX4ifmDu14,18339 +gradio/templates/frontend/assets/KHR_materials_volume-m22R6kQq.js,sha256=h9zDiJ7OvfdASLcPz-PF895vN8I4ql0bT1ekL7dedf8,1888 +gradio/templates/frontend/assets/KHR_materials_volume-m22R6kQq.js.map,sha256=OChwVJbZLNY1t_LpA63mV6M_yQpUfsuUOphAMP9Enx4,5971 +gradio/templates/frontend/assets/KHR_mesh_quantization-DRjaYVe5.js,sha256=gzNBgXS-ibAgGxwKGdZLyF8tSnsgHr2eKrJ7gy0gc4Y,337 +gradio/templates/frontend/assets/KHR_mesh_quantization-DRjaYVe5.js.map,sha256=ohv1zMUXB82p1AJRlMhsz0QKIrpATAUZkQcpYR8F0cg,1424 +gradio/templates/frontend/assets/KHR_node_hoverability-DtuaHJb3.js,sha256=PibfHBhbmVU9WnA3XNm2ddySxtWg4D6smBvXBzAT4Sk,3462 +gradio/templates/frontend/assets/KHR_node_hoverability-DtuaHJb3.js.map,sha256=1pxlMqjsouA3j7ueOUEzddzq2cO3xSZKU8lKywetr88,11365 +gradio/templates/frontend/assets/KHR_node_selectability-Bw8uJ62d.js,sha256=YjxS57n83OKQtWzmc-CehOjk9B21RyhQdtHdIsRjMBY,2246 +gradio/templates/frontend/assets/KHR_node_selectability-Bw8uJ62d.js.map,sha256=b4cY6dGcymzywWJ-4zD5ytqwb0a0dMLunUrA2AuheDQ,7351 +gradio/templates/frontend/assets/KHR_node_visibility-C_53WdIL.js,sha256=-vU4e10tBB6eBRUw6LHMwJq1OFEDAyKjRDfvgUY9Erc,1164 +gradio/templates/frontend/assets/KHR_node_visibility-C_53WdIL.js.map,sha256=Ic2Om733DntX-vQovh52dax-y-T_n5QIz2D0XkHK_40,3804 +gradio/templates/frontend/assets/KHR_texture_basisu-BDX8BNQm.js,sha256=Dz24vV2DzC3_6PNeJzMM3pbRfhmxe6TVZrZw_UEmA30,965 +gradio/templates/frontend/assets/KHR_texture_basisu-BDX8BNQm.js.map,sha256=qP5_4NRa2fW-0zRQWtZCLfhHrNc0kqifc80Rc8Ab1g8,2882 +gradio/templates/frontend/assets/KHR_texture_transform-DHEIKUY1.js,sha256=xsOyFiV3kjXN_4CzD3WYMV5OwHzWGNgvhQvUF0UuFcQ,1009 +gradio/templates/frontend/assets/KHR_texture_transform-DHEIKUY1.js.map,sha256=L2nVmMdJvdXSW9X1h5-OYtISd1ZhstCE7b1Fp5XjDgU,3641 +gradio/templates/frontend/assets/KHR_xmp_json_ld-C9Ws3mg1.js,sha256=QUT5FEDy41nAWhjIWd7YH19mHqYigLpb14XZQhs6-oI,740 +gradio/templates/frontend/assets/KHR_xmp_json_ld-C9Ws3mg1.js.map,sha256=UP3UIGcBTeI2BHkOy8_jNOv77lLPLuRMexvBtQTO1jw,2715 +gradio/templates/frontend/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2,sha256=DN04fJWQoan5eUVgAi27WWVKfYbxh6oMgUla1C06cwg,28076 +gradio/templates/frontend/assets/KaTeX_AMS-Regular-DMm9YOAa.woff,sha256=MNqR6EyJP4deJSaJ-uvcWQsocRReitx_mp1NvYzgslE,33516 +gradio/templates/frontend/assets/KaTeX_AMS-Regular-DRggAlZN.ttf,sha256=aFNIQLz90r_7bw6N60hoTdAefwTqKBMmdXevuQbeHRM,63632 +gradio/templates/frontend/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf,sha256=B9jjA85PwStLtU8QBBcN0ZCh89tF1AD-aAYN8-CJcmg,12368 +gradio/templates/frontend/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff,sha256=Gua9dHVZDpfn8UWongnM3jIvemvAuRYHsci47igpD-0,7716 +gradio/templates/frontend/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2,sha256=3ncB5Czx9M8LdmwD-yeXcgfu4vT9XXb6ghiEBtpD6kw,6912 +gradio/templates/frontend/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff,sha256=M5jdAjAlV6eT8oY_iOAtls4Q3yq_-gfI6fqQd1EW5lw,7656 +gradio/templates/frontend/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2,sha256=XVPnCtYHwjUhYt7J4JI_tU7Nr6zL9gTNjc99APrLmJs,6908 +gradio/templates/frontend/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf,sha256=7Qt0Ny_u_LucBmay4hDaN7fkn6f7vz7rEdtfaT2s-7c,12344 +gradio/templates/frontend/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf,sha256=kWPfnHEiQy5klbQin6kHHPmuhqdYrl78SSTsLhptvOE,19584 +gradio/templates/frontend/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff,sha256=m-fOuIAEq4rRJAgiRvv8ykCR42OF1Oxu0d9nN12tUPs,13296 +gradio/templates/frontend/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2,sha256=dERO_Vk8AF4_RXO0RSRwTArwqTf-kRzKnpQGjQ0UDT8,11348 +gradio/templates/frontend/assets/KaTeX_Fraktur-Regular-CB_wures.ttf,sha256=Hm-VeekOLKw3-PYKWXxDbgdcEUOFZSt8vrDewEISkbM,19572 +gradio/templates/frontend/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2,sha256=UYFNJw0G_wJV26B5mZT6TYyE0R8JlR1HWV9Kux82Atw,11316 +gradio/templates/frontend/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff,sha256=Xih1O-cX2sl_VZ9JvBC-nPPBJN3KvaZlnRHLaP68ZGM,13208 +gradio/templates/frontend/assets/KaTeX_Main-Bold-Cx986IdX.woff2,sha256=D2DRuJeTjskYyM4HMJJBG6-UOPZzlGVpP_GLD50gsCE,25324 +gradio/templates/frontend/assets/KaTeX_Main-Bold-Jm3AIy58.woff,sha256=x2xdaWKX1RucsWOcfaQzTw597IG0KxEhO14l72cbuCI,29912 +gradio/templates/frontend/assets/KaTeX_Main-Bold-waoOVXN0.ttf,sha256=E4rCjRZjswN-nF9SNx-lxj2DJPSjjSLNVz5uo6P9DPg,51336 +gradio/templates/frontend/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2,sha256=mc1Co8By2Rjy9EmEqAfPeqFuE1Rf0IdfwHxsZfmecVs,16780 +gradio/templates/frontend/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf,sha256=cO4fZKIPIEjCGUDvRtAUT9IVuqlTymmv0eMemFRPcI8,32968 +gradio/templates/frontend/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff,sha256=pvfsDYRqx62XWtuJWcN-1JuUrLxK5DbbnOniAofkpkw,19412 +gradio/templates/frontend/assets/KaTeX_Main-Italic-3WenGoN9.ttf,sha256=DYWufMMPI3kKfxpYxKES_cqKrnaba6EUKa8dmLG2yzo,33580 +gradio/templates/frontend/assets/KaTeX_Main-Italic-BMLOBm91.woff,sha256=8dbvhvOxGlKL1RhRmb0kQ-yysN6tltiGdLWiwSviS98,19676 +gradio/templates/frontend/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2,sha256=l0ecpszpBqvJYeyslvql-couYbjnZw1HWCa83umnwmc,16988 +gradio/templates/frontend/assets/KaTeX_Main-Regular-B22Nviop.woff2,sha256=wjQs2Lhp4BdSqTIdwXIT_EDU0Ex5aIwdQ_LPMWq9eGY,26272 +gradio/templates/frontend/assets/KaTeX_Main-Regular-Dr94JaBh.woff,sha256=xjaNh-iho6XTN2I9g9jcS4aPJCqa1HYjfW-NHg8WjNw,30772 +gradio/templates/frontend/assets/KaTeX_Main-Regular-ypZvNtVU.ttf,sha256=0DMvUoaDcP2Drn-kZHD5DI8uqy_PErxPiAgLNAyVqDA,53580 +gradio/templates/frontend/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf,sha256=-Td6sCcc2lmvJLz_vUak0MijVy_6_bs43irV6nsNXuU,31196 +gradio/templates/frontend/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2,sha256=3Ec0TbtstbZVyEYNVh9N9fUBuQyAStPGzsZf4yI1GrE,16400 +gradio/templates/frontend/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff,sha256=hQwK9cIjhJf-uvXkYdiAv0WMNB9C9PMw8bGrVpixmY4,18668 +gradio/templates/frontend/assets/KaTeX_Math-Italic-DA0__PXp.woff,sha256=io0kRYE3GRK48_WiPiQ3yypZzZvK67A0bnIsBXN6JXE,18748 +gradio/templates/frontend/assets/KaTeX_Math-Italic-flOr_0UB.ttf,sha256=CM6Y5RsE1YlFowHmOeAraZivKf39Yae4r90Hu_xHnUo,31308 +gradio/templates/frontend/assets/KaTeX_Math-Italic-t53AETM-.woff2,sha256=evWMXsjxMqLd3pAnxteBTezOTTuCKhEZKkKiDi6XMmQ,16440 +gradio/templates/frontend/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf,sha256=Hs4D95-VJ31X3H9rQ1p04TebDUYQSoUwKGtg_0k2nqA,24504 +gradio/templates/frontend/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2,sha256=6ZrlEUS_EjLvzBv-Wt02JixoZrD6qyT6dXQOG5hXemI,12216 +gradio/templates/frontend/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff,sha256=7OA8_YPiLCEs3vZv64RC0loIO-uYjbPxiD8_lzjXULo,14408 +gradio/templates/frontend/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2,sha256=ALJqyCXiCVBWOW4FU7isJtP4rRWMOCbii0xFs4XEcUo,12028 +gradio/templates/frontend/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff,sha256=ke5nUAzAEpqgrOOsXGH_FpIQLw8x0CtpNH-6Ndy3W_I,14112 +gradio/templates/frontend/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf,sha256=OTHdgfrthroCG7K73Db1vtmjjWtPQHespZsmWqGwIIM,22364 +gradio/templates/frontend/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf,sha256=826ol-GfSi5XHR6QDk43EOQ43rBahCSGBFugo-YWpK0,19436 +gradio/templates/frontend/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff,sha256=EeTcimRx_21u5WHVPRD96PdInnmCV_9EnF03wZdDVgU,12316 +gradio/templates/frontend/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2,sha256=aOjHPvQq_TzOxYvw-6MCzORIk45_wCCl4x-KlS7uE0I,10344 +gradio/templates/frontend/assets/KaTeX_Script-Regular-C5JkGWo-.ttf,sha256=HGfwaP6ouwm_CZwIixz2S9J1Fqbgf0aENEhzVku2amc,16648 +gradio/templates/frontend/assets/KaTeX_Script-Regular-D3wIWfF6.woff2,sha256=A21OlRSbaf-bzAzVV3Hv6yX_o5Ryk-aazXjVrDKMaEs,9644 +gradio/templates/frontend/assets/KaTeX_Script-Regular-D5yQViql.woff,sha256=2WzfKzvdTWSo_V90pMRn8SOopzkxzUNYifCP-vm_lHo,10588 +gradio/templates/frontend/assets/KaTeX_Size1-Regular-C195tn64.woff,sha256=yUPMmGOE9Z6GvqX9fcUKnE3-Vnp8BetA1nkHIN6tl8k,6496 +gradio/templates/frontend/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf,sha256=lbbS8aUBc7_tuMY-HRyZsQQn0KTfQgHLRFE7ImlRois,12228 +gradio/templates/frontend/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2,sha256=a0fEAWa22-IaXfyncYQT8hR_0jmb4bpgXYrTnO3yXf4,5468 +gradio/templates/frontend/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf,sha256=prIJn7VVxg46DbOgiELr8dcyxutOS_RJE2E77U_E45s,11508 +gradio/templates/frontend/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2,sha256=0ExUIZ-ersbU1P1C37KHhZdaR5TWsvxx5Wa5zW24Qt0,5208 +gradio/templates/frontend/assets/KaTeX_Size2-Regular-oD1tc_U0.woff,sha256=IBTFI8MhC8wWZkjE1MxX8Ft0ffB6JCd79xxR5n3Hnj0,6188 +gradio/templates/frontend/assets/KaTeX_Size3-Regular-CTq5MqoE.woff,sha256=ara2Lpti2uLADdkPeRvRCVC-Dsw0kNfWBF9Rwuj-CUk,4420 +gradio/templates/frontend/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf,sha256=UA4E1U8NUWZjMsnSCJqoA74iqoeOylOeWfpTxuUisII,7588 +gradio/templates/frontend/assets/KaTeX_Size4-Regular-BF-4gkZK.woff,sha256=mfnGdQtInJRivwSQC9P5Od-bgpM52qqqme9Ulc3d6lg,5980 +gradio/templates/frontend/assets/KaTeX_Size4-Regular-DWFBv043.ttf,sha256=xkc2fR3U4WJGhxfQIOH8Dx3Fwm6_3_vlUmFxO_iMWHc,10364 +gradio/templates/frontend/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2,sha256=pK99QURAocF5CCXPtwDPnPQ7DyxLBPDrxSMBGtmFPsA,4928 +gradio/templates/frontend/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff,sha256=4U_tArGrp86fWv1YRLXQMhsiNR_rxyDg3ouHI1J2Cfc,16028 +gradio/templates/frontend/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2,sha256=cdUX1ngneHz6vfGGkUzDNY7aU543kxlB8rL9SiH2jAs,13568 +gradio/templates/frontend/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf,sha256=8B8-h9nGphwMCBzrV3q9hk6wCmEvesFiDdaRX60u9ao,27556 +gradio/templates/frontend/assets/Login-BMGWFjDF.js,sha256=xdnKUX1d0jCJMAo52yF0HxOYx0BBGgjKoJJBwF0Aizw,5646 +gradio/templates/frontend/assets/Login-BMGWFjDF.js.map,sha256=opGEaXu0uo_l-Cmnv-9o-mMF9xFfq9PrlhEDXeC0hTo,4911 +gradio/templates/frontend/assets/Login-NNqXlI-L.css,sha256=nDzA60TP2DetL139EpQ2X47LdS1H7xyjmJHmxE9ohwk,578 +gradio/templates/frontend/assets/MSFT_audio_emitter-DWXlGOc0.js,sha256=-7M9dcvodCGWTyBiZ-QN5BqlvNiCOyR3ExZCN1dBIKI,36955 +gradio/templates/frontend/assets/MSFT_audio_emitter-DWXlGOc0.js.map,sha256=p665xsuhHwpR2Xh2xVs3oJicpoyFQjoHxXXOdOKMheI,131375 +gradio/templates/frontend/assets/MSFT_lod-DBH-CmU1.js,sha256=wIiwCsp6jnfZdCmfGdYvn4qkHhi-FGZwfk2FsWWEO0I,6003 +gradio/templates/frontend/assets/MSFT_lod-DBH-CmU1.js.map,sha256=2DLk1AcABczbrjETfgpINaGo2GiCRycyEfPwfkHg7tI,22145 +gradio/templates/frontend/assets/MSFT_minecraftMesh-BjiIHEgO.js,sha256=Gk0an21maQSYkamtgcs3fo5HfDCCuXgsBEVi0nrr5yE,940 +gradio/templates/frontend/assets/MSFT_minecraftMesh-BjiIHEgO.js.map,sha256=0qBlc35oRLb0XjEHoWtQm76BD-h0WIlRGi8zGFVWaZ4,2881 +gradio/templates/frontend/assets/MSFT_sRGBFactors-UBPuhZ-t.js,sha256=-9MPRIXTprc72a45Xx6WedRdNOZaC28JJFQ4XpOj2NM,1008 +gradio/templates/frontend/assets/MSFT_sRGBFactors-UBPuhZ-t.js.map,sha256=GiCcKVvcMpa90x7LT0hDiSwGq_W3NfInVie7XdLZYso,3129 +gradio/templates/frontend/assets/MarkdownCode-Ca9FjBJK.css,sha256=oGRS2u3OYkd4XIa2cZsx-XdsSrgx7-ZkqMQKQi5qTHU,5155 +gradio/templates/frontend/assets/MarkdownCode-DTX-UkhB.js,sha256=IcKzrfN-lQi2feo6sa1wNcBIc9B25VmOHVq__qFgJZM,97553 +gradio/templates/frontend/assets/MarkdownCode-DTX-UkhB.js.map,sha256=HBDTXtB-3CcDcQvhrbo85fFkvSknUD7WscG7hQ-4SaY,288597 +gradio/templates/frontend/assets/MatplotlibPlot-CU3kl0KV.css,sha256=FjyW59ACE0ikEFE2_IDo0vIPCcyMEMBbaDlVOae3RSI,253 +gradio/templates/frontend/assets/MatplotlibPlot-Szs_zUfS.js,sha256=Rxjgzj0PKzPZ8W5qS9aAzG3g7AzIosmb0rLuWYtjj5g,1028 +gradio/templates/frontend/assets/MatplotlibPlot-Szs_zUfS.js.map,sha256=IFFxzXanYvhvKTua1_hNLbHYqslu9FEI9woad2M5qXQ,1154 +gradio/templates/frontend/assets/ModifyUpload-CMsAygJb.js,sha256=pvgwZGwEtF42myZZFCxP6mBJivBQnyDGW6bMvc5PlW0,18412 +gradio/templates/frontend/assets/ModifyUpload-CMsAygJb.js.map,sha256=Wmyzs4tXREpicHEff_qOWABaMFWP3OgTFFPyvibmjmE,32873 +gradio/templates/frontend/assets/ModifyUpload-REHVxGq-.css,sha256=IxQ8sG8dtxNyf-JeqTG7f-34_aT_7kD8XdcwHCICIFY,2094 +gradio/templates/frontend/assets/Plot-m9koEqIw.js,sha256=imFaAbqqiQkeLcpzcR314KK34ZO8FVgYseN4OYKyuyw,6072 +gradio/templates/frontend/assets/Plot-m9koEqIw.js.map,sha256=ngu8j-ihei1xNImcssn7sqPFKG9G4N1q7tdpwCRBCBU,3732 +gradio/templates/frontend/assets/PlotlyPlot-CVVZkV50.js,sha256=YyRTDHIysdUOUKIUFdQJUCzDXdrl5tnf_oYUyHpR2zE,4619548 +gradio/templates/frontend/assets/PlotlyPlot-CVVZkV50.js.map,sha256=4lS0Xc_OQC7_zM_6RpIFyXndiGm9-nJaEx4SL1ga84M,10867731 +gradio/templates/frontend/assets/Settings-BELQ81Ru.css,sha256=_GRdTUxXFGzKH-Hfd3ly_xqpGFj6JXWgG3H7fKezhQY,2675 +gradio/templates/frontend/assets/Settings-DWGeY4PJ.js,sha256=HJi0J5U3AM0fRxy9xfc6WguJby8WxkGmAR0xU7iIm34,11018 +gradio/templates/frontend/assets/Settings-DWGeY4PJ.js.map,sha256=rHZAdjMTUi9qXNbEGyZghHGwiUSBqfLCeFsH-8hhqu0,14776 +gradio/templates/frontend/assets/SharedSystems-OU6wCEA7.js,sha256=KPK5v4hM45AdFuCWngFIqDYQTqttW67XLHOd3FJCaOo,50310 +gradio/templates/frontend/assets/SharedSystems-OU6wCEA7.js.map,sha256=rlbsd2UzmQwbwaRpXfRr3WQmAZMzXvDjoT518Ud7r1o,172936 +gradio/templates/frontend/assets/StaticAudio-B8mpyYv7.js,sha256=5GYlmXn0I2P8thF_8YqG34es-OGBIjs9QawWDwM5IrU,6970 +gradio/templates/frontend/assets/StaticAudio-B8mpyYv7.js.map,sha256=6tF5lzmzy7aTubKypP4vsN_MezkSyTLtIqyo_XGi2UM,4422 +gradio/templates/frontend/assets/StreamingBar-BtwDBaPl.js,sha256=fp8N7v-4hRUMoccuBkgVaSQy_prKddANQV0S1HVv4_M,30494 +gradio/templates/frontend/assets/StreamingBar-BtwDBaPl.js.map,sha256=jLAUrYYeZ-9Qe524pEKNlOpxPJkAzl_JCkOkLXL_7eo,73450 +gradio/templates/frontend/assets/StreamingBar-Dq7cCzkm.css,sha256=lL-M2kxuW79MQwfIZghXaw-UGCzpXI8iLy8JzelRp3I,9363 +gradio/templates/frontend/assets/Video-Dxr2ByHH.css,sha256=qAw3K4D7yNVXazTJKnrqyWL7dwp-lY_7ekFq7-UWH0k,847 +gradio/templates/frontend/assets/Video-NpeJCQXG.js,sha256=z5-riymCkLjdNKOzqZuHxN9A6o3L8GCg1CmbpMU-kQk,21777 +gradio/templates/frontend/assets/Video-NpeJCQXG.js.map,sha256=aWRr16zcz5irmf0Px9liZpDcNibw3ULXfqDeZbgbEvw,56765 +gradio/templates/frontend/assets/VideoPreview-CFjQSOD8.css,sha256=PjkGWhpaBjwd-8gamQ1ogoa9aVdMSZsVx0yAoWfYD6A,4356 +gradio/templates/frontend/assets/VideoPreview-DvsC5hxs.js,sha256=ungXMXOlXt98rNSf094DdcCqzEboc3bn5HHz5UxhJo0,28375 +gradio/templates/frontend/assets/VideoPreview-DvsC5hxs.js.map,sha256=G4m9L02Qyp3LAobuGyw2Cop8BeXXsh9_X4fTQKFNwbI,34598 +gradio/templates/frontend/assets/WebGLRenderer-CKvIAv9Q.js,sha256=PXuiqAwP4U4snzoqywrSxLUCCCWqLNxn-BXxZYwL6SI,62347 +gradio/templates/frontend/assets/WebGLRenderer-CKvIAv9Q.js.map,sha256=zOwu7RwwLhIsU7gMnST4RLTR7zuAUurvs7W1BnvnrYs,207139 +gradio/templates/frontend/assets/WebGPURenderer-DhQIiuFv.js,sha256=h7vOo4swafh1SQaQqgC3VGGkyL5FZ8YbUmwJcUxqHKU,37228 +gradio/templates/frontend/assets/WebGPURenderer-DhQIiuFv.js.map,sha256=iVs_wmc3ZTGW9Qcic3d70z51fUeob5WjxoBkeTsNCYk,123942 +gradio/templates/frontend/assets/__vite-browser-external-D7Ct-6yo.js,sha256=gLgqz-uHvyy2pHsKpI4HiVG4omFv5QWc7HvEbdZQYh0,191 +gradio/templates/frontend/assets/__vite-browser-external-D7Ct-6yo.js.map,sha256=RzUTYvOSuJHzxj3DlmuLodPaw_efLdZDyf1_nICbw74,222 +gradio/templates/frontend/assets/_basePickBy-ojZ-FwUK.js,sha256=AJm1WtJ6efzKLWQFw_dUnqQPPbHMgcdC1OrvMZfeVlY,2636 +gradio/templates/frontend/assets/_basePickBy-ojZ-FwUK.js.map,sha256=Q8ktkJT1Z5w7YcwFclpk5oL5sKMF797PA3w8t8wAXqw,26242 +gradio/templates/frontend/assets/_baseUniq-CSZt17fj.js,sha256=V4uhpW9RFAGz15pbQu6usI_7esWTbIzOVqr0KxOP4cw,11938 +gradio/templates/frontend/assets/_baseUniq-CSZt17fj.js.map,sha256=mn1KiMPf9zTNyBOZ-QDjvmfJLAF98zXIXWbTiW6BXLI,106636 +gradio/templates/frontend/assets/abstractEngine.cubeTexture-pIobeeXZ.js,sha256=vQGtZgbkVTPArizyXJkf-csDQcVyffGyXyQT_VVIfN8,2168 +gradio/templates/frontend/assets/abstractEngine.cubeTexture-pIobeeXZ.js.map,sha256=-4FDMGAXc64fbvauaZW96IyUnMYQKdI1LoiWhmtbPQU,10093 +gradio/templates/frontend/assets/animationGroup-DnocM-DY.js,sha256=ATqDw9zvda-8EHHH-tyf42Ys4Z9f8vbOiR8yTz9j9gs,34162 +gradio/templates/frontend/assets/animationGroup-DnocM-DY.js.map,sha256=rZ2mbODBwmu2RRXWc8M8UwQvNTWZBCFHXAmkystLL6M,150837 +gradio/templates/frontend/assets/ar-CANZ1fin.js,sha256=XAtl90oVMTUw3Zv-v1MWWC6nvbAGxe3ctvamIIyRak8,6246 +gradio/templates/frontend/assets/ar-CANZ1fin.js.map,sha256=sweildZck91qZXCareSVS14Ydiv_rYJzY26_IO4o1Cg,95 +gradio/templates/frontend/assets/arc-p6jRFgkU.js,sha256=WsO7QAl7AGBx-D1W-yllBGlHdtYnQl5SUIrqXbNkF9Q,3459 +gradio/templates/frontend/assets/arc-p6jRFgkU.js.map,sha256=YyKP_nRUE9xb613vAkulHavSvpraONwMBw9b2KfejrI,16993 +gradio/templates/frontend/assets/architecture-O4VJ6CD3-1bBLl1fc.js,sha256=haurGcJQLiETQOqniwOkzNkTVsmLWrTHiJDO45gIdAU,483 +gradio/templates/frontend/assets/architecture-O4VJ6CD3-1bBLl1fc.js.map,sha256=ZT1CF96HXOrxoGGMVQBYCV4g0CBd1tIZ-rJeaZ3J9rM,114 +gradio/templates/frontend/assets/architectureDiagram-KFL7JDKH-ByGrt6rG.js,sha256=SolTyRvwj5LrvH1mGb2_IEV1T_BxkftrvmSP09pNpvE,148512 +gradio/templates/frontend/assets/architectureDiagram-KFL7JDKH-ByGrt6rG.js.map,sha256=Du2HOT0KJ955PcuL6m0aS5dyMdfkkYWwfUCkB884pE0,589849 +gradio/templates/frontend/assets/assetContainer-DR1FyqM0.js,sha256=FhT4ChzmDnzsdZrrYP3d7Zhb--j-O0VZHZ5rewimYdM,25023 +gradio/templates/frontend/assets/assetContainer-DR1FyqM0.js.map,sha256=-VMxnfgpBh9KumrL4hFnBqDLcpAt3fClTZ-mrEcL3NM,101785 +gradio/templates/frontend/assets/audioEngine-DRYYoHQA.js,sha256=9M8piHerv15zxV6kxDu65_ZkD9zLcf61eH3WzsmjkPE,5924 +gradio/templates/frontend/assets/audioEngine-DRYYoHQA.js.map,sha256=nnmKLkTuUU-nanNASAgqK6EcfydaGltLdWLpo3N54Sw,17100 +gradio/templates/frontend/assets/auto-render-DsjrxxwK.js,sha256=YlB808HRAlJruTZ4Q-JPZfqnMcQRWROIIHTH5b-c8c4,2663 +gradio/templates/frontend/assets/auto-render-DsjrxxwK.js.map,sha256=po0MqKkUHjk0uc8FuLBp19Q_yCuypxSZ1v2h-85FEGg,11169 +gradio/templates/frontend/assets/bakedVertexAnimation-BmKhdyoh.js,sha256=H8K2a1XVTVVLzpkkZjc_m6sdj2l05sA1WIEm0HJ8X0U,5718 +gradio/templates/frontend/assets/bakedVertexAnimation-BmKhdyoh.js.map,sha256=EhML3ooZekM7O3CqQIEsKUl8np0xz2Ni_JXZRomB6iQ,8397 +gradio/templates/frontend/assets/basisTextureLoader-C3Dert6x.js,sha256=FkoclZviDc_JqKnNJdQn03AlrXCCNhD34mxOYPMn_xg,8227 +gradio/templates/frontend/assets/basisTextureLoader-C3Dert6x.js.map,sha256=ymx2Quxn65k-3bd7RgQTxgQ6F8Y0qxZIqKpQpQmFO-k,38613 +gradio/templates/frontend/assets/blockDiagram-ZYB65J3Q-DZp0DPsD.js,sha256=wCUf2p8r985_bLkEmaJDUyQo9H42c6JZ7_eaJnTwyA4,72015 +gradio/templates/frontend/assets/blockDiagram-ZYB65J3Q-DZp0DPsD.js.map,sha256=73HkF_JM3mnleWKT9jCzfi8ZnxHSwOFREA_fXUkC5cg,246977 +gradio/templates/frontend/assets/bone-DryszBbm.js,sha256=fwl8FiwZs5LqYb9TygmIgdj09gPTh1OCAoj-LdpkRCY,12075 +gradio/templates/frontend/assets/bone-DryszBbm.js.map,sha256=4erEopQ5gKW6XltNPVi5xBLgnx2lVHm1ZXe2cWABCDc,57093 +gradio/templates/frontend/assets/browserAll-6wJi0gZg.js,sha256=cKhs_ibUuzS-LQOQhwAL4zSRXVCd1oudRH5p1fNe5Y0,39635 +gradio/templates/frontend/assets/browserAll-6wJi0gZg.js.map,sha256=ecBrHHJuj1ncf_FGHjejjXUelAHHDOq5xkb1AIsrzmI,155581 +gradio/templates/frontend/assets/c4Diagram-AAMF2YG6-Dkrh69Ch.js,sha256=0qdwwbhNdd5_9jCpHOYUM3PGNvE1v2f8XDPOHmmdY0E,70316 +gradio/templates/frontend/assets/c4Diagram-AAMF2YG6-Dkrh69Ch.js.map,sha256=JlnHFiNgEcOCJrvd-fg82kdaGHPNhL_h2T8gs8NEjwk,204021 +gradio/templates/frontend/assets/ca-BawhR5IW.js,sha256=TyTVhO0r-cyHfL08l8v-PNJ7kL93FU0DyHPh0j7F9Fw,4816 +gradio/templates/frontend/assets/ca-BawhR5IW.js.map,sha256=lvzypYKxK_QepxWP89IdcRb7eGB4R0CP424hLnvLI4g,95 +gradio/templates/frontend/assets/channel-BHJ0cURP.js,sha256=GR51vNAUQPSCttmtb1VsAG5RO8GHBrywspbxwarb7qs,158 +gradio/templates/frontend/assets/channel-BHJ0cURP.js.map,sha256=WnpgP0cbXLN9IycdwmWkoBbIdiBdaJX_5Yb0oRLokto,567 +gradio/templates/frontend/assets/chunk-ANTBXLJU-CInu_uLR.js,sha256=OfHaz0-x9fQMTg57iQN94_zBWAxtfBcawCzgkkWHYv8,279 +gradio/templates/frontend/assets/chunk-ANTBXLJU-CInu_uLR.js.map,sha256=UzkW07aMiUFsxiHaoIJm_ZBrWA9BV0-D-p4txRD_7nM,892 +gradio/templates/frontend/assets/chunk-FHKO5MBM-oq4nb1U9.js,sha256=rspK4kdDjJFKf6GoeVCKRWScuR54qedBmG6faFQ30_U,247 +gradio/templates/frontend/assets/chunk-FHKO5MBM-oq4nb1U9.js.map,sha256=lRUfOzana1AWQ1yRV3J16qc_HPqm0Rq3nlh1Vw50CDY,879 +gradio/templates/frontend/assets/chunk-GLLZNHP4-BIq5M8Ya.js,sha256=5SbSZr5opz545iMMPp3oPBB7xgJEDPWFGFn45e-NMQI,418 +gradio/templates/frontend/assets/chunk-GLLZNHP4-BIq5M8Ya.js.map,sha256=HFYHg2f1odGtBGu4QYwP5EkvgcrlxqOLfIgcAZB22FI,862 +gradio/templates/frontend/assets/chunk-JBRWN2VN-BHFQ3H3j.js,sha256=7hKoITt2C7NlLoZ7JBBWS7crFvK5r3TEMo0UlrM3YbU,45296 +gradio/templates/frontend/assets/chunk-JBRWN2VN-BHFQ3H3j.js.map,sha256=kjEO9vRq3_v1WdOCaOczMfiUIeEIwu4bYXEi5-FGaUw,139892 +gradio/templates/frontend/assets/chunk-LXBSTHXV-D8xC8lAw.js,sha256=QxEPF6C8S0vVgPPzryZ607nNtxPeKlSVQlEDwuztdeQ,36391 +gradio/templates/frontend/assets/chunk-LXBSTHXV-D8xC8lAw.js.map,sha256=CvSk59uNgBNQO6BadHwUbGgt9xSbAs4EAVnvQGPJ8D8,121701 +gradio/templates/frontend/assets/chunk-NRVI72HA-CIqkE629.js,sha256=beCw7Kx8ffgNluQr9yxLDYJ_x6kc6FVDG5n5xwY2I30,558 +gradio/templates/frontend/assets/chunk-NRVI72HA-CIqkE629.js.map,sha256=9gP-XN7me-E-lJ9qYPzjAz_zhHmNEaIzD4E1MWG6no4,2296 +gradio/templates/frontend/assets/chunk-OMD6QJNC-Bs06rIhE.js,sha256=jai4X5n1oLLitu1LF48BksaKw0IJW--P8k_6i5d9Dp8,1465 +gradio/templates/frontend/assets/chunk-OMD6QJNC-Bs06rIhE.js.map,sha256=FXHR0VkGRKxH_JBxZ4EZ-Bbr2wd1Ou02l-YAQTXK7BI,5822 +gradio/templates/frontend/assets/chunk-WVR4S24B-BPhD9GX4.js,sha256=xagiPJo9mROTC9lvBXGncrHuswJAVfQbdiZFlDSRLGk,321 +gradio/templates/frontend/assets/chunk-WVR4S24B-BPhD9GX4.js.map,sha256=XRYtz6LJz7bUWbZmUPvqo9iYICgbSFgdLtdWpvUfs2E,1110 +gradio/templates/frontend/assets/ckb-DJglGH6y.js,sha256=VE6KlwVUcMwXFjAU6e0y7t64fSQJeD8ExKCAIwZr17U,6680 +gradio/templates/frontend/assets/ckb-DJglGH6y.js.map,sha256=hRnA3UUPlIo2Raius6Jzkg9yB7l4SQZhlvvWzBVIV0Y,96 +gradio/templates/frontend/assets/classDiagram-3BZAVTQC-HAGTk__T.js,sha256=Z3CI2Mq0h9QEgMeW72SQFKwQ2kgDAjSlkqZUNyBFMjE,630 +gradio/templates/frontend/assets/classDiagram-3BZAVTQC-HAGTk__T.js.map,sha256=udKRkEVsFJiFS6X_6_hpQp5UjxlMK7Iyi73pLj4NSgQ,1544 +gradio/templates/frontend/assets/classDiagram-v2-QTMF73CY-HAGTk__T.js,sha256=kWkRdT8DVDDcP18PtUdW634995XKI1uX5S3qpxClyWk,633 +gradio/templates/frontend/assets/classDiagram-v2-QTMF73CY-HAGTk__T.js.map,sha256=jDvxtKJIrLZu6Mn6GfN_TICivNFzJhvOEvLpeks1N-g,1553 +gradio/templates/frontend/assets/clear-CvR6Cdu7.js,sha256=ilmi-yXOnsGg_fwiku34Obdr3kMLbYRMqxe-tpEABjQ,1201 +gradio/templates/frontend/assets/clear-CvR6Cdu7.js.map,sha256=vK71PIlLVXRzbw0tWspoSXcYN8cpS3zBBEDhbQKziLw,1124 +gradio/templates/frontend/assets/clike-Cr_nJiF2.js,sha256=U7TzwsqEGNkfhxJW75G9nHYgSxOeRnclWNc67_laFRI,22347 +gradio/templates/frontend/assets/clike-Cr_nJiF2.js.map,sha256=OXrAJtzhIvCqhIalE3Yr6cTmzlh8OoJJjRSRInt-dZQ,59727 +gradio/templates/frontend/assets/clone-D-TuPeCM.js,sha256=fluYDLygOUMS30fUz9oJqWRoGymJ9L9mYM5upHji-TA,139 +gradio/templates/frontend/assets/clone-D-TuPeCM.js.map,sha256=8mFaTZZd9Od7y7XEXVpeibLlpwCWC2kHueMmiSH9Pd4,1432 +gradio/templates/frontend/assets/color-DtFW6XtC.js,sha256=6RummcetLHqq00FTQ2w_QO8GRyo3Ie2MIHRgYGOXqdo,118 +gradio/templates/frontend/assets/color-DtFW6XtC.js.map,sha256=hBKVa_oxM0O8lAUwf2K7xyhykheXbdOAuA-0XRpKplM,418 +gradio/templates/frontend/assets/colorToUniform-KTpA7KSL.js,sha256=SguMeLgd0I-E4bjBFizo-2KR8fi6jLVO53WG47Yj9IE,1737 +gradio/templates/frontend/assets/colorToUniform-KTpA7KSL.js.map,sha256=GpBALues4Fwv1XCbQ_JVCmhXyHIlCJlKirJ905XaQns,4691 +gradio/templates/frontend/assets/cubeTexture-BQLIF84D.js,sha256=BmO1vPnkynXn7sgNNj54LMqyuKRsgMFYXwY4EnWTCaw,6027 +gradio/templates/frontend/assets/cubeTexture-BQLIF84D.js.map,sha256=q1H12ncUZayPDaaOnuY6pjlQe9it9ER4iGBg0aBZtxU,26153 +gradio/templates/frontend/assets/cytoscape.esm-BPoQaFli.js,sha256=_li4k0GjjLfaCpRHMSdWzd7CQ7Py1ilF_ko6M89Sw38,425620 +gradio/templates/frontend/assets/cytoscape.esm-BPoQaFli.js.map,sha256=DSbpma9uYxehUzJ8BEFLHgNuaXZCPIRmftxgTJtz_Bw,1802636 +gradio/templates/frontend/assets/dagre-2BBEFEWP-FIgrWBoJ.js,sha256=JXjR2pn_gCVt9jD05Z0LJzwe30SU3WQlCH_tZ7VSM_0,11197 +gradio/templates/frontend/assets/dagre-2BBEFEWP-FIgrWBoJ.js.map,sha256=8ub9eL1C1ZyDUJ0p1qPy4ZL-IuwVvvfwaXcdco1PX0U,41713 +gradio/templates/frontend/assets/dds-uXUs1pA2.js,sha256=gCkq3I1wNgrOzQTLg_Y6sX-vtchKC3g-0NFPl6cjh9k,7147 +gradio/templates/frontend/assets/dds-uXUs1pA2.js.map,sha256=E0AqOtg479Cc3XXLOasVKyRO9n7mwFRN3m1l-3IyzQs,38620 +gradio/templates/frontend/assets/ddsTextureLoader-NtGTlKk0.js,sha256=0lyzgvwl7GNIZLpT6yWTANXCqi5fCZb5xiaxslyIdG8,1420 +gradio/templates/frontend/assets/ddsTextureLoader-NtGTlKk0.js.map,sha256=J4KrKo62ZW3CopYfkpc__q2IFNU9dR-cXZvJlgalc58,5760 +gradio/templates/frontend/assets/de-1aCSmaRd.js,sha256=XVP-1LWg843mbZsfe3dkFb6kTvOQEz39Sj2LDWQAfpU,4905 +gradio/templates/frontend/assets/de-1aCSmaRd.js.map,sha256=_-6hxyBx4AKO_WxYvdYLeqYPAxqabLbxpAkk1cVS-4Y,95 +gradio/templates/frontend/assets/decalFragment-DvXBUyjk.js,sha256=8RBVx3YBzSEa_zodT3UnhK6Pey3vVzwoNlFvBTl-Djw,490 +gradio/templates/frontend/assets/decalFragment-DvXBUyjk.js.map,sha256=MxLbQ9DbWWgHq-yHHnkXJPG8bujdsmByjG2fBUVFvXw,1109 +gradio/templates/frontend/assets/declarationMapper-7xPzi61q.js,sha256=Ylp4GlXstXymu4SjWpUnNFoenaH_3tEofHcT-D1z9Xo,32039 +gradio/templates/frontend/assets/declarationMapper-7xPzi61q.js.map,sha256=JH2LgEVhOzn8zAW_vCM76dVPZrTHcF9mSGvnOMFV1YU,135874 +gradio/templates/frontend/assets/default.fragment-BIt79vBt.js,sha256=vmLz-95qza2IyncQNQq0jeAAPVmhIBYr8dtiaoqVx4g,21869 +gradio/templates/frontend/assets/default.fragment-BIt79vBt.js.map,sha256=gA2725OkYYB45ZHEoiqkAJG_cDq5jpbiPCiVi7wHIoI,26530 +gradio/templates/frontend/assets/default.fragment-C_Z6J5yX.js,sha256=SPuS6-SIsZFQdVvUM_pfV7eXXiVIJmkXtDzr0YXFPSA,20693 +gradio/templates/frontend/assets/default.fragment-C_Z6J5yX.js.map,sha256=d2DuzJVSPBNHkCdB8CGjrEBK5UYvmG4T7ur7Rfn1h9I,27004 +gradio/templates/frontend/assets/default.vertex-9och29br.js,sha256=b2ZtMZxphGMCDqH4t2R1o6r_GxbjSNuiKmW2sEDM2a0,7173 +gradio/templates/frontend/assets/default.vertex-9och29br.js.map,sha256=BTYgtD5eg-CyQMxnxUxbxX1LTmEt6P7rkMBdBeoWIFk,11363 +gradio/templates/frontend/assets/default.vertex-Bgd7W53G.js,sha256=dpRwxEBpdONSdH_zWA7z-msvADPA1Vs7NiF7ZESHEhM,7600 +gradio/templates/frontend/assets/default.vertex-Bgd7W53G.js.map,sha256=XQ-BIGrUwJvzVdaAh_EVTXDO-GbC9ppvqorW-j-uuBY,11001 +gradio/templates/frontend/assets/defaultEnvironment-C15qoIsh-DPUnnTO0.js,sha256=c-zK5cBYU1Im8DxeZ6r7TjguZL6YNtri3-7y5LPaotI,83859 +gradio/templates/frontend/assets/defaultEnvironment-C15qoIsh-DPUnnTO0.js.map,sha256=gjmw6WSCNJXR3f616btE-PqXLulT072jezZSZtpThFM,84300 +gradio/templates/frontend/assets/defaultLocale-CNpUPyHh.js,sha256=cwgWkQ3yQv3DgwTlf_lSx2Pkb-WCibpdTsAOYi6zkx4,4605 +gradio/templates/frontend/assets/defaultLocale-CNpUPyHh.js.map,sha256=XZhk7f63PPruwQaSvOhRBR2mqMYgD9SgGPIcanNDMc4,22123 +gradio/templates/frontend/assets/defaultUboDeclaration-B70J9z20.js,sha256=_Wd31EQFpGRCDsDxo0FmnbrEGZhkrwgvlBVc_n150AU,1183 +gradio/templates/frontend/assets/defaultUboDeclaration-B70J9z20.js.map,sha256=3tby-w6NdJ4CiJWUqMEOjpwb7T7lxM3ttWkU3aurO4Y,1827 +gradio/templates/frontend/assets/defaultUboDeclaration-C-hGTH7Q.js,sha256=AnQNG65kmuKlwMcjBfgnoKC-_nBBTY5tBNrMPc-pJ_U,1525 +gradio/templates/frontend/assets/defaultUboDeclaration-C-hGTH7Q.js.map,sha256=a3cfrC9S52LXSxCM8YoO5boI7IjAMVh-8GFOpHCGkKw,2166 +gradio/templates/frontend/assets/diagram-4IRLE6MV-BIUTEVYJ.js,sha256=brk9hNSv2oiJMp-asaUTutNqLrq7dF2AayaQvM8FBYo,11343 +gradio/templates/frontend/assets/diagram-4IRLE6MV-BIUTEVYJ.js.map,sha256=ArtEimzvyL30yMcbNp9zMf7wjqkSNmVy8hLi9Hk3ANk,37784 +gradio/templates/frontend/assets/diagram-GUPCWM2R-C_q48ZBl.js,sha256=EiPceQwBmKZ-h9fHcCK80A2K5J63-fBookAexUcUyDg,4507 +gradio/templates/frontend/assets/diagram-GUPCWM2R-C_q48ZBl.js.map,sha256=xoquQt7GR9Iz4d7yKzELJQI0RZxQeiCWs0MCFyWZndY,13616 +gradio/templates/frontend/assets/diagram-RP2FKANI-CF_0GFm_.js,sha256=ZcR13YaiGSWztE2Sf4ZkjyAUNOPHtZSc8EJhsc-vYf0,6108 +gradio/templates/frontend/assets/diagram-RP2FKANI-CF_0GFm_.js.map,sha256=wcE7YlrlT97PDGt9uA750Gy0t9TMD5O1T2cvadU3-kU,20735 +gradio/templates/frontend/assets/dispatch-kxCwF96_.js,sha256=Net6n-9075LOhVI9j4bCbVwYVjv7fiLHpB_4D_ca0Ww,1586 +gradio/templates/frontend/assets/dispatch-kxCwF96_.js.map,sha256=j_oLlcnqUd9PBlC7pm_GxVhSDjOFit91lg4XQLbjQds,5753 +gradio/templates/frontend/assets/dockerfile-D3l6Kuvz.js,sha256=BV438z3OFq0UZlNkvDAQ6k4BXCcyJ6peAHJdXFggZNk,4166 +gradio/templates/frontend/assets/dockerfile-D3l6Kuvz.js.map,sha256=WyUjmDMsNCaanu-z34dKf7AlJuu4IgQo3rd5cSU4LOU,14888 +gradio/templates/frontend/assets/dsv-DB8NKgIY.js,sha256=EFxoW9KsE0aBRfSu23OVdhlOpxub7HPQzVVLDjS9Rt0,2189 +gradio/templates/frontend/assets/dsv-DB8NKgIY.js.map,sha256=hiLCgvJjDSRpFCNZvLIPCE8BdHuDKkriI4E7NNvkJ50,9579 +gradio/templates/frontend/assets/dumpTools-CYA3bbBU.js,sha256=Vynd2Bix7gK0kNb9CbNlXR0DVhi0BSLr30dFoyqEcaE,2680 +gradio/templates/frontend/assets/dumpTools-CYA3bbBU.js.map,sha256=wXMXNUK6SZVYdXbMT9A6engzbo2x7tW0wi2mhPWg3BA,13437 +gradio/templates/frontend/assets/envTextureLoader-DwpXDTds.js,sha256=0wYpNjLrPPBcFXDNdkwObI9_Oyo3j6bLtteHqV4lx0E,740 +gradio/templates/frontend/assets/envTextureLoader-DwpXDTds.js.map,sha256=3FHvxoHPwhYXL10Z0Ht6kw98lKKz04GJqgGKTrgiNcc,3262 +gradio/templates/frontend/assets/environmentTextureTools-CUb-PZkT.js,sha256=zKFYhpChpfPEUw-PaAKaCp52P8KlZxgZvJETs88TRCs,6593 +gradio/templates/frontend/assets/environmentTextureTools-CUb-PZkT.js.map,sha256=YxQaZi_J4ooAwpSbX-hvcdOlTXSq5VpQRofQJhT28Pk,42422 +gradio/templates/frontend/assets/erDiagram-HZWUO2LU-YNkW1FvP.js,sha256=ov6RjMsVaRpgGdz5eOg5GOV7tQvOz_N2iRyLW-G9pUc,25437 +gradio/templates/frontend/assets/erDiagram-HZWUO2LU-YNkW1FvP.js.map,sha256=vX7-z5-oGRreUnXDrdeneXbhch7aQXjATglEFnck-Is,85617 +gradio/templates/frontend/assets/es-DnL3K9UL.js,sha256=hjhPPyj7ahCRHDLoT9e5MJxnzXEwZHoaLK06a84gUVw,4910 +gradio/templates/frontend/assets/es-DnL3K9UL.js.map,sha256=ukGfXeZMpNx0kTvJny2Vhn1ytgKhoCTQqWFcZrijzVs,95 +gradio/templates/frontend/assets/eu-CVD4vzPg.js,sha256=D1mh4ll1PU0fKR2nauaWHanIeoTFz8VSxZKXuqFyCkQ,4680 +gradio/templates/frontend/assets/eu-CVD4vzPg.js.map,sha256=RuhlcEJuThMErnIxkvOXFP5GT4qFirEVPUn6zfAU-88,95 +gradio/templates/frontend/assets/exrTextureLoader-CgIQ5mLN.js,sha256=PDh_08EXdyvjhkZk3pBz9ibRe2teUPFkeHo7YDYKzlI,14885 +gradio/templates/frontend/assets/exrTextureLoader-CgIQ5mLN.js.map,sha256=65IZNq8c-Byg4kCZXlJWCWjAOhcuWpWZhJRICcOOxbI,101518 +gradio/templates/frontend/assets/fa-EPplD9mS.js,sha256=GPITIxKVNepmiyE-Y1eBrMtKLXFxBCNe9nSP8Ep75R8,6189 +gradio/templates/frontend/assets/fa-EPplD9mS.js.map,sha256=r5MkLGXCc3L3CbSpkIBynoenB3q_8DXwbC7TSFcQJ0Q,95 +gradio/templates/frontend/assets/fi-B30SrT2N.js,sha256=icVouwSYyrZJMQ3kv_uOHQrb03nNZXiM85lt8VAtChY,4683 +gradio/templates/frontend/assets/fi-B30SrT2N.js.map,sha256=Zp1lYdDINOabElEhPNTxhg4UfvGQUwK3_Lm76DwJUvA,95 +gradio/templates/frontend/assets/flowDiagram-THRYKUMA-C64aIknq.js,sha256=9unoV3Bux98QepX5u_WaXSdqILxkHQTj2z50g4bhEfM,60649 +gradio/templates/frontend/assets/flowDiagram-THRYKUMA-C64aIknq.js.map,sha256=gUhR1u9s_9cTF11Z6cy1JG4o6hWkW1uSQmIIjWpUeTs,189872 +gradio/templates/frontend/assets/flowGraphArrayIndexBlock-BpXdri53.js,sha256=xZjiEIpjxLU3k_mdBcXQb8jw9RcBxdwuM0tUxVhi69A,823 +gradio/templates/frontend/assets/flowGraphArrayIndexBlock-BpXdri53.js.map,sha256=ESv4uoxYi8UiV2H_iAgdj_8hJvqIQASMZ5E8IG85SOE,2795 +gradio/templates/frontend/assets/flowGraphBezierCurveEasingBlock-6pHaLqlb.js,sha256=mYMOQVamxED9YxrJrJIT0WSR7nLZBIwqN9mKPGV105A,1116 +gradio/templates/frontend/assets/flowGraphBezierCurveEasingBlock-6pHaLqlb.js.map,sha256=YkC2MYXV_PonIOxFOaGs0weM9deQuJrJy10lrWEsRK0,3488 +gradio/templates/frontend/assets/flowGraphBinaryOperationBlock-qTC58JQu.js,sha256=HTVTUXkyvjzwJUgXtbJEyUo-_767A3LzuHbDrvA6AFg,442 +gradio/templates/frontend/assets/flowGraphBinaryOperationBlock-qTC58JQu.js.map,sha256=d7aSWy2ItGUuQNa7Q4uwERifkq1eu54JD1XNh-QB7uk,2026 +gradio/templates/frontend/assets/flowGraphBranchBlock-B4yNg-Pq.js,sha256=MPF9attOAjxut5j5uPjy_dXbgoLlsQBipRhkpJef7lE,703 +gradio/templates/frontend/assets/flowGraphBranchBlock-B4yNg-Pq.js.map,sha256=kKJH98cIjcNtCup2gZXJDWrMkv33TvuU2bJKpzJ4pWo,1890 +gradio/templates/frontend/assets/flowGraphCachedOperationBlock-BmxlZefY.js,sha256=7IMlnuAB1GTBIWaumqXvB8SjWip9gOmD8lXZoMWTJhU,812 +gradio/templates/frontend/assets/flowGraphCachedOperationBlock-BmxlZefY.js.map,sha256=yKBcXar1D3xnR5mz5BKfxdgpGj0v-Cmw6udj-umKGLE,2994 +gradio/templates/frontend/assets/flowGraphCancelDelayBlock-Cp9PPeWA.js,sha256=lq9tmElE8q-fmya-nGBO2HP6dVvfc00hzsZMlaPL4fk,758 +gradio/templates/frontend/assets/flowGraphCancelDelayBlock-Cp9PPeWA.js.map,sha256=p58WbykiubCzzcOJCvTH1qi6CVUYcJp2QDWMMM-Dnns,2347 +gradio/templates/frontend/assets/flowGraphCodeExecutionBlock-DBdfgztp.js,sha256=l8yP5UnVdZuZEydeIV5AgrAQi63vKWP37ZdRQBfGFec,716 +gradio/templates/frontend/assets/flowGraphCodeExecutionBlock-DBdfgztp.js.map,sha256=jntMQBvD-Xf0mow0GgzvtIGggESzu5xQfYFUDl8TwI4,2167 +gradio/templates/frontend/assets/flowGraphConditionalDataBlock-BiMa8ZyM.js,sha256=7HQj4eeS9lWbEltIYHHDbyupiGPTFbmj4Cj3Sa8iGlw,808 +gradio/templates/frontend/assets/flowGraphConditionalDataBlock-BiMa8ZyM.js.map,sha256=grc6DOq0wmF6HyBEMzAB1wFfzQ59R4VNaoXo7YKZeE8,2387 +gradio/templates/frontend/assets/flowGraphConsoleLogBlock-BPpWemTB.js,sha256=1ClZnKHdIAzTo4L0vSH_K51WxRrEGsIgHJSbEJp3ISQ,1253 +gradio/templates/frontend/assets/flowGraphConsoleLogBlock-BPpWemTB.js.map,sha256=NF2Z2hdbKY_FFpWCpAG9uaoowFiKS3TyeXeaMyniZWk,4176 +gradio/templates/frontend/assets/flowGraphConstantBlock-DIoBWBLO.js,sha256=26tdAmM_dpXfUkhPnYOZgzNXASO4_GHN5A-VIt7Jdkk,671 +gradio/templates/frontend/assets/flowGraphConstantBlock-DIoBWBLO.js.map,sha256=-uEGGNJQYHfNmDBMpT1jNqwORn011gkuK3_0mFBQRE0,2346 +gradio/templates/frontend/assets/flowGraphContextBlock-qunsn4Qu.js,sha256=hWq8JDl6cT9FPGDbaygfhfPVV8ALdTuPm_1CKntZvQE,719 +gradio/templates/frontend/assets/flowGraphContextBlock-qunsn4Qu.js.map,sha256=M2G2g7KEzbxANvXC3Jy-g5IvIHd6X29b21kN8yiMqtY,1837 +gradio/templates/frontend/assets/flowGraphCounterBlock-DVYEwdJV.js,sha256=ZzGypwKDOOxNTnBGMawEYJ7ATQcPs4aredwIxUln6gM,804 +gradio/templates/frontend/assets/flowGraphCounterBlock-DVYEwdJV.js.map,sha256=6D062a3kyLdzHdj9vlHuM5j-8IRmAp5_IfVsU-lQ6tM,2364 +gradio/templates/frontend/assets/flowGraphDataSwitchBlock-KKr16rqO.js,sha256=oDy4I-uTab_jHhJ0QI0EgAU3FnyYk55R2PY3vyISS8Y,1055 +gradio/templates/frontend/assets/flowGraphDataSwitchBlock-KKr16rqO.js.map,sha256=3HNAlax2TzWDDZFjy4h91UtNfHuZw5nUUWoHldq-m9g,3518 +gradio/templates/frontend/assets/flowGraphDebounceBlock-DHonEZx5.js,sha256=2L12z2fUi5XagtvWGOTkUaSf7Sx5i3ToO3xPk0DoTMU,942 +gradio/templates/frontend/assets/flowGraphDebounceBlock-DHonEZx5.js.map,sha256=yi2-FiN2Yz1qQ8602TkQa-yqGwChW0V5STYr2Pnww1s,2739 +gradio/templates/frontend/assets/flowGraphDoNBlock-mfETcECD.js,sha256=ieiT33XaRLvu4VNoewwYRToPs1w8wOfvfIbPHADtqiU,944 +gradio/templates/frontend/assets/flowGraphDoNBlock-mfETcECD.js.map,sha256=ryqKZl0x3gyo0nEu3S5LMUbPTZuWYPsb6KUhR-kbVeM,2918 +gradio/templates/frontend/assets/flowGraphEasingBlock-BYFY7Osk.js,sha256=ayYpDQPwPsV7AuBJ1CE4zgdw5oJWkQq09cmsTudTZr8,1801 +gradio/templates/frontend/assets/flowGraphEasingBlock-BYFY7Osk.js.map,sha256=9zEhGCWU36ATxwhMOFJutXwVyRBXhXceR-lEGv5fgdo,6760 +gradio/templates/frontend/assets/flowGraphFlipFlopBlock-ZyL2IkMr.js,sha256=2rKobNtNDV0TD6WpS41pQ07UpqBYJBQoOEuzhH-6mZU,852 +gradio/templates/frontend/assets/flowGraphFlipFlopBlock-ZyL2IkMr.js.map,sha256=MaEPd05NMh_2UpMYl8AiW7kD7TT-OHNARXH9gKNh6sY,2326 +gradio/templates/frontend/assets/flowGraphForLoopBlock-XOBk-mg3.js,sha256=FwuDqwl1Q_vmSObuE1tCN_GSnpvTVvO0uZ181-4ko6o,1181 +gradio/templates/frontend/assets/flowGraphForLoopBlock-XOBk-mg3.js.map,sha256=91uYUhwmvSLlESa4kirMwx3xNnP-Znqa60e8Ojo2Lfg,3751 +gradio/templates/frontend/assets/flowGraphFunctionReferenceBlock-CgAWCR0o.js,sha256=xxcA0CFupQqIQQw0ycGQBKaLJDnv3JsTNl1O3TchPkw,888 +gradio/templates/frontend/assets/flowGraphFunctionReferenceBlock-CgAWCR0o.js.map,sha256=GzysiNA25XB8KBvtiDk6LKfnI2VWgSNUsXi_D978e2g,2625 +gradio/templates/frontend/assets/flowGraphGLTFDataProvider-CtMWFOo4.js,sha256=XqWYx6kX_46Zv67YRIwYsfW3pbuZKgWsoqSpLe4by80,659 +gradio/templates/frontend/assets/flowGraphGLTFDataProvider-CtMWFOo4.js.map,sha256=sq900DlHz2XQbDx8OlbNSETwlWKGCNSyM3rGGmXHWt8,1775 +gradio/templates/frontend/assets/flowGraphGetAssetBlock-BGDIqzhO.js,sha256=hMD2DFUQn4nyOd5MKw8hpl-FAIT5yjqCFVdkR9UUUmg,811 +gradio/templates/frontend/assets/flowGraphGetAssetBlock-BGDIqzhO.js.map,sha256=r3U7apiRVBtnvwUlubBRGK7It_Pd93OqDotTyYmgfFg,2930 +gradio/templates/frontend/assets/flowGraphGetPropertyBlock-B3zz0gqe.js,sha256=4AfPvTChgGqCD_y_m41Z_sL3HSLOQMqXXRBwlGIRGLM,1092 +gradio/templates/frontend/assets/flowGraphGetPropertyBlock-B3zz0gqe.js.map,sha256=z6RqHtDMQaPu5dimHx2u1cEtUu4FtMc-LBdGDlpwTjU,3605 +gradio/templates/frontend/assets/flowGraphGetVariableBlock-ZnV-YJDL.js,sha256=MqWkMfXDWevMojgresvkmIftBh2YZZfmE7-1rxWpzac,719 +gradio/templates/frontend/assets/flowGraphGetVariableBlock-ZnV-YJDL.js.map,sha256=fie5uOjMAQkmjNRYohZTyvgfdRlLmnajoLYSMW_pKFY,2369 +gradio/templates/frontend/assets/flowGraphIndexOfBlock-ujY1If3T.js,sha256=KixmQwTmWxPrjOOUZOM_hkx3b13WRkJ-mIMVbEGuo0U,781 +gradio/templates/frontend/assets/flowGraphIndexOfBlock-ujY1If3T.js.map,sha256=eTRRow8Vg7I_JvX7eLhzAy2aM_WVTFhjvbitjlAp3sI,2623 +gradio/templates/frontend/assets/flowGraphInterpolationBlock-BSxxaD4w.js,sha256=BTgxmd1JlCKHLVagUyIpQQvHwhU_LAxObfea2XeqIXo,2278 +gradio/templates/frontend/assets/flowGraphInterpolationBlock-BSxxaD4w.js.map,sha256=8UxZDQ2E3c21OQGONrs89iUjlpTJSHFU0FtFHQANJUQ,8315 +gradio/templates/frontend/assets/flowGraphJsonPointerParserBlock-DNtP7CCH.js,sha256=5l5XZg7iaA7PYFdH7CbANlF62cnGV-1_MHB3lOmEvFE,2975 +gradio/templates/frontend/assets/flowGraphJsonPointerParserBlock-DNtP7CCH.js.map,sha256=v8o_JOBHKFaOWtl8d_fZ7gOzBLc4Jb9zjwD1BUmWEcQ,11527 +gradio/templates/frontend/assets/flowGraphMathBlocks-BOaAw3SK.js,sha256=PqvOA7TkE_IqaeIhwhpoiztY6vJZfv8tBzcPDEWafjo,17440 +gradio/templates/frontend/assets/flowGraphMathBlocks-BOaAw3SK.js.map,sha256=PrAgXcLV95UXHEGYuDmb37fXSKrI7fFeiRVzjZHOAt0,70096 +gradio/templates/frontend/assets/flowGraphMathCombineExtractBlocks-DBJpQdoS.js,sha256=ligB793mV8sRytBkF-vTnwbihwORO3jTtm-bt9vWgDI,8134 +gradio/templates/frontend/assets/flowGraphMathCombineExtractBlocks-DBJpQdoS.js.map,sha256=NGqmUwWpg8K4Jpp4H5iWvRYd8UUYFd_6bYh87Bog6bc,24717 +gradio/templates/frontend/assets/flowGraphMatrixMathBlocks-BEq8ibO0.js,sha256=68F0vElVNOCQbW0qOiZKiabJsMMWY-KyH89sQ4h0HCU,3744 +gradio/templates/frontend/assets/flowGraphMatrixMathBlocks-BEq8ibO0.js.map,sha256=F3LHuFTrW78TnOAdoTLAwv7n7KlTIm2mjkjyn-JiqyM,12260 +gradio/templates/frontend/assets/flowGraphMeshPickEventBlock-APveDtXy.js,sha256=29GYVswx7tVf_Dezm5TuQCDsOCmfIHnYJ-Zbc_oGTX0,1599 +gradio/templates/frontend/assets/flowGraphMeshPickEventBlock-APveDtXy.js.map,sha256=Af-NdcVnJAMbl4Me58Z7B74sx6ZLiCb9tWeXjPG2kbA,4937 +gradio/templates/frontend/assets/flowGraphMultiGateBlock-Cwi26wdE.js,sha256=quLniHhy6wIdKoVtuNdC8vQESLE9Zh_ltXfC6p5zTLo,1834 +gradio/templates/frontend/assets/flowGraphMultiGateBlock-Cwi26wdE.js.map,sha256=bDtlJBBRmVqrf-JLio8smaOudSxLqKB79SW6RP2Y9dw,6322 +gradio/templates/frontend/assets/flowGraphPauseAnimationBlock-Bpa8mkTl.js,sha256=bIGP3cY0wp6XMR0IXfQ9PP4pGu1Wr4kMD6NaID0IRuk,629 +gradio/templates/frontend/assets/flowGraphPauseAnimationBlock-Bpa8mkTl.js.map,sha256=GzaBraFVfAmGMScI0YxsB_9eoXnWWCwndN7ZZ36RG8E,1777 +gradio/templates/frontend/assets/flowGraphPlayAnimationBlock-CZCZPppI.js,sha256=dV4lp89UEjLTy68mQtpKiTxADRgecqpt_0bfkvkkU3Y,3890 +gradio/templates/frontend/assets/flowGraphPlayAnimationBlock-CZCZPppI.js.map,sha256=AYjJWDZ9dzC3q1WtRBGNCq3UM2Y8O1XZnMesbIc8MT0,12729 +gradio/templates/frontend/assets/flowGraphPointerOutEventBlock-BDipP5ba.js,sha256=MKn4O5ODgjeGl-FQgs5NcQmKTLStC4ic2tVBL0ogwr8,1005 +gradio/templates/frontend/assets/flowGraphPointerOutEventBlock-BDipP5ba.js.map,sha256=gYSwSTBt7TVoQNO0mAia6YzIGNGp8Q_ej88PD1z0acg,2900 +gradio/templates/frontend/assets/flowGraphPointerOverEventBlock-D06tSh3h.js,sha256=k_5W3ZXvqgjSGp0JQFk5I_eVUEYcecb3oTUsV1Z9cFw,1016 +gradio/templates/frontend/assets/flowGraphPointerOverEventBlock-D06tSh3h.js.map,sha256=jaJg-EcMmjgMn1WRn6f7gJH009QRYEx5Idqn_jL1HE4,3027 +gradio/templates/frontend/assets/flowGraphReceiveCustomEventBlock-DeHKC3bJ.js,sha256=PEkY1kloDYlABCnnt8lnBgZ0L01eflz-U1Zrdgfyezg,1409 +gradio/templates/frontend/assets/flowGraphReceiveCustomEventBlock-DeHKC3bJ.js.map,sha256=cHC7QQJO2Kt-npkTSxtozyrQ9iODvwUzubE5IZiZcQY,4244 +gradio/templates/frontend/assets/flowGraphSceneReadyEventBlock-BIZ8SzVs.js,sha256=_OcnvLIOjsJ2n6WVXt8s2RDs6OArwniq8debO-ebTCQ,621 +gradio/templates/frontend/assets/flowGraphSceneReadyEventBlock-BIZ8SzVs.js.map,sha256=Kn7EIwpEvf3m9SlDRrZY8gyTlmuyeziyof2tR-XRLiw,1650 +gradio/templates/frontend/assets/flowGraphSceneTickEventBlock-p1e_7Y2T.js,sha256=XdbCiscUXMK-LyxSdYF-tSiNkkgw7O5R63NOfE_drLc,809 +gradio/templates/frontend/assets/flowGraphSceneTickEventBlock-p1e_7Y2T.js.map,sha256=QVWnnbsAvZp9sbU9xxgIPCfmme1n-SQSvTAgaN4veC4,2262 +gradio/templates/frontend/assets/flowGraphSendCustomEventBlock-D4QQsIrX.js,sha256=5h7x6t1Jk_GdLwGUHaD7tmqMQg6pk4-PI2jvBAVyfH0,794 +gradio/templates/frontend/assets/flowGraphSendCustomEventBlock-D4QQsIrX.js.map,sha256=nLQo1__XEp1FV7GQCIGS3KXWjGHJsEvQ1GHPrucv-cI,2580 +gradio/templates/frontend/assets/flowGraphSequenceBlock-BFVPegB-.js,sha256=-pAiKZo9ckJnnMp614Q2o1AFTk2PnjTFxsTxcs6usnE,946 +gradio/templates/frontend/assets/flowGraphSequenceBlock-BFVPegB-.js.map,sha256=dtzVu-c_CSiSHYWzmIe9D7t0yVqhV8Ddic2dv4COSkQ,2862 +gradio/templates/frontend/assets/flowGraphSetDelayBlock-Ng1bBXry.js,sha256=AekTtLaNypKC-21XT3deyhcBtvlKE4JnvmE3EvZQ_iE,3891 +gradio/templates/frontend/assets/flowGraphSetDelayBlock-Ng1bBXry.js.map,sha256=xhbCE6DC4thJXk5QkURihH0Ls9qK47cLlGmvXmKWaPw,14047 +gradio/templates/frontend/assets/flowGraphSetPropertyBlock-Cev7-fkn.js,sha256=qKaavoTcpTlAbiiYXD8HYhyfyMo_xMRGmqAy37Xmp4k,1145 +gradio/templates/frontend/assets/flowGraphSetPropertyBlock-Cev7-fkn.js.map,sha256=hYUUnMLwLls9IhVBIE5aPDF9d8oUhh3I_mc_sXbSlDM,4202 +gradio/templates/frontend/assets/flowGraphSetVariableBlock-Dj_sCq5f.js,sha256=0ALAdI6wcOyNFBierBJER5s8dBHvjaYr9Nl7Zhbghqg,1498 +gradio/templates/frontend/assets/flowGraphSetVariableBlock-Dj_sCq5f.js.map,sha256=F4tjkzs0go50IEhd5UV_aFqzmidbul3937p8i2sNd1A,5554 +gradio/templates/frontend/assets/flowGraphStopAnimationBlock-etf7qIwB.js,sha256=pDc8JTK_gLtunlWIBeD6fqs51kommGxLJZhDIll2EK0,2063 +gradio/templates/frontend/assets/flowGraphStopAnimationBlock-etf7qIwB.js.map,sha256=FQY-0DQX6yUW_X0ubJyZtbwt5Y8FOZQuCxTZxXJ5xxg,7261 +gradio/templates/frontend/assets/flowGraphSwitchBlock-C0x9GPK-.js,sha256=F4fSBFBigiBJQacmT2vT-2byGfxUMGrnf9bSiW8WguE,1299 +gradio/templates/frontend/assets/flowGraphSwitchBlock-C0x9GPK-.js.map,sha256=sBgMrJGsSWVrkDyKpewGBk6X3e1vilFtvmh0FT9ioG4,4645 +gradio/templates/frontend/assets/flowGraphTernaryOperationBlock-Bm0T1zrF.js,sha256=ZU2HldsFw5RnHn3EPrs_delHkV4ivL9E5m3Pf3O_2uE,487 +gradio/templates/frontend/assets/flowGraphTernaryOperationBlock-Bm0T1zrF.js.map,sha256=caycbSalHmi7gscc6JJuu51Da9wbF4YjuIXb2sAEkzk,2007 +gradio/templates/frontend/assets/flowGraphThrottleBlock-BJO6jkKe.js,sha256=-_3m5Jg_iFsrrR87-sO2OR-QQjph-VXPk7D0DDb3QtE,1537 +gradio/templates/frontend/assets/flowGraphThrottleBlock-BJO6jkKe.js.map,sha256=nuFWUZRfxYM5jH6m5pIHgBoT3ZyYhNM8AC2Jpa6cNWQ,4805 +gradio/templates/frontend/assets/flowGraphTransformCoordinatesSystemBlock-_Z0P-yk6.js,sha256=939BuOTJFjzvh3Uxc-Zf_YBavZ0iuPF_yXeR6i_5n4Q,1141 +gradio/templates/frontend/assets/flowGraphTransformCoordinatesSystemBlock-_Z0P-yk6.js.map,sha256=TDZr1_apFoSzfxj9KKO4NA41LCaBJJcohiCxcPhaxws,3954 +gradio/templates/frontend/assets/flowGraphTypeToTypeBlocks-BRy91q4W.js,sha256=ZZ18-shpiuNcuIfYGE69pmklMByHaqvS2DJpfVKZC6c,1450 +gradio/templates/frontend/assets/flowGraphTypeToTypeBlocks-BRy91q4W.js.map,sha256=JKRIf0_8bLaP6ThtX2elOuWHu4DZc5Q_Qc14EmtPowA,5079 +gradio/templates/frontend/assets/flowGraphUnaryOperationBlock-CQzZaqQK.js,sha256=sSBdkf9oHUwbdiq7v26t52ECKktLU0OSIKVLIy-tUbY,369 +gradio/templates/frontend/assets/flowGraphUnaryOperationBlock-CQzZaqQK.js.map,sha256=b50gbmImpG4yELjHsJjK22SqC_O5OSbTjjkp_piYwSg,1745 +gradio/templates/frontend/assets/flowGraphVectorMathBlocks-D8MTFGdo.js,sha256=XxizUMtyNpJdXydW0psGdXlxzKNrYIFND-6OqoVOcFU,3032 +gradio/templates/frontend/assets/flowGraphVectorMathBlocks-D8MTFGdo.js.map,sha256=aQ4_Vze-IDMgyXGcxwSlR1V2R3QT1G94r8VVivn4MFE,11031 +gradio/templates/frontend/assets/flowGraphWaitAllBlock-D_HxMnyB.js,sha256=6sFHqjygJhz9LsKt3Uxi2ZU6ik_mg4QYp4C1rk-Vmf8,1684 +gradio/templates/frontend/assets/flowGraphWaitAllBlock-D_HxMnyB.js.map,sha256=2_8PCzdkqtiZrTCYEUuSWVjzNNAh8y7wN3fJhNJ6MBk,5475 +gradio/templates/frontend/assets/flowGraphWhileLoopBlock-BvV_fZFF.js,sha256=gCz8dUxzmartCVKXxZxQtva7FR502x1iUzRli3m548k,1037 +gradio/templates/frontend/assets/flowGraphWhileLoopBlock-BvV_fZFF.js.map,sha256=S1gAMqlxiNnan9v9OkudiaQESKKgneFf9oDKLIc2IXs,3164 +gradio/templates/frontend/assets/fogFragment-CFdAg03W.js,sha256=GZ0QmHIZKmUEeMY92BqvdqkSdx93iETkVuCcvz6X1iw,2319 +gradio/templates/frontend/assets/fogFragment-CFdAg03W.js.map,sha256=UtKyj7cGFG0GzszGmEq1JyaFAyUt1v9iFAlg4KUjSt0,5330 +gradio/templates/frontend/assets/fogFragment-D6wChTUo.js,sha256=hgbfPlZ-tRwbSKSF52b_LcH1VT24w0u5UfA4WKekpqk,2591 +gradio/templates/frontend/assets/fogFragment-D6wChTUo.js.map,sha256=m11C6LjMBc6cdwVEhB8q6CPQTXbYcxbxPTF73GqBmCE,5636 +gradio/templates/frontend/assets/fr-BtMjEOuI.js,sha256=7CBSMXK-LdipO6nsqtLoNFdmarnyqjAKZk8M_zLSkGI,5065 +gradio/templates/frontend/assets/fr-BtMjEOuI.js.map,sha256=FvHnoiHbdBvBDOooFPUtvVdmsGB--gyZtd0uccmJI0c,95 +gradio/templates/frontend/assets/fresnelFunction-CklZTIaN.js,sha256=wiQSmqvbC9XfGusy_eBUQV_TmuutcKz2bi77LRtjM7Y,409 +gradio/templates/frontend/assets/fresnelFunction-CklZTIaN.js.map,sha256=aFDcXhpoV3pmjbpvNmaqdZWGlYsiswdQlZaqiz-BFWU,998 +gradio/templates/frontend/assets/frontmatter-DO27yz_u.js,sha256=DzTkGXjVYPEwo_seFwbX8_dUHkcMIPldwfxXmrec9AY,1141 +gradio/templates/frontend/assets/frontmatter-DO27yz_u.js.map,sha256=5y1-pNDTWEiuiRUm3urqoiwc7hnP-6f0AivS4Ml5n40,3071 +gradio/templates/frontend/assets/ganttDiagram-WV7ZQ7D5-BFRLWvpx.js,sha256=UhLEio6ryLmh-OOkIvAjwXWMs8MGWX7dW39UXgmxhlI,45559 +gradio/templates/frontend/assets/ganttDiagram-WV7ZQ7D5-BFRLWvpx.js.map,sha256=X55lLHAxCs-duP6HhZQnSLj9s1JZU-SKoc736BlTS_w,151914 +gradio/templates/frontend/assets/gitGraph-ZV4HHKMB-Bw6ouG5o.js,sha256=t0T4cWrRhiEpbvh4AABzHtRozh0vzH-mRUr-Fv60LpM,471 +gradio/templates/frontend/assets/gitGraph-ZV4HHKMB-Bw6ouG5o.js.map,sha256=d1Hy4soVtTi5A2eSkDUH5dcA5aM17oxM7fLHDfrZmRs,110 +gradio/templates/frontend/assets/gitGraphDiagram-OJR772UL-QR5MZowm.js,sha256=yjNyDl77-5hvvFNDh0UhmFT2z1uhHW1RrFc-xta14zk,24346 +gradio/templates/frontend/assets/gitGraphDiagram-OJR772UL-QR5MZowm.js.map,sha256=1zLWhGwOXVMEKQv0YTRAdmoQnNB2DW3F4awNnzSlvnQ,102313 +gradio/templates/frontend/assets/glTFLoader-DPkYMcjx.js,sha256=KdTCVqiVCZsiYvhQRcxGtYoZ3HlQfbywvHnDThPmUqc,107607 +gradio/templates/frontend/assets/glTFLoader-DPkYMcjx.js.map,sha256=fQ4fcimVt9-dEPsWdkvhD9y6o-cFUrthjtdy11kGqzo,417879 +gradio/templates/frontend/assets/glTFLoaderAnimation-CzrPpHFt.js,sha256=LKaHIYJTgfNHgNunbolYai1_Fh4Jf-tWYA2eKV8ppms,1842 +gradio/templates/frontend/assets/glTFLoaderAnimation-CzrPpHFt.js.map,sha256=01p7BFbj8CZJ4rrw-qB_FP5JHni1I9bRIKyd26A4D1M,6506 +gradio/templates/frontend/assets/graph-CNGcdbSj.js,sha256=vEJwM8UoVcVVikPRx9rAFkhaik6PH_4LJ5DCJWSaw2g,5963 +gradio/templates/frontend/assets/graph-CNGcdbSj.js.map,sha256=DPeiCEFdpy8DxVLp7eRv7ObvYbiXaBzh7FYZrQLGn14,23041 +gradio/templates/frontend/assets/harmonicsFunctions-CwSD8EQ1.js,sha256=-TZFMSP_EZ2oo1cbdUmcE2ZCr1oJF6nMMAbGB_KaU9w,2637 +gradio/templates/frontend/assets/harmonicsFunctions-CwSD8EQ1.js.map,sha256=sF5s5epzDspIwWlWGvqYP3Yyn-cdbfstclC4QwccZs0,3856 +gradio/templates/frontend/assets/harmonicsFunctions-Jp_q-PZV.js,sha256=jKCmWF24aQtfG_rOFRXmzurWDEStfCWy4CkacVM7cic,3470 +gradio/templates/frontend/assets/harmonicsFunctions-Jp_q-PZV.js.map,sha256=T5GU1hmE6YV3aLrNtRkz0pVw2oamjAjJeGWnFXblzDo,4700 +gradio/templates/frontend/assets/hdr-CgliAF0O.js,sha256=mpsSxyby3rhWwwz7iy3dKMNt2oHydKlaTqH63dS5eLM,4077 +gradio/templates/frontend/assets/hdr-CgliAF0O.js.map,sha256=GN9jc7bUDmIJSOL80kuZqXjW2Ps7VCpTgg3bFUt5a3Y,23609 +gradio/templates/frontend/assets/hdrCubeTexture-CurKAHWM.js,sha256=vmZt4oKsaIzGQTx0sVSLzuYnR5qDbMYrA2mW-aADfAs,30073 +gradio/templates/frontend/assets/hdrCubeTexture-CurKAHWM.js.map,sha256=NCIoyBPFGMoqBhkvvV5ksWqxxovZ0u4pAanlqu2JoIU,103693 +gradio/templates/frontend/assets/hdrFiltering.fragment-CbT12z8a.js,sha256=hKhq3qQ_quISCSo5lj1uPaimnKlYpZxM6yzIr8v8kaY,906 +gradio/templates/frontend/assets/hdrFiltering.fragment-CbT12z8a.js.map,sha256=y7nlt3gQ-9dfkuTL3An7SC81wfgU84HoAKCL0-GprUk,1581 +gradio/templates/frontend/assets/hdrFiltering.fragment-Dlsj1R72.js,sha256=X9f0eARt7nw6teJMLzQa6j_KvjZm8SG0SpBWo2DpkOg,740 +gradio/templates/frontend/assets/hdrFiltering.fragment-Dlsj1R72.js.map,sha256=rWuLXSPWcaQw8RGV5SBr1Ruf7gl4LhRG4ABrkdQ7zCM,1397 +gradio/templates/frontend/assets/hdrFiltering.vertex-BBd1acFX.js,sha256=6nXbTsihUga59d2dkzkmKDCgfaC-iULh73ZBYA6zzA4,618 +gradio/templates/frontend/assets/hdrFiltering.vertex-BBd1acFX.js.map,sha256=kYv4_cribtRZcrBCfqp0qMTCvWjRUS_2qCX6FaCBDAs,1159 +gradio/templates/frontend/assets/hdrFiltering.vertex-P0ufb6uO.js,sha256=088EFbE7KAwXcWWSNIetBjDM7cDO0kzzDdI-pEyzwME,757 +gradio/templates/frontend/assets/hdrFiltering.vertex-P0ufb6uO.js.map,sha256=wB5ZSpYWbpbg0CiJvPSS_4I_j9m1Xu7UmNE1K5ODOIM,1316 +gradio/templates/frontend/assets/hdrFilteringFunctions-B_7F7DJR.js,sha256=yBEe508fxT5Kdbc_jfRaej91AbkT6dZmBraa-TXm7zw,14042 +gradio/templates/frontend/assets/hdrFilteringFunctions-B_7F7DJR.js.map,sha256=5haTBSFJSPnBtt2OrIv22FLwMJpBPie3-x3LTcgtfqg,16909 +gradio/templates/frontend/assets/hdrFilteringFunctions-BzebQNW2.js,sha256=ZV0ciJj2VZhyWfeO0A16M4LunNtPVvcLvzsC1TFw4Go,14544 +gradio/templates/frontend/assets/hdrFilteringFunctions-BzebQNW2.js.map,sha256=XEEIw7QlnCsjXJlihr6nDc_A_8Y7l332bJ6mAHwHTgU,17327 +gradio/templates/frontend/assets/hdrIrradianceFiltering.fragment-CkZKlihX.js,sha256=iEs5thZZCrUj_OicVQDNEEH2-Y-NsTIj3LhcU-GeRHk,854 +gradio/templates/frontend/assets/hdrIrradianceFiltering.fragment-CkZKlihX.js.map,sha256=xFMNiITaOZRHDVPTTLaJxsz2LmlLKzt_cXn2ZeH3PXE,1589 +gradio/templates/frontend/assets/hdrIrradianceFiltering.fragment-CstyMXi9.js,sha256=HhbFiZoTEFbdRyY9HrnjZO0_O4FyO8CZdZsKgcsi8OM,1066 +gradio/templates/frontend/assets/hdrIrradianceFiltering.fragment-CstyMXi9.js.map,sha256=vHkJrTRQlzrdxShfmMtDNKKUYHgOgVDzIWIRvNPXvvU,1819 +gradio/templates/frontend/assets/hdrIrradianceFiltering.vertex-BjF_mFBZ.js,sha256=HTFKskt1KNVSqcclbRA63TfxhXxS5xDERz4UotSa_ys,648 +gradio/templates/frontend/assets/hdrIrradianceFiltering.vertex-BjF_mFBZ.js.map,sha256=eW74u46uprdtx4-8TO3eVB4GlnGUh8TnoSqiiWY8KEo,1219 +gradio/templates/frontend/assets/hdrIrradianceFiltering.vertex-DYL50I-z.js,sha256=tlhojzimHmYlnREMay_q1BD8CmP40y72iX1mJkB9EK0,787 +gradio/templates/frontend/assets/hdrIrradianceFiltering.vertex-DYL50I-z.js.map,sha256=J8A9h-QYfL4TaOOHpYD_6KN9lp7-7Rxp49eZLRvdKOc,1376 +gradio/templates/frontend/assets/hdrTextureLoader-Bw5Byv4j.js,sha256=SByfExmlX1HmwKKQMwhy4WdPpH6tBL3SEBiRDyjPHwM,669 +gradio/templates/frontend/assets/hdrTextureLoader-Bw5Byv4j.js.map,sha256=1n7kFsxoFM5sJADgZvlDfRleYfnb9b-dt8_HTekInV0,3250 +gradio/templates/frontend/assets/he-C03Xfbr8.js,sha256=raf778GfRJrTtuZ8whDvxAsTcCDCMDC7PwPgKMCx6kI,5159 +gradio/templates/frontend/assets/he-C03Xfbr8.js.map,sha256=KTS6HHoYIxxPaE9sCsPKIWhK5OvB7xh3noB0Y-b1iW0,95 +gradio/templates/frontend/assets/helperFunctions-BW6ATkfQ.js,sha256=flP4Y2dM42SoqB2Lkro4zHbkvo7D1buh5jttKG5OHiY,5520 +gradio/templates/frontend/assets/helperFunctions-BW6ATkfQ.js.map,sha256=E-VapCx7eyLHwWshG4VvuuYksi5tbvuvE-lHnKzhHss,6691 +gradio/templates/frontend/assets/helperFunctions-BtnS2zOM.js,sha256=uh7MOhxTXaWP_KAqa9BtPcTZK66NpxWqVRJVmY2w3r4,5357 +gradio/templates/frontend/assets/helperFunctions-BtnS2zOM.js.map,sha256=2w_GJ0iY1Xvi32iMoxanTVDyt4UuXWD5rEzCpjeLrt8,6373 +gradio/templates/frontend/assets/hi-DaWfWT5u.js,sha256=IScXLNIdtgptwM8D1hPIobuWKmyhLfNH3ebgs7b-muo,8360 +gradio/templates/frontend/assets/hi-DaWfWT5u.js.map,sha256=inDNdYF3GufukaclHcLB2rcCI_0My5LCHp4Pq8pkTUs,95 +gradio/templates/frontend/assets/hls-C7-VjdhD.js,sha256=tQnsXrPDyDswd3KwV0SxV0AXoDCp92HztDGjbF-kOYQ,395829 +gradio/templates/frontend/assets/hls-C7-VjdhD.js.map,sha256=aRRuwVjlxA7a2s2kQbMY9_8WiehS0bS-KGggUlSqN9s,1558824 +gradio/templates/frontend/assets/iblCdfDebug.fragment-CSuV2Jv3.js,sha256=7m-ReKprYvPGmn5g4Hma9HPBhgiDEtai99EJ1gSXzv0,3163 +gradio/templates/frontend/assets/iblCdfDebug.fragment-CSuV2Jv3.js.map,sha256=ISamVJW7KtAzvSL1WaffIsuCR-tYLvccvjR6ggeMYjk,3880 +gradio/templates/frontend/assets/iblCdfDebug.fragment-DVtl6iWR.js,sha256=QNily6gGxD9qiIZUE66qzMFqAJ04zgHAyyi3bJly1NY,2788 +gradio/templates/frontend/assets/iblCdfDebug.fragment-DVtl6iWR.js.map,sha256=-XKqt2TnqeM8QYoJwKjD_eR04mmi_91FJTx9lyddAG4,3540 +gradio/templates/frontend/assets/iblCdfx.fragment-QyHPOuHU.js,sha256=BrANcZZP5OaCYTMkmxqcEcMzgZYVRKRS9Q0zqAiXCUM,605 +gradio/templates/frontend/assets/iblCdfx.fragment-QyHPOuHU.js.map,sha256=DZMpDXrUz2BoQrLj0uKMhFj3dpq06ryvy3eXkbKdcec,1117 +gradio/templates/frontend/assets/iblCdfx.fragment-YwdgT4iK.js,sha256=GjHM4r6PV7K4qs4VeTYAhOH9BALi3hg6xzetu0M9A-M,673 +gradio/templates/frontend/assets/iblCdfx.fragment-YwdgT4iK.js.map,sha256=gpyRZw2ea8G-OuJui1DsGwgGzywBoAqOPDVPObLjE8M,1197 +gradio/templates/frontend/assets/iblCdfy.fragment-CHO7aPsJ.js,sha256=yACI-nx0RZyc-YVPbm01uO1S4_S3ekxTwdWfKQ9OXrs,1271 +gradio/templates/frontend/assets/iblCdfy.fragment-CHO7aPsJ.js.map,sha256=JN1_Lpl0fkGAvYZ8bgTKdi16le3fwkkPX8ZexnLqYds,1915 +gradio/templates/frontend/assets/iblCdfy.fragment-DNmqsyFP.js,sha256=hyQF54wKpM6kcAB7xhjVWdD7kdQMRN80UWOShkvkpZM,1367 +gradio/templates/frontend/assets/iblCdfy.fragment-DNmqsyFP.js.map,sha256=e8WTUa7_glLP07fjQKbmTNHRsaJYfx969t7Q2wXI1HM,2024 +gradio/templates/frontend/assets/iblIcdf.fragment-pdBg2lQN.js,sha256=sFzXczxEYRyOvWPg2uqKGeCDO-nA61Ksh0zshH8i_rY,2949 +gradio/templates/frontend/assets/iblIcdf.fragment-pdBg2lQN.js.map,sha256=J-ScpkdldqhSbMPJW-C--GXkdZLHrJzt8qx2_ra2AXs,3665 +gradio/templates/frontend/assets/iblIcdf.fragment-veGoSptT.js,sha256=iuj0sd3hJMBDVpYwV-JUISggXGNyE9QvHtJVn19Xklw,2567 +gradio/templates/frontend/assets/iblIcdf.fragment-veGoSptT.js.map,sha256=iSfUHlIixUJmnr9jtlKbKLHeJUQenU3-hpGZWCTz-ig,3270 +gradio/templates/frontend/assets/iblScaledLuminance.fragment-DfgSJxRg.js,sha256=QFoXi5huqOmilYa2le4I3hT4HwRpaRfBB8C2D0y7AC8,1143 +gradio/templates/frontend/assets/iblScaledLuminance.fragment-DfgSJxRg.js.map,sha256=gxGgyoBb8BEsdYYU1EAaDLVlGmhooq38CV2TfQdv8WU,1778 +gradio/templates/frontend/assets/iblScaledLuminance.fragment-kd94CiBQ.js,sha256=rBFGS44dnYjzLFGZwXa_ineObuKfuDMIfTRCnJskPBI,1000 +gradio/templates/frontend/assets/iblScaledLuminance.fragment-kd94CiBQ.js.map,sha256=BDp6d1xovdQ8MMDhg5W6Rlt9RSCX_zNM2FQ6Yx0T6T4,1629 +gradio/templates/frontend/assets/id-DT7UMZdQ.js,sha256=ywSwXRcRyO6BlPtY470pDyBQwpWKjrzDpk6CZJ3fHdk,4599 +gradio/templates/frontend/assets/id-DT7UMZdQ.js.map,sha256=cWcUVLVx6-K_NempecRm9bTiHU-PS3eDMcKlk5e5dOc,95 +gradio/templates/frontend/assets/iesTextureLoader-BuL1b5Lr.js,sha256=bfS_rpOQUIPnRNudFoKWT0aVi8x8Xln6pftc9q4n96g,2799 +gradio/templates/frontend/assets/iesTextureLoader-BuL1b5Lr.js.map,sha256=I_PFX3rbpmb3U4TTx19T3WsSsJbbOz8nzt43ctNRrzo,12341 +gradio/templates/frontend/assets/index-8eNLWKe4.js,sha256=J0q1ryIxkG66oLtzDYJChwIm36TCUNVULwVkGslT3OU,29012 +gradio/templates/frontend/assets/index-8eNLWKe4.js.map,sha256=XDcw4fZlJW91ldmqTcSgJqA9dsEUm8e9_UPUNpxDDqU,76758 +gradio/templates/frontend/assets/index-Bi7T_FA4.js,sha256=y_IK9UfvPXhej3qGeXLp9GDx0ObhFH6B7-HKKiA3hUE,4901 +gradio/templates/frontend/assets/index-Bi7T_FA4.js.map,sha256=GAMK2espYkTTZ9OmoQXWTFgI09ma2HXi3NRYyjkIi9w,23561 +gradio/templates/frontend/assets/index-Bsg08AHY.css,sha256=ju6sTexxG14ZCP0jy02BnRvbcKf2XNDp6NP7_TW-_Gg,346 +gradio/templates/frontend/assets/index-BuGJD51F.js,sha256=l9dSHu_z9qPeUZkVABtkQAmm7OwrVReV0b-p83PWD-s,26098 +gradio/templates/frontend/assets/index-BuGJD51F.js.map,sha256=9F2_tjMgy3e1bUjCAmifGlRtJdrk5ksUWPxbYDkDh_s,110316 +gradio/templates/frontend/assets/index-BzpxcIpX.js,sha256=Q1ZjAWBNYd9lMccGVbLIYV6SJ8hNbjHFnUBfXmGHnBI,386 +gradio/templates/frontend/assets/index-BzpxcIpX.js.map,sha256=n-ctOoyLAhfAiH8wrZQqeZWXBg2RjN3vMgAfpNzCIrQ,98 +gradio/templates/frontend/assets/index-C2d42dEp.js,sha256=b6UwiCgqAIvngtgZsqiU6rSOqjUU8XnZ8Uiq6x2Xqvg,1216776 +gradio/templates/frontend/assets/index-C2d42dEp.js.map,sha256=kUWCUGJ-H6REYoJquHaePlVeO3-4PS6csnP9j3Rk3bo,5109867 +gradio/templates/frontend/assets/index-CCA5X64I.css,sha256=NMWW6GV9PZFexWkO-UA3qJfRIbC71U0QIPE_-6N8bm0,24425 +gradio/templates/frontend/assets/index-CU3nGNJz.js,sha256=L6rvLpB2Qc7zGbmCvn6IBPrg52SxWTHmD1nuFrdgr-8,21306 +gradio/templates/frontend/assets/index-CU3nGNJz.js.map,sha256=1j8Lgd7s7kY8WrYtzJKzDYshagt8F9g2ULa-X-HYVTA,18044 +gradio/templates/frontend/assets/index-CWx9LkNn.js,sha256=ktY5VGpCWQBo_t-HnvqkOBG7elGidGVxNBDXpJWVuB8,515 +gradio/templates/frontend/assets/index-CWx9LkNn.js.map,sha256=jhSV5AT4eNc6ZvqNRQk_RQjnPHBdW-R9PK3CL7RT5Gw,98 +gradio/templates/frontend/assets/index-CgpuqYrI.js,sha256=4mj_NuTA7fmhcD7tHLu6uPGJqj4hukn6ejwZp_JTa8k,23233 +gradio/templates/frontend/assets/index-CgpuqYrI.js.map,sha256=o5g8mGIGWhKkqhMW2JbBqVe931MlOYQFD5pKWIMko6g,44100 +gradio/templates/frontend/assets/index-Ch8-kTSr.js,sha256=6df8cZR3F0gLENI_EhPL199wLk6pTlhcTi8NWsWIyIU,56342 +gradio/templates/frontend/assets/index-Ch8-kTSr.js.map,sha256=tMPodlLtjz1o3pjEYYU-q95-H1dLULAVoULAldKTVx4,82335 +gradio/templates/frontend/assets/index-CnqicUFC.js,sha256=xbt3v51tkQzxJQyXwW3J_8KKfIqdgYXp3FqN13Pdv8Q,522 +gradio/templates/frontend/assets/index-CnqicUFC.js.map,sha256=xcvB0G5Em7B5dhcYSxdbFCOdvH0L9DfMOcgIHRkaWd4,1813 +gradio/templates/frontend/assets/index-DRdm5M3o.js,sha256=eAwHvoA7Q35Y8d7pkC5L1b-fINJbH-DVs316_N3LFZM,43286 +gradio/templates/frontend/assets/index-DRdm5M3o.js.map,sha256=FZjylX-TX5N-vrsdamgDkOaf96-HLROlLkOS57TijtA,174843 +gradio/templates/frontend/assets/index-DlKYCOpQ.js,sha256=kd12Jl4J4-g_bh9OcS_pH2Tw_OvUMdh5jYdk_jfmGDM,2683 +gradio/templates/frontend/assets/index-DlKYCOpQ.js.map,sha256=bMsvegKMzi9ta9E1dNEJad6cU-8tqY3mEgCuNfNflOU,5939 +gradio/templates/frontend/assets/index-DputZZxm.js,sha256=EQo73Qj6DL50YTeaN3QjBpWoAfmOHReSTBBfLxSPSdM,43712 +gradio/templates/frontend/assets/index-DputZZxm.js.map,sha256=_-dZGLbPMmLTXJHRTwX77AlgTlgucPS-xi64rR3b4uA,179087 +gradio/templates/frontend/assets/index-VBBlDNay.js,sha256=3q5o45cbyON0AnshEFdmvIqic1wNN1geUIBjd8vevjE,14211 +gradio/templates/frontend/assets/index-VBBlDNay.js.map,sha256=cHqmOLxEhkrMhdmioTktYUoBWnlmCKr-cNcPoGLGLCI,13179 +gradio/templates/frontend/assets/index-cQ65agm5.js,sha256=z_8C4BrlICaBrPitJPLJ2aPVNSccRboNRrw-JBX0w-c,78818 +gradio/templates/frontend/assets/index-cQ65agm5.js.map,sha256=my0lC0HWVuoF3SD-yU_I_eQHHzM4QRyrSXBpFhSjrJk,109728 +gradio/templates/frontend/assets/index-tFQomdd2.js,sha256=ABjs60m3UXjYE57Zj1oyblzW2ovNA7WG9oY5ITmE7C8,1107 +gradio/templates/frontend/assets/index-tFQomdd2.js.map,sha256=vrQSLWSeYwmO_KmdW-wG8sVUbaa7eAD1pVGtx3jFW1Q,4091 +gradio/templates/frontend/assets/info-63CPKGFF-BBh5yhjh.js,sha256=H-VqrHTQMJFkPRRBZLMr0vVLNs0h9tdUXAeq5GBDfkg,459 +gradio/templates/frontend/assets/info-63CPKGFF-BBh5yhjh.js.map,sha256=DpdROIBN-4Lyv6ir-m7qrBNQ-JksRc7iGwjheI8NR1M,106 +gradio/templates/frontend/assets/infoDiagram-DDUCL6P7-QSj5pY12.js,sha256=vbsTMYhMJv_DVpqxdcS3lL3MuAkRCqVgUzaJ5OESj7I,893 +gradio/templates/frontend/assets/infoDiagram-DDUCL6P7-QSj5pY12.js.map,sha256=fiB4-ei1PS6TIcWWVg4XeqReWDiItxkJPAvYIdu5Pn4,2376 +gradio/templates/frontend/assets/init-CYI6iZYC.js,sha256=9fsU4JMCa0yGL39XOjFUC46pE8t3l14dXdlvpAbeK3s,103936 +gradio/templates/frontend/assets/init-CYI6iZYC.js.map,sha256=CTAP1O0SQVzHnATk9bdWDeIr2sITpMlMqpDB0VS6oTk,354867 +gradio/templates/frontend/assets/init-DV_66Kck.css,sha256=Ukl7zc4qcAYVR7Tm-hCDnBcAe3QB9MOw41NY5SsaK2E,3375 +gradio/templates/frontend/assets/init-DmgGIVbk.js,sha256=hd3G4XC1dus1H6uQb8FahzC_s2Hrznpe9o7UhK736tI,62229 +gradio/templates/frontend/assets/init-DmgGIVbk.js.map,sha256=BqNg_Wa8y0PjFK1jvTT4ZzD5XKyzxN4XIrd7cNsucGo,213006 +gradio/templates/frontend/assets/init-Dmth1JHB.js,sha256=e2B9eab_dO34eIAfsY62frdm_vXZ70jK4mInUVpuSDY,419 +gradio/templates/frontend/assets/init-Dmth1JHB.js.map,sha256=RnF9y8NxeS5PNuINgsJilvIp-xt2JRdu2NNl03Phb_s,1382 +gradio/templates/frontend/assets/ja-BTBiRAkN.js,sha256=bH_QOditT2ewgPv1mcC16e1h4snxurav6ls0x-FcHFE,5673 +gradio/templates/frontend/assets/ja-BTBiRAkN.js.map,sha256=ShQEg2NTLDUr7P9huroeo2onARx3PKAK1YwyLZ2Knyc,95 +gradio/templates/frontend/assets/jinja2-C4DGRd-O.js,sha256=24e8PSC26afbvflwftjMJy5TSiZ2lknHo7ORQ0bMRdo,2660 +gradio/templates/frontend/assets/jinja2-C4DGRd-O.js.map,sha256=Xft8SBerfGux0DNijpGCgAnRa5iCKvR4iGmk4F5RMME,8363 +gradio/templates/frontend/assets/journeyDiagram-FFXJYRFH-Cwj7yH7o.js,sha256=K_S3NTsDOZfTSQGYkCGXtqOmPXPJ4QwNiH15K1CtWS4,23762 +gradio/templates/frontend/assets/journeyDiagram-FFXJYRFH-Cwj7yH7o.js.map,sha256=JcXghg0Dngc0s2son8eBI978FI3n7fw2kj_FCHV5YqU,80493 +gradio/templates/frontend/assets/kanban-definition-KOZQBZVT-M74Keujt.js,sha256=RgyJ60llYnkPe84z-qJLr0bLrILfvKRi3FfHVo9Xjks,20397 +gradio/templates/frontend/assets/kanban-definition-KOZQBZVT-M74Keujt.js.map,sha256=J5xJ0eg_W6-LHtZdxEC5VK25hSNwInXKMCD9K9CEYaE,68010 +gradio/templates/frontend/assets/katex-D7pEq4z3.css,sha256=6me66U3XAlxHMSItEYViIBJntG8fFR-QBqDDDdZSpUk,39799 +gradio/templates/frontend/assets/katex-DsmCZfJr.js,sha256=TYfZx88II0-lAwEQsBFz1m1RHSZsxgtrTV7r5ERhLfA,265473 +gradio/templates/frontend/assets/katex-DsmCZfJr.js.map,sha256=IHrU7zb23frq7FWzJ9aF9e2lsMf2cBsgAxYHrT3CY_4,988229 +gradio/templates/frontend/assets/ko-C9Hiv2KW.js,sha256=XkKrMF7PJCuxurE817_2s8MUZmuEUSJDmWu4WInQwtU,5070 +gradio/templates/frontend/assets/ko-C9Hiv2KW.js.map,sha256=XV1gNY0JS5DfulkZlUZq2EOlEGBvATvEGsCXnhPBD9k,95 +gradio/templates/frontend/assets/ktxTextureLoader-DxyNMW0c.js,sha256=dSISqRxeSSGnKXXTGp1Z3G92ndYumuM7JBHk36TP1bM,14308 +gradio/templates/frontend/assets/ktxTextureLoader-DxyNMW0c.js.map,sha256=Kjnmew6cnD57uXM5IH3KWxtQLDoWtsJ1o8Wt7DwfysQ,54935 +gradio/templates/frontend/assets/layout-DQ1zOf5h.js,sha256=vJQcIOFalBRmRiM_GtuFiPLvPJ9JkVjLGB2a0-yXzvw,27250 +gradio/templates/frontend/assets/layout-DQ1zOf5h.js.map,sha256=Lok1_STxpcSq_2xBU9URsfaVYdhIBhvcpieu8GB7HZA,162863 +gradio/templates/frontend/assets/linear-CD2whRFK.js,sha256=HpCpZ0kQJ-qVRx9k-kWox2Ybw8pPGPgh5rrhomC-Agw,6036 +gradio/templates/frontend/assets/linear-CD2whRFK.js.map,sha256=gPGOd4PYDZZGJywacbt4LgDCM2y_bVYlNNEMjlAy2bI,28476 +gradio/templates/frontend/assets/logDepthDeclaration-W0lVC1c8.js,sha256=OyVXjtyWq-sTrwlj7NgWA89mRQ3lOJkiEDH-igcaLkU,296 +gradio/templates/frontend/assets/logDepthDeclaration-W0lVC1c8.js.map,sha256=aZize29ueT05DLyq4sP10hWqVNDkm60tZpJEG5zKQlA,891 +gradio/templates/frontend/assets/logDepthDeclaration-_-vQoNOA.js,sha256=zre17skM63y6dozWJBkwRQRt6T5zddRFqfgGJnF7R44,810 +gradio/templates/frontend/assets/logDepthDeclaration-_-vQoNOA.js.map,sha256=EpYW6kPgTvZIY5mIJUw_AW9A2h_RnMag8oxdU133y1E,2476 +gradio/templates/frontend/assets/logDepthVertex-D7ur_Vwy.js,sha256=_x-tngrh-AXTtkCPupc6AzVKBwMy3dfYinnonWEVifs,2030 +gradio/templates/frontend/assets/logDepthVertex-D7ur_Vwy.js.map,sha256=XkBRI5_Hzswo_lN6SgOkmqXbkdgZWAMDEK0RDn0T5H0,4923 +gradio/templates/frontend/assets/logDepthVertex-v7yKqzZ6.js,sha256=Pr_mwwnNplZ91gRu8g8W_4j2u4AS4EdbmBcuShV4kuo,1654 +gradio/templates/frontend/assets/logDepthVertex-v7yKqzZ6.js.map,sha256=DSbcce5nCSXnE8hrZxhHEPcKBVVfYXOKTufO98NK-Gs,4483 +gradio/templates/frontend/assets/lt-Z_MxAT26.js,sha256=NIe9yf6Ciqgdkute4G0CE2lUNJnYUKOqtYkukoXGOZw,4896 +gradio/templates/frontend/assets/lt-Z_MxAT26.js.map,sha256=Dm7FMxq4txEdnZYQuiHt5jDav1Dif-IfgCDJSJrqoIE,95 +gradio/templates/frontend/assets/mainUVVaryingDeclaration-BvSS6NAr.js,sha256=psruIIPN_sdeo_rPjYJGPq5tNv81uGyogQXzRT2t2vg,249 +gradio/templates/frontend/assets/mainUVVaryingDeclaration-BvSS6NAr.js.map,sha256=Zod7tIaQlQ-JS1uJ9AffvpTd8U5iT4WRNhczH0wkSw4,851 +gradio/templates/frontend/assets/mainUVVaryingDeclaration-C35ZcpfH.js,sha256=xfWPzxMrpehPcrwBrqQ-PeofAXrm6P-qCeiVyMVmIIY,259 +gradio/templates/frontend/assets/mainUVVaryingDeclaration-C35ZcpfH.js.map,sha256=PB9ncWVhqu0NPm811RpUIoP-pdLUvHb6uH0vF1nx2xA,869 +gradio/templates/frontend/assets/mcp-DNm9doVd.svg,sha256=Dak6acRJHMkXH9h8HKvE7RgG_RjZOlBUGo9tkD_edKQ,9975 +gradio/templates/frontend/assets/mermaid-parser.core-D-Wm7Ko_.js,sha256=YUpJafJSFfuPHL5kDQ2hxw7f7prmZ_qDmzl3eY5JdR0,328934 +gradio/templates/frontend/assets/mermaid-parser.core-D-Wm7Ko_.js.map,sha256=jlt7rCCCwbJ2UGPalAC7ZmTZo6nZ7el53cDvEqFwDPA,1357657 +gradio/templates/frontend/assets/mermaid.core-B-q2cD2X.js,sha256=WgEXMDeszP0xj1EAGceGLELLN_BwA_BomPDINGubfls,440567 +gradio/templates/frontend/assets/mermaid.core-B-q2cD2X.js.map,sha256=XjhcE-UGQKs9n2qgk_nu3jPP25jv24HHVGb4a34zI9M,1502500 +gradio/templates/frontend/assets/mesh.vertexData.functions-BYooUupK.js,sha256=zrBJJbkLMYPuSekCYqwdcU2p9cnCFmOJaOkgkCrz9pc,981 +gradio/templates/frontend/assets/mesh.vertexData.functions-BYooUupK.js.map,sha256=ldxtB_DNcLkWAdr8tdfm-Ao3ot-vuyddld9OElmAK1E,6506 +gradio/templates/frontend/assets/meshUboDeclaration-2DCAXNK-.js,sha256=_sZO14nFmKw946CmxW10dFgLcjnGs1x4S2M-CoPkP7g,613 +gradio/templates/frontend/assets/meshUboDeclaration-2DCAXNK-.js.map,sha256=Z6uPc0TpOKh5082bnL11NPgJe61T2TYiQHmuaOPj4uM,1772 +gradio/templates/frontend/assets/mindmap-definition-LNHGMQRG-CzRZKjxo.js,sha256=hnDdihnlQScv7Uv6RU8Iwx2G7b3Uldye_Q2MfMwg2qM,101652 +gradio/templates/frontend/assets/mindmap-definition-LNHGMQRG-CzRZKjxo.js.map,sha256=NSjSB2fnalWPYsNj_fulwupD4r0jFbI90wae-MvCxJs,367276 +gradio/templates/frontend/assets/module-Bv4JZ_cX.js,sha256=F67qid7C4lzddHSgHETucHkIjjNv-qFzpN1zwj_pKAw,91333 +gradio/templates/frontend/assets/module-Bv4JZ_cX.js.map,sha256=1AsPTOB4UfSmfPrf752ubWWj0TeNXMyH7frjAS3SB_g,568402 +gradio/templates/frontend/assets/module-C-VadMaF.js,sha256=sONT5t6wGMTmS4ARFacVpTtrJatsU000v1BpAO6sdS4,1670 +gradio/templates/frontend/assets/module-C-VadMaF.js.map,sha256=nFUDaa6RH4MW37dQ9NquhXA9eScwDPe3cPS3kewUOr0,11710 +gradio/templates/frontend/assets/module-moYYmAFH.js,sha256=ft6eW2RcBaHAcNnBnJFZ0Q6ryGA5mDA2AUSWDOuPg5k,9929 +gradio/templates/frontend/assets/module-moYYmAFH.js.map,sha256=DoTF_rL_Ol10n7V02Wa6sYcSf7oe_wQqZVDW2wZxvcg,12853 +gradio/templates/frontend/assets/nb-CGxYPyHM.js,sha256=ajGD-3NzqxM_PL5pBo60D3RLOj93GBv9X-YMJffoSko,4490 +gradio/templates/frontend/assets/nb-CGxYPyHM.js.map,sha256=UVVBrHYLeXoQN7cEq-66SnibaSJ2Csue7zZDGxKXmc0,95 +gradio/templates/frontend/assets/nl-Dw1IiFHs.js,sha256=43I4d0HWVKFhiSXNh-wMTbQ_QqeGUt6Ad8CSXFwtVUY,4811 +gradio/templates/frontend/assets/nl-Dw1IiFHs.js.map,sha256=9xk5C9XJneYWxEY5PiICHRPezbWuS_pDc-dZrWGhJWQ,95 +gradio/templates/frontend/assets/objFileLoader-D7HzXugl.js,sha256=N_eUSTeyhiPPUVbYor8tVl-SG5ercWOrFbQ7ZAQ8-1M,18749 +gradio/templates/frontend/assets/objFileLoader-D7HzXugl.js.map,sha256=nV8fimiymKz8_Vw6IkiOj8TgYY6_nVjZNXL5s_klyIw,90028 +gradio/templates/frontend/assets/objectModelMapping-BYp-hBQ7.js,sha256=TUVuEAiuRaFsl6fjsr4iWn716zKEAtVZIAPjYCelaEQ,36510 +gradio/templates/frontend/assets/objectModelMapping-BYp-hBQ7.js.map,sha256=cNdh87-0ypxmZOh6fStdlOGTlYe9eVWft5UK98ssFJE,143266 +gradio/templates/frontend/assets/oitFragment-CrouZEnW.js,sha256=9G_5M4njX7H9D4MJeVCgX_Z2lv4dvTPifsaIjv_ZMcA,68702 +gradio/templates/frontend/assets/oitFragment-CrouZEnW.js.map,sha256=3WHCGGJOQG59C8R_wXFMrfLSTp_-BtdHEvzgCk0pu9g,85104 +gradio/templates/frontend/assets/oitFragment-Qp3lyXyH.js,sha256=SCAZ3KH0C607PY2C55Z-B41O3ZcLx09ZeHZpZ2472WQ,73148 +gradio/templates/frontend/assets/oitFragment-Qp3lyXyH.js.map,sha256=A0oIzsCJS3SbIYbbs58lHaOBbV0X4-RkZSASI2PdLsI,87285 +gradio/templates/frontend/assets/ordinal-BeghXfj9.js,sha256=90xYpgQJqq3BAP8QG2vzLXR7mvMBXz-JoIzR4Zpp9Is,1518 +gradio/templates/frontend/assets/ordinal-BeghXfj9.js.map,sha256=L30ApMHelwYRZi-O6V5Ny_82cRirHMEZi9Q4zZwd-9E,5589 +gradio/templates/frontend/assets/packet-HUATNLJX-BftxlHm8.js,sha256=ZXJVCIsWofux53W3ekpPXQHr6no0cn_GoFsnZLPJQyM,465 +gradio/templates/frontend/assets/packet-HUATNLJX-BftxlHm8.js.map,sha256=JUJ34Q3FiBT-x6ane7QBvZ6VUWiBQKnH_TvNPn9HfqU,108 +gradio/templates/frontend/assets/pass.fragment-3qtFV6lH.js,sha256=OKT2HyVVPeuIZQABO_V4gTY2GRCDjFcrT9mlM115lFg,557 +gradio/templates/frontend/assets/pass.fragment-3qtFV6lH.js.map,sha256=0IrTTa7Go-egzxFHwZqX0Xx0kVHIg0vMrTfNylNdpe8,1072 +gradio/templates/frontend/assets/pass.fragment-BEIcvPpm.js,sha256=d1lMIpXqsl6lwNgZpr8rbcqiz9mZzVWKVPC5CF7ULmA,423 +gradio/templates/frontend/assets/pass.fragment-BEIcvPpm.js.map,sha256=Y0NVmslfIef_sOWg_HNWcq4_eXGNZtziiqnIVPAJj5w,926 +gradio/templates/frontend/assets/passCube.fragment-BMjvSgRO.js,sha256=NsSOMCgqHOTtyumvzn_HvUUxkkRcGXVYOKFB2Rb6Z0s,1241 +gradio/templates/frontend/assets/passCube.fragment-BMjvSgRO.js.map,sha256=wDybCP_sb4-_4mZKsPgtrkrGnlKyYap-ZBOKeC_qfn0,1882 +gradio/templates/frontend/assets/passCube.fragment-BUsaJZla.js,sha256=bGsgKpc2GyO1uPXQQxC0ciznQyiePRBmBIAzGEKP6cY,932 +gradio/templates/frontend/assets/passCube.fragment-BUsaJZla.js.map,sha256=r-ziUxDnps91sosY8Bsu2UZblAvoPGB468xXRPbrB3c,1561 +gradio/templates/frontend/assets/pbr.fragment-DpEnpnvh.js,sha256=8oL6MFhs12QF8M-7lRR1qgfrsA6wSlrfQKTwVoiF65c,108775 +gradio/templates/frontend/assets/pbr.fragment-DpEnpnvh.js.map,sha256=VlwIjHZAj31LZCKNXhuCh57RfWR9wVNuPF5ENMGpo7g,146890 +gradio/templates/frontend/assets/pbr.fragment-qLgsgmY9.js,sha256=vV__zLsamX3P02Zqx0PFKjpAs698GDlscp5tj0Uk6TA,113031 +gradio/templates/frontend/assets/pbr.fragment-qLgsgmY9.js.map,sha256=8LRd6hRlpy_VNRg4SmjnK3NeejlW-jUDJZoCjVz84Ac,150511 +gradio/templates/frontend/assets/pbr.vertex-BC5Bhoax.js,sha256=MJ-PEVKfApk8JjqNc68BOhoUdqbvXUXhCZwkqPZqnOo,15047 +gradio/templates/frontend/assets/pbr.vertex-BC5Bhoax.js.map,sha256=5OOxyEB1dqPz2dyFhX91EztyDT3fHd5r8PB-tHXTBtE,19601 +gradio/templates/frontend/assets/pbr.vertex-Bz6yCfw_.js,sha256=DrwKrXHGcEB6nsOffP6uu94i-ctAMgj0PMWIwsBniYw,11756 +gradio/templates/frontend/assets/pbr.vertex-Bz6yCfw_.js.map,sha256=WEec1dBW-gjiIf1uL6NA6_MJB2OJnHaxh4LZfHuFBFI,14830 +gradio/templates/frontend/assets/pie-WTHONI2E-DjRzxAZC.js,sha256=WwFH88HOYLO0heIWXa3kqPt_plTh0FX21E9aj-sJcUs,451 +gradio/templates/frontend/assets/pie-WTHONI2E-DjRzxAZC.js.map,sha256=23us8IYCqDGoxIbkY1SkBhrmhvCVBNRwIFIn9PKxfwM,105 +gradio/templates/frontend/assets/pieDiagram-DBDJKBY4-DSZTTBNK.js,sha256=mUOQa5KdJENK43Mbw1V9EKhKW1i2J2KaRVe9Ll1bKbw,5447 +gradio/templates/frontend/assets/pieDiagram-DBDJKBY4-DSZTTBNK.js.map,sha256=JuzJruIGmwNgBSHiEryu_1N0Vckpz1flmR7XC-dzmj0,18762 +gradio/templates/frontend/assets/pl-CewrFAug.js,sha256=4qrbf2iYyL17V2KbGr4bnN3NrAmxEff86dlzG7CM5n4,4849 +gradio/templates/frontend/assets/pl-CewrFAug.js.map,sha256=ydPbboHsjYqtU3osfVALE6teTC5wkkFn0vyWGsae5v0,95 +gradio/templates/frontend/assets/postprocess.vertex-lCgcyq6r.js,sha256=e1jrHa3ZuoMlvaKBhjO5Xo_Am1WIVnCi5hxH_SFbatE,694 +gradio/templates/frontend/assets/postprocess.vertex-lCgcyq6r.js.map,sha256=yt6kyVdnzDedv96BJ_CUDaVkhdxHhrar6c27B8P0-lY,1256 +gradio/templates/frontend/assets/prism-python-oCRsS_S4.js,sha256=IbTQn9FGwdWf-bBa8dQDALIJpTyctuDoppVFNAK2cxA,21380 +gradio/templates/frontend/assets/prism-python-oCRsS_S4.js.map,sha256=Fnzemm6JA2SNwz7rlOMoyUvMmz05WAhOZGAWN7IDX9w,88775 +gradio/templates/frontend/assets/procedural.vertex-B49y7HnQ.js,sha256=nG-s-SxuLTs3dnyXm4RLw6rzpqBzDCnfsXkWWOF-zL0,701 +gradio/templates/frontend/assets/procedural.vertex-B49y7HnQ.js.map,sha256=8TcBi0HSKVsvun3oQC3tkOmLCF00lOmKUY5omZO5LoU,1254 +gradio/templates/frontend/assets/procedural.vertex-CEVw0oT_.js,sha256=Fr7MhfOCme2OPkd9EfRzIxgoa2HpGCLFsk87e9p35nk,582 +gradio/templates/frontend/assets/procedural.vertex-CEVw0oT_.js.map,sha256=8E-FESnpsKPZQryPov1sngAQh0VGt5_1UQ1e1xk2G2s,1117 +gradio/templates/frontend/assets/pt-BR-DZjK3tkX.js,sha256=4p8KXnaieznjdLutQaggzw3CuAWJVY3IS8nzPqfb0_4,5007 +gradio/templates/frontend/assets/pt-BR-DZjK3tkX.js.map,sha256=5sp2qMHMXBWv_kBLPvCcP11ucnsSrveRT8fuHjfHhkA,98 +gradio/templates/frontend/assets/pt-DH1R3DI2.js,sha256=gcPM0y2HQE2Sf-ZvBguasRwunCmKS6QwuoXlNYAZeFA,4969 +gradio/templates/frontend/assets/pt-DH1R3DI2.js.map,sha256=z72z6EePWHrRBqfzOaqAo-s-XA3xV5M9WEinKTri_rE,95 +gradio/templates/frontend/assets/quadrantDiagram-YPSRARAO-BQLPJbAj.js,sha256=aSCvd9YHUSNdgjbEMIoI823IQILZ0NAFbMJUzx-z6sM,34043 +gradio/templates/frontend/assets/quadrantDiagram-YPSRARAO-BQLPJbAj.js.map,sha256=sLvegXVIIgcxYHfTGw1oEHYejOi9uYLB-00d4w2LEYo,110542 +gradio/templates/frontend/assets/r-DUYO_cvP.js,sha256=sCFWKfxIp9PvuZUQjlwtC7zX44Jby5eN7LVE5rPabM8,2974 +gradio/templates/frontend/assets/r-DUYO_cvP.js.map,sha256=yQb7hApxlv1A7p7RSZk0A3jWODCjWBMj5opjuogIheM,10648 +gradio/templates/frontend/assets/radar-NJJJXTRR-DsdzgkHM.js,sha256=bVrus-k8O48_2DxXXJgtUTi1mffIItwKUZxFfOQr5jc,457 +gradio/templates/frontend/assets/radar-NJJJXTRR-DsdzgkHM.js.map,sha256=9kW3qjYn-80GmTT8wCCzEDWydzUnlwffFuSPwc-RwbI,107 +gradio/templates/frontend/assets/range-OtVwhkKS.js,sha256=eo9NnFRMiL2G-mvoOQQmUC4GBfONOx-fjxfmeNyuC2c,223 +gradio/templates/frontend/assets/range-OtVwhkKS.js.map,sha256=7uHiLmhTZ_nuGtRoYWz0SYoojc4rsL7GmI6HvADVAiE,937 +gradio/templates/frontend/assets/rawTexture-CP6XYxlO.js,sha256=wuD8uXMkchH7LpesM7sIcdz51gLe_L79CIkAOxf9I5o,1916 +gradio/templates/frontend/assets/rawTexture-CP6XYxlO.js.map,sha256=g_2h6_s0LxJBTMJE0wgqmW1JUwoslRlTGeLsMfYe7rY,15096 +gradio/templates/frontend/assets/ray-CyMIc6bU.js,sha256=_vqO9W6Iok9r0lFq3BwBNPkhm7f3laspuIvt4kcirAY,11065 +gradio/templates/frontend/assets/ray-CyMIc6bU.js.map,sha256=n21VyGSulHnLmw6StOQp2tPfqwnlYs0Cui2j44LRysA,61955 +gradio/templates/frontend/assets/requirementDiagram-EGVEC5DT-E8I1_OXK.js,sha256=m9D7PildkZHJMUlzrBcaL1-Z1Jc2JHwz5_UrMwM1GxU,30285 +gradio/templates/frontend/assets/requirementDiagram-EGVEC5DT-E8I1_OXK.js.map,sha256=csb5RgZ9wEMAK7moRXqvizJIkJbKc1C2mMW4409EFHw,96646 +gradio/templates/frontend/assets/rgbdDecode.fragment-QFVy_YHT.js,sha256=dUztZyjNpdmf8vcYSJ34AsSQWeL6vNixbkDDhPOvKi0,525 +gradio/templates/frontend/assets/rgbdDecode.fragment-QFVy_YHT.js.map,sha256=CB1wi2F86UyQkXXj4uT3bn2TmkoNLOlTl40amzbIWAw,1063 +gradio/templates/frontend/assets/rgbdDecode.fragment-q2qGJMdF.js,sha256=hmNqgF23Jz0OVAdgxG9SPZnMqTwKkIEaYjTMyN0HlgI,660 +gradio/templates/frontend/assets/rgbdDecode.fragment-q2qGJMdF.js.map,sha256=vil_E3uFvgcoiOhHNfjsiZKHPT2Qw6KxANi7LJu4LjE,1210 +gradio/templates/frontend/assets/rgbdEncode.fragment-6aX9tvba.js,sha256=KTgGtpdWvSMxb_s7F0hX8jhdZ0fsfmQuHq06WVC0rTM,651 +gradio/templates/frontend/assets/rgbdEncode.fragment-6aX9tvba.js.map,sha256=Juv_CemgsWTUys4iSXdUI-dW_IXxi-1jNNcJIcTUPaA,1201 +gradio/templates/frontend/assets/rgbdEncode.fragment-CBy55Z_F.js,sha256=ie36-NtlB5XnV0_jUUQ7Ow203HHDqiir2iCsyfKvDE8,517 +gradio/templates/frontend/assets/rgbdEncode.fragment-CBy55Z_F.js.map,sha256=voQ01STker6TuEr0NNYZ_QqRRRiDtYvOoyFNhNMs5ng,1055 +gradio/templates/frontend/assets/ro-boSZHd3M.js,sha256=v67-aOUo5ZA0iZn9CWZGnf4sOlIOudjBIrHtad6T8EE,4995 +gradio/templates/frontend/assets/ro-boSZHd3M.js.map,sha256=fmdE3PJLWqXDM1mxtgVyuavX_PP0eHvPDylQ-ZNzl-o,95 +gradio/templates/frontend/assets/ru-BgQGKwpu.js,sha256=5WXjEzhVCTMG8O2yok2Jy30dHNhn7YSH700Z5Zs17cM,6940 +gradio/templates/frontend/assets/ru-BgQGKwpu.js.map,sha256=vcmdEe_g03bVneQ-jo3fE5gYoIBRv_CX8jMH9O327iU,95 +gradio/templates/frontend/assets/sankeyDiagram-HRAUVNP4-XO3tv7DD.js,sha256=TsYOLj5ploR09yqjExUxD2m6Nq57Bgv3nFbUVIPyVvY,22319 +gradio/templates/frontend/assets/sankeyDiagram-HRAUVNP4-XO3tv7DD.js.map,sha256=zRlJri7sDXZmihBP3-u10D-eQE98ToZLcSA8TjVChzM,85421 +gradio/templates/frontend/assets/select-BigU4G0v.js,sha256=4CQGo9W3zi3YZJT73QfZKyfQOC3ojbY_QLIajE5JkYo,12222 +gradio/templates/frontend/assets/select-BigU4G0v.js.map,sha256=1rdg2BWTi1K25eocd44dEwi3Bpus0C0-TBOvlwGHEOk,54460 +gradio/templates/frontend/assets/sequenceDiagram-4MX5Z3NR-EybBX4qa.js,sha256=xKIz3UCIivruFAQ5EMjhxu4_mT5R7_hS3phT7Z8RB4g,88744 +gradio/templates/frontend/assets/sequenceDiagram-4MX5Z3NR-EybBX4qa.js.map,sha256=LT2SrYw9IlyxSySgkG3YzJwT4g4gNFWOC774nbIjzp0,262269 +gradio/templates/frontend/assets/shell-CjFT_Tl9.js,sha256=BOzJwvmr0JKrhnPWsrWuVt-nGNMJd5F4jWIozz2Rh-o,2614 +gradio/templates/frontend/assets/shell-CjFT_Tl9.js.map,sha256=v8Dn0RhL6bQm0h-uIKhDvNWtiy7ncuzSAj2nmm5Al24,8823 +gradio/templates/frontend/assets/splatFileLoader-CC7oMwBF.js,sha256=k4sFEpI25a_0fHsbeQfRgb6sQ4wYYzHwDu_KbQDBSKc,61253 +gradio/templates/frontend/assets/splatFileLoader-CC7oMwBF.js.map,sha256=GQnfNF3Gq08zZdspTeKHeJR7tykTuG2qVB7iVnb0qZ0,242963 +gradio/templates/frontend/assets/sql-D0XecflT.js,sha256=UPpfwhQaoWaccUD8gz5P-raNdlXHzhkWlMRnXhArm2Y,37093 +gradio/templates/frontend/assets/sql-D0XecflT.js.map,sha256=iX_cyoVcy3-O_q1JJR_0baf5a8Fg5Gdyamc2tcn9Ke0,56022 +gradio/templates/frontend/assets/standardMaterial-2H1L4AvE.js,sha256=SjSCWq-HpT1OSonbErojZY34hTlDL7Ttp-J4cOZYEUI,41558 +gradio/templates/frontend/assets/standardMaterial-2H1L4AvE.js.map,sha256=1E88nUek-pzZ8JVFQMdvRTtVGNUzWhQWM-Y6ehn09q8,117401 +gradio/templates/frontend/assets/stateDiagram-UUKSUZ4H-CJcHrC1o.js,sha256=V1MJBgLNotwx3Cb9WQ0iCpftr8WVo4P5bJXqE1Ref6o,10596 +gradio/templates/frontend/assets/stateDiagram-UUKSUZ4H-CJcHrC1o.js.map,sha256=AY8pilnX4oF1z7VkN8AXlM3ugUm8t2aZOzfn6cv-ZUI,35759 +gradio/templates/frontend/assets/stateDiagram-v2-EYPG3UTE-BGKfOK_C.js,sha256=ZGpLgTl_pssgj4f2tZsn8nrK8uEt9hGj1ZfMDaNam9w,594 +gradio/templates/frontend/assets/stateDiagram-v2-EYPG3UTE-BGKfOK_C.js.map,sha256=nHXxhKg3_ZMUqXi8jdmum-vZNoWxE9lqihvCXYE2SRM,1531 +gradio/templates/frontend/assets/step-Wxge9qY-.js,sha256=D4E-3HnoPCNC6A70mnEUu2JiLLxGFI1jK-EB6SQyn_g,30754 +gradio/templates/frontend/assets/step-Wxge9qY-.js.map,sha256=O398xjcwdJZhGT6mgKFYFZs1sUGowUOwzFlBdsVkRpk,106815 +gradio/templates/frontend/assets/stex-C3f8Ysf7.js,sha256=eV80mhfF73iQU9vJmGox8kc15BKLzkelcVSUcrumFjQ,3166 +gradio/templates/frontend/assets/stex-C3f8Ysf7.js.map,sha256=AkY4PchtszqYeT-Q0Ye0ru39bRQ5_k7Rti6Pxp98hYg,11957 +gradio/templates/frontend/assets/stlFileLoader-ppiTfK5J.js,sha256=d8e6ewU_PyXo_J9XOWPIxRyDdot2cZ2IVvVQRkbFU6M,3206 +gradio/templates/frontend/assets/stlFileLoader-ppiTfK5J.js.map,sha256=QqacCbCEts_gmQtF4nYOkhYflTwSqcBKUuCrLFmfXRI,15137 +gradio/templates/frontend/assets/sv-D1nuPeJf.js,sha256=H-VQZYDjWon-5v9fS5t1AO8Br6uXkj0HzLJ3_G_yTGg,4591 +gradio/templates/frontend/assets/sv-D1nuPeJf.js.map,sha256=ntyBVA8usF5cCPM_QTB9aedl6m5XVxnJaVzVth70K_A,95 +gradio/templates/frontend/assets/svelte/svelte-submodules.js,sha256=78HYJ6tO9J2ZiNtF_5jpdC15Rqw6rS9ZeyN6RAIr8lk,9830 +gradio/templates/frontend/assets/svelte/svelte.js,sha256=NKrr42KwGhtVr3aElC9anChGzNq_M7FdehvPjfBCjJk,35081 +gradio/templates/frontend/assets/ta-Ex4E4CrJ.js,sha256=buXwXwpS0vsI5dnerijYpnstsKuqrrkDTZpye5BXxFE,9758 +gradio/templates/frontend/assets/ta-Ex4E4CrJ.js.map,sha256=XZnmo6T3k-tJDcKluKuhog-1kAkVLIAEOkwKonQ9oKM,95 +gradio/templates/frontend/assets/tgaTextureLoader-BReyNnsx.js,sha256=tEJubOgj3CPIJvSG_lnRBO-MttYNovya_RaQOmZxnbs,3637 +gradio/templates/frontend/assets/tgaTextureLoader-BReyNnsx.js.map,sha256=XVQ0ecW5zguQAyIz6Pip07ptu-Bd2fxLdhpZjnmiN84,19729 +gradio/templates/frontend/assets/th-DGNowuDO.js,sha256=4YHHflIAdfZeX0-f2c6YbMWpY_UyqF65uJdkeR8g6RE,7972 +gradio/templates/frontend/assets/th-DGNowuDO.js.map,sha256=TF-dWKuSLloWKkxJ097XqvRu0r5p7IJrPERR8qLjuQA,95 +gradio/templates/frontend/assets/thinInstanceMesh-DUjUMLvK.js,sha256=mGNXvmWLAtx7G5MoLbZWZ44CX6FAi8j87gLFH3obM5o,10421 +gradio/templates/frontend/assets/thinInstanceMesh-DUjUMLvK.js.map,sha256=zKqfcsGgYt1omaMtQzxux8ZWzYNGFh5A4U6SWmHVTKI,24480 +gradio/templates/frontend/assets/time-DpM-irFf.js,sha256=NU0S3CTqDwICd812GyyaHmiXqikUcan77i7v8Ijcd8I,17611 +gradio/templates/frontend/assets/time-DpM-irFf.js.map,sha256=2OGt1kfjt0ay9aQzlJACEQYO-L_t00Ax0gG9y2UgdYM,79814 +gradio/templates/frontend/assets/timeline-definition-3HZDQTIS-CP_UPx91.js,sha256=M37_bdq0QzkmWaWyswUuvm47SFSmZF9lODhru6dRgZg,23807 +gradio/templates/frontend/assets/timeline-definition-3HZDQTIS-CP_UPx91.js.map,sha256=7gzcZo2S7vG-w66DQglJ8HdttXvjE1aXxvR4-h8ucfw,82158 +gradio/templates/frontend/assets/tinycolor-Begke6kS.js,sha256=dVWAm8CKCQJs4BYPqy2BvdxAsu2jkRAeky2NWHaif1E,15295 +gradio/templates/frontend/assets/tinycolor-Begke6kS.js.map,sha256=xC4U5gbPuorF6-48-JrHftrTpjY0IXfhMQ1qJkFCBKo,60127 +gradio/templates/frontend/assets/tr-Cez09yqM.js,sha256=czusx2mb8dzM6H3GwAPftKDW3nVs-4LSMHp9yV0iCSo,4915 +gradio/templates/frontend/assets/tr-Cez09yqM.js.map,sha256=bGD_u-jT1nLlNB5Ew_FKiOIxS8P9etQhLgU8GrJQGrQ,95 +gradio/templates/frontend/assets/treemap-75Q7IDZK-DqcFoeEm.js,sha256=vAAaQS3ULiFl8eeUnSv43AFV276sax1k3mJ7EoUZaBI,463 +gradio/templates/frontend/assets/treemap-75Q7IDZK-DqcFoeEm.js.map,sha256=gRpgLNuZ56lt8fUdJP6EPGLfksZ0v-LgzuwJrJpNWyI,109 +gradio/templates/frontend/assets/uk-C_6kyB1E.js,sha256=s3lGvxKxilZ2bbIqxP8HEW64QiOmHF8HqxPdCElhVJw,6893 +gradio/templates/frontend/assets/uk-C_6kyB1E.js.map,sha256=lWVgjZ3vT6tuxSuYdpOmeX4571Qm-qKJLNpWsnQaqTs,95 +gradio/templates/frontend/assets/ur-1gg1Zkwj.js,sha256=3LbiFzhA_m4uAXo67RbctiE_WQaLw4okGVUaQb08Kg8,6498 +gradio/templates/frontend/assets/ur-1gg1Zkwj.js.map,sha256=ir7FdNoVPzRiNwAb1cShglbbQUAv-CAYUmXBt3lCSrg,95 +gradio/templates/frontend/assets/uz-CVKNjEjc.js,sha256=JO5LUuA_mMnHEjHlXXCx3T3dsfXW2o3fx1tHcMfO5AY,4919 +gradio/templates/frontend/assets/uz-CVKNjEjc.js.map,sha256=zZPwGZ8DFiYeA7GaRUiyAqmCLaX3XV79P5WXskuqoV0,95 +gradio/templates/frontend/assets/vega-embed.module-C-_2IHjq.js,sha256=A_KuMxrNWNdt319mQoCkLpNhl6PxBRSstcZtsp3dHKU,286946 +gradio/templates/frontend/assets/vega-embed.module-C-_2IHjq.js.map,sha256=jnAcsi1756XZJliF7dziLRiv1nQHUFIwdOHsi_5WeEM,1414962 +gradio/templates/frontend/assets/vega-tooltip.module-CMCXBF_b.js,sha256=ioM2XWGO-b26aXWMQYo_ATOhi451f5zFQBLYTREwO6s,498984 +gradio/templates/frontend/assets/vega-tooltip.module-CMCXBF_b.js.map,sha256=hLuVTakzFi2dOZimImOpXYYssph8s5Ss3oWZY3l88KY,2173745 +gradio/templates/frontend/assets/vertexColorMixing-BBG-_ass.js,sha256=cSmo61pnonwnIAgP6U3rO9JLMmKjCvnmL6jdi0CXKyA,16674 +gradio/templates/frontend/assets/vertexColorMixing-BBG-_ass.js.map,sha256=qLFXT-wYwiddBOtRJaSFKUF_mhv7JKn0Ly-k_eZB1kM,27643 +gradio/templates/frontend/assets/vertexColorMixing-CFczAsRa.js,sha256=6qExKbcsKexwS_bqsQxQB4_L3U71Kg6FkqE6IQ7yolc,18434 +gradio/templates/frontend/assets/vertexColorMixing-CFczAsRa.js.map,sha256=305dYO0jSw2W806ymrffMBmvJJ_saG6BX1o4NSejTDU,32845 +gradio/templates/frontend/assets/webgpuEngine-Chkwhj3S.js,sha256=0JDl--SD4TTOwxhT-lhoklAqw6yJwlplezDoM7OzEGE,215628 +gradio/templates/frontend/assets/webgpuEngine-Chkwhj3S.js.map,sha256=BxkVtCrmIhP5d4irGWduyu8M_G5XqJahZJHK-UywqnE,793868 +gradio/templates/frontend/assets/webworkerAll-v607P1NK.js,sha256=8BvpBYJjBGCvyK6eRXHrrQyZ7jvcX1-TBHvivlgZksE,557 +gradio/templates/frontend/assets/webworkerAll-v607P1NK.js.map,sha256=aflwPbVWhsMGvrrdqHnMpJ81tzwhOt5dwGH5T9w4JOk,105 +gradio/templates/frontend/assets/worker-DJ3jufjD.js,sha256=8etal0e46Ik7GYt93q3Boakxg8_gI06CcDywv_L8AXo,2369 +gradio/templates/frontend/assets/worker-DJ3jufjD.js.map,sha256=1AnM8bdSOef80MZGUNV0TBxUunu-H2rJLt6PKe20SDo,10185 +gradio/templates/frontend/assets/workerPool-CfMXSLnf.js,sha256=ZtzsJHEzxK5xYiKH2qpPLLLGpPxUcO41FCC34mmqar8,1352 +gradio/templates/frontend/assets/workerPool-CfMXSLnf.js.map,sha256=aL4qyDDixZz6xbM14SiMlk8sVCW0qTATIln73TmoNW8,6059 +gradio/templates/frontend/assets/xychartDiagram-FDP5SA34-CLk2HzjA.js,sha256=tXsRaEnd6dA27ijeROS6kzmI_FEniq6TanHgGASNMz0,40260 +gradio/templates/frontend/assets/xychartDiagram-FDP5SA34-CLk2HzjA.js.map,sha256=Y7A8oo0DI477Tos_jjTNbgoD00bx8TCnZ6xfIwVeCM0,132373 +gradio/templates/frontend/assets/yaml-DsCXHVTH.js,sha256=Eydcz4fWDbevl7y0MlinPMyRGIzzFnWOeODNwQbnYLU,1564 +gradio/templates/frontend/assets/yaml-DsCXHVTH.js.map,sha256=hjy2ORA0WR-0S7Ks7XAn2US7qbUFi08qDb47gwueYd8,5026 +gradio/templates/frontend/assets/zh-CN-C4t77Jdq.js,sha256=MlLgbylNo8mcd5OOflSzydXGjfa_GPbZkNj6UhmjImQ,4396 +gradio/templates/frontend/assets/zh-CN-C4t77Jdq.js.map,sha256=gfSu8dznaEHb1YdA1ZcUs-X-734qO8kj2IWu9AhvEcw,98 +gradio/templates/frontend/assets/zh-TW-DnQkjK12.js,sha256=wDqakep4aSaXW9pq4FKC2svE5-JoHToGUGZqXZOIuOE,4374 +gradio/templates/frontend/assets/zh-TW-DnQkjK12.js.map,sha256=cMBghJVGC1XSuXXSF-fiXxPF0TCLT3b534VBcF-tIUM,98 +gradio/templates/frontend/favicon.png,sha256=K_x7Y4Jps6jl9lAtcaC4kBCJkQ3YDt6Dlr3FkPEwIBc,3127 +gradio/templates/frontend/gradio.js,sha256=vvDpifJnGBwi3l_x0EhxZXtb-YfHVa510wbJcTFI_5I,38 +gradio/templates/frontend/index.html,sha256=kMIXNUzSwX2zx2efjZLZBccSVnDECp-nRrhJF4zmLnE,3797 +gradio/templates/frontend/share.html,sha256=kMIXNUzSwX2zx2efjZLZBccSVnDECp-nRrhJF4zmLnE,3797 +gradio/templates/frontend/static/fonts/IBMPlexMono/IBMPlexMono-Bold.woff2,sha256=8HPeTEWcpj0YH_vr8mW1gHxm2XL2WOuLS3dz3uu1r8A,36904 +gradio/templates/frontend/static/fonts/IBMPlexMono/IBMPlexMono-Regular.woff2,sha256=dWXn22ppgRRZyKQk1vHl2DE0_jgoDLRHHVJIBZhjVco,35536 +gradio/templates/frontend/static/fonts/IBMPlexSans/IBMPlexSans-Bold.woff2,sha256=iJm2LXTQb0gvEytgDUnJpRzxOj2DCsNdFY-MzmUHnCA,56112 +gradio/templates/frontend/static/fonts/IBMPlexSans/IBMPlexSans-Regular.woff2,sha256=3WzVK_FdL1v3UZzT2HauLTcwbnfRqVpj6GfmyVq5xJ4,56184 +gradio/templates/frontend/static/fonts/Inconsolata/Inconsolata-Bold.woff2,sha256=MhfJ7ncBcWJiH0NDky7t3-sVSspadVOkAjNknRM8B8A,39264 +gradio/templates/frontend/static/fonts/Inconsolata/Inconsolata-Regular.woff2,sha256=Ti4Ji6rCDml3DZrNUiCQzf9tqxOCvqHxg1nrygwYE9w,38608 +gradio/templates/frontend/static/fonts/Montserrat/Montserrat-Bold.woff2,sha256=KUZT3BRm3NoCfI_02A97yPsHT8DarKua_eaMH3ZGux0,86804 +gradio/templates/frontend/static/fonts/Montserrat/Montserrat-Regular.woff2,sha256=l27-Q4SCO5u9s0mkG1VhQYPldjh3Je4GhSruLEcebDk,73632 +gradio/templates/frontend/static/fonts/Quicksand/Quicksand-Bold.woff2,sha256=Jp7WidXR175zzpSQrfbRPQ7h3-XKkz2QhA2KrGiXdbg,29460 +gradio/templates/frontend/static/fonts/Quicksand/Quicksand-Regular.woff2,sha256=2DDCphSj6Wo1uWLzuwMqB8tsMJ-ys-no8Jq_-ZJzN5c,30864 +gradio/templates/frontend/static/fonts/Source Sans Pro/SourceSansPro-Bold.woff2,sha256=S3rVTBe1OvHFenqRl84ky7FhpgbbzSk2j8s8RoppKB4,102576 +gradio/templates/frontend/static/fonts/Source Sans Pro/SourceSansPro-Regular.woff2,sha256=QxuP-bUGPl1I5OYkFYNa6u6GmpGcX-cJACeae3sDSpY,103012 +gradio/templates/frontend/static/img/api-logo.svg,sha256=U0bxk-F8XMEQqDlMPZTzwrFgCmNOj5wBz2nV5CTCMh8,1544 +gradio/templates/frontend/static/img/camera.svg,sha256=SpId6c1K484Wkh_BWPCYM0Y4hQtIWLhPDfV2pW7Sko0,349 +gradio/templates/frontend/static/img/clear.svg,sha256=vwpFiqfMn3jDAFS1a72C1q4BEHLTaJZKurG0RIpX9j4,1920 +gradio/templates/frontend/static/img/edit.svg,sha256=gvIbS-99UVGmYE5a38K1AcsPD_KmwwBe3hKdYzrzbHc,1427 +gradio/templates/frontend/static/img/javascript.svg,sha256=hQz5S4qCD6CWtmPhbRryjIljsJ9kcLBqGxtguImqYh8,742 +gradio/templates/frontend/static/img/logo.svg,sha256=PRMb_z_hW8uz5uZVKovuJTd8NmZyOpy-aM7KlT6mE98,1107 +gradio/templates/frontend/static/img/logo_error.svg,sha256=WkTxoBCQ8Hvcx-sBsZbhDpwInU_WUhqvvdssj0wG8o0,4609 +gradio/templates/frontend/static/img/logo_nosize.svg,sha256=if12hwcvbBq1K-M0hJTwQQwnD0U-gwYQVxmy4_cJFGk,1082 +gradio/templates/frontend/static/img/python.svg,sha256=IOOckruIxuSlu-lfxORc-Gze5YUTCOE1mIQZplzkgLQ,1111 +gradio/templates/frontend/static/img/undo-solid.svg,sha256=6O_Pyjo59fCCynMz5XhWU4wI1egQ3anNpToH9fpmISw,767 +gradio/templates/hooks.mjs,sha256=qSu36ayhEE5FZuhHtwufI_u6_o24a_zvkjSQ2tDHgY0,619 +gradio/templates/node/build/client/_app/immutable/assets/0.CIhHAKwE.css,sha256=lhbBzM87ILSFOhvKEwxbBeelmv0ZEL78tYRHPR80Brc,23621 +gradio/templates/node/build/client/_app/immutable/assets/0.CIhHAKwE.css.br,sha256=Jemfqv2qUUqgsMgu3XSQjqN3IhMlaX18LZSUbc0Eops,4888 +gradio/templates/node/build/client/_app/immutable/assets/0.CIhHAKwE.css.gz,sha256=5s0YQMkcpNrperCHSw49ds2XjCTZkhU8fYkfAH1M7yM,5678 +gradio/templates/node/build/client/_app/immutable/assets/2.DQyR9B4u.css,sha256=VGPjGGIKkA1WEyfJtTG9DXiy0MghmR4UI_NHnXX9udE,38209 +gradio/templates/node/build/client/_app/immutable/assets/2.DQyR9B4u.css.br,sha256=suLehxR2HIbIrjtkFBsemjnjmf_WaGupGCFciixCnOs,6083 +gradio/templates/node/build/client/_app/immutable/assets/2.DQyR9B4u.css.gz,sha256=sTemkYc8Py3m_g0XTMQjqyKOq3fQLs6uLTfQT1LnYwY,6789 +gradio/templates/node/build/client/_app/immutable/assets/AltairPlot.CSe9xcFj.css,sha256=GstHlQBXaihn5CFTKFkdxUgn4uNaWtSPYIrvFYe0EqY,880 +gradio/templates/node/build/client/_app/immutable/assets/AltairPlot.CSe9xcFj.css.br,sha256=1LTUBxG37fyncbhs3sv2p6BCnPoe0ZubLQtJRCg8a7k,265 +gradio/templates/node/build/client/_app/immutable/assets/AltairPlot.CSe9xcFj.css.gz,sha256=ytHpXzfyofigVYWD4UBcOij_uzuPDyrlOtzpLexGYLM,343 +gradio/templates/node/build/client/_app/immutable/assets/ApiDocs.CrTYCJN9.css,sha256=BkNP3FcvI1KLbTnxFJXNHI_0MDGEMbppr7iqCK_9ggI,14944 +gradio/templates/node/build/client/_app/immutable/assets/ApiDocs.CrTYCJN9.css.br,sha256=DOg-QQQK_eBS_3Gkgn8YwCp3mlVBsMc9OhtH8Xy-Hzs,1937 +gradio/templates/node/build/client/_app/immutable/assets/ApiDocs.CrTYCJN9.css.gz,sha256=950yhl2MLXVxr8lyQ2EGWem4MSypA_Ge99YXLEFnGkQ,2238 +gradio/templates/node/build/client/_app/immutable/assets/ApiDocs.DGt9JoLE.css,sha256=HbrGjh0FPGyyjoAXYKTOpPN9CO8tiKWpIjLCc5PnbaQ,14830 +gradio/templates/node/build/client/_app/immutable/assets/ApiDocs.DGt9JoLE.css.br,sha256=px4kob5oFArAu2L3x8DU9DR4ahay311lV6y7u4x7JpQ,1926 +gradio/templates/node/build/client/_app/immutable/assets/ApiDocs.DGt9JoLE.css.gz,sha256=sDeiViuZg90vLhQMuSldXcyC4pBakUOSv1fTF1BW3no,2220 +gradio/templates/node/build/client/_app/immutable/assets/ApiRecorder.7UmvbTxs.css,sha256=Crd8s3gL70HPXPudZ10AYeGvJEwBzGdUYmP8xfdhmLE,781 +gradio/templates/node/build/client/_app/immutable/assets/ApiRecorder.7UmvbTxs.css.br,sha256=pCiYhd6qI1BE_KSB8fJv19LBbGNq9HNrSN1nAhdXSMw,281 +gradio/templates/node/build/client/_app/immutable/assets/ApiRecorder.7UmvbTxs.css.gz,sha256=OHtYlRzM2YcXCjAN0MAd95fOTAxAIijMdoheWwqvVKQ,362 +gradio/templates/node/build/client/_app/immutable/assets/AudioPlayer.BlTLLQbX.css,sha256=YPVn0NiTdyg8D6Se2AmZ_x8Yz5xYCflCb2XpLLoc7B8,4245 +gradio/templates/node/build/client/_app/immutable/assets/AudioPlayer.BlTLLQbX.css.br,sha256=9-xtNVadI9yonPI3GuhXxiDbDFzLtxE0EOX-o6VJOMU,850 +gradio/templates/node/build/client/_app/immutable/assets/AudioPlayer.BlTLLQbX.css.gz,sha256=_1J7dFEVP2hkW4rKHCqYFN99Pi0dXYb6U3TP-QTwYTY,1055 +gradio/templates/node/build/client/_app/immutable/assets/AudioPlayer.BoZZFzLH.css,sha256=4gVvmezikgvX3hlMAZgA5n4mTaPUTMkp7EHvU0sCRE0,4287 +gradio/templates/node/build/client/_app/immutable/assets/AudioPlayer.BoZZFzLH.css.br,sha256=eYnyrZ13oXmZ4dZUHKp_eFiQEyt4kqQQL4RoLYFqAAA,860 +gradio/templates/node/build/client/_app/immutable/assets/AudioPlayer.BoZZFzLH.css.gz,sha256=h_ICHIM6B5b2tFlCCL5BHZXLPSLJgtPilDtODpnFeS0,1059 +gradio/templates/node/build/client/_app/immutable/assets/BokehPlot.Cd-I2ErV.css,sha256=8PW6X7eeBzZ1_ZxGXEwdzDbUWjWYq_XAa23_UZ7mtwM,66 +gradio/templates/node/build/client/_app/immutable/assets/BokehPlot.Cd-I2ErV.css.br,sha256=5CQHJVSk581dZuqy7VL9uBANffY5fFsksYOIjj033tg,65 +gradio/templates/node/build/client/_app/immutable/assets/BokehPlot.Cd-I2ErV.css.gz,sha256=qotZU6GtgBvkVoMUHrNHcrTOQKH_28xFiuo3koTUX8o,84 +gradio/templates/node/build/client/_app/immutable/assets/Checkbox.HTxjVTe0.css,sha256=ZHuNEhnBhOjn0Z2_OjmAQ4SodoDLqUQLhszF4KgMYPQ,2507 +gradio/templates/node/build/client/_app/immutable/assets/Checkbox.HTxjVTe0.css.br,sha256=5zQPTHI8656cN_RywhWwEhnI4ApG1Sr3RvALt_sUCQk,407 +gradio/templates/node/build/client/_app/immutable/assets/Checkbox.HTxjVTe0.css.gz,sha256=AsCRn-WlBsR-XBvmsrDkiq5mpMKNBhxdX8swlNUcmq4,512 +gradio/templates/node/build/client/_app/immutable/assets/Code.DloLYeAi.css,sha256=XpQdJaOWWIq1wCytnVsaaJI4Ae3ukmlIfAWeD9R1SGk,278 +gradio/templates/node/build/client/_app/immutable/assets/Code.DloLYeAi.css.br,sha256=wmi3tDDuH8DO5q-Is3oE0QMHlEiGrrznw7UZEAUtNE4,137 +gradio/templates/node/build/client/_app/immutable/assets/Code.DloLYeAi.css.gz,sha256=kv495OOwVtXMuAhujZkTtyhOT3fdgUUQSSIfqjblwV8,198 +gradio/templates/node/build/client/_app/immutable/assets/Dropdown.CWxB-qJp.css,sha256=t9EkwoJJ_9u6urZPj2GBR82jq7rtysRIRPL-wcdvqiI,5092 +gradio/templates/node/build/client/_app/immutable/assets/Dropdown.CWxB-qJp.css.br,sha256=G8A-ZLQ-x5EHkFRxMS4Twv06SJu1EsCVJvHnFNLTvks,849 +gradio/templates/node/build/client/_app/immutable/assets/Dropdown.CWxB-qJp.css.gz,sha256=zIUUEqJAiu91_ZnBAtRm9t7fZU3A06k1kWChQRXiBcU,1045 +gradio/templates/node/build/client/_app/immutable/assets/Example.1kVNej19.css,sha256=X_nt4sEVM_OMmDSB02l4924ZHAlyFWsCTO_jU_Q_NcA,1097 +gradio/templates/node/build/client/_app/immutable/assets/Example.1kVNej19.css.br,sha256=s0UQSXRcDns6W7fkpxyO4vkRU6W9eM5skOxz0AVK3AQ,292 +gradio/templates/node/build/client/_app/immutable/assets/Example.1kVNej19.css.gz,sha256=-PeDINwZr1iWGfnYXc3byuTSourKVRGqSNzVZs2y468,384 +gradio/templates/node/build/client/_app/immutable/assets/Example.6rv12T44.css,sha256=j14fOWIu8-l1EzzGdtTB6XztpF6XrM6snh8XGg7-yW8,451 +gradio/templates/node/build/client/_app/immutable/assets/Example.6rv12T44.css.br,sha256=v6pDh6dtUP6m4yFOGaaN_fMlS17Axqyopxv-idCGZes,156 +gradio/templates/node/build/client/_app/immutable/assets/Example.6rv12T44.css.gz,sha256=97BOC6ogWbv9GswyH9akv0OF_PGkcp-28t8-d1f2fM4,208 +gradio/templates/node/build/client/_app/immutable/assets/Example.B5CSTz0f.css,sha256=lCmly42A6cBMsZedc_U9JlAUqyE6L0U522Sj5VQxmx0,552 +gradio/templates/node/build/client/_app/immutable/assets/Example.B5CSTz0f.css.br,sha256=HvjkDwlm6VayzstQdGMn13XwFFTuEbm_gMdtY3JbZlc,179 +gradio/templates/node/build/client/_app/immutable/assets/Example.B5CSTz0f.css.gz,sha256=sWPnVTTxsdyEe3PVguHueCvRRHYRVhbwaXpg6fsIV7Q,236 +gradio/templates/node/build/client/_app/immutable/assets/Example.Bw8Q_3wB.css,sha256=7pNbDDioQpVq4Nh24s0dCGLMWTgb3WzdVwWUU9jdIIA,97 +gradio/templates/node/build/client/_app/immutable/assets/Example.Bw8Q_3wB.css.br,sha256=yFmo693pEUuxy10W0JEHHFiv5wZ0JhHg7BKdmTnvHWI,82 +gradio/templates/node/build/client/_app/immutable/assets/Example.Bw8Q_3wB.css.gz,sha256=Ut6gvvBMM2D_imalHEH4egptvu2KPRDP1JAC5j4SrFY,91 +gradio/templates/node/build/client/_app/immutable/assets/Example.C6fDlAyr.css,sha256=ieU1iBlq2LM5elVQSPyeu2l1gZk3OJLZ6gDU1bkytpc,2026 +gradio/templates/node/build/client/_app/immutable/assets/Example.C6fDlAyr.css.br,sha256=kyXK7zDD0UAdM2e7X0-NRKJVrVWFZNuE-Ge03tgw-b0,433 +gradio/templates/node/build/client/_app/immutable/assets/Example.C6fDlAyr.css.gz,sha256=bFnc8Aov6MV89eZjVF3YPp-jY3is3ZjmkRjDy66vL1I,556 +gradio/templates/node/build/client/_app/immutable/assets/Example.CCTTJ5R1.css,sha256=O4i35uwKBSekWp-_qNvjDMEJMcuHrm83nszbiAwO9dw,746 +gradio/templates/node/build/client/_app/immutable/assets/Example.CCTTJ5R1.css.br,sha256=rtRPfzeXS5BTCPJy5TcUiUV62_-BQcj1BaqGrmapxRQ,252 +gradio/templates/node/build/client/_app/immutable/assets/Example.CCTTJ5R1.css.gz,sha256=xim9HwIXNhQaRu3IY2zJ8fAe-CkiZ90J4z4r1hFa2F8,331 +gradio/templates/node/build/client/_app/immutable/assets/Example.CG7uBGLE.css,sha256=JqFvmFuRC1-pV3fs6HX0BXI8f6oZtseyLe3x-LzU-Bo,526 +gradio/templates/node/build/client/_app/immutable/assets/Example.CG7uBGLE.css.br,sha256=K9FTttz9E69VFy-WAjulTzTN5Pxpg8GrGiWUxBE59uQ,178 +gradio/templates/node/build/client/_app/immutable/assets/Example.CG7uBGLE.css.gz,sha256=yNpsHQZaY4LInM91E9WA8A31k70C5p4lN91OpAFhQcE,237 +gradio/templates/node/build/client/_app/immutable/assets/Example.CSw4pLi5.css,sha256=nO_TtzchGr2yRJh7skxXU6VN08V1Oczg5wXeqXRxV7k,46 +gradio/templates/node/build/client/_app/immutable/assets/Example.CSw4pLi5.css.br,sha256=wZjzy8qbtrqIGmhfWzER6Pfwbee37TaBpM298xAvcjg,50 +gradio/templates/node/build/client/_app/immutable/assets/Example.CSw4pLi5.css.gz,sha256=6z399p9dRsXhjCLzwIY1Pxn2H_8DZaH9wRw5vAj9_mA,66 +gradio/templates/node/build/client/_app/immutable/assets/Example.ClKJOMGh.css,sha256=jw3zti8Eo0HA958JHF7xMjIo4jQrxRRLQGmUn0hfPMM,115 +gradio/templates/node/build/client/_app/immutable/assets/Example.ClKJOMGh.css.br,sha256=4YSuLDYNhiHzkWdIU4vuScR9Jd0cbri-t-EDsxJ3l0k,79 +gradio/templates/node/build/client/_app/immutable/assets/Example.ClKJOMGh.css.gz,sha256=boUDO1EiM14uHi44Lg0ZE3FezbfgaXQXR4kB3qo0zNw,108 +gradio/templates/node/build/client/_app/immutable/assets/Example.D7K5RtQ2.css,sha256=mPwrLCP67zJxLaJpIH8hlELYAgSh0qoFQxeeXxfnqKw,61 +gradio/templates/node/build/client/_app/immutable/assets/Example.D7K5RtQ2.css.br,sha256=UBIoy7nPaoKEPtZSJ1tx96QuDnZBs_BH6TA_D6wF5EU,63 +gradio/templates/node/build/client/_app/immutable/assets/Example.D7K5RtQ2.css.gz,sha256=paNQ-Z4jG8fTQuKlml9k6rM_NKioBdZ0IUaRLSk-ClM,70 +gradio/templates/node/build/client/_app/immutable/assets/Example.DfhEULNF.css,sha256=pn4qPfiZbAGQPDCNIVuD2kcOJjFJtfhNaaRJ5cHWu1o,234 +gradio/templates/node/build/client/_app/immutable/assets/Example.DfhEULNF.css.br,sha256=q408tGV6A2WFF-N6c9K7p845au6Ddy8sfJSS3WtI28Q,135 +gradio/templates/node/build/client/_app/immutable/assets/Example.DfhEULNF.css.gz,sha256=7woxbcDGhZ5_WMGaM2NJPoZJ7MonodCzhFcFMa5EJlc,170 +gradio/templates/node/build/client/_app/immutable/assets/Example.DikqVAPo.css,sha256=vPvlZ9Le6qqi_YSNzHqTgBqwq47qHTDBgXUAqEaFfb8,448 +gradio/templates/node/build/client/_app/immutable/assets/Example.DikqVAPo.css.br,sha256=pamzXGiC7qI0KMKYepqJZIX4nGnUKwSObF5rCXaShf8,167 +gradio/templates/node/build/client/_app/immutable/assets/Example.DikqVAPo.css.gz,sha256=GdbBHH7GA9Dq5Xt4hZPxkFxF507xdcv91wHUBACLHgI,221 +gradio/templates/node/build/client/_app/immutable/assets/Example.DpWs9cEC.css,sha256=HNpkFYu7Ir2Kjx_inXdII02VD6diCu7jjfTA2NRaiso,199 +gradio/templates/node/build/client/_app/immutable/assets/Example.DpWs9cEC.css.br,sha256=PNbVp-QyIUvx62yLBEcnE8RfPS8ZELNKCZic1MdoziY,115 +gradio/templates/node/build/client/_app/immutable/assets/Example.DpWs9cEC.css.gz,sha256=IY-fc-6AvykbS6MNqogqb2tRRzVllDKiAG6cA8bUloA,157 +gradio/templates/node/build/client/_app/immutable/assets/Example.fMB4cHw6.css,sha256=Zau5ysRzUrXEyr2GQ2woKTyVyRqBSu8CKo5ax2WJzmg,880 +gradio/templates/node/build/client/_app/immutable/assets/Example.fMB4cHw6.css.br,sha256=7E8V7f2GntIwmutY6t-0TDWbegKGbWnwNv-RWSYe9vk,256 +gradio/templates/node/build/client/_app/immutable/assets/Example.fMB4cHw6.css.gz,sha256=z11AQvWLK_fqvM1rWqd92NOBZrOJvn2G0s-HAabqv-g,330 +gradio/templates/node/build/client/_app/immutable/assets/Example.oomIF0ca.css,sha256=91y6EEN27aDOpSwJS62qQSdZg5SrLEGcnsisPD-YYCM,94 +gradio/templates/node/build/client/_app/immutable/assets/Example.oomIF0ca.css.br,sha256=Rg04_Ti6hTR8vQY020wSda-j5Mpgan7EkMZmaEm7Wwk,72 +gradio/templates/node/build/client/_app/immutable/assets/Example.oomIF0ca.css.gz,sha256=qkKBzKaZsh9rSupiob_dhO53upmkeB-GkqEvzB3w4FY,92 +gradio/templates/node/build/client/_app/immutable/assets/FileUpload.b2Zdge9M.css,sha256=k7mfEaT5qLE9ltJeQeaziJoRBLBdK7V9t_uJs8Oqmhk,2125 +gradio/templates/node/build/client/_app/immutable/assets/FileUpload.b2Zdge9M.css.br,sha256=7PvhvUWbprzMyZYU2PM-oHXcXm35Zaq0Q_HlovgyVr8,494 +gradio/templates/node/build/client/_app/immutable/assets/FileUpload.b2Zdge9M.css.gz,sha256=kHtCspT7Mn7ypaZ6-uD3hG_QCslxjAh5vjINlhiq_hM,614 +gradio/templates/node/build/client/_app/immutable/assets/FullscreenButton.CMXoZSZV.css,sha256=2duHxWsN9Om0s1CG7EtEUolUYXQCpeNHF2Y8WG2kKhw,8884 +gradio/templates/node/build/client/_app/immutable/assets/FullscreenButton.CMXoZSZV.css.br,sha256=QM4hQQauhuUG8feFasTMkUY77NaN02Ctw3jkUDE3Irg,1845 +gradio/templates/node/build/client/_app/immutable/assets/FullscreenButton.CMXoZSZV.css.gz,sha256=gnPHmT7VTTyycW98LU5ybUWRxjQk3zZaNwyGvZ_jyZc,2126 +gradio/templates/node/build/client/_app/immutable/assets/Gallery.Cs9Ilp9M.css,sha256=dzIMF1zLQQl4EXJETCrzfRHz8sHdCYSyo3HwiNaMthA,5097 +gradio/templates/node/build/client/_app/immutable/assets/Gallery.Cs9Ilp9M.css.br,sha256=a2SWTFB7hxQy4zJadTpfvLDvD1-NXnDw011pv8ZrlUs,1028 +gradio/templates/node/build/client/_app/immutable/assets/Gallery.Cs9Ilp9M.css.gz,sha256=RdgVdGut7yHgxUvGAfgJK8DloS1k03Vy_UdC4yC9UNA,1227 +gradio/templates/node/build/client/_app/immutable/assets/Image.B8dFOee4.css,sha256=wvliu0UpszhKHZH7tOsAnOAVD6KZ_xCAlY9B6v77Ww4,37 +gradio/templates/node/build/client/_app/immutable/assets/Image.B8dFOee4.css.br,sha256=JVKLPL0PWzVtuW5xfQyp_whrVoEXgdBP9JTQXN_uiBo,41 +gradio/templates/node/build/client/_app/immutable/assets/Image.B8dFOee4.css.gz,sha256=1AKe3TPz9-CpsvRMZZiYx9uoFcxEdr6RYbHC8OTeKgA,57 +gradio/templates/node/build/client/_app/immutable/assets/ImagePreview.C_qhEOxI.css,sha256=9W79xtNHpowNVqS07hGBrdCwuGvUAUzVKiNR4Avjwf8,801 +gradio/templates/node/build/client/_app/immutable/assets/ImagePreview.C_qhEOxI.css.br,sha256=kVca1Xv1LCyvW-F07YysjtrdtFCyG6n3Evi8dt2LZwM,238 +gradio/templates/node/build/client/_app/immutable/assets/ImagePreview.C_qhEOxI.css.gz,sha256=SbKz0iDPjE-sEICh1NR_LY7tPH-ZIyGjg0OgF68jmIo,308 +gradio/templates/node/build/client/_app/immutable/assets/ImageUploader.DMdYP1a9.css,sha256=czy7Mi0EFZpNxEtN0UVQ71cS8IUVWo5puXWaehp81vk,3340 +gradio/templates/node/build/client/_app/immutable/assets/ImageUploader.DMdYP1a9.css.br,sha256=HbxtJmCZzRENVbhVpcJUxt87N6aCsVBGzK51xdSNHEQ,759 +gradio/templates/node/build/client/_app/immutable/assets/ImageUploader.DMdYP1a9.css.gz,sha256=dNAoRQzJimHVGmyBtqcY9Fl_ZPCMgEtMJ__4Vs080JA,948 +gradio/templates/node/build/client/_app/immutable/assets/Index.-UpFQsHg.css,sha256=ID8wXpsM930AywKzV6bE4jK5FdgQA4Ye2K2FB1vxzuo,2674 +gradio/templates/node/build/client/_app/immutable/assets/Index.-UpFQsHg.css.br,sha256=KgzJKmjJPWVWM85qbLl3zmZZeAHLpVTPbyuHm7oMTXs,454 +gradio/templates/node/build/client/_app/immutable/assets/Index.-UpFQsHg.css.gz,sha256=oKSfUXdYqWxLgvOssHFXN_Pl53X3nW_oDye0rPFK6X0,571 +gradio/templates/node/build/client/_app/immutable/assets/Index.1zeyvqK2.css,sha256=tx8966KfHHKGOLkOzoWW3WmlsMf1slWterMY5i8YBjc,4924 +gradio/templates/node/build/client/_app/immutable/assets/Index.1zeyvqK2.css.br,sha256=sZxwD8xB84F6PeHRDDxc0w65G7mBIW60sZ2pgjV5Tf4,1009 +gradio/templates/node/build/client/_app/immutable/assets/Index.1zeyvqK2.css.gz,sha256=MeE-qDiqzbpcJq7DzNRufbHwWyNWZ2EFG7clgTqnzXA,1232 +gradio/templates/node/build/client/_app/immutable/assets/Index.2z2XN1av.css,sha256=ZPANRZmpHMpRxQewK6J_--wFWRt8Ip_Qf5C5ojtpqyc,7187 +gradio/templates/node/build/client/_app/immutable/assets/Index.2z2XN1av.css.br,sha256=kthYpqGHP5MENSgVvdRwCjySP-iiwgYzAciLVi4_vjQ,1459 +gradio/templates/node/build/client/_app/immutable/assets/Index.2z2XN1av.css.gz,sha256=cUA6fG_NNcL4IGU-z6Bo71YgDu1rz8nAtTZheZBEKWw,1724 +gradio/templates/node/build/client/_app/immutable/assets/Index.6AICi3cy.css,sha256=Q_5znBEgZSHAvOg5QMTwOKpS5pKDT9FMSZkpmegfXsg,205 +gradio/templates/node/build/client/_app/immutable/assets/Index.6AICi3cy.css.br,sha256=yY347JJ5F_kdnJ6iDM--x5toTR_fEGKGcuqL_LdMEDM,120 +gradio/templates/node/build/client/_app/immutable/assets/Index.6AICi3cy.css.gz,sha256=nb1F1tUZ-bYZr2mSU_tkYhWHxHhbQZkvWgRiSOhTeg0,161 +gradio/templates/node/build/client/_app/immutable/assets/Index.96R23gaW.css,sha256=GQfdOKaAlfjO4mncDK6nCiB-i2fJOeL_lzXSxpFceZg,7202 +gradio/templates/node/build/client/_app/immutable/assets/Index.96R23gaW.css.br,sha256=VixNm33PoKbrAQiTPaO7E5tLpsBnUYO0ilRRj2inT8s,1291 +gradio/templates/node/build/client/_app/immutable/assets/Index.96R23gaW.css.gz,sha256=0XiiRJzfomG0WyUa0CK0cJqTtvUqtnN4N1q528Nkv24,1534 +gradio/templates/node/build/client/_app/immutable/assets/Index.B0hFno2n.css,sha256=Eg2HtrcTKCu7aXKFSmql5BsIBVTlQXH9W5LU8kIz6Y4,3250 +gradio/templates/node/build/client/_app/immutable/assets/Index.B0hFno2n.css.br,sha256=rlv6wnvnhc8F1ee46WTRhuJ5QJUpQferupyszsWI2SQ,698 +gradio/templates/node/build/client/_app/immutable/assets/Index.B0hFno2n.css.gz,sha256=-lt13jcWdY2VXzZnrcQSbpOJRxDai1dEJfg30cZ1gH8,829 +gradio/templates/node/build/client/_app/immutable/assets/Index.B8nnhpUu.css,sha256=MQGDwfJzNreLqC7K5OVItReEEUAB_D2f3cYBos-HijI,1863 +gradio/templates/node/build/client/_app/immutable/assets/Index.B8nnhpUu.css.br,sha256=jHxCXIBw4QgThWpdHHpGxkwVOLcglK-FdymMqP9R84g,496 +gradio/templates/node/build/client/_app/immutable/assets/Index.B8nnhpUu.css.gz,sha256=cmZQuNydeOCqZxDMN3PDOCPxHsMldEM6dkzvShiz4gQ,599 +gradio/templates/node/build/client/_app/immutable/assets/Index.BKaa_GXG.css,sha256=jkqpox6Kna5iZGYU3hrNVVhFksRDCRi5lPUkm3UlBW0,2126 +gradio/templates/node/build/client/_app/immutable/assets/Index.BKaa_GXG.css.br,sha256=G9uu0LVFK7GHYKClGnSmue4IQaCszES7CJgmfybpK0Q,563 +gradio/templates/node/build/client/_app/immutable/assets/Index.BKaa_GXG.css.gz,sha256=laeIJi17Lp0rT4dZ-d9iWskRq6lllxLKksclIPvOSVo,700 +gradio/templates/node/build/client/_app/immutable/assets/Index.BTXaMQgd.css,sha256=Ampi7bie1ouN_MmhWt4PoloMK26NwRWnkF24aEjlsCc,427 +gradio/templates/node/build/client/_app/immutable/assets/Index.BTXaMQgd.css.br,sha256=8MqVQ3i4M0ig5Kiwyn7WXEC6FPcr0q8_foDKA7_N3RI,169 +gradio/templates/node/build/client/_app/immutable/assets/Index.BTXaMQgd.css.gz,sha256=VlRhXuZae-zCCIH1zJov3ywQAxDieb5VyJmX-Ype2Z0,234 +gradio/templates/node/build/client/_app/immutable/assets/Index.Be3F7oKw.css,sha256=pKkAd8hkQ3IRliuD-GDIRU3G4XDfbcLKbpaMBMBWM0o,579 +gradio/templates/node/build/client/_app/immutable/assets/Index.Be3F7oKw.css.br,sha256=CRFypaEto8a2I75PotTQbE6rf_P0dfEHiuHeYvFz8bs,155 +gradio/templates/node/build/client/_app/immutable/assets/Index.Be3F7oKw.css.gz,sha256=oB6ka9oQGfayNWpnTVPwFiJ0jtSiAaTCVSn0Zu7E2IQ,212 +gradio/templates/node/build/client/_app/immutable/assets/Index.Bk5ZTHOI.css,sha256=fmgA5VGsmr-CAe18yjQ-9EatoAggPK5uy_09s3Q5BhQ,6341 +gradio/templates/node/build/client/_app/immutable/assets/Index.Bk5ZTHOI.css.br,sha256=yq9nZnPRJw9Ji4Klg0QYt9Eemy84Un5IuTDvS4b8srU,937 +gradio/templates/node/build/client/_app/immutable/assets/Index.Bk5ZTHOI.css.gz,sha256=6m6bWktL8jG4A_iEGeqVpJXsXfzfd9b51SFNHIoY_Ug,1132 +gradio/templates/node/build/client/_app/immutable/assets/Index.Br8OrD4S.css,sha256=YnrWuWvMt0A3bpTnxgqPrZSoOM0jv8UXR46wrAA8XYo,7258 +gradio/templates/node/build/client/_app/immutable/assets/Index.Br8OrD4S.css.br,sha256=FuMM7yi_ryzthjGwV0fTf-ef_yI_1pn9X_DgFOTayTg,1304 +gradio/templates/node/build/client/_app/immutable/assets/Index.Br8OrD4S.css.gz,sha256=jg39QpU7AfRiq_qxED_nJG2Z0_BvXz0Wf7QEejpt8OY,1549 +gradio/templates/node/build/client/_app/immutable/assets/Index.BrMg3htP.css,sha256=TTqlWTZp2McJvdfVfkJHzfqHn1NyaBDwCSi2yLpnn5U,20351 +gradio/templates/node/build/client/_app/immutable/assets/Index.BrMg3htP.css.br,sha256=EcIwIYsuycWsNuqbUR9G5OgeIJss5MHyzvDdWzXeVF4,3094 +gradio/templates/node/build/client/_app/immutable/assets/Index.BrMg3htP.css.gz,sha256=WHUo4YlJTMiRoDRCiPbJOgGhltl2Xc6e1eogMvFcCjg,3464 +gradio/templates/node/build/client/_app/immutable/assets/Index.C0mowOU5.css,sha256=TNXcs8LqN-1qjQavb7VArVSvxBOXj5EnyQSNOaZvP_k,5008 +gradio/templates/node/build/client/_app/immutable/assets/Index.C0mowOU5.css.br,sha256=Wpk4fGrXecq5nqimPiN4AegRf5Jca5LsOwnu5YoBqRc,889 +gradio/templates/node/build/client/_app/immutable/assets/Index.C0mowOU5.css.gz,sha256=o8oTcon1n02iitsMQ-c554Xx2oSe5iyKaGQowgD2L7Q,1082 +gradio/templates/node/build/client/_app/immutable/assets/Index.C5NYahSl.css,sha256=BYw8aNj37nBAYjxQJFSnuZ7VffSpwuzp4ll-SBXtHZQ,348 +gradio/templates/node/build/client/_app/immutable/assets/Index.C5NYahSl.css.br,sha256=J19NyjC5VZA6TcMkjlXPOm2LSQIGAWtqsmkwBYxch_I,158 +gradio/templates/node/build/client/_app/immutable/assets/Index.C5NYahSl.css.gz,sha256=N4iUAoFu4RhVN4KAuuRewfGAQnqox9PRnDoql94LWEI,211 +gradio/templates/node/build/client/_app/immutable/assets/Index.CCAzyDPy.css,sha256=rBUQ9UjiQ52D6rsSB6DWMzbhAROCOV9S30ptDUkfS-U,13692 +gradio/templates/node/build/client/_app/immutable/assets/Index.CCAzyDPy.css.br,sha256=JpYCTtTGFpng9pJwcE_RJ4wPhcnuEBiVvZSsagrUf8Q,2428 +gradio/templates/node/build/client/_app/immutable/assets/Index.CCAzyDPy.css.gz,sha256=GizJB_NxSpWKR_tEkI2KWfxzs9mleOAgm-RFnmKYkls,2748 +gradio/templates/node/build/client/_app/immutable/assets/Index.CHmdF0QV.css,sha256=uNhtKP8WKwJKwT953pHIZ7m2dPSzbhQUYmJ30kmDKvI,18353 +gradio/templates/node/build/client/_app/immutable/assets/Index.CHmdF0QV.css.br,sha256=ucvPSP44IBu16r-pbvAo5NlD06o5dE93WKZqilTqB2Y,3018 +gradio/templates/node/build/client/_app/immutable/assets/Index.CHmdF0QV.css.gz,sha256=-0qV7v6vYUnGroxqWVfhVwfwDHBONJlsGxq5mMose-g,3408 +gradio/templates/node/build/client/_app/immutable/assets/Index.CIMAvdMc.css,sha256=ltuT4zV4tj3CAQsqNW2k96cFl7wqxK0UndOuKXNGjXw,1888 +gradio/templates/node/build/client/_app/immutable/assets/Index.CIMAvdMc.css.br,sha256=wV0qXf23PcU9a_q1smEl4TBOiBvDNviYu7CGwe-ZQaM,500 +gradio/templates/node/build/client/_app/immutable/assets/Index.CIMAvdMc.css.gz,sha256=p7wb_EH8rtKf7k0W3r8-2rb3ejEd5SaK96nVRkk-VgA,607 +gradio/templates/node/build/client/_app/immutable/assets/Index.CQVu-hjH.css,sha256=Uh2BV4YMBxUssMDuli6g_c-KZmf-xUnkFHREqMlsHUs,2100 +gradio/templates/node/build/client/_app/immutable/assets/Index.CQVu-hjH.css.br,sha256=kpgwzRFqH4PdTcrngEoiTpVDzgmCPe0_Jo5trgiZ64E,491 +gradio/templates/node/build/client/_app/immutable/assets/Index.CQVu-hjH.css.gz,sha256=AcOX1sJwxJdpxt4pRjz48DcN9Ee4B9AuREdb5KNFwY0,607 +gradio/templates/node/build/client/_app/immutable/assets/Index.CQemKtTr.css,sha256=6Fw0_PzkhcgQHYJzVnTd4QZj9bNJ7SSIJ1lEgjhdVeU,475 +gradio/templates/node/build/client/_app/immutable/assets/Index.CQemKtTr.css.br,sha256=rhd4a0j_GMom4e5vpPCZ7iW2PEJ7ovVFn-VmeJipUuk,184 +gradio/templates/node/build/client/_app/immutable/assets/Index.CQemKtTr.css.gz,sha256=F5NhwGmZbg2cuBJpnEKzXDSX_LH_xztVw8h9gAa7iIs,233 +gradio/templates/node/build/client/_app/immutable/assets/Index.CTOeqf6n.css,sha256=U5AzLUjsep4FwWQYXrap8tReQyFZNSI6ryCDLOZDGkk,3072 +gradio/templates/node/build/client/_app/immutable/assets/Index.CTOeqf6n.css.br,sha256=RFdO3IifY7GPMl7fkyQdWlddH4gwyr1fE6FMqiZfhxE,798 +gradio/templates/node/build/client/_app/immutable/assets/Index.CTOeqf6n.css.gz,sha256=dsAeY0udNq8PailkBjnvSucyEnOAmuxWIN6LERJk3vg,938 +gradio/templates/node/build/client/_app/immutable/assets/Index.CWsqmWBE.css,sha256=9q_mQteovaWIyJXFeCHtS4YvHmLd7zb0nm3plt3gtiY,6844 +gradio/templates/node/build/client/_app/immutable/assets/Index.CWsqmWBE.css.br,sha256=3sJI7Af1AGWoSFznfaEyIBsaByOQCVIsEm4OZn4FBvE,1226 +gradio/templates/node/build/client/_app/immutable/assets/Index.CWsqmWBE.css.gz,sha256=YWNe9LI4ai-EZKo7BdlvQQrdlISDyxacnlpKMMDg5ik,1457 +gradio/templates/node/build/client/_app/immutable/assets/Index.CWxB-qJp.css,sha256=t9EkwoJJ_9u6urZPj2GBR82jq7rtysRIRPL-wcdvqiI,5092 +gradio/templates/node/build/client/_app/immutable/assets/Index.CWxB-qJp.css.br,sha256=G8A-ZLQ-x5EHkFRxMS4Twv06SJu1EsCVJvHnFNLTvks,849 +gradio/templates/node/build/client/_app/immutable/assets/Index.CWxB-qJp.css.gz,sha256=zIUUEqJAiu91_ZnBAtRm9t7fZU3A06k1kWChQRXiBcU,1045 +gradio/templates/node/build/client/_app/immutable/assets/Index.CfowPFmo.css,sha256=YcvJYAw-514UKSvE4LUH_zfMHScPwiJRjIm5F_awPw4,722 +gradio/templates/node/build/client/_app/immutable/assets/Index.CfowPFmo.css.br,sha256=DUqKbZdCeJ503_Pk--Du-GrXIEaaiwIhgTMF-NCiiQI,270 +gradio/templates/node/build/client/_app/immutable/assets/Index.CfowPFmo.css.gz,sha256=KHrjZ0rQu0z7nBbfGTIclXeGb_rDbLoeiOiQwkGQB-o,331 +gradio/templates/node/build/client/_app/immutable/assets/Index.CgDrEMlk.css,sha256=pZspzer_pU1TojkwfMWOWJf1S6BPNoAb5ObAOcOVHWU,811 +gradio/templates/node/build/client/_app/immutable/assets/Index.CgDrEMlk.css.br,sha256=sCEFNyDVrSOZJGQG358QonzkC1EgHggtyEoVXO4giME,261 +gradio/templates/node/build/client/_app/immutable/assets/Index.CgDrEMlk.css.gz,sha256=RBdv5xqB5mnZQLfkSMvmWCj4uCIJlsW1IVW3fYop6Lg,314 +gradio/templates/node/build/client/_app/immutable/assets/Index.Cgj6KPvj.css,sha256=DMbaY8lCSKTCov7OjbUaB7a1jm1HTXiwuEV9UE_r-Ok,333 +gradio/templates/node/build/client/_app/immutable/assets/Index.Cgj6KPvj.css.br,sha256=92ZKDKcvS74I45oPufJZn_LZpGhIFRewzEQDGpNZHuM,146 +gradio/templates/node/build/client/_app/immutable/assets/Index.Cgj6KPvj.css.gz,sha256=189idWJbRVnEZVAKcG4_YITPGXUyjBHiusab_NFaB3E,201 +gradio/templates/node/build/client/_app/immutable/assets/Index.ClP1ItfE.css,sha256=YjzCYrHvR8gPcUHH1K3YY31qL0Q3R1a1JLbx8xpuTzk,13670 +gradio/templates/node/build/client/_app/immutable/assets/Index.ClP1ItfE.css.br,sha256=HdO5pNLHkE0BrYjs-uMAUyivgY8A4cRnk22IjK78yUM,2433 +gradio/templates/node/build/client/_app/immutable/assets/Index.ClP1ItfE.css.gz,sha256=npAifxblT0JUU1s-2-581w45EOSn6vP5YWb14x6ov5k,2753 +gradio/templates/node/build/client/_app/immutable/assets/Index.Csm0OGa9.css,sha256=ZX69e6dnM9x_-wKMLTHPLfmBspH4JDEKVmm8TpKOZVw,154 +gradio/templates/node/build/client/_app/immutable/assets/Index.Csm0OGa9.css.br,sha256=99hB9uD60p67fOHVnazN-yZV8GV2nRU4-Wfe1HlPxO0,103 +gradio/templates/node/build/client/_app/immutable/assets/Index.Csm0OGa9.css.gz,sha256=9eY-4aY5G6wrQIIlmvCmZwZoMDszVUrujehbyh_r_qs,123 +gradio/templates/node/build/client/_app/immutable/assets/Index.Cwr2RydD.css,sha256=-byjuadAnEMETWtu2gL779SUrBZsaFT7Y1e5v4hJI84,3388 +gradio/templates/node/build/client/_app/immutable/assets/Index.Cwr2RydD.css.br,sha256=SESsAEEM7Xjq-ACxvUXbrvft5HmGwOTyqFPjrIh5xyQ,730 +gradio/templates/node/build/client/_app/immutable/assets/Index.Cwr2RydD.css.gz,sha256=4Ys3T1vHzLFuAi7Wu7a9pk19LS-S7xIgyMZ9E8EIuKs,863 +gradio/templates/node/build/client/_app/immutable/assets/Index.D-5U5m91.css,sha256=XaVZtv6-28M11Lh6lGDmrtnyrJ2mBjQLhsYygcMEDTY,478 +gradio/templates/node/build/client/_app/immutable/assets/Index.D-5U5m91.css.br,sha256=9aMubk55tmd2QHdcXNx7DdyTICHIUJWyy_lM1Oumv_k,194 +gradio/templates/node/build/client/_app/immutable/assets/Index.D-5U5m91.css.gz,sha256=bRMSIgQ1mpaa9yjTdTlJq8MJ8-uIP8Aq4RexF3HKQ6c,243 +gradio/templates/node/build/client/_app/immutable/assets/Index.D3BKJl5I.css,sha256=mNM5gk_u6OoGvwQ510GU6lg-ZiF75eTtnntgZubQnvw,2492 +gradio/templates/node/build/client/_app/immutable/assets/Index.D3BKJl5I.css.br,sha256=4Je766x-n6EAg3SnA8i7DOjHPA795GApa9zjAPaSH2g,480 +gradio/templates/node/build/client/_app/immutable/assets/Index.D3BKJl5I.css.gz,sha256=uurZmlxh_HxxajsTixL73-Lvb8wzeEtWIS0iNcpMSAw,584 +gradio/templates/node/build/client/_app/immutable/assets/Index.D3f6Hf9S.css,sha256=zjCpyXzLvJTOghtqMv4NmzBALzxVotpu6pImfLOnaAA,2680 +gradio/templates/node/build/client/_app/immutable/assets/Index.D3f6Hf9S.css.br,sha256=36Spp0GJDjHPkTzl_RfWccdnWHHTpCKXbUWjTsFwSmY,504 +gradio/templates/node/build/client/_app/immutable/assets/Index.D3f6Hf9S.css.gz,sha256=gQmz9uH8rV0CPpmarWwr1xzHR6RZ6zkl9MRAEeBXaIw,630 +gradio/templates/node/build/client/_app/immutable/assets/Index.D6bhueJw.css,sha256=mmJb8PFkBTF0MuzcaXpEwk5TXddktxsJU3IE6uIEO3o,4946 +gradio/templates/node/build/client/_app/immutable/assets/Index.D6bhueJw.css.br,sha256=CrJQIIw-lq7gLry-b_acGTePXxRiTZKVhpWRXPCpKlY,1021 +gradio/templates/node/build/client/_app/immutable/assets/Index.D6bhueJw.css.gz,sha256=aMcI9Tq78C1h4DKVh4IlXGXd17dZTExsrOEcb7vd26Y,1238 +gradio/templates/node/build/client/_app/immutable/assets/Index.D8xrG_DT.css,sha256=6_VXDDi98fNi772a-_GavH2QyY0H6oVt5UvgVCHJCN0,3268 +gradio/templates/node/build/client/_app/immutable/assets/Index.D8xrG_DT.css.br,sha256=r2TzPIEFnCl4cmIMgCcWgfAdTWA2pdkEzzJljtCRuhg,532 +gradio/templates/node/build/client/_app/immutable/assets/Index.D8xrG_DT.css.gz,sha256=xHatk5GcILMtWofvCVRuEg0XT4-T7mZDtX07wkJifr4,683 +gradio/templates/node/build/client/_app/immutable/assets/Index.DCIxV6YO.css,sha256=UOBFVvPtUXo-8yMQphFt03bUw0sbZOYNGm2rTk7DFvU,4438 +gradio/templates/node/build/client/_app/immutable/assets/Index.DCIxV6YO.css.br,sha256=Nl6Rh1dXSbQGzhveHJW_p9vPU6e3zkZOMkGLl0rjdLs,572 +gradio/templates/node/build/client/_app/immutable/assets/Index.DCIxV6YO.css.gz,sha256=rEOiUtmyztQKwnvlPqizDIHhopkI0JOh4XFgabu3uxI,712 +gradio/templates/node/build/client/_app/immutable/assets/Index.DEBLc7i-.css,sha256=aY6rE2rH3hzdfL00CgTGEO85BYSf8DtFas4_N_CZpyg,18309 +gradio/templates/node/build/client/_app/immutable/assets/Index.DEBLc7i-.css.br,sha256=Ca1VZBVA7AP6wj5B6wdunje_msrTfawukpqz1iAKA5g,3010 +gradio/templates/node/build/client/_app/immutable/assets/Index.DEBLc7i-.css.gz,sha256=lpIq4x9ipXrQjPBrRyEADc3JcWl2VOnlHrrcnULIXyM,3400 +gradio/templates/node/build/client/_app/immutable/assets/Index.DMdYP1a9.css,sha256=czy7Mi0EFZpNxEtN0UVQ71cS8IUVWo5puXWaehp81vk,3340 +gradio/templates/node/build/client/_app/immutable/assets/Index.DMdYP1a9.css.br,sha256=HbxtJmCZzRENVbhVpcJUxt87N6aCsVBGzK51xdSNHEQ,759 +gradio/templates/node/build/client/_app/immutable/assets/Index.DMdYP1a9.css.gz,sha256=dNAoRQzJimHVGmyBtqcY9Fl_ZPCMgEtMJ__4Vs080JA,948 +gradio/templates/node/build/client/_app/immutable/assets/Index.DMyoXqAi.css,sha256=YOuUd4-geKXWUDqcoa1HKdWxlR9WObxN6fmamqXSn1k,3342 +gradio/templates/node/build/client/_app/immutable/assets/Index.DMyoXqAi.css.br,sha256=odbo4X4a1byZdfex8zfUINbaroxO4l6A7BynKbyx6O0,648 +gradio/templates/node/build/client/_app/immutable/assets/Index.DMyoXqAi.css.gz,sha256=eCcEKqJD72_F9ps_JdEuAD5rPSLNciCg5Cbm1sOKt54,830 +gradio/templates/node/build/client/_app/immutable/assets/Index.DTfMPm_f.css,sha256=l284XOHKOh3i74lUdyFY3gC8TNFHbexybWeytG9utUc,6849 +gradio/templates/node/build/client/_app/immutable/assets/Index.DTfMPm_f.css.br,sha256=5wIpzFY6c7nIPiG_feWIjCRXOaxwNQipbfU7RspdQSc,1243 +gradio/templates/node/build/client/_app/immutable/assets/Index.DTfMPm_f.css.gz,sha256=2m4Fzo9gVt0oMfzSJxsKRkH0g7H1Yt1bMDjiagke_wg,1470 +gradio/templates/node/build/client/_app/immutable/assets/Index.DYDmCduo.css,sha256=79HrJ2F1fVdICe4oUHMKYre6r9UY2rrHdEveKN75M7s,137 +gradio/templates/node/build/client/_app/immutable/assets/Index.DYDmCduo.css.br,sha256=DVpLAA3xrCBMglMJKs9uK7TgQR_5Gf2AtokjeYSPYT4,83 +gradio/templates/node/build/client/_app/immutable/assets/Index.DYDmCduo.css.gz,sha256=vPUNQVe94lUEsXhM_nZOy8sFZAYuhzc4q4Y7M7ARXhc,111 +gradio/templates/node/build/client/_app/immutable/assets/Index.DloLYeAi.css,sha256=XpQdJaOWWIq1wCytnVsaaJI4Ae3ukmlIfAWeD9R1SGk,278 +gradio/templates/node/build/client/_app/immutable/assets/Index.DloLYeAi.css.br,sha256=wmi3tDDuH8DO5q-Is3oE0QMHlEiGrrznw7UZEAUtNE4,137 +gradio/templates/node/build/client/_app/immutable/assets/Index.DloLYeAi.css.gz,sha256=kv495OOwVtXMuAhujZkTtyhOT3fdgUUQSSIfqjblwV8,198 +gradio/templates/node/build/client/_app/immutable/assets/Index.DwWu86Nh.css,sha256=oBdSLbYXJC8D-NUJdX1dmSS5SWVsT7UszqKHts8fdaY,3235 +gradio/templates/node/build/client/_app/immutable/assets/Index.DwWu86Nh.css.br,sha256=ngf4dsBk79dbGozoQNCSOGYEX91prrti04C8McN3Mr0,739 +gradio/templates/node/build/client/_app/immutable/assets/Index.DwWu86Nh.css.gz,sha256=49lmVaEvv5sSiVi6dppBvW0DSDdRekTsvwzCMdvxB9Q,880 +gradio/templates/node/build/client/_app/immutable/assets/Index.Dwy3Ni24.css,sha256=4k_GdSNcjt-z9RlBJR2LIe-xT0c57ue2oLk_JcDqD50,5297 +gradio/templates/node/build/client/_app/immutable/assets/Index.Dwy3Ni24.css.br,sha256=nY0Z1azBi0PVNaA5cPA49K96R83VFSmULWNgJtOA7KQ,813 +gradio/templates/node/build/client/_app/immutable/assets/Index.Dwy3Ni24.css.gz,sha256=UjlJegk0fp5SRJswQJapQPA-I5X4Po6aGLusjfdH5Dg,964 +gradio/templates/node/build/client/_app/immutable/assets/Index.E3yBBMTH.css,sha256=oRXTZzGFFbyS6o3zuZ8WpUZdKmp8Cd5QDIv0j6vGUHg,1094 +gradio/templates/node/build/client/_app/immutable/assets/Index.E3yBBMTH.css.br,sha256=-sxOzP78_balHPE0IExByD3f7Hbmc-lrWcDCOjIk0Ps,292 +gradio/templates/node/build/client/_app/immutable/assets/Index.E3yBBMTH.css.gz,sha256=TievJphJP_Mp5wD3JwtDGMiCJl6kBwsR_aTPC4WsUBA,377 +gradio/templates/node/build/client/_app/immutable/assets/Index.HTxjVTe0.css,sha256=ZHuNEhnBhOjn0Z2_OjmAQ4SodoDLqUQLhszF4KgMYPQ,2507 +gradio/templates/node/build/client/_app/immutable/assets/Index.HTxjVTe0.css.br,sha256=5zQPTHI8656cN_RywhWwEhnI4ApG1Sr3RvALt_sUCQk,407 +gradio/templates/node/build/client/_app/immutable/assets/Index.HTxjVTe0.css.gz,sha256=AsCRn-WlBsR-XBvmsrDkiq5mpMKNBhxdX8swlNUcmq4,512 +gradio/templates/node/build/client/_app/immutable/assets/Index.KsvjhaTn.css,sha256=HTR_vjBL01uffvofnEyFuMHuO66pOpT86k_C0HKgRR0,5447 +gradio/templates/node/build/client/_app/immutable/assets/Index.KsvjhaTn.css.br,sha256=5ku2FMy5n7vVOgS8EyAg38vnY4_lHHsXm6Uqa1is_3M,818 +gradio/templates/node/build/client/_app/immutable/assets/Index.KsvjhaTn.css.gz,sha256=axR4KyKg-OOtdu6qsfRx0KqO6zlpmab988n5uKcguhU,976 +gradio/templates/node/build/client/_app/immutable/assets/Index.MxHcWSnO.css,sha256=SP462B9o-aomtH7_LJKNZT4A5Joe-JwQdG8htM0Cy34,1428 +gradio/templates/node/build/client/_app/immutable/assets/Index.MxHcWSnO.css.br,sha256=K1kSq4vNjgVT_jj3WLc_73N2J7uGJxJqZahSexoVdxI,370 +gradio/templates/node/build/client/_app/immutable/assets/Index.MxHcWSnO.css.gz,sha256=K38QSRt_MzLF_FjGFLScF-M_lsam6dOkpZqhZ76BXho,481 +gradio/templates/node/build/client/_app/immutable/assets/Index.WdTVQ0oj.css,sha256=mXrkgPXih5Lar82kaFDSLBRYh5yQefURMzdf4wsqgWU,445 +gradio/templates/node/build/client/_app/immutable/assets/Index.WdTVQ0oj.css.br,sha256=kFEaKJiWvCiuRpmZgSrIa5HW94H7I32PrhOZtzWfAgs,173 +gradio/templates/node/build/client/_app/immutable/assets/Index.WdTVQ0oj.css.gz,sha256=FeD1qgu5LpkrJyNIfE525Bnqf0fMXdOjWJBaTmwYsrI,247 +gradio/templates/node/build/client/_app/immutable/assets/Index.ortdYhGb.css,sha256=R0ntggIvwIC936zXqvcG3c1So1NWKfN0xPI79qlk62s,7150 +gradio/templates/node/build/client/_app/immutable/assets/Index.ortdYhGb.css.br,sha256=0XowOLKV-iIBbGIarx9733zTRRYzwNOCrgIw2wdIb1c,1447 +gradio/templates/node/build/client/_app/immutable/assets/Index.ortdYhGb.css.gz,sha256=9dES6Pm_RnK2qY6XitVtGEuVSbk1XhZ0IaNrq1vx0ko,1713 +gradio/templates/node/build/client/_app/immutable/assets/Index.tcNSQSor.css,sha256=xAdFpslGVCdsVpMohnFcgOc9JbbDoYz9GDKfh74PYEk,102 +gradio/templates/node/build/client/_app/immutable/assets/Index.tcNSQSor.css.br,sha256=givDECxkAbV3yAekjBiN_KUjuLb20_Kp8vGdfTpCjro,78 +gradio/templates/node/build/client/_app/immutable/assets/Index.tcNSQSor.css.gz,sha256=hLGRlWM-IzbnU_vH6X-9mC0O10SqPMBpcgZxNoI4AyE,97 +gradio/templates/node/build/client/_app/immutable/assets/Index.ucfmx5ZO.css,sha256=A3pD8WalkYc7qEFPrQ3MUSf0KWLQRoy9wlqpDzR_wmU,20376 +gradio/templates/node/build/client/_app/immutable/assets/Index.ucfmx5ZO.css.br,sha256=IjQq7Sjd1Dp2O1i9iDlaoMmF7tDMc_CxNlIwLOFw_-A,3096 +gradio/templates/node/build/client/_app/immutable/assets/Index.ucfmx5ZO.css.gz,sha256=LITRvuflZ5sZMM-D3UD2AVhLumsWgD7D1MMu9tq0-Xk,3467 +gradio/templates/node/build/client/_app/immutable/assets/Index.w1Ra_uQ1.css,sha256=QiNazTWepRM3wUQhukmSoakSYtrKs7tlLMuwnFXfF20,3180 +gradio/templates/node/build/client/_app/immutable/assets/Index.w1Ra_uQ1.css.br,sha256=Y2ajXwswcI4ghxX7yiTAqMd5P-wEktMn697hwoRlxLo,615 +gradio/templates/node/build/client/_app/immutable/assets/Index.w1Ra_uQ1.css.gz,sha256=GZbXu9ULFvJKen-9gEoZKk9RCxX2D17YagbuL9FVCjM,725 +gradio/templates/node/build/client/_app/immutable/assets/Index.xkmfPIkL.css,sha256=o0e3U0YitBxL1deOHhIQP3r7YKWpXFSlMQhl26fWH1s,3119 +gradio/templates/node/build/client/_app/immutable/assets/Index.xkmfPIkL.css.br,sha256=cfI7lrKhJsn9tlOGdwpSwphzBxnZ1koFuLoInzui31M,803 +gradio/templates/node/build/client/_app/immutable/assets/Index.xkmfPIkL.css.gz,sha256=7AgjPLsg6psKF4mu1C0YOoTduhCTpga69TpOrC-3oTs,953 +gradio/templates/node/build/client/_app/immutable/assets/Index.zdBaScbz.css,sha256=tXf77rI-isPCMvtSVO-bDXHtWq1FCIPDAy2EGBVcvts,4921 +gradio/templates/node/build/client/_app/immutable/assets/Index.zdBaScbz.css.br,sha256=GptbmUqgMffkc5EG7XuzSAvjH0JCxbW9_gVxxkGEogw,887 +gradio/templates/node/build/client/_app/immutable/assets/Index.zdBaScbz.css.gz,sha256=9xbWePjm7ORNSdpegfJMpqFjx8fiduwZZwFPOD43UWs,1079 +gradio/templates/node/build/client/_app/immutable/assets/InteractiveAudio.B76TQFG-.css,sha256=jeVtIM1654vbhMm-DNUPSu19LzGDXET6X2VnDavk1-o,6505 +gradio/templates/node/build/client/_app/immutable/assets/InteractiveAudio.B76TQFG-.css.br,sha256=kVA-VzGKZUCDtUWZx3s89Gvp1WxNbAbZphW38qEOl10,982 +gradio/templates/node/build/client/_app/immutable/assets/InteractiveAudio.B76TQFG-.css.gz,sha256=DvXcr55u8Qqj9vM-aG0f4nFti0COIB57IjP2a6PGp88,1132 +gradio/templates/node/build/client/_app/immutable/assets/JSON.AVFPpFex.css,sha256=6n-ZzbLYrJdspYFIx4NrHl-f3vi45pbW0LbRaz8vhNQ,2351 +gradio/templates/node/build/client/_app/immutable/assets/JSON.AVFPpFex.css.br,sha256=3oK9F1IGqLDnFsRW3bso_6ngkFs5jxhVkfLMqfiUwlI,682 +gradio/templates/node/build/client/_app/immutable/assets/JSON.AVFPpFex.css.gz,sha256=Plv9kzWdtwGctNssAZzAC0CfivfTWNWm09WRI4IhoGo,834 +gradio/templates/node/build/client/_app/immutable/assets/JSON.DItMwpQq.css,sha256=53DymkTNZs-ATZ8D8AJGkkipL-43I1KO10TN_x9GKpk,2301 +gradio/templates/node/build/client/_app/immutable/assets/JSON.DItMwpQq.css.br,sha256=ZhRnANMgxoDkc3qpVNrEh4ojAMDZ4evyLgE_GF5qtLs,678 +gradio/templates/node/build/client/_app/immutable/assets/JSON.DItMwpQq.css.gz,sha256=mi72bZGHV9BcyF8_pcs1w-Blx8jXMqKqGY6JlP_J16I,824 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_AMS-Regular.BQhdFMY1.woff2,sha256=DN04fJWQoan5eUVgAi27WWVKfYbxh6oMgUla1C06cwg,28076 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_AMS-Regular.DMm9YOAa.woff,sha256=MNqR6EyJP4deJSaJ-uvcWQsocRReitx_mp1NvYzgslE,33516 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_AMS-Regular.DRggAlZN.ttf,sha256=aFNIQLz90r_7bw6N60hoTdAefwTqKBMmdXevuQbeHRM,63632 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Caligraphic-Bold.ATXxdsX0.ttf,sha256=B9jjA85PwStLtU8QBBcN0ZCh89tF1AD-aAYN8-CJcmg,12368 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Caligraphic-Bold.BEiXGLvX.woff,sha256=Gua9dHVZDpfn8UWongnM3jIvemvAuRYHsci47igpD-0,7716 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Caligraphic-Bold.Dq_IR9rO.woff2,sha256=3ncB5Czx9M8LdmwD-yeXcgfu4vT9XXb6ghiEBtpD6kw,6912 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Caligraphic-Regular.CTRA-rTL.woff,sha256=M5jdAjAlV6eT8oY_iOAtls4Q3yq_-gfI6fqQd1EW5lw,7656 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Caligraphic-Regular.Di6jR-x-.woff2,sha256=XVPnCtYHwjUhYt7J4JI_tU7Nr6zL9gTNjc99APrLmJs,6908 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Caligraphic-Regular.wX97UBjC.ttf,sha256=7Qt0Ny_u_LucBmay4hDaN7fkn6f7vz7rEdtfaT2s-7c,12344 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Fraktur-Bold.BdnERNNW.ttf,sha256=kWPfnHEiQy5klbQin6kHHPmuhqdYrl78SSTsLhptvOE,19584 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Fraktur-Bold.BsDP51OF.woff,sha256=m-fOuIAEq4rRJAgiRvv8ykCR42OF1Oxu0d9nN12tUPs,13296 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Fraktur-Bold.CL6g_b3V.woff2,sha256=dERO_Vk8AF4_RXO0RSRwTArwqTf-kRzKnpQGjQ0UDT8,11348 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Fraktur-Regular.CB_wures.ttf,sha256=Hm-VeekOLKw3-PYKWXxDbgdcEUOFZSt8vrDewEISkbM,19572 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Fraktur-Regular.CTYiF6lA.woff2,sha256=UYFNJw0G_wJV26B5mZT6TYyE0R8JlR1HWV9Kux82Atw,11316 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Fraktur-Regular.Dxdc4cR9.woff,sha256=Xih1O-cX2sl_VZ9JvBC-nPPBJN3KvaZlnRHLaP68ZGM,13208 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Main-Bold.Cx986IdX.woff2,sha256=D2DRuJeTjskYyM4HMJJBG6-UOPZzlGVpP_GLD50gsCE,25324 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Main-Bold.Jm3AIy58.woff,sha256=x2xdaWKX1RucsWOcfaQzTw597IG0KxEhO14l72cbuCI,29912 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Main-Bold.waoOVXN0.ttf,sha256=E4rCjRZjswN-nF9SNx-lxj2DJPSjjSLNVz5uo6P9DPg,51336 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Main-BoldItalic.DxDJ3AOS.woff2,sha256=mc1Co8By2Rjy9EmEqAfPeqFuE1Rf0IdfwHxsZfmecVs,16780 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Main-BoldItalic.DzxPMmG6.ttf,sha256=cO4fZKIPIEjCGUDvRtAUT9IVuqlTymmv0eMemFRPcI8,32968 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Main-BoldItalic.SpSLRI95.woff,sha256=pvfsDYRqx62XWtuJWcN-1JuUrLxK5DbbnOniAofkpkw,19412 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Main-Italic.3WenGoN9.ttf,sha256=DYWufMMPI3kKfxpYxKES_cqKrnaba6EUKa8dmLG2yzo,33580 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Main-Italic.BMLOBm91.woff,sha256=8dbvhvOxGlKL1RhRmb0kQ-yysN6tltiGdLWiwSviS98,19676 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Main-Italic.NWA7e6Wa.woff2,sha256=l0ecpszpBqvJYeyslvql-couYbjnZw1HWCa83umnwmc,16988 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Main-Regular.B22Nviop.woff2,sha256=wjQs2Lhp4BdSqTIdwXIT_EDU0Ex5aIwdQ_LPMWq9eGY,26272 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Main-Regular.Dr94JaBh.woff,sha256=xjaNh-iho6XTN2I9g9jcS4aPJCqa1HYjfW-NHg8WjNw,30772 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Main-Regular.ypZvNtVU.ttf,sha256=0DMvUoaDcP2Drn-kZHD5DI8uqy_PErxPiAgLNAyVqDA,53580 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Math-BoldItalic.B3XSjfu4.ttf,sha256=-Td6sCcc2lmvJLz_vUak0MijVy_6_bs43irV6nsNXuU,31196 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Math-BoldItalic.CZnvNsCZ.woff2,sha256=3Ec0TbtstbZVyEYNVh9N9fUBuQyAStPGzsZf4yI1GrE,16400 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Math-BoldItalic.iY-2wyZ7.woff,sha256=hQwK9cIjhJf-uvXkYdiAv0WMNB9C9PMw8bGrVpixmY4,18668 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Math-Italic.DA0__PXp.woff,sha256=io0kRYE3GRK48_WiPiQ3yypZzZvK67A0bnIsBXN6JXE,18748 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Math-Italic.flOr_0UB.ttf,sha256=CM6Y5RsE1YlFowHmOeAraZivKf39Yae4r90Hu_xHnUo,31308 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Math-Italic.t53AETM-.woff2,sha256=evWMXsjxMqLd3pAnxteBTezOTTuCKhEZKkKiDi6XMmQ,16440 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_SansSerif-Bold.CFMepnvq.ttf,sha256=Hs4D95-VJ31X3H9rQ1p04TebDUYQSoUwKGtg_0k2nqA,24504 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_SansSerif-Bold.D1sUS0GD.woff2,sha256=6ZrlEUS_EjLvzBv-Wt02JixoZrD6qyT6dXQOG5hXemI,12216 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_SansSerif-Bold.DbIhKOiC.woff,sha256=7OA8_YPiLCEs3vZv64RC0loIO-uYjbPxiD8_lzjXULo,14408 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_SansSerif-Italic.C3H0VqGB.woff2,sha256=ALJqyCXiCVBWOW4FU7isJtP4rRWMOCbii0xFs4XEcUo,12028 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_SansSerif-Italic.DN2j7dab.woff,sha256=ke5nUAzAEpqgrOOsXGH_FpIQLw8x0CtpNH-6Ndy3W_I,14112 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_SansSerif-Italic.YYjJ1zSn.ttf,sha256=OTHdgfrthroCG7K73Db1vtmjjWtPQHespZsmWqGwIIM,22364 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_SansSerif-Regular.BNo7hRIc.ttf,sha256=826ol-GfSi5XHR6QDk43EOQ43rBahCSGBFugo-YWpK0,19436 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_SansSerif-Regular.CS6fqUqJ.woff,sha256=EeTcimRx_21u5WHVPRD96PdInnmCV_9EnF03wZdDVgU,12316 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_SansSerif-Regular.DDBCnlJ7.woff2,sha256=aOjHPvQq_TzOxYvw-6MCzORIk45_wCCl4x-KlS7uE0I,10344 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Script-Regular.C5JkGWo-.ttf,sha256=HGfwaP6ouwm_CZwIixz2S9J1Fqbgf0aENEhzVku2amc,16648 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Script-Regular.D3wIWfF6.woff2,sha256=A21OlRSbaf-bzAzVV3Hv6yX_o5Ryk-aazXjVrDKMaEs,9644 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Script-Regular.D5yQViql.woff,sha256=2WzfKzvdTWSo_V90pMRn8SOopzkxzUNYifCP-vm_lHo,10588 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Size1-Regular.C195tn64.woff,sha256=yUPMmGOE9Z6GvqX9fcUKnE3-Vnp8BetA1nkHIN6tl8k,6496 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Size1-Regular.Dbsnue_I.ttf,sha256=lbbS8aUBc7_tuMY-HRyZsQQn0KTfQgHLRFE7ImlRois,12228 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Size1-Regular.mCD8mA8B.woff2,sha256=a0fEAWa22-IaXfyncYQT8hR_0jmb4bpgXYrTnO3yXf4,5468 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Size2-Regular.B7gKUWhC.ttf,sha256=prIJn7VVxg46DbOgiELr8dcyxutOS_RJE2E77U_E45s,11508 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Size2-Regular.Dy4dx90m.woff2,sha256=0ExUIZ-ersbU1P1C37KHhZdaR5TWsvxx5Wa5zW24Qt0,5208 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Size2-Regular.oD1tc_U0.woff,sha256=IBTFI8MhC8wWZkjE1MxX8Ft0ffB6JCd79xxR5n3Hnj0,6188 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Size3-Regular.CTq5MqoE.woff,sha256=ara2Lpti2uLADdkPeRvRCVC-Dsw0kNfWBF9Rwuj-CUk,4420 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Size3-Regular.DgpXs0kz.ttf,sha256=UA4E1U8NUWZjMsnSCJqoA74iqoeOylOeWfpTxuUisII,7588 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Size4-Regular.BF-4gkZK.woff,sha256=mfnGdQtInJRivwSQC9P5Od-bgpM52qqqme9Ulc3d6lg,5980 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Size4-Regular.DWFBv043.ttf,sha256=xkc2fR3U4WJGhxfQIOH8Dx3Fwm6_3_vlUmFxO_iMWHc,10364 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Size4-Regular.Dl5lxZxV.woff2,sha256=pK99QURAocF5CCXPtwDPnPQ7DyxLBPDrxSMBGtmFPsA,4928 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Typewriter-Regular.C0xS9mPB.woff,sha256=4U_tArGrp86fWv1YRLXQMhsiNR_rxyDg3ouHI1J2Cfc,16028 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Typewriter-Regular.CO6r4hn1.woff2,sha256=cdUX1ngneHz6vfGGkUzDNY7aU543kxlB8rL9SiH2jAs,13568 +gradio/templates/node/build/client/_app/immutable/assets/KaTeX_Typewriter-Regular.D3Ib7_Hf.ttf,sha256=8B8-h9nGphwMCBzrV3q9hk6wCmEvesFiDdaRX60u9ao,27556 +gradio/templates/node/build/client/_app/immutable/assets/MarkdownCode.DG3USZRO.css,sha256=tmg5JE4hUGAlwrFQZ9g7XfcxANc-dlYbCsAQ-Y_K4cQ,4940 +gradio/templates/node/build/client/_app/immutable/assets/MarkdownCode.DG3USZRO.css.br,sha256=euLYIftnp4BF4inhSEIpsMCd8Dzo0C8V-CZRjeV1uHo,1004 +gradio/templates/node/build/client/_app/immutable/assets/MarkdownCode.DG3USZRO.css.gz,sha256=Z46TxLFj2Mp0fH5bhLHpsCPqOBqO0jrQjmS7w97bgmY,1209 +gradio/templates/node/build/client/_app/immutable/assets/MatplotlibPlot.AF_QcUtc.css,sha256=FjyW59ACE0ikEFE2_IDo0vIPCcyMEMBbaDlVOae3RSI,253 +gradio/templates/node/build/client/_app/immutable/assets/MatplotlibPlot.AF_QcUtc.css.br,sha256=ElD6hM5BX9ZBfETkGoTW5YKjoYSnPkB_xIWAf72h7Ug,134 +gradio/templates/node/build/client/_app/immutable/assets/MatplotlibPlot.AF_QcUtc.css.gz,sha256=3_dit6hfn2fmsrpMN6Sl8J4GYLeoc9B2BlMLiFqAFcw,175 +gradio/templates/node/build/client/_app/immutable/assets/ModifyUpload.L7mprsyN.css,sha256=IxQ8sG8dtxNyf-JeqTG7f-34_aT_7kD8XdcwHCICIFY,2094 +gradio/templates/node/build/client/_app/immutable/assets/ModifyUpload.L7mprsyN.css.br,sha256=RjB-3YHbofoDMPU97cmITnuSCoHXz4MFMsPVz2UHKrs,542 +gradio/templates/node/build/client/_app/immutable/assets/ModifyUpload.L7mprsyN.css.gz,sha256=COMM8m22VAXxqtJh54eLGL8QYfUiBaPg21hYazJfF8U,671 +gradio/templates/node/build/client/_app/immutable/assets/Settings.BVvHX4gg.css,sha256=_GRdTUxXFGzKH-Hfd3ly_xqpGFj6JXWgG3H7fKezhQY,2675 +gradio/templates/node/build/client/_app/immutable/assets/Settings.BVvHX4gg.css.br,sha256=SzKPH8NozO6bvRwmcrzvLALniR7UgTYIIR-GJG7oVjs,569 +gradio/templates/node/build/client/_app/immutable/assets/Settings.BVvHX4gg.css.gz,sha256=a3HB7dJ6dKx2HsWkojbj3T95sAcAohqtIyPEeYrYCNI,707 +gradio/templates/node/build/client/_app/immutable/assets/Settings.D01KD214.css,sha256=Ma06xtcUKj7_9UvMhIqqGhCrjAPneSdhLfRiIPT59v0,2700 +gradio/templates/node/build/client/_app/immutable/assets/Settings.D01KD214.css.br,sha256=d825LgAdpy1VTC54svdM5gk04hzYSQSjV9WPRrts38Q,572 +gradio/templates/node/build/client/_app/immutable/assets/Settings.D01KD214.css.gz,sha256=eEbOGuiBKWqCiaPOXivg6BgivVgj7vCFBAxVs2eBPYU,713 +gradio/templates/node/build/client/_app/immutable/assets/StreamingBar.CW9MoLa7.css,sha256=lL-M2kxuW79MQwfIZghXaw-UGCzpXI8iLy8JzelRp3I,9363 +gradio/templates/node/build/client/_app/immutable/assets/StreamingBar.CW9MoLa7.css.br,sha256=sgQjilV5u4jTPtAOgzX8VZshNKXSR7cMpJlwVsGchds,1555 +gradio/templates/node/build/client/_app/immutable/assets/StreamingBar.CW9MoLa7.css.gz,sha256=TcZ8IPgNRjYPzkCK51C16EOk12nLOKjt-UeDkF5oxms,1790 +gradio/templates/node/build/client/_app/immutable/assets/Upload.L7mprsyN.css,sha256=IxQ8sG8dtxNyf-JeqTG7f-34_aT_7kD8XdcwHCICIFY,2094 +gradio/templates/node/build/client/_app/immutable/assets/Upload.L7mprsyN.css.br,sha256=RjB-3YHbofoDMPU97cmITnuSCoHXz4MFMsPVz2UHKrs,542 +gradio/templates/node/build/client/_app/immutable/assets/Upload.L7mprsyN.css.gz,sha256=COMM8m22VAXxqtJh54eLGL8QYfUiBaPg21hYazJfF8U,671 +gradio/templates/node/build/client/_app/immutable/assets/Video.DJw86Ppo.css,sha256=qAw3K4D7yNVXazTJKnrqyWL7dwp-lY_7ekFq7-UWH0k,847 +gradio/templates/node/build/client/_app/immutable/assets/Video.DJw86Ppo.css.br,sha256=JrrOnRdMBpSLxlVH9BY-7jj1E2dosLi9LG9qC7B3p2U,258 +gradio/templates/node/build/client/_app/immutable/assets/Video.DJw86Ppo.css.gz,sha256=Hn5_D0ni7jHllcCjrKDU7xrFEiy6uz7OFo_l8CU32CY,336 +gradio/templates/node/build/client/_app/immutable/assets/VideoPreview.BeECudjn.css,sha256=u2Got64cu9SYxzpR9s9YoCBkKdFVLUiKImO0taIIasg,4381 +gradio/templates/node/build/client/_app/immutable/assets/VideoPreview.BeECudjn.css.br,sha256=4B0vV-cp-RVb8NkLmSH-2ATdxmLYkrGegC6kqwlNnNk,946 +gradio/templates/node/build/client/_app/immutable/assets/VideoPreview.BeECudjn.css.gz,sha256=bdn7i8_dJtHEvc1yhNu9zj10MFpBH8WCmjSPDarUf6E,1122 +gradio/templates/node/build/client/_app/immutable/assets/VideoPreview.wQufNXbv.css,sha256=PjkGWhpaBjwd-8gamQ1ogoa9aVdMSZsVx0yAoWfYD6A,4356 +gradio/templates/node/build/client/_app/immutable/assets/VideoPreview.wQufNXbv.css.br,sha256=ubQQe8UT7DoZ2-VzNd6il97gwtqjGq9lBv6MRBFNXF8,941 +gradio/templates/node/build/client/_app/immutable/assets/VideoPreview.wQufNXbv.css.gz,sha256=YYV8FCoNukwYaehmUv2CFd48udHVRJjyxXguC40frvw,1115 +gradio/templates/node/build/client/_app/immutable/assets/Walkthrough.DTfMPm_f.css,sha256=l284XOHKOh3i74lUdyFY3gC8TNFHbexybWeytG9utUc,6849 +gradio/templates/node/build/client/_app/immutable/assets/Walkthrough.DTfMPm_f.css.br,sha256=5wIpzFY6c7nIPiG_feWIjCRXOaxwNQipbfU7RspdQSc,1243 +gradio/templates/node/build/client/_app/immutable/assets/Walkthrough.DTfMPm_f.css.gz,sha256=2m4Fzo9gVt0oMfzSJxsKRkH0g7H1Yt1bMDjiagke_wg,1470 +gradio/templates/node/build/client/_app/immutable/assets/_layout.DVSeeagb.css,sha256=LLApS-IgHzuEtMGb8KKylHL3xTbcihEeG0GNof__png,23484 +gradio/templates/node/build/client/_app/immutable/assets/_layout.DVSeeagb.css.br,sha256=DcAwi8kw0uwmH1kXd2FKSA43lqNvA1rWN9FbD3_cijo,4854 +gradio/templates/node/build/client/_app/immutable/assets/_layout.DVSeeagb.css.gz,sha256=msAFcKs0Dq_VIgA0j_SRYE59n6QJdZj7wH8Dl5sSJmY,5659 +gradio/templates/node/build/client/_app/immutable/assets/_page.BHfhJXMJ.css,sha256=mTcyDPAcz5Nl93n1Rg6oBRQ289pqM42oJ_NL9Wqg1_c,3008 +gradio/templates/node/build/client/_app/immutable/assets/_page.BHfhJXMJ.css.br,sha256=zV51WIVxqXngBMTMQ7iljj8gykPU1P1uQN9EkWpsI3E,616 +gradio/templates/node/build/client/_app/immutable/assets/_page.BHfhJXMJ.css.gz,sha256=mWrrxcep7he4dh2Q3_Qcy9C_wYP_UENibKilcixN_GM,731 +gradio/templates/node/build/client/_app/immutable/assets/client.CZ5Iq-nv.css,sha256=PNF6VSMNUIyYNzC1K_h-ZANcn1dKn0y1ErlvOZZto3c,3428 +gradio/templates/node/build/client/_app/immutable/assets/client.CZ5Iq-nv.css.br,sha256=idCNGaPs5JbvmwYQq7jHnCtozDiq0ETYZ7m2wwz6kwg,724 +gradio/templates/node/build/client/_app/immutable/assets/client.CZ5Iq-nv.css.gz,sha256=ERaMUgPuOk7RnJAzWSfC8sFUHZTqasUR2Wys2zlPvbs,880 +gradio/templates/node/build/client/_app/immutable/assets/index.CFBZQE_H.css,sha256=ju6sTexxG14ZCP0jy02BnRvbcKf2XNDp6NP7_TW-_Gg,346 +gradio/templates/node/build/client/_app/immutable/assets/index.CFBZQE_H.css.br,sha256=emUY49ZX7sfWfUmRQzBZSi6RuV47INm826NuewtycKc,149 +gradio/templates/node/build/client/_app/immutable/assets/index.CFBZQE_H.css.gz,sha256=pRIjnc5jAxMI7PsGu_cpdXFJOJIoSKLyWisgCcSq8LE,203 +gradio/templates/node/build/client/_app/immutable/assets/katex.DlGe0zfI.css,sha256=YsLtmV0TTqi1fFCdCysMnSjFCxmYY_PqKsvETIR6SkI,37909 +gradio/templates/node/build/client/_app/immutable/assets/katex.DlGe0zfI.css.br,sha256=rYyWcFqmjiPt1qI_A6S9MKoq1UGjGxPyD6MSOvE492k,7040 +gradio/templates/node/build/client/_app/immutable/assets/katex.DlGe0zfI.css.gz,sha256=JtGVkSoyoqjQu8fgYn-fche3wpG_lZM80BKyAsOvoYk,8028 +gradio/templates/node/build/client/_app/immutable/assets/mcp.DNm9doVd.svg,sha256=Dak6acRJHMkXH9h8HKvE7RgG_RjZOlBUGo9tkD_edKQ,9975 +gradio/templates/node/build/client/_app/immutable/assets/mcp.DNm9doVd.svg.br,sha256=2CCo-MdkALa9uAjthk5G96cs1aAFSHbm0gWynZmls1M,4394 +gradio/templates/node/build/client/_app/immutable/assets/mcp.DNm9doVd.svg.gz,sha256=bPvxlpZPvG5EvAgub7ZmMMfDQmkP9hD90xzxEkGXwOk,5070 +gradio/templates/node/build/client/_app/immutable/chunks/2.XmRMbGVn.js,sha256=i3MPQCEA36LFRH8W2eR3KNje3-31-r-qWX1j6fA4-aM,415277 +gradio/templates/node/build/client/_app/immutable/chunks/2.XmRMbGVn.js.br,sha256=-MLbX0ejTqKo8uqU2TgJFtqnrBmOVUzOthohx4wGXvo,113197 +gradio/templates/node/build/client/_app/immutable/chunks/2.XmRMbGVn.js.gz,sha256=giDlIR4gp6FI7JIsB4Z08V45xtaKBFz0xNwb1oy1Txw,137508 +gradio/templates/node/build/client/_app/immutable/chunks/2.XmRMbGVn.js.map,sha256=-NfkdT7jePwIK9QBm4peYY2doUfMGZTe4bPGxABcxF0,1145321 +gradio/templates/node/build/client/_app/immutable/chunks/AltairPlot.LQxwk--E.js,sha256=k6rgC6ytZ_2T3QJr1rafML8c-BnrAlKpvFR5jOHW7uE,303172 +gradio/templates/node/build/client/_app/immutable/chunks/AltairPlot.LQxwk--E.js.br,sha256=rLPJ9u-CWNTUDg9b3lrgWojVW2B-Wb5KYnvRHQ3k8DM,86401 +gradio/templates/node/build/client/_app/immutable/chunks/AltairPlot.LQxwk--E.js.gz,sha256=R5X4Z3HzLI1p_nV_oL7aAib1n0MaCPeimbNDQUBE4bU,99386 +gradio/templates/node/build/client/_app/immutable/chunks/AltairPlot.LQxwk--E.js.map,sha256=_O9zJEMXrFz5gKYaFy0PIB9w0VXTjyBulCOeQuvyLV4,1434186 +gradio/templates/node/build/client/_app/immutable/chunks/ApiDocs.CEoavypC.js,sha256=V6rxR4gIGG9isQuu0GUU8S6gTw1qvfJj6-HBzBUeEF4,105960 +gradio/templates/node/build/client/_app/immutable/chunks/ApiDocs.CEoavypC.js.br,sha256=VFaiq_14DVk7s9OkyQcJ_PNrx-7QgTtcUILU-4PSAr0,25863 +gradio/templates/node/build/client/_app/immutable/chunks/ApiDocs.CEoavypC.js.gz,sha256=g3B31YKW0oX3ZQi8iMBfRc7QFAOi5fjVAPyGf9fg00w,32270 +gradio/templates/node/build/client/_app/immutable/chunks/ApiDocs.CEoavypC.js.map,sha256=gNjUUNnqtrX1JKlsS538upbZeGHhXRStTqXpmasq0m4,120916 +gradio/templates/node/build/client/_app/immutable/chunks/ApiRecorder.8J3LHl90.js,sha256=dd3Pjm8IEowSUqoE5uPI-sefKG4niaj2X19ytT0B-9k,2635 +gradio/templates/node/build/client/_app/immutable/chunks/ApiRecorder.8J3LHl90.js.br,sha256=9N1QOy7zsEvw_eb3K9NE-LAv_6mCQwCA-HW6-oAeGVA,1124 +gradio/templates/node/build/client/_app/immutable/chunks/ApiRecorder.8J3LHl90.js.gz,sha256=ePR5WDtjVR5rghmhdP1QojVeHRwwrTtDaPbavtf8r84,1254 +gradio/templates/node/build/client/_app/immutable/chunks/ApiRecorder.8J3LHl90.js.map,sha256=mJOX--t4rDPlfrQpmXUPi-J2_UC6hOFyqmz6NnI-SAg,2810 +gradio/templates/node/build/client/_app/immutable/chunks/AudioPlayer.CVwHOniI.js,sha256=zlS-Fj1o8kuXlsYj9vb8c5XJuW4s1Z7mrDrwPtD214w,66261 +gradio/templates/node/build/client/_app/immutable/chunks/AudioPlayer.CVwHOniI.js.br,sha256=_dX4WWuRTGGIMvXd0sl-uOHFWWR6qc19d_Oj8gCtQLs,17057 +gradio/templates/node/build/client/_app/immutable/chunks/AudioPlayer.CVwHOniI.js.gz,sha256=IGoHUuchomwHpZrL5Rs3dNqbvmlP0q48YUZfDmZVtrc,19313 +gradio/templates/node/build/client/_app/immutable/chunks/AudioPlayer.CVwHOniI.js.map,sha256=sUS8bGtpLQV2KEnx2X-qVwxdw4u4oSzzSMzUbydBxJ0,153188 +gradio/templates/node/build/client/_app/immutable/chunks/BlockLabel.CUEZCGj6.js,sha256=llKt-mTRR64nTQBO5s_YuJ2KKRUkjGSAk5zDYJr9vIg,1860 +gradio/templates/node/build/client/_app/immutable/chunks/BlockLabel.CUEZCGj6.js.br,sha256=9fe9r-PbP1SE2RaEngypiCgFuHi8bWRhhca3D8PhHf0,855 +gradio/templates/node/build/client/_app/immutable/chunks/BlockLabel.CUEZCGj6.js.gz,sha256=ttnOcy3pIpMVBshTxw_6RThy0OX4moPxdP0wpRhpVb0,955 +gradio/templates/node/build/client/_app/immutable/chunks/BlockLabel.CUEZCGj6.js.map,sha256=0UBrzUsrga9kGQohwuKpz-e0b_YJHKbXz8y50sqb26Q,2983 +gradio/templates/node/build/client/_app/immutable/chunks/BokehPlot.BywEwpiC.js,sha256=_LnZKxBgr03sV-HXKXgUTztVLATZ0gfU2n2kKP7X1vI,2055 +gradio/templates/node/build/client/_app/immutable/chunks/BokehPlot.BywEwpiC.js.br,sha256=GhcdiuuEBVa5tZJefbKHGU0OrS6I4iVEyqSpbC7AcsQ,900 +gradio/templates/node/build/client/_app/immutable/chunks/BokehPlot.BywEwpiC.js.gz,sha256=G1w2qig4A2ym9k9tNX92ZVFh9i9bNX6Py7YhXmtJpZ0,1041 +gradio/templates/node/build/client/_app/immutable/chunks/BokehPlot.BywEwpiC.js.map,sha256=3vl6_eqZ46qZE6FeJo2OoiBJpc5mxJjjzsX-RSWe2Ng,4388 +gradio/templates/node/build/client/_app/immutable/chunks/Canvas3D.C1ee5xfR.js,sha256=o4UjeCNJjg3a_kRQHTpRVqs9vNGA6KMpyef4avbv4RI,2348 +gradio/templates/node/build/client/_app/immutable/chunks/Canvas3D.C1ee5xfR.js.br,sha256=e3a5VaQro7NdmtuyWFnK-rZ29rbMTB1LovOyLrAXUxU,1168 +gradio/templates/node/build/client/_app/immutable/chunks/Canvas3D.C1ee5xfR.js.gz,sha256=do2AkD58OGn6mreY3q_o044vDBa82xAcSqger2Y36Lw,1274 +gradio/templates/node/build/client/_app/immutable/chunks/Canvas3D.C1ee5xfR.js.map,sha256=1w1NXhSFtRIYMf4pv1vBZ5jnNva_7gKGtBBpCV3sX4U,5094 +gradio/templates/node/build/client/_app/immutable/chunks/Canvas3DGS.BcViPffL.js,sha256=qiTAUCiYvvau3GIV6aMNhn7FOG8lb0TnwbZ4EykJrEM,116110 +gradio/templates/node/build/client/_app/immutable/chunks/Canvas3DGS.BcViPffL.js.br,sha256=8xHDYJQ1JR-e8piZFxXssf1h2qvVduxq-aLZA9BNXpo,35660 +gradio/templates/node/build/client/_app/immutable/chunks/Canvas3DGS.BcViPffL.js.gz,sha256=OdVFzSSvndP1XfttrlDZlMitfi9gq73_VdCW3etSrAc,42036 +gradio/templates/node/build/client/_app/immutable/chunks/Canvas3DGS.BcViPffL.js.map,sha256=TmqLjfQq5C7EmIPGxvTrwGANscFZ61qRpFPTOHPSLt0,234619 +gradio/templates/node/build/client/_app/immutable/chunks/Checkbox.DNIYXYiK.js,sha256=IXU0wdlvllUD-jXwtTK2aFLiyCx4zwW1s3HF1GY0Tzs,2149 +gradio/templates/node/build/client/_app/immutable/chunks/Checkbox.DNIYXYiK.js.br,sha256=Llr57CzaUAuzvQvOcoURRmEi6Rd-AvnxyGyRXSkMceM,956 +gradio/templates/node/build/client/_app/immutable/chunks/Checkbox.DNIYXYiK.js.gz,sha256=UJCR40HFKeJYp4IlsLBNfpJzXX_6YiYKW7jb-HhOg04,1083 +gradio/templates/node/build/client/_app/immutable/chunks/Checkbox.DNIYXYiK.js.map,sha256=3b5buXZPVoyGIJlIQo83r23R1mFjWl0K2xFXcBQCCgM,5081 +gradio/templates/node/build/client/_app/immutable/chunks/Code.CmGr0qgG.js,sha256=NjyUJzYJ6YVysMfy1j8R-wcqZJUMzoPhQHCv76I1AMQ,383061 +gradio/templates/node/build/client/_app/immutable/chunks/Code.CmGr0qgG.js.br,sha256=SVHXLw2rQ8V2V4ibEA7XinOP9Ecr4KpXQtYzm0uGOMU,106580 +gradio/templates/node/build/client/_app/immutable/chunks/Code.CmGr0qgG.js.gz,sha256=9UgBfNWPZ5pJenDtJUXaJMzJClT4SssYsg1tGVeLZMI,124367 +gradio/templates/node/build/client/_app/immutable/chunks/Code.CmGr0qgG.js.map,sha256=bybjALZ4X-nVFmVbPYE3Uhsc63QgnNJHP2PRLmyYK6s,1658598 +gradio/templates/node/build/client/_app/immutable/chunks/Code.DWo5KduI.js,sha256=w7I6fNZFKDTrjxesoEzLjUjMClGstl3dFeB9KMj5Ml0,886 +gradio/templates/node/build/client/_app/immutable/chunks/Code.DWo5KduI.js.br,sha256=hfIwviiEOYmInVIezJmGOVsJ3or9_qggHyrt0MwRKmQ,512 +gradio/templates/node/build/client/_app/immutable/chunks/Code.DWo5KduI.js.gz,sha256=RLxxfxLQcpWE8hMRq8eyVPH2TgozHMWWHyNYG7XNoTc,564 +gradio/templates/node/build/client/_app/immutable/chunks/Code.DWo5KduI.js.map,sha256=VvVN2V3Bwqkiqv5r8AJCzoaevwv2s2O-Rpjrhk5RZZw,527 +gradio/templates/node/build/client/_app/immutable/chunks/Community.i_uzCNAp.js,sha256=Cn0HdbebsEjfnmc-XX3WX6n3tXYQPPPjspJSUeYzWfY,1112 +gradio/templates/node/build/client/_app/immutable/chunks/Community.i_uzCNAp.js.br,sha256=2RpJPstkBY_hA9qyfgK-psuzU6_eGBUlANBnXJY7j2I,580 +gradio/templates/node/build/client/_app/immutable/chunks/Community.i_uzCNAp.js.gz,sha256=isSh61O_xF_AF_ApR4XsebL5d6jhSSIzOMJYgc2to8E,646 +gradio/templates/node/build/client/_app/immutable/chunks/Community.i_uzCNAp.js.map,sha256=SRxR5r3e4Ri4BOC1p6rbJAknVtZswHdCR4r1bZuaJ1w,750 +gradio/templates/node/build/client/_app/immutable/chunks/Download.CpfEFmFf.js,sha256=OpmP6WhQ9YXAngJR63qC4Gzkg0-OlexZa1_O13ZhGSg,917 +gradio/templates/node/build/client/_app/immutable/chunks/Download.CpfEFmFf.js.br,sha256=MTAAvaltswGg6T8VqxwLnVVZN6CNG9pLP0eHqlB-FeI,508 +gradio/templates/node/build/client/_app/immutable/chunks/Download.CpfEFmFf.js.gz,sha256=8xP9XTP5jKpOKLEUJsdsF0gXn6Ob3e2ndd-ch17aVjA,576 +gradio/templates/node/build/client/_app/immutable/chunks/Download.CpfEFmFf.js.map,sha256=PMLaPYu6L5n2sK4iafzQZmd46PiyR4q0cfzSFBiWafU,560 +gradio/templates/node/build/client/_app/immutable/chunks/DownloadLink.B2NLb5On.js,sha256=VLWRVk3O0epDyCecoTfDC6NBAUxfbEX5uhXosDNvK3s,1888 +gradio/templates/node/build/client/_app/immutable/chunks/DownloadLink.B2NLb5On.js.br,sha256=HMrz4JCmnMpHnRxclxA4TOYyZPIpo0MnIXhfK6ysCz8,943 +gradio/templates/node/build/client/_app/immutable/chunks/DownloadLink.B2NLb5On.js.gz,sha256=-xq7aeA1fG9HjhnL4WjJx2uZhoigGPqhC12dVFmwcSk,1050 +gradio/templates/node/build/client/_app/immutable/chunks/DownloadLink.B2NLb5On.js.map,sha256=ENB4DLMBBYrXMCRlFHcf1_ZiGsgWQGJdMncJW_UaLFs,1473 +gradio/templates/node/build/client/_app/immutable/chunks/Dropdown.A6prMBVI.js,sha256=3cr_F_ntMc-qCNjd5cyMqWnikvqrBLP3iHf3qTl3MHo,12045 +gradio/templates/node/build/client/_app/immutable/chunks/Dropdown.A6prMBVI.js.br,sha256=j4NS1wAyLNKkjy8Yxqcyj8m1DfqMfQrA_y4XWYdZX4I,4335 +gradio/templates/node/build/client/_app/immutable/chunks/Dropdown.A6prMBVI.js.gz,sha256=_gEMDfPMkZlLcKktWCYnSiveTKXfMXWI_UwBrKLU_6E,4924 +gradio/templates/node/build/client/_app/immutable/chunks/Dropdown.A6prMBVI.js.map,sha256=k1irZxYNwPOzHOM-2T5s4opVeBLVUKhp1uKCNeYU2RQ,24558 +gradio/templates/node/build/client/_app/immutable/chunks/DropdownArrow.Bx7xoQkz.js,sha256=W1uWOXPj-xbZBP3zQrZHDt9bj8HW-KGxlPRaMmOkN_k,860 +gradio/templates/node/build/client/_app/immutable/chunks/DropdownArrow.Bx7xoQkz.js.br,sha256=TMw7YHo17E1LttyW9GnB_aEzR8hjdV1PFhArDMqTDx0,466 +gradio/templates/node/build/client/_app/immutable/chunks/DropdownArrow.Bx7xoQkz.js.gz,sha256=enTIm6HKWp4Fdz7ymxP2YSJ_3tU-e41VrXQKGNc8doA,534 +gradio/templates/node/build/client/_app/immutable/chunks/DropdownArrow.Bx7xoQkz.js.map,sha256=Ad7Vtb4du3rS0h3V_Tqigz0OYcB2red_buE9F_8yLNY,607 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_lights_ies.TfXTlsqD.js,sha256=YQf1gW_JOF41AJucPzSWOIUCpMXBWuiRpR7rkFPwFAg,1704 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_lights_ies.TfXTlsqD.js.br,sha256=H_l3JE53BT0_bRdZfgtvNqGMqOw1MrgEvs1xHXyRxs4,779 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_lights_ies.TfXTlsqD.js.gz,sha256=0vInv2Hp1h7xPo9w19PrxZ23maLUuo2fOQPCOefPKck,861 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_lights_ies.TfXTlsqD.js.map,sha256=Z_Ve15GmuA9qdc_NqasEOw_7H2pGTH4-d0wW3vpVL4Q,6249 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_lights_image_based.CTLLHlq2.js,sha256=LLBHD5lkSbr0u5JtuzlOakS5BAJZ320WRJmLTvuuuFk,2978 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_lights_image_based.CTLLHlq2.js.br,sha256=IVu8gPoFqnTyp5UfRnJ-yPUv8riJyriKB9FJQLp-qTE,1192 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_lights_image_based.CTLLHlq2.js.gz,sha256=uwu69H3SIrmY1ig7LqJd2JAM35ELIZHEu1CVUwlOz48,1311 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_lights_image_based.CTLLHlq2.js.map,sha256=Qd6cOGdx98GBIIvHzb2rfPIzUCP5n6enFD7K0BJfCuw,13410 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_mesh_gpu_instancing.ItkCO5J3.js,sha256=QdnFJAE3m8P75alZErMpW_D3gdsqYf1v_QWNQepBxAI,1675 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_mesh_gpu_instancing.ItkCO5J3.js.br,sha256=KdkGW2yhJ1zC50XJUTwtDk7x4bQuKCGQ58tWRi5LV7w,779 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_mesh_gpu_instancing.ItkCO5J3.js.gz,sha256=5TPTg4AQZXEcMyZ24wQpXc3aOItPGqbPUgKAiwbRJb4,861 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_mesh_gpu_instancing.ItkCO5J3.js.map,sha256=MFhtqEE67qeANMzxMmqrq-M6cRhJFplAxS6gbEtGKD0,6570 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_meshopt_compression.CtpJ6PMj.js,sha256=8LN3o1_gbw8VLOo11AP2lB9Im-Db6SIaOPkUa9D_t7k,1438 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_meshopt_compression.CtpJ6PMj.js.br,sha256=oon4QM_OZEHPEPfnjr4L8jpwH2VwznbZgRP-J8T_9l8,637 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_meshopt_compression.CtpJ6PMj.js.gz,sha256=HwSw0FEpm32qhKD4Ko9Ho-WZEpT9nuv4RocYhpl0BPg,720 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_meshopt_compression.CtpJ6PMj.js.map,sha256=kvXuIXyMJVrGFr3b_EsYWfpN_XlnyxF-v5TCMfhXIps,7584 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_texture_avif.D7otWbwU.js,sha256=cZNlhaImP3j50EFYS4MRF6jfT42_gFDoBIj5BO2qDDE,695 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_texture_avif.D7otWbwU.js.br,sha256=1REQCWwHcTp6Ft5nT-c3gfb_dbpFydfvZLNnZ46Z5Wk,372 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_texture_avif.D7otWbwU.js.gz,sha256=AGInnpu214jdrktTKRPUF_uRk9FoHTgOp2rT6BlI9kI,423 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_texture_avif.D7otWbwU.js.map,sha256=opmJnRiu5UGTIiLF_2S5fQB5xXvUBVb0cVhaMKUSwUk,2815 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_texture_webp.D7AS9p0M.js,sha256=2DZnHPLB_u9dQx3mpqW9x8bpOTEfYSn6FOz5dQU1j2s,695 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_texture_webp.D7AS9p0M.js.br,sha256=IfQ_1TdDsrmFRKYyi2dy83CjYGtl96AMhhhKO8kCe8g,375 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_texture_webp.D7AS9p0M.js.gz,sha256=qFtjCXXqKiiZWshR3lC5uEVqiWuJQRm22-Mob4QExr8,424 +gradio/templates/node/build/client/_app/immutable/chunks/EXT_texture_webp.D7AS9p0M.js.map,sha256=ftmqCffWmVa33Cg1E3vCe3_pnNPKssixeHHxL1bc_yc,2753 +gradio/templates/node/build/client/_app/immutable/chunks/Edit.jvyxqbov.js,sha256=Z7eZZQyoKAn0g97xke2I4XR4u2ABevouYNHEndXnahg,1075 +gradio/templates/node/build/client/_app/immutable/chunks/Edit.jvyxqbov.js.br,sha256=renldYQehwdF_h-MwDPrdQdKo14ScdApr3jsdIsKjvY,543 +gradio/templates/node/build/client/_app/immutable/chunks/Edit.jvyxqbov.js.gz,sha256=SvIPv3UivzMA6jGAPnvmLtDe2YXDRz8uFhQk_WCw8tw,609 +gradio/templates/node/build/client/_app/immutable/chunks/Edit.jvyxqbov.js.map,sha256=5uRObTfqm7MEmy_uxnrlVz2kNTcXvkPWZWJltsyPh6w,619 +gradio/templates/node/build/client/_app/immutable/chunks/Empty.B4hNSxwn.js,sha256=IAXch2VrDgO2znXFk4G2wgzQak_PkDn6WHY-SdjbxAI,1907 +gradio/templates/node/build/client/_app/immutable/chunks/Empty.B4hNSxwn.js.br,sha256=ACaXSF0CxlcJWfcztazZhR7CIUCDnbKUfyJF03eLy4o,911 +gradio/templates/node/build/client/_app/immutable/chunks/Empty.B4hNSxwn.js.gz,sha256=LxQysWzdC0TNWOkX3OIEVJSE2rGZxo8HiLqf01zRI0M,1006 +gradio/templates/node/build/client/_app/immutable/chunks/Empty.B4hNSxwn.js.map,sha256=jAHdo6xccNi7uZlNmy3DanWFOVMNg7xfFBxPBPDmoN0,2198 +gradio/templates/node/build/client/_app/immutable/chunks/Example.7rhdKtvr.js,sha256=kXBvlR-AyF2GIVjM0U17fVPS-zWXuEWgNKqX7zky3mM,1155 +gradio/templates/node/build/client/_app/immutable/chunks/Example.7rhdKtvr.js.br,sha256=NU3rWDfbsiv0dHj99Ye0afQQukprPMnoALWpas69uNY,589 +gradio/templates/node/build/client/_app/immutable/chunks/Example.7rhdKtvr.js.gz,sha256=ysTxZQUaGBKSIxcfApbXMhET9jUg4YohB044b6ZphFI,656 +gradio/templates/node/build/client/_app/immutable/chunks/Example.7rhdKtvr.js.map,sha256=xq9vDA9_kxqhAUTmGQldPEpBwnatFtZxYM1DDBUAYQU,1056 +gradio/templates/node/build/client/_app/immutable/chunks/Example.AaUiXLZ_.js,sha256=BmkRofLC38ILf9lk9Yqx4ZYOVDqFtDUAG-5vpIFVTmE,1287 +gradio/templates/node/build/client/_app/immutable/chunks/Example.AaUiXLZ_.js.br,sha256=TU-Wn32Xcbnw1odnaZuecHnX7oMap_XGzBgz7z56FHo,647 +gradio/templates/node/build/client/_app/immutable/chunks/Example.AaUiXLZ_.js.gz,sha256=PCp9GkYOrs7l9o3xonQyAjaAaOZiSPJ3DNxjRp0ENgI,723 +gradio/templates/node/build/client/_app/immutable/chunks/Example.AaUiXLZ_.js.map,sha256=CmSzuMzmm0M88BeBJLlodlZGdt5B2bp-K9jHXIyCWTk,1604 +gradio/templates/node/build/client/_app/immutable/chunks/Example.B-yMNQmV.js,sha256=wkXvjkEG4XftDAW_Vva43DXFa8It4Kh5sb_-pGHj_pQ,1094 +gradio/templates/node/build/client/_app/immutable/chunks/Example.B-yMNQmV.js.br,sha256=5kpf991My1IVxDS4dQPfJsGbFmkMjxu5rnA4k8DuSac,558 +gradio/templates/node/build/client/_app/immutable/chunks/Example.B-yMNQmV.js.gz,sha256=kyWWBIfTAjgRNVZQuq_W7wZKLyktGvHw4WlIxVA_fgc,622 +gradio/templates/node/build/client/_app/immutable/chunks/Example.B-yMNQmV.js.map,sha256=fwNR4v4KCcKlFtZ-hw7NH1awE3wRTUagw7kXob_Hy2I,695 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BBdSzwmg.js,sha256=tFXNBocDAAusk8zxIcslU8w2s5Svp1j8PPhqKVqjLrg,1068 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BBdSzwmg.js.br,sha256=JceWl5eXEouGSadgI_KODEo-DC9iIYjT-t5CYpOp8nU,558 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BBdSzwmg.js.gz,sha256=__vuzxrDw_JYXji4Gh0a7uUz6aucZGQa83j-n1On4Mk,622 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BBdSzwmg.js.map,sha256=slMAQEkEDeyUGlCCsBT8VGkDJY7F0RIKGnDYDOrNiFo,900 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BDZv3quJ.js,sha256=q16pKwIPh1uO0_CgXUBEaIXuLfe5OAjAE1CSvpvIxw0,1882 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BDZv3quJ.js.br,sha256=8G08oaNSBw0MBOhmjekfz9DumvmuaQNMs5MM11J9LlI,876 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BDZv3quJ.js.gz,sha256=ol7ckCePyYEmNS2VXeqd-MSj5K-JqPrq7XGEHEvmRbM,985 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BDZv3quJ.js.map,sha256=rehAkSagtuW3SOE_5h_RZL8_rdCog3mw0S3ZZoufIVs,2062 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BHb8pvZm.js,sha256=0GqzMG-9XMtAsA0-8T9Lj1Nbwwsp7Z17hc-wQoL2WAM,4464 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BHb8pvZm.js.br,sha256=RDHXJOw2wHZd8fCUdhOpI1TEMQEz9IvsXFVX75lmafY,1467 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BHb8pvZm.js.gz,sha256=Nlr4hXLJqzPOKlPxOga1l9Y1DUHfbkF7D_-kiMi5kLw,1669 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BHb8pvZm.js.map,sha256=_6chdxWShBMV3zwPoG4DjnUQUR6oGo57Um957kUh9TI,5412 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BioRcyBn.js,sha256=98hQJxgI9afVTBh4HeTGetctE37GTKzp8rKTY5q_aqM,1107 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BioRcyBn.js.br,sha256=7NcPHdTOae_SKF4Au55xEhGSX9rrZNM9CSKVgPPfAt4,565 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BioRcyBn.js.gz,sha256=BnNh2-y8c7JfSw5qaerRxXknT_tIQTmrqAfEEha4BjI,637 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BioRcyBn.js.map,sha256=BUI04VLYlnMKw_bDI5A98Ah2h7BNrkcE4F9WsDW9HZc,999 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BtYdbMfl.js,sha256=e_VnURTL0z8_ns7Fyz_DT-84WiidFNYs5Lr9Vz6zL8Q,1065 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BtYdbMfl.js.br,sha256=Xnn3tPU3bPWirTqo3Fih9yIJC79-HRGX6HoR2JREntY,530 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BtYdbMfl.js.gz,sha256=_qo1HBzdrIeXHx4gZmVT7UivXEx6dtiKsv_ren9uF1I,603 +gradio/templates/node/build/client/_app/immutable/chunks/Example.BtYdbMfl.js.map,sha256=Kytr0Sp5NH_mf_R7C2eHw14bLIl55aIeow7-3Ig1-HA,1030 +gradio/templates/node/build/client/_app/immutable/chunks/Example.C3O8QWdg.js,sha256=8xgFxZhpaNdnhd9ReAItXq1F6bAlhLA20mu1edreYjY,1575 +gradio/templates/node/build/client/_app/immutable/chunks/Example.C3O8QWdg.js.br,sha256=hmYbCpu25srLQEYCymXGJXgnBC6Jo6qxnFu4TjvadBs,702 +gradio/templates/node/build/client/_app/immutable/chunks/Example.C3O8QWdg.js.gz,sha256=l63LdeHLj_nl0ZE_-3oCzO9RyVpz5t6HmzuWCzRkaA0,791 +gradio/templates/node/build/client/_app/immutable/chunks/Example.C3O8QWdg.js.map,sha256=TslbCzftaudJ022DbYW-wX1rFB-CF_6Jd9x1MHeIagI,2452 +gradio/templates/node/build/client/_app/immutable/chunks/Example.C4Pa_8-p.js,sha256=tjm_vZRuGr5a8CITSSdOHhZskHI6NZC4B4ubvxYhMwk,1244 +gradio/templates/node/build/client/_app/immutable/chunks/Example.C4Pa_8-p.js.br,sha256=RAQ-XKoNLZeC8xWZEYeWrVI7zVL2pgJJJ-oYqnFSrlk,632 +gradio/templates/node/build/client/_app/immutable/chunks/Example.C4Pa_8-p.js.gz,sha256=v_xZ3XtvEkD-lXhfEQoviwsFQacCoF6Ot12XdAqwMpg,700 +gradio/templates/node/build/client/_app/immutable/chunks/Example.C4Pa_8-p.js.map,sha256=Xo-di5lWN-jiH1fMM5NhFWLOV1ugXnnxm04wn6vQ198,1469 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CO-COJlt.js,sha256=xdo9L7hdRWq0Xx7SzPDVZvdN4fvRTGLS6PVbcqxjS6g,1201 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CO-COJlt.js.br,sha256=Refga4oBVDauPZyPjqo9DhqIUQJh2nILGEI6KKa0iLQ,608 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CO-COJlt.js.gz,sha256=tE777L-6z4KEpd12rcSsZ3J3Zo9uDmeOWH7cz64gHQw,688 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CO-COJlt.js.map,sha256=WZhtcqUGgq0bOQC-ITP4o0jv_vgNNuqeBEZeGJGr42Y,1467 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CZOpiQG0.js,sha256=IG5C_Fo1ZBq882M5pD7fRLuVYYHZ0uu6VLj3DpdH1ic,1236 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CZOpiQG0.js.br,sha256=JvC1SibZItQPn0v5nI3FftdGQH-O9oWhX02cIw8LZGQ,606 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CZOpiQG0.js.gz,sha256=zC1lLSCw7QxipbCo2TVMBYv-Lc43oIWaZ2pljjOoNK0,682 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CZOpiQG0.js.map,sha256=aP2HRyhxGRJW-EBwYhpgL7lQ4AxYdF5_SpYg8z8SwHM,1409 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CkanuOg6.js,sha256=eqaJZ5sN45OsSqK7gi4FzuSu4-LF1X8XO1643D_W2qU,2980 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CkanuOg6.js.br,sha256=PGUfmIWeTEHUgLf3ICClCHwAo77VobsdbGleiDZCl4k,1292 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CkanuOg6.js.gz,sha256=XRWRrpM-TafxmmaBmxkSKOGf2QheP7f6u-YdRb7eBRQ,1461 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CkanuOg6.js.map,sha256=Zp0wIwOnKrd3pfzSWYRKjwNeJJDIXTBeReqZTlrAmME,3210 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CoiXaiz9.js,sha256=tGe_qgtYN-HZb2HbPE2XziyhzTQMjJC2sRuUV27vq2w,1595 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CoiXaiz9.js.br,sha256=bfqm_wsvVXD3qn3escnCu0rfKumqpnf_IZGFO_l38Ag,823 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CoiXaiz9.js.gz,sha256=TOuciSvUM4bGM2RmNcVbcdoXtiHLv07h2EGXzwGltk0,936 +gradio/templates/node/build/client/_app/immutable/chunks/Example.CoiXaiz9.js.map,sha256=uKZCDWvVQKcyDbwgBB0lik5tAilF0n_ZgInflizLDCo,2213 +gradio/templates/node/build/client/_app/immutable/chunks/Example.D0SjheNh.js,sha256=FG79XTlHWEYpjNbmTzMa6RNdo-8-LihVXkDhogZ6G6k,1093 +gradio/templates/node/build/client/_app/immutable/chunks/Example.D0SjheNh.js.br,sha256=JpcnlFarySCdsQKaYcntUTWDbcxDCdBhvLU1w7Qx0Tc,558 +gradio/templates/node/build/client/_app/immutable/chunks/Example.D0SjheNh.js.gz,sha256=wO1FCLOhmpsP2RFi6-49jCiKCxGAB_nXq0xmyLMHdG0,624 +gradio/templates/node/build/client/_app/immutable/chunks/Example.D0SjheNh.js.map,sha256=OIDuP5qn-UNdc2HgYGhJ4AsCc9saIJo7429Nb8nbCeE,924 +gradio/templates/node/build/client/_app/immutable/chunks/Example.D3rBtlTs.js,sha256=TSL3ubCRG5YVjoLKyFYgLvLXnEiJz5DoEfNhJGvD6HA,1600 +gradio/templates/node/build/client/_app/immutable/chunks/Example.D3rBtlTs.js.br,sha256=lBszAJYnXpaOG7Rh_5b0cYAh7OC1vUp5EE3dgmCdNRg,735 +gradio/templates/node/build/client/_app/immutable/chunks/Example.D3rBtlTs.js.gz,sha256=UvkOBH3Cnuhy3fTGDSXQRn0-VXWgK4gJPYCOrdDKIDw,838 +gradio/templates/node/build/client/_app/immutable/chunks/Example.D3rBtlTs.js.map,sha256=q2O5knNYBafTWcqvE35CDeL2Ih22OoN30NlPtIOzVxo,1738 +gradio/templates/node/build/client/_app/immutable/chunks/Example.DIn8XSl7.js,sha256=b7vlDFFGN2igG06q0IfETd5h2FtibKEXX35OGUvgPzo,1744 +gradio/templates/node/build/client/_app/immutable/chunks/Example.DIn8XSl7.js.br,sha256=HerbWDkvSrHS-Hlyn93GEALAIETP3e0TPDZufzv8ip8,795 +gradio/templates/node/build/client/_app/immutable/chunks/Example.DIn8XSl7.js.gz,sha256=M1S40XrtK5QRMfFsWfNQroQqvngUR1Q7tcC4E0YYWHU,898 +gradio/templates/node/build/client/_app/immutable/chunks/Example.DIn8XSl7.js.map,sha256=kGozQw42luNfWomqjSNtkqiV6TszvDMndg0HctI4owg,1740 +gradio/templates/node/build/client/_app/immutable/chunks/Example.DSf4H_Iq.js,sha256=Q7FkqC7atH8mmpCghp2TYPQfybr9g6nIvs6QSUU_NQM,4546 +gradio/templates/node/build/client/_app/immutable/chunks/Example.DSf4H_Iq.js.br,sha256=AXm8xJr4zXBgjRUaqYhTWqGutk13614pe3_FjmGtA-A,1502 +gradio/templates/node/build/client/_app/immutable/chunks/Example.DSf4H_Iq.js.gz,sha256=jJX9fUeFXLWhps1rsclQzO-VqIa5SZqr4f6p0zN17FQ,1727 +gradio/templates/node/build/client/_app/immutable/chunks/Example.DSf4H_Iq.js.map,sha256=-X0HLhQJ1qyQ07lQ3DZzs-RCFpCkddmLqT1g4KCMpmA,4638 +gradio/templates/node/build/client/_app/immutable/chunks/Example.DbEDtHpU.js,sha256=2CUYWO1vDFooG1NOSb1ytzYiYYi3p5nFaMVPF0i4mNk,2580 +gradio/templates/node/build/client/_app/immutable/chunks/Example.DbEDtHpU.js.br,sha256=LnmIgChKWimXnBKF3amQ416K_CHhsNv6f0VxKLUQXkQ,1119 +gradio/templates/node/build/client/_app/immutable/chunks/Example.DbEDtHpU.js.gz,sha256=kDrtvoHWf1yGKmuMCXZdTktoJ6ePr-qpocx3m87egHg,1245 +gradio/templates/node/build/client/_app/immutable/chunks/Example.DbEDtHpU.js.map,sha256=qVJcVvYIqzgS4EfkN7JOrUAsurD1cSlHyAsEV-J0uYU,1964 +gradio/templates/node/build/client/_app/immutable/chunks/Example.Dl9poLS6.js,sha256=lAKeV1raO7wrsB82hrTFHVy25hGJf1Qf2_qYeEIsOSI,1191 +gradio/templates/node/build/client/_app/immutable/chunks/Example.Dl9poLS6.js.br,sha256=5cPAAoWApOBZKdGnwBRqNEtkR773MmhEtX-wkTp10bs,641 +gradio/templates/node/build/client/_app/immutable/chunks/Example.Dl9poLS6.js.gz,sha256=5KduglDDZrdBZ2MnrrBfiKd97_zFf4pGy_3SLts2RWE,685 +gradio/templates/node/build/client/_app/immutable/chunks/Example.Dl9poLS6.js.map,sha256=GgIyMyHm7TbxDLgm2sThZQ43SRzntEXORcW5ZooS49w,1356 +gradio/templates/node/build/client/_app/immutable/chunks/Example.Du75eb0D.js,sha256=5e5zBgCJ-6hWMWzfccuOLo0fbIEBmsW7s4dyJYvY2Ms,1121 +gradio/templates/node/build/client/_app/immutable/chunks/Example.Du75eb0D.js.br,sha256=zWs6xHEoaKswbHjxP8MjfYyOAwcIjSDFRg1EyEcTwT4,575 +gradio/templates/node/build/client/_app/immutable/chunks/Example.Du75eb0D.js.gz,sha256=iynwA2v4klweh_jMuvmgghjOoK0IDeS1uB40fJ8hbQY,644 +gradio/templates/node/build/client/_app/immutable/chunks/Example.Du75eb0D.js.map,sha256=Qr9SmLrUbAbEq6rxME3hyBwBibUgcvObfH73RugueUk,1034 +gradio/templates/node/build/client/_app/immutable/chunks/Example.FcPgDijm.js,sha256=W_zTX2aqYnvTpE0PkSc2NiRIuoEigd_X51oEHchgQgA,1069 +gradio/templates/node/build/client/_app/immutable/chunks/Example.FcPgDijm.js.br,sha256=EXsXMJ8ldKe2CoHwUnXH8Ql244ycnCkL14_MBoUaAyM,548 +gradio/templates/node/build/client/_app/immutable/chunks/Example.FcPgDijm.js.gz,sha256=VyAWn263iYkKnrEu2xPAPpf20JOAVqMxiqYR3Bt_T9o,613 +gradio/templates/node/build/client/_app/immutable/chunks/Example.FcPgDijm.js.map,sha256=_pLMCl5gRX-IigidCCh4IrmgI2xBZA-tpz5Q_NQqJZ4,910 +gradio/templates/node/build/client/_app/immutable/chunks/Example.If9xUByI.js,sha256=CAu7xYMSiuPTqWi321P6jLoY5UN3RK82BRXoS6ony9k,4265 +gradio/templates/node/build/client/_app/immutable/chunks/Example.If9xUByI.js.br,sha256=DNFkl-xIrDlN8YTwr_MY0mmqWpargVM8VXSn0rHIwTY,1709 +gradio/templates/node/build/client/_app/immutable/chunks/Example.If9xUByI.js.gz,sha256=xxWOnRnaLZ7V406VAGzAxdxTYy9bY173iDzqYcOkK8c,1930 +gradio/templates/node/build/client/_app/immutable/chunks/Example.If9xUByI.js.map,sha256=YmXhSz8zwZV2-ZlKLmYW569HAcAUbtIFYfL6G-SMUro,4313 +gradio/templates/node/build/client/_app/immutable/chunks/Example.PQjTM3-g.js,sha256=6i-rMvcev_MR3a4Wsy86-wvF84J1nRxsIEcxM74tu-c,1069 +gradio/templates/node/build/client/_app/immutable/chunks/Example.PQjTM3-g.js.br,sha256=bnHERiyn5UQxlPiizfWWvGbEkK5Ip8BCQWJ7ntt_2Jo,548 +gradio/templates/node/build/client/_app/immutable/chunks/Example.PQjTM3-g.js.gz,sha256=mFf6k4-PUJtyqqTO-gNttww4wRfR0a65mDuoDkyDwR0,615 +gradio/templates/node/build/client/_app/immutable/chunks/Example.PQjTM3-g.js.map,sha256=_-kGi6NoxvLY9EzncO3gt1aJkybd2quiuNueNGc4KQA,908 +gradio/templates/node/build/client/_app/immutable/chunks/Example.V12cx6oG.js,sha256=tclu01-TuiT9Dcw6k6eHTxmQ9GDwagN8lp4TdcWYOKk,1107 +gradio/templates/node/build/client/_app/immutable/chunks/Example.V12cx6oG.js.br,sha256=zbzUo8v28v70lZz9oP7seIC34v39cJmhOaJHPnnPXnA,568 +gradio/templates/node/build/client/_app/immutable/chunks/Example.V12cx6oG.js.gz,sha256=8qenicGz4U5A0iQBlxle4BjRIv6znBWw2ASRtSav-rc,638 +gradio/templates/node/build/client/_app/immutable/chunks/Example.V12cx6oG.js.map,sha256=wlyc55wQjRpetSAzjuqnLgb8sYTLzk-p5Bw41ni1tZI,997 +gradio/templates/node/build/client/_app/immutable/chunks/Example.cAwV0exA.js,sha256=mmlNbTqUccUzojfdFyxXBFQb1iDa4JbhaSlrAIZmdT4,1896 +gradio/templates/node/build/client/_app/immutable/chunks/Example.cAwV0exA.js.br,sha256=xaiystbWJb0crC4hk8UTTY7-ks9FJyHuCfcMmZS-66o,852 +gradio/templates/node/build/client/_app/immutable/chunks/Example.cAwV0exA.js.gz,sha256=gX3AADNeg9UwAQ7-yzVbWJXvRjQNy-ZZxFLKLhM-QmM,952 +gradio/templates/node/build/client/_app/immutable/chunks/Example.cAwV0exA.js.map,sha256=mzVNTJtdiytoz4aDpWpvSjtmYv9mgtBb2BfVxQBqBRU,1919 +gradio/templates/node/build/client/_app/immutable/chunks/Example.cOvhHY2p.js,sha256=qlqCvcme7mksVLtMUCdUb_M7bZwKNLldo8avF_6zGo4,1069 +gradio/templates/node/build/client/_app/immutable/chunks/Example.cOvhHY2p.js.br,sha256=8ecEarN9NAYxFX9odRY_liTxAxsmt73iFHEKPvMfwf8,550 +gradio/templates/node/build/client/_app/immutable/chunks/Example.cOvhHY2p.js.gz,sha256=9DSBb_czXY7ms-Fs9NOyrXBa9I2tzRA9SpMW1DTJ_Ag,613 +gradio/templates/node/build/client/_app/immutable/chunks/Example.cOvhHY2p.js.map,sha256=hrrRKvc_yiAcUvfDhesabTuvAIK-jE7JZexdTBly8b0,910 +gradio/templates/node/build/client/_app/immutable/chunks/Example.p5DpXI6u.js,sha256=0C2dNdwlEiI94QYBPbehNqPETOTyi-Akx4TEBo_hrVk,594 +gradio/templates/node/build/client/_app/immutable/chunks/Example.p5DpXI6u.js.br,sha256=WVDB-_IExUu7fCbOsZaRrhujvLt7i_u2Nimt6V2dcRI,357 +gradio/templates/node/build/client/_app/immutable/chunks/Example.p5DpXI6u.js.gz,sha256=siFt6X2jczywN09SOT_prBds-zR69EO73ZK6cTPEEyY,405 +gradio/templates/node/build/client/_app/immutable/chunks/Example.p5DpXI6u.js.map,sha256=Z5lUC4uOeDrW08Bq_XJ4MOymS-aafPl_3mD24nJloAU,415 +gradio/templates/node/build/client/_app/immutable/chunks/Example.qq1Un4eO.js,sha256=W81dtYEAWd7BYCqWGqPUeAuvgYZo_kXW4Nczb3989Ts,1193 +gradio/templates/node/build/client/_app/immutable/chunks/Example.qq1Un4eO.js.br,sha256=aHkkzqLuby_RFUND8SJZkLD6TLE3R-2H3jzZWPJ_SRo,622 +gradio/templates/node/build/client/_app/immutable/chunks/Example.qq1Un4eO.js.gz,sha256=Af842LDI-lGjapzjwLYsH-_jTR7quOFhOOy-hY-dklw,679 +gradio/templates/node/build/client/_app/immutable/chunks/Example.qq1Un4eO.js.map,sha256=14GzzlgcnTgg7snx-xSdN5P0P4glthBdzdkoxfASp44,1114 +gradio/templates/node/build/client/_app/immutable/chunks/ExtrasAsMetadata.Dux_ho8M.js,sha256=m0c6i4LPjYKWCGBwrjvlXyIHq8m_Zsq1oIhbX6aXSo8,708 +gradio/templates/node/build/client/_app/immutable/chunks/ExtrasAsMetadata.Dux_ho8M.js.br,sha256=jsuApiJWOhNI_8GlgUjyXTazyVBht6E1z5WOvnRQOcU,335 +gradio/templates/node/build/client/_app/immutable/chunks/ExtrasAsMetadata.Dux_ho8M.js.gz,sha256=0H-hFHQlpwV4do4nsXmyhPc41zZMOs4anKhTDREEORg,369 +gradio/templates/node/build/client/_app/immutable/chunks/ExtrasAsMetadata.Dux_ho8M.js.map,sha256=L66L91837zTOf0Nj93df72KX9hRky3W5cWZHbvP82so,3365 +gradio/templates/node/build/client/_app/immutable/chunks/File.Dl9hvYLG.js,sha256=M7tu8OcjfAdnbJSaL8xwMlgB2Uip8bxYNv-qNJOrk7c,1178 +gradio/templates/node/build/client/_app/immutable/chunks/File.Dl9hvYLG.js.br,sha256=PfGqFX3VWKsdT1D5622PUztEgcEGNZQv0oOXezKgUxY,583 +gradio/templates/node/build/client/_app/immutable/chunks/File.Dl9hvYLG.js.gz,sha256=Z7GtaOd2plY-fofnxouutjw5iPT06hM2DGDNWM0eXFk,642 +gradio/templates/node/build/client/_app/immutable/chunks/File.Dl9hvYLG.js.map,sha256=uW0bViYzEfuE2LuVv-UxG2DkVa3gV6SuS7pCnUgqJm0,698 +gradio/templates/node/build/client/_app/immutable/chunks/FileUpload.wb9qzOzt.js,sha256=H6dFAtS-qj3TvC1q8qT5r4EmkPIECRkeLEQMeaItsiY,17588 +gradio/templates/node/build/client/_app/immutable/chunks/FileUpload.wb9qzOzt.js.br,sha256=ncfuqISwpMfwRBsXI_f4qFnHivIOoM-IV8pGN3aIrms,5318 +gradio/templates/node/build/client/_app/immutable/chunks/FileUpload.wb9qzOzt.js.gz,sha256=SBgV_5_sj208z6lIEsiJzrT4tvRhfmsZ7JmVYv02vIY,6101 +gradio/templates/node/build/client/_app/immutable/chunks/FileUpload.wb9qzOzt.js.map,sha256=-Xq1k37gCh21cC9pTs7oBhl9681Dwec2Hbl6n_6p6rg,21399 +gradio/templates/node/build/client/_app/immutable/chunks/FullscreenButton.DV2zoYeE.js,sha256=u0XtpiO07QweYYlmDbCbdHaem5A7NudDzsVAmJx_dnc,2538 +gradio/templates/node/build/client/_app/immutable/chunks/FullscreenButton.DV2zoYeE.js.br,sha256=LZycftKPg2ci_hPmiKiQGG4IQ3HhHSyNiATumTCdq4Q,1071 +gradio/templates/node/build/client/_app/immutable/chunks/FullscreenButton.DV2zoYeE.js.gz,sha256=an-Zcg2fvrfsYERhpmqs0P56t47cjLgH926KrDU9bhg,1171 +gradio/templates/node/build/client/_app/immutable/chunks/FullscreenButton.DV2zoYeE.js.map,sha256=-giqOsNLr7i49XXs0k1qWCCYjXPRuzDlbZbTSHVB8DU,1559 +gradio/templates/node/build/client/_app/immutable/chunks/Gallery.L-TGqxFr.js,sha256=UrDs9oSk7lfZiTTdPiqChBu-IGxSPNUoQiNVz6ZSSzg,23879 +gradio/templates/node/build/client/_app/immutable/chunks/Gallery.L-TGqxFr.js.br,sha256=ovLop2TN01iHBTLwc7pWVurUsEB49ewyACBpweMmWow,6984 +gradio/templates/node/build/client/_app/immutable/chunks/Gallery.L-TGqxFr.js.gz,sha256=rOrM03x-k61q32D-tpqIUcGvdZ-Ch615y5rbwoLBAlY,8089 +gradio/templates/node/build/client/_app/immutable/chunks/Gallery.L-TGqxFr.js.map,sha256=JFEoQhw43reYrK7CUvMrFsSs7-OAiwbiAzGMTA1V3Ag,35215 +gradio/templates/node/build/client/_app/immutable/chunks/Image.CTVzPhL7.js,sha256=5slF0WoSsFNaSbkGVx65Lbmfi_pXvIEWXXHmSXx3W4k,1358 +gradio/templates/node/build/client/_app/immutable/chunks/Image.CTVzPhL7.js.br,sha256=Lp6Pnx8oAnnC6rxACenCf8sEKGlIS8nL3rqqIywHx1M,621 +gradio/templates/node/build/client/_app/immutable/chunks/Image.CTVzPhL7.js.gz,sha256=wuyiq_5SaoRjZJKblT_tkuuhmtwL_RmsDQpUmy97k8s,694 +gradio/templates/node/build/client/_app/immutable/chunks/Image.CTVzPhL7.js.map,sha256=WwjzezWcqpKFrNtE6RZ6OI2c29gHoPHG-TXuAMGfByU,779 +gradio/templates/node/build/client/_app/immutable/chunks/ImagePaste.QeBpp0hK.js,sha256=YjrcUNBVaS0qWnyDwiukbohaaUIoyEEDmigcU0O5ufI,1081 +gradio/templates/node/build/client/_app/immutable/chunks/ImagePaste.QeBpp0hK.js.br,sha256=oG0rU2k0Edh-5IO96QuJQMrc8M9faRVBsOAAd469MwY,584 +gradio/templates/node/build/client/_app/immutable/chunks/ImagePaste.QeBpp0hK.js.gz,sha256=fdo63qTDZ4ETwDiTTP-na_Hr1EjNp6WAoafQf4Nl288,637 +gradio/templates/node/build/client/_app/immutable/chunks/ImagePaste.QeBpp0hK.js.map,sha256=sDIwyLqQoUg8yQR2oEz1Z1hE6enqf8NEBT-Jm5BH6xY,726 +gradio/templates/node/build/client/_app/immutable/chunks/ImagePreview.L1-jTqqD.js,sha256=R8Tt8SRBXm1qjaGMrCtRXSv0qPzIGNZzF2s86MMsfPo,6730 +gradio/templates/node/build/client/_app/immutable/chunks/ImagePreview.L1-jTqqD.js.br,sha256=twOeH6t0IVq5ns-kOI6P_P9-eFB4SLGBrEazEYB8qho,2213 +gradio/templates/node/build/client/_app/immutable/chunks/ImagePreview.L1-jTqqD.js.gz,sha256=jWDvjEG3rj0jWIAO7Twl57KVJKq8_GR6H5cxaAaD9Bg,2499 +gradio/templates/node/build/client/_app/immutable/chunks/ImagePreview.L1-jTqqD.js.map,sha256=5hl80v2xLVTMOnxTN5STPQ2uCM6woXagMCowElbkJvE,5764 +gradio/templates/node/build/client/_app/immutable/chunks/ImageUploader.BcyWhk7S.js,sha256=XD-LwO-_hTPne57FSiJDYyDlVMJmXHbt8a-X83Xm-jU,27787 +gradio/templates/node/build/client/_app/immutable/chunks/ImageUploader.BcyWhk7S.js.br,sha256=7ZhxFKZU2j2JVAiMPwAYX8CnPskqDJXCp1sJHE_bApg,8593 +gradio/templates/node/build/client/_app/immutable/chunks/ImageUploader.BcyWhk7S.js.gz,sha256=P6-ou7H_HtU1yn-_oGR-WDXrur1Ru4lx34_wVlA2V9s,9838 +gradio/templates/node/build/client/_app/immutable/chunks/ImageUploader.BcyWhk7S.js.map,sha256=NIsHNG2a8sGzWDXUAG1It-BMdy2aSizCEqeqkc_rSUs,39353 +gradio/templates/node/build/client/_app/immutable/chunks/Index.4UVGk7QM.js,sha256=Mogua0y6PpKvowyXRFOf3JNBVFhGLvwyCNfd3fswiMU,29819 +gradio/templates/node/build/client/_app/immutable/chunks/Index.4UVGk7QM.js.br,sha256=bgHpDVGyVoLllD5yK5JZRy4kHNTDz037OXLam-TJT-Y,8680 +gradio/templates/node/build/client/_app/immutable/chunks/Index.4UVGk7QM.js.gz,sha256=RuEswfneIyYV2pjG3XRFdXHiDbJJ2u_sbQ-MRxhxEME,9998 +gradio/templates/node/build/client/_app/immutable/chunks/Index.4UVGk7QM.js.map,sha256=TmoPnN2nJMQxSVFk3YLlVGcr_2OeHj9h9Yqc6Euxf6U,51231 +gradio/templates/node/build/client/_app/immutable/chunks/Index.AXxdvHJd.js,sha256=3eX_ju6I2eEfGo-WIR-ZtJR64E4okMAAk87G0NwUYn0,4860 +gradio/templates/node/build/client/_app/immutable/chunks/Index.AXxdvHJd.js.br,sha256=_wImPH7SUAmZKKQ5b6b4zeLMf9K6duTQlygvTJkWvvU,1786 +gradio/templates/node/build/client/_app/immutable/chunks/Index.AXxdvHJd.js.gz,sha256=NaPBNrkyfAdQwjUO069O_4nYIJvgytTBR36wvHwYG_s,2010 +gradio/templates/node/build/client/_app/immutable/chunks/Index.AXxdvHJd.js.map,sha256=bGHkSP3iTPS1kKMLC8LXhI-QvjTmyk09TggvMmz4RH0,4901 +gradio/templates/node/build/client/_app/immutable/chunks/Index.B2BSmGPN.js,sha256=xHUuOJNUtL6UYBOmriIXFEqS4Q-RKUbX2x-bLhGzJ4c,15443 +gradio/templates/node/build/client/_app/immutable/chunks/Index.B2BSmGPN.js.br,sha256=AP6_-t6XegVlbEDvH8ODOMxgtMZgMEd6DQxeb-uqlao,5001 +gradio/templates/node/build/client/_app/immutable/chunks/Index.B2BSmGPN.js.gz,sha256=6psRTrADtAWDB5KlQUp5STmPmS1VILOb6xNHt3TScHI,5824 +gradio/templates/node/build/client/_app/immutable/chunks/Index.B2BSmGPN.js.map,sha256=aTXwPFb57AkJnqCm_r9oPjy681PxKERwrhyeaMfhDr0,16857 +gradio/templates/node/build/client/_app/immutable/chunks/Index.B40BA5A6.js,sha256=Tnv6-n6F12ePS9O_-HjZAgDDXJ171lNwIU6Jpphz-7I,7408 +gradio/templates/node/build/client/_app/immutable/chunks/Index.B40BA5A6.js.br,sha256=AW6pEAWuOyzy3YE2KyPhoc28wTtPmL1ubprwQ9z3kaE,2758 +gradio/templates/node/build/client/_app/immutable/chunks/Index.B40BA5A6.js.gz,sha256=v0gkVRRL7PdXSTO-4OD5GP2G_8jTppXkrpDi9IUme_Y,3118 +gradio/templates/node/build/client/_app/immutable/chunks/Index.B40BA5A6.js.map,sha256=-rwbBQXbM8V1mz5MVPw45MttVC__X2V_IQ9znEmfmeI,12167 +gradio/templates/node/build/client/_app/immutable/chunks/Index.B85Go98U.js,sha256=WCA7DkQVq6NS0PU3S0ARB8CghG0TFFek-QztEFhz-Pk,706 +gradio/templates/node/build/client/_app/immutable/chunks/Index.B85Go98U.js.br,sha256=GfCQQteo_RR-ADlx0nGtc7tPNA_9LTgPAaXXaZJZwBs,390 +gradio/templates/node/build/client/_app/immutable/chunks/Index.B85Go98U.js.gz,sha256=iW-onxfkWuYfI8WF9X_-pbIXsoT9OFhcwdjrpx1kgqw,462 +gradio/templates/node/build/client/_app/immutable/chunks/Index.B85Go98U.js.map,sha256=-SeZdxplitk8VXfBKXwZ7E8qFDmmnuHuUIzha11Emjc,1249 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BPiIDnBW.js,sha256=KBRql9AINztUppZmrwfoxbtLtFlimBfTIO7utbR9AvE,5633 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BPiIDnBW.js.br,sha256=e3FrWZltdZRvRRM3Sk_ouZc4QrO46W0HNyv_0l6kV5w,2229 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BPiIDnBW.js.gz,sha256=qUeuLEpRvvnVNJMDrEpHv6zyj4qQ6tdvnDOp9L36oas,2529 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BPiIDnBW.js.map,sha256=nmEAqN1LDPobHDO1gg5akz1c3paBEW6o2v0ApgQjr9k,6738 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BUdP1gsE.js,sha256=pYznH_Rax_P79IUw8Ry1SiOKyozK1r8pnnAfYzAG47c,4402 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BUdP1gsE.js.br,sha256=JuNBitg9_2FLUMQXmRG0A5jTRmVpN6SgzBT6qTCxZkA,1796 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BUdP1gsE.js.gz,sha256=Kd8hVwAYJXZ1et6tIaCJzJBruz9Nx3n__gudfbEB6R4,1999 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BUdP1gsE.js.map,sha256=noF2aM1VxGC3TapA1QpnnlSA5fm2vJqx3nKgkUxPMTw,3571 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BbTVRlN3.js,sha256=FTWRbN598wPnF1tlWpJMIOcJXOg2_ELd8UpZ9S9WTqw,7115 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BbTVRlN3.js.br,sha256=GR51LyvRUVNGHxOgYB9aezzmaRuthiHrep4a7JxKcjA,2806 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BbTVRlN3.js.gz,sha256=xt_AAy8RFMaLkA37urpOqZ21d0aKijx3BIIarJlaJag,3153 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BbTVRlN3.js.map,sha256=4BQI4ocsGFJtZf8JMHN3X20W6NuPql2vN6tYwgxu-XY,8913 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BdtkdF6d.js,sha256=oiRDsZVqJlY7UT6iOvd3MrMA2gAB5cu6uaGPDS8Zlj4,16128 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BdtkdF6d.js.br,sha256=d9_r55IycliNL24PS9tpSXmve6DTDtXvVunLQUORKzM,5188 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BdtkdF6d.js.gz,sha256=62H5ud984IIRNLDnc2ncdKrsx2QgWt6ydDIGgXoDZ0s,5935 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BdtkdF6d.js.map,sha256=8QWDMAKPvjXtHL_AdMw17N-cShG1xhC7mX9bhjnPhdo,23179 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BgwHXxYk.js,sha256=moDZGCt2UaGo8mxEVvZATEKKim0zN5iuAe1sUGG_Zb0,1767 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BgwHXxYk.js.br,sha256=e4eUcjLZoC_sVklxvEgQXU7ZAUOkVc9_V3G6vtsOog8,818 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BgwHXxYk.js.gz,sha256=V31Yrvrc-aJE8-URzs9ClawkCok8Iv30Z1lSp3RJzBk,914 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BgwHXxYk.js.map,sha256=aAhu5DE9cHg32oWIUFTbRVvsNkYl2DS2bzeJMqw4_Ug,1580 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BhfnOJaJ.js,sha256=s5b2NGnQjp73XY95Esss8CapTumi4hk_v1SZo512AFA,4359 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BhfnOJaJ.js.br,sha256=CSHNVX67pQmI5YEwtTN4Nyc_n6FOl7nREKHvio236Zg,1719 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BhfnOJaJ.js.gz,sha256=OFhaed05LOzalLO0S5AMGYMgBVqiF7aLLm90lhwe-TM,1923 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BhfnOJaJ.js.map,sha256=zJOIGYQ4rcChzJwhB_VbsfYhgqhvEFyCWkA_a6hm_uo,3808 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BlcZdiZT.js,sha256=sFHdFK0ZWdM1GU4HWzo14mL90dxybMnKO5RSeCPIi3k,10322 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BlcZdiZT.js.br,sha256=ZWUv_rVmYLlWOAn-86p4QRZE7DPcOlu9sSYwLnNEryE,3310 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BlcZdiZT.js.gz,sha256=qZL-tVkVsJ9afw14cw3oXfgD3-A53NGjwoo38OKuFcQ,3755 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BlcZdiZT.js.map,sha256=D7Ae6_b8ut3z88ZVWYWKs-k-nPSqTrt7K0OE0CHO47E,9053 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BlqpkHa6.js,sha256=2e3DddLCNSCPBr6Jk_tQjsvZglGMX48MbbkC1rbzIvQ,55323 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BlqpkHa6.js.br,sha256=noY3OIJnJdsHNsi20LZvLG2K8wSiGSBSK4Aq6BnkT7o,13925 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BlqpkHa6.js.gz,sha256=XOIv8slYxsG0w_CxKFyLk_A7Jmt0rkwnrnnIq3sqc38,16162 +gradio/templates/node/build/client/_app/immutable/chunks/Index.BlqpkHa6.js.map,sha256=HNPpY4DUd9t7ul5kMlfIJxldF-HHmqPTEjT21F1LdDc,83730 +gradio/templates/node/build/client/_app/immutable/chunks/Index.C19UFE7E.js,sha256=eOurps1SgS9L3gBlGQAanskbxdvIgQcu_366u_1tpWg,9488 +gradio/templates/node/build/client/_app/immutable/chunks/Index.C19UFE7E.js.br,sha256=VuEEWYfBjSYMsTPxOMZ2qOQxJE-VZZMG0wcH3lPhucs,3195 +gradio/templates/node/build/client/_app/immutable/chunks/Index.C19UFE7E.js.gz,sha256=tb44D28pMX5lZW0dDXIFXlftJKkaV2aHKrlkjA-wED4,3573 +gradio/templates/node/build/client/_app/immutable/chunks/Index.C19UFE7E.js.map,sha256=EgBUvc5kmgT6egn4v76pnYHiA0FLRaNbphxqDSmg9RA,11231 +gradio/templates/node/build/client/_app/immutable/chunks/Index.C4zC1VuD.js,sha256=fw9_xUctqURALLMLLFTwQrqlfqFXl3h3oTGIGItu8Rs,6474 +gradio/templates/node/build/client/_app/immutable/chunks/Index.C4zC1VuD.js.br,sha256=1F8tdud9gDKhp54GJIOs88Uhod9p-pouFK8O2h9Po0g,2534 +gradio/templates/node/build/client/_app/immutable/chunks/Index.C4zC1VuD.js.gz,sha256=W6HjiBiEBHyRdNm2zwZzDANBxvKAfpI-qrbzPvBe4Xc,2891 +gradio/templates/node/build/client/_app/immutable/chunks/Index.C4zC1VuD.js.map,sha256=H0PUuiK4rtrJOSdCAsdATAutFaLTHLYgTxTA8P8FoYE,10511 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CEEW3mwl.js,sha256=5ha4Vn54o98qjA_41BJyazPpUYIUCUQSSErcl-nhJ64,33031 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CEEW3mwl.js.br,sha256=oLQ6k1inl2Y3PRG8_UnV1_Jj3Fw1DSm5cAP08yso5d8,9854 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CEEW3mwl.js.gz,sha256=ehqVpRWD48Q6A2NjjynK7uZ3LoZ9x-jj_-N2Xo2b6IQ,11389 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CEEW3mwl.js.map,sha256=Ak7v6d89D_EcuKS6WE8UfuOoK2m3mXFdHQzgp0xvgp0,43981 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CIqK-Zw-.js,sha256=Oyxmir9abcOjNUBz5Gss6WwV-nNq7akLoILWgUhmQ8c,267 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CIqK-Zw-.js.br,sha256=XtOr60d0PJuLE3DtIm7qBcz9VNPbVhD0BhmnSQf78Eg,182 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CIqK-Zw-.js.gz,sha256=3UQrqVvPx5R9cS7iQXv3NB80oNajF3xqz3CWm_98iu8,211 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CIqK-Zw-.js.map,sha256=u8NKqJCl06AJNiwYFIs8xlF3GiDmPDCS-VNscb3aPWs,98 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CPV_QhGF.js,sha256=6weRzWHKnVr_zPW6HnVY8als5APg0ksScxPNmJBj1ko,139828 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CPV_QhGF.js.br,sha256=IQbQPq9IyXTm8IOZhHV7GBk9Yn1vgx3ueF24X_omkZI,32892 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CPV_QhGF.js.gz,sha256=35TeM0IdEADt-5pLCqpfgbRk4VUie0pLK35XTU3zxbA,39671 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CPV_QhGF.js.map,sha256=G5qFlCyfrTJZPmpLp9RJDUTt5J0VobyEGKFweR222wo,262133 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CRM-kWKv.js,sha256=jX195l23Q6iaxYKW6aNs6jkK_KZhhD4yahizBtKzPzY,475343 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CRM-kWKv.js.br,sha256=7gRsUzSb1ydbd2Y3ra30wcB57dpGOo8z7ymuFTHv__c,114571 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CRM-kWKv.js.gz,sha256=-dB8iuh_5uhA6qfR5RTLCWO_g4aei3eMlklz_R17hio,135613 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CRM-kWKv.js.map,sha256=FPa2bvjnmUw0kIUIiJTDjhJKPdwualvCFu6zXwQb-ZI,1718997 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CRn0czLt.js,sha256=r1wpaDofVZ7DsuD4r5cxVaOC8pCAPi_8YZ1AyO2BpYw,4564 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CRn0czLt.js.br,sha256=qL8avq7qJVpq0hqNUJK9OPIDKQ0K-O1PczUrAHtYoiM,1737 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CRn0czLt.js.gz,sha256=_Ib77GKUQVBqA-FbldXK1xPkpsXXVrE7g3bKbbkvL3c,1972 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CRn0czLt.js.map,sha256=OhU2sfHzgQMpDgy8f--VJrvHxbmU_JySJ5h389bLt-s,4591 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Ca8mPvaY.js,sha256=XslCGC31pjHvO0RF7boAkuzda1VgqjtsO442HG0Czao,38822 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Ca8mPvaY.js.br,sha256=oI0OuBYCUYExX03DMVvcXnlUFdlvWASAKUKfk-glfyQ,9054 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Ca8mPvaY.js.gz,sha256=6aVgKIBwqbjTevm_Zu2Wa2Rzuv0dwAx-_aiqj0LYi5U,10608 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Ca8mPvaY.js.map,sha256=3EAnIP88WWdV2vDHTIBkZtO8LDQRTU3qaXQzlYUGGr8,52467 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CcZE6zXt.js,sha256=7DKep6qQHmwDFvqEhIfNwxKa7iOTKpEefsuNBqz9eqA,10213 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CcZE6zXt.js.br,sha256=5w-Ff2ismSJ59V--cfliTjPCMgDzv9pCfIbP4ds0x1k,3533 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CcZE6zXt.js.gz,sha256=Wgu-EA1JIoTu83GyC5gfkS-Lq4lypur-u_wuQYebZ7A,4049 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CcZE6zXt.js.map,sha256=b7o5u3UaTAGFEHIZqxv1t_XEterPw6bGIIqwlOMzXAA,10971 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Cf8RBvic.js,sha256=Vo_tGvGAlgP_Q-rFawfn12hUTHbTYPIiJsfb3wHvJ-Q,72184 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Cf8RBvic.js.br,sha256=xz_c9cZLIG4fBFLa-fOhWC0GM5ThfUfXQ8xsOWAaRks,22320 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Cf8RBvic.js.gz,sha256=XnYeQG8PoMFZdLFWzBYJfuLQ08_u4hulOus0wCZLuCQ,27486 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Cf8RBvic.js.map,sha256=FFfP6IPaRHJp6Zi5iru5uEIgQjs0jVeEbGcMjMrCO_c,355412 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CloDueXJ.js,sha256=XJ7Bu5-TXE8aCcmcMuP33m0sITUAxsJr-DBp1SRVySc,3800 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CloDueXJ.js.br,sha256=enzMwB93bGXXqjnMpXk6zCblf0JXqHIf9tVtl_A6_Dg,1571 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CloDueXJ.js.gz,sha256=4bu6ScfuXhKmHeH6dwSRTgcXsXsE1f7wfg3WWxS6uOU,1757 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CloDueXJ.js.map,sha256=gwCGXhA5uN8MeI-hcCg3v000Tc5S9p0eECQfFN4ByB0,5060 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CmIipLQ-.js,sha256=8ABjVHOdzmlY7S-dKHIVifKlYMDtJ497zns9iFOfnmo,111093 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CmIipLQ-.js.br,sha256=v79hpd-Fouu6xl0dlE2y9fPRjgwBOVIKb3D45yZINJo,24601 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CmIipLQ-.js.gz,sha256=kcrU0EXZSK3zQRxnDOyt-Liki6y20hX4dRf-WyKgQq4,29608 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CmIipLQ-.js.map,sha256=p0I71gr60pYfNIP7lOb3nRDzGDnxr_F7zuCGrE2wvhQ,146408 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CzGK6cwb.js,sha256=sg3_ToX7lGh8Z4IHcOGzskCfWhFJRsKGX9BrnBOrBQA,5969 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CzGK6cwb.js.br,sha256=1j4phOMSe_9jWl0YGml7gd0gtaCd6KAdwf3uRTft_PE,2312 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CzGK6cwb.js.gz,sha256=WJ2zLAMHdwzFqo21fwdT5eSKEJI8nytlKpiDdLbM_Kg,2580 +gradio/templates/node/build/client/_app/immutable/chunks/Index.CzGK6cwb.js.map,sha256=GEUhNSKZV5U6-VGYBbE5PvSkTNh9DYiCbatTzx33k6E,7456 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DEzXiUWX.js,sha256=wKtvKaJFWwATtPOJulxVTJYC7IxRNhUr_ag-PbtLXm8,4866 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DEzXiUWX.js.br,sha256=ae8_pfpUtjKt5yDHT6s-bvwhPZiAvTOAg8bfTHgyP4s,1896 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DEzXiUWX.js.gz,sha256=yECQ4mZ4hn-qfnnZ2R4sNFkXXpQvdie42pTq8oNUDNs,2142 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DEzXiUWX.js.map,sha256=WIdOWIAyKr1LwpIGdq3x-hGb_zlnICZiz2lnzZvU69g,3373 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DNa-aMjf.js,sha256=tIaIzwHPGWllAyZ0T362O4KNlpRwk4Bfy5Nv4fs9q5c,9155 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DNa-aMjf.js.br,sha256=m3I2s3Km1mL8HvteK8DpvO3W-TPXKlr6rjkiYrAY7qs,2833 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DNa-aMjf.js.gz,sha256=XBFpYazvrVIf1ovEeHvKx400_Evrm5qwK0oWYE2U58A,3230 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DNa-aMjf.js.map,sha256=RJQgb9V1i9a_Ja1HnIz1JP8zxTHpBsppinq6IUOp95I,8572 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DQJN-Dva.js,sha256=IJgTPnVaK58O720brV1GFPN3AkoBI5ywLkXfdpxSveA,13343 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DQJN-Dva.js.br,sha256=K66KrmEEuV-4Bj3yMcSn0EzwIWyIbcezP4coCiwbk00,4483 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DQJN-Dva.js.gz,sha256=Uss-_gvwq-WcwZrEN9XgbS6-EaqdjaR081e0t4yJzmI,5071 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DQJN-Dva.js.map,sha256=tuCaZbLCloivesFywBSQ3WJh97i7jjFAoQrY9lMvNo0,20462 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DQwOV6Tk.js,sha256=NCALYNHoYkF73UQJbiTEUpBs2wVbHh0b9xl94aqDU3Y,21478 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DQwOV6Tk.js.br,sha256=TI05alyy26G3P39OKUCi4ou0u7pkepcCsUAO2jGa_TE,5565 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DQwOV6Tk.js.gz,sha256=XDsLNSORJcIlh9dcyUUbWjMP78q0Wkiz8XFV_3yuukw,6473 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DQwOV6Tk.js.map,sha256=pq1VFGkRVBtw_uC3kmzu2UXiqxMkHA0CocLmADArYB0,18525 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DkzSiTko.js,sha256=TzeNIgghuBxbIf9vrNQtNTFIIO1uwqJP3VL5IDrAyvk,15867 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DkzSiTko.js.br,sha256=fit8QpdRZUSaNo4lodZ_80QZLWjGENuqTfO5bsNW9ig,5389 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DkzSiTko.js.gz,sha256=6q65sDkaN83V0TL9_hV1HbTzISAXht-9p1y5Athqqr0,6233 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DkzSiTko.js.map,sha256=85DYbZv9-saKeqnZ_YNa0X8pde2CbOOpEk-nFKnczIk,28989 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DlpdhdKo.js,sha256=ZF-pM9S72e008i9nj9qV-whQbUxWMZO0RCBlBLRDlAI,16841 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DlpdhdKo.js.br,sha256=6wlmBxJtQ7bKEmqAnHjG5U_2wn9IniNwmV5jva9H0zY,6116 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DlpdhdKo.js.gz,sha256=PsxVrwt6BBY73y-cqloEo9SjzR6cTkvstIrZQv2BDIA,6883 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DlpdhdKo.js.map,sha256=eWCh9HaoET5aATUfNYWnBhVR0n7t5_l2iZYu9QPYb-k,37736 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Dpqs4STX.js,sha256=bnsCZetu1GBee7l6quUAAvRHJqGyXUAi9bjPCE1KKoM,8665 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Dpqs4STX.js.br,sha256=2R_yXZGl3dZudRwyV8uzz7ownK5N_Cw59dvP7OGUdZU,2666 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Dpqs4STX.js.gz,sha256=eeGTksX0ev4nVhe5SO6FyfPUZAx4lSt-_Tni5dC9-yU,3086 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Dpqs4STX.js.map,sha256=VCsB5h4G3kGW2Po9nLbvA5PwVfqPJrbQ9flwMa6bcqY,5736 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DuAu_hxD.js,sha256=CkDShpNZTVcXVKQmw5a8c4d9zZaiTwLLblN1rsz1PkA,8947 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DuAu_hxD.js.br,sha256=TQljk6AfeMXk-d5uvVZ3wznlL34imBjgRXYAKCtYDJA,3034 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DuAu_hxD.js.gz,sha256=E8KetOX4JFhdaFYQ9lf7GkyEip9VMozS7eBd0s9oFGM,3494 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DuAu_hxD.js.map,sha256=oAyaVMEPJSqHluQu84T9UGqmS2BnTkhE_oRUr-t5UfM,10229 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DzAuytsV.js,sha256=hJ1jICEcjvVWFJdT2kpWq-zo-ytVahxU_p5NUKNoE6M,6266 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DzAuytsV.js.br,sha256=9u0pSZqhS0jQbKrQ_W7cFwQoUrAX3v7Tl-DYCTHYZNU,2250 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DzAuytsV.js.gz,sha256=GFAigIMGOv5QPHiu_70b3HMFvNeDUYnjcK6kZswk9u4,2586 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DzAuytsV.js.map,sha256=HrLbpXx7YR8uJqBvnTD0OkuePvgO0uEyZOZVJpOH2rU,16529 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DzoWjft_.js,sha256=wLM1pUtnEfW-ZPb2ReGxWhk-OAo_nbozT5R6x5rRrmo,8352 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DzoWjft_.js.br,sha256=wPuvxj9dcCND4S5jn1BMlTeEXI-uyjaGIiqiPHjBmkw,2595 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DzoWjft_.js.gz,sha256=Sle4dh2gRTWbJ2wIUmRHkHFdHgazMtsLoBcCysyWiP4,2951 +gradio/templates/node/build/client/_app/immutable/chunks/Index.DzoWjft_.js.map,sha256=1AgPK4n4os8RGkOEC8z3oxKBIPDa-UPe6zmc2WzSH6k,6638 +gradio/templates/node/build/client/_app/immutable/chunks/Index.ED2kgwFo.js,sha256=lxiW83TQ_FocajqrILN52XNLpke6LSGtwgGBhsjSkic,9676 +gradio/templates/node/build/client/_app/immutable/chunks/Index.ED2kgwFo.js.br,sha256=J_wV2F9q5i7aGw7xoxRt97T7h582TTrYCIdFt-6iMo4,3490 +gradio/templates/node/build/client/_app/immutable/chunks/Index.ED2kgwFo.js.gz,sha256=p0YC5dYIa8mL9CHe7C-zjrY3vEmQq2G1RgXJDO4BtKs,4010 +gradio/templates/node/build/client/_app/immutable/chunks/Index.ED2kgwFo.js.map,sha256=6iu_0ln-ormHbsMGC1h8eKvMgEmP8IAE4yD4qUpqFCA,16894 +gradio/templates/node/build/client/_app/immutable/chunks/Index.GnBGuK_y.js,sha256=hjIa0qR7d09cVWFURxOWOCozYo0TZXvznwDYAXPVnQ0,7265 +gradio/templates/node/build/client/_app/immutable/chunks/Index.GnBGuK_y.js.br,sha256=WFA2g6Zms-oHYg4rk06O30iiWgVQIBVsD6CcA_vkjtE,2719 +gradio/templates/node/build/client/_app/immutable/chunks/Index.GnBGuK_y.js.gz,sha256=Eg7KhdITWJth4Xejpdg-r6MAnFc5mbudfYErObIsucU,3076 +gradio/templates/node/build/client/_app/immutable/chunks/Index.GnBGuK_y.js.map,sha256=hewwRGp53lNzGYQ4SdokKXr9GsMPD_HOxYA2jMxqA40,8923 +gradio/templates/node/build/client/_app/immutable/chunks/Index.M49UGAm5.js,sha256=mw6Ub5eulb8sySGd_L0wsTjGv6KiQdB1Aq1a47msAK4,5237 +gradio/templates/node/build/client/_app/immutable/chunks/Index.M49UGAm5.js.br,sha256=yN44cM2R6fMTTwZxphhxqPN-IA24hPeBWIWYe0biosM,1937 +gradio/templates/node/build/client/_app/immutable/chunks/Index.M49UGAm5.js.gz,sha256=76vH-3hgJiM8DWm285LLK2iGREp3_Cq7943ZUweOCGo,2198 +gradio/templates/node/build/client/_app/immutable/chunks/Index.M49UGAm5.js.map,sha256=MjBLqxk4bwCryJtC4CVYcv-Fd7Pw8gxfnQULwplyJKA,3962 +gradio/templates/node/build/client/_app/immutable/chunks/Index.QgCMginr.js,sha256=B8AhZNxdyiadYZOSsrEO0KI7HcVj-E6t_1Q-aun2rK0,15477 +gradio/templates/node/build/client/_app/immutable/chunks/Index.QgCMginr.js.br,sha256=mj9cwGYxC71Z4FTGL6OEru8x8WDpCVhIOIm7uPI44UY,4087 +gradio/templates/node/build/client/_app/immutable/chunks/Index.QgCMginr.js.gz,sha256=ZYxNfDtjZA98sf1EzPNiVs5anz36aRf_Gdk8CSpG-Hw,4738 +gradio/templates/node/build/client/_app/immutable/chunks/Index.QgCMginr.js.map,sha256=Jg5_1WoFUrUiT1XTUWN4zXAUMHmG5Kd_teioU8uEgKA,12425 +gradio/templates/node/build/client/_app/immutable/chunks/Index.WpI12aFk.js,sha256=IQEciJbirMQ1nZOJ0NnvavJ12YvLTfzGhL5Q0F8fVP4,7240 +gradio/templates/node/build/client/_app/immutable/chunks/Index.WpI12aFk.js.br,sha256=L4ZUUN9U-vasoKD-Ds9RyD8GfMIeEcxBFUYcO07Qvl4,2444 +gradio/templates/node/build/client/_app/immutable/chunks/Index.WpI12aFk.js.gz,sha256=qOZHJR7cLeTN4Fc1qY--O_aKkoLGf40AST0Yos1UU-k,2789 +gradio/templates/node/build/client/_app/immutable/chunks/Index.WpI12aFk.js.map,sha256=JLUshpHRVEXfmcZJOYFmO6sXG-bt2P1K3FxMqmMrFRw,8843 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Zns9B8np.js,sha256=DBLqoArHn9-Fld-lWefFJgUXk8Njqm_zEyIVSjYrUc4,19987 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Zns9B8np.js.br,sha256=lKTiIJnUpvt_UexJlkBMcEq3anzt-OsFbh6Y55rd5Jg,6458 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Zns9B8np.js.gz,sha256=r8MyZP97jEHT_wXOT_HfvUk0HReJkCzc_7JqxdD1VUY,7412 +gradio/templates/node/build/client/_app/immutable/chunks/Index.Zns9B8np.js.map,sha256=vjy2c8D36L5c0PRncbuMRnBvvbp2FxkG2jeu3H1Np5s,23052 +gradio/templates/node/build/client/_app/immutable/chunks/Index.fALBQSWF.js,sha256=QeFr8GN5nxsHjHEZpfvTiNATGJLkgyRrB5VdQn8XcFU,20867 +gradio/templates/node/build/client/_app/immutable/chunks/Index.fALBQSWF.js.br,sha256=v-fmPEr7wccfxHLXeB-uXy-c_1mwuglhovnUG-U9qzA,6303 +gradio/templates/node/build/client/_app/immutable/chunks/Index.fALBQSWF.js.gz,sha256=CBqeMsTpo5OECkTBI5NhBLXABofa4D3BtNAhIfnQ2r0,7310 +gradio/templates/node/build/client/_app/immutable/chunks/Index.fALBQSWF.js.map,sha256=jOTzKnbolEU6vdjAHMnjk5I4wH5MxvCMgxynFaehVyY,36835 +gradio/templates/node/build/client/_app/immutable/chunks/Index.l84jYP4N.js,sha256=Xnu_CgrHQDFpNnz0owPaXt925hywDRM3LL_frP1KWtc,13108 +gradio/templates/node/build/client/_app/immutable/chunks/Index.l84jYP4N.js.br,sha256=HD5_ySK9MC8EoBVDVZZ_nDFk72LwbK51EriVvLPpNzA,4510 +gradio/templates/node/build/client/_app/immutable/chunks/Index.l84jYP4N.js.gz,sha256=3yCb_XkiAfkvk8dFAMfRShSo6FA5dPcUltBZaOBPRWI,5145 +gradio/templates/node/build/client/_app/immutable/chunks/Index.l84jYP4N.js.map,sha256=fK5J-jnN_CC8uxBZQBa9apafr54-n2qzlYGZcAQcOBU,21560 +gradio/templates/node/build/client/_app/immutable/chunks/Index.lYljNAvS.js,sha256=-Kk67s0RlrRwN3U2Hh18uwsYnoFrmzjlFOEpd4QqQEM,1502 +gradio/templates/node/build/client/_app/immutable/chunks/Index.lYljNAvS.js.br,sha256=VnCHUVv8ujYjPHUNAq5fDe8eP2ahcplkUGxsPzbdZbA,701 +gradio/templates/node/build/client/_app/immutable/chunks/Index.lYljNAvS.js.gz,sha256=4iOo4rMj8Z3459AsMOLUAyxWMk8hsj0AiSN3R17t4Vw,780 +gradio/templates/node/build/client/_app/immutable/chunks/Index.lYljNAvS.js.map,sha256=n0FcYcsP-tIV2oHd7jSxDZG3WmoTBBfSk4xiI4cr3X0,546 +gradio/templates/node/build/client/_app/immutable/chunks/Index.l_xd479o.js,sha256=taAQpHu0XmnYRcJwvtQYZ3fgvUDgTFZZX8I28RcvxIg,2184 +gradio/templates/node/build/client/_app/immutable/chunks/Index.l_xd479o.js.br,sha256=D0ndX_dCSq1pVHcXVPbbimRcPAL-5Nti5FswFj7rnD4,991 +gradio/templates/node/build/client/_app/immutable/chunks/Index.l_xd479o.js.gz,sha256=YffmVxB6yzTHHoEAy2EcZHOZoBNLo0u9tNX77BWC0Jo,1095 +gradio/templates/node/build/client/_app/immutable/chunks/Index.l_xd479o.js.map,sha256=iNfPAMs0VZ0FJEX6tZwJz4Lzr7B3mou0ttycZy_SY-E,1919 +gradio/templates/node/build/client/_app/immutable/chunks/Index.r703Cwvo.js,sha256=E04U5gUhO44HR7YZfnFUvuvHANR45nS90BA3yqaqGmA,7528 +gradio/templates/node/build/client/_app/immutable/chunks/Index.r703Cwvo.js.br,sha256=33g-RPuZP8GxccSGh4nO4O-7JeWYud1rZcvUZzFTuB4,2764 +gradio/templates/node/build/client/_app/immutable/chunks/Index.r703Cwvo.js.gz,sha256=Cr1n-h202Wyh2WdO0UHyf8Hi5iWSd7-VskmIQtcyiOE,3155 +gradio/templates/node/build/client/_app/immutable/chunks/Index.r703Cwvo.js.map,sha256=M5j9t5BSe0HVuVdxtnazfWchEBsDu4kl-t9YF1uv82s,13200 +gradio/templates/node/build/client/_app/immutable/chunks/Index.svelte_svelte_type_style_lang.C_Nte0rq.js,sha256=8CQgzSpWX2bocLoIIVygEegQKFiv6dF8qzR7XuvB72A,4335 +gradio/templates/node/build/client/_app/immutable/chunks/Index.svelte_svelte_type_style_lang.C_Nte0rq.js.br,sha256=ncCgII9uoHbkNEcy7AkyapPWf3xUBilijr_CGTXFTMc,1743 +gradio/templates/node/build/client/_app/immutable/chunks/Index.svelte_svelte_type_style_lang.C_Nte0rq.js.gz,sha256=k2YF7InAQoP-yALuXBlqz-Pjb_YP_X3NARI1A61saLM,1946 +gradio/templates/node/build/client/_app/immutable/chunks/Index.svelte_svelte_type_style_lang.C_Nte0rq.js.map,sha256=EXqVRdzboPWvvV7uBzbQPDRMFSVJhRIKZMFDTGVHb_I,5059 +gradio/templates/node/build/client/_app/immutable/chunks/Index.w3VL8wMB.js,sha256=_Xg9wpEmafB2Pa0Qswy0y-Ilmv3FQqurTRbqrpnWRk8,1270 +gradio/templates/node/build/client/_app/immutable/chunks/Index.w3VL8wMB.js.br,sha256=ys03TwjmpvjZUfz4Apl1xRCN81Bo5ryHror3_9pP5As,643 +gradio/templates/node/build/client/_app/immutable/chunks/Index.w3VL8wMB.js.gz,sha256=r0R1csx7wD09vB5ed2mlsEfZngAB80nRYXTAHXeezck,711 +gradio/templates/node/build/client/_app/immutable/chunks/Index.w3VL8wMB.js.map,sha256=5HHkKF_hO7cmA04dW5uPZtj0CBntOH0H3Ajbjmfr2IU,1633 +gradio/templates/node/build/client/_app/immutable/chunks/Index.zIazTE8P.js,sha256=fa3SOM4WJU7XRbNqtO-4I4os_HxKj6bg2zc-vtSydJw,3756 +gradio/templates/node/build/client/_app/immutable/chunks/Index.zIazTE8P.js.br,sha256=--eZbnQKSb2P_9Z-GyGnnZX_o5LTINQg-N60eHLnz0Q,1535 +gradio/templates/node/build/client/_app/immutable/chunks/Index.zIazTE8P.js.gz,sha256=MteV5qxYwc3TyCPYS9NcQetWM5PFmHowBHbwR5nk7Ks,1711 +gradio/templates/node/build/client/_app/immutable/chunks/Index.zIazTE8P.js.map,sha256=YxvkslYu0ZgXAqDHmAM_DZmMiHaTaPJQe6HmQXwdC2I,3218 +gradio/templates/node/build/client/_app/immutable/chunks/InteractiveAudio.DSjIJjpt.js,sha256=eFgs8B_XyomncNgmqG8gFC483302ZFjK6RSh1TvmzvM,36096 +gradio/templates/node/build/client/_app/immutable/chunks/InteractiveAudio.DSjIJjpt.js.br,sha256=7hLu-UsHIz5fXa8lXk72-fRKtFp_a9E6VfL_YH5zYrg,10755 +gradio/templates/node/build/client/_app/immutable/chunks/InteractiveAudio.DSjIJjpt.js.gz,sha256=uCswtvKgR3EzYeAwfUP3YyQS3nLx4-t7sH3gGp1jDEo,12311 +gradio/templates/node/build/client/_app/immutable/chunks/InteractiveAudio.DSjIJjpt.js.map,sha256=yKbSKP8dqjFgH4fqPFct4RrwUxsKxn-ZZKbOy34TNss,55983 +gradio/templates/node/build/client/_app/immutable/chunks/JSON.B6dFeLTJ.js,sha256=pU_tB_sI7979OLLZguy53GeOQXfKLU_Vk8_nAEhKNCI,15693 +gradio/templates/node/build/client/_app/immutable/chunks/JSON.B6dFeLTJ.js.br,sha256=Wc0YgFAiLIW6TYqV22ySKJIeBYiDmoUeIFAx8TUtvhU,4862 +gradio/templates/node/build/client/_app/immutable/chunks/JSON.B6dFeLTJ.js.gz,sha256=4Sb5TM0TV3ojuXI74ffuAqE6ThjVBC5vGzID5IhuC7U,5524 +gradio/templates/node/build/client/_app/immutable/chunks/JSON.B6dFeLTJ.js.map,sha256=Ndv_iW_dc7zw9jFSWxSZEOr33LT65a31t25OMP8Gulo,17247 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_animation_pointer.MxLqiGMN.js,sha256=2EEWIRMqW1iUDbGL89OYUYgRh4JEukPpHIYJG0cTVh8,14882 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_animation_pointer.MxLqiGMN.js.br,sha256=H_vvUmPMjZpWLkI1_XE3o61gubtzhJUDaXdtghkzzTk,2064 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_animation_pointer.MxLqiGMN.js.gz,sha256=C7UKO9imj40xHMPAQ1hRdXW6aXSYh0Nm9ESZ3WY2yRA,2375 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_animation_pointer.MxLqiGMN.js.map,sha256=13NGebVSc_5ACtZ90HlnawMX2jR4wfKSLt_OfSx758A,37162 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_draco_mesh_compression.Cfxf1Uh0.js,sha256=1czlQfr7fJ6LtiqaCDMWLiqiJN9QX3o3xHozHELvXZM,9026 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_draco_mesh_compression.Cfxf1Uh0.js.br,sha256=AEjuBZAvowNXdPcVt4dMHqAtnE4u7FWIAm6F_zCbyKE,3110 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_draco_mesh_compression.Cfxf1Uh0.js.gz,sha256=jq4afQRrTFl8Ff-A00d70Qj-avO1SLiaQK44TCUdc0I,3427 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_draco_mesh_compression.Cfxf1Uh0.js.map,sha256=wxOlMOzV6gn5hSUjBa8S53g_5Y1rJqkCL9j4O-fHYNU,47646 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_interactivity.DEAVS2UW.js,sha256=g9XfB_GG9bjKSB-KClUDUWSwPYN59wpF_IDKk0YfXI8,66761 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_interactivity.DEAVS2UW.js.br,sha256=-ceMgSPA4rGnftCLMa0U2xZBhXqgHvGup4RUFkhGib8,11758 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_interactivity.DEAVS2UW.js.gz,sha256=tmElhEN_MobgO2iOLeYzDjm0UANjRg7lzYI8sUGa6V4,13808 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_interactivity.DEAVS2UW.js.map,sha256=yr4FEf8ubWuAhoLD9NUQFhKXzobkrQ_Mv7Q-7wAcZgw,202919 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_lights_punctual.BmG3zBWC.js,sha256=mDTlqdY4L9h_0bdL5L4YwdPVL53X0SGp2Qr5bpTTvXQ,8639 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_lights_punctual.BmG3zBWC.js.br,sha256=xEH0POkOxB7cgdHnIAAVBdPa-hiP2-9It9v9RvnWAV4,2289 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_lights_punctual.BmG3zBWC.js.gz,sha256=GOjiMc8vW5oA47l7vpZ9aavlW0aHWmBuZoIsR5qbfQU,2513 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_lights_punctual.BmG3zBWC.js.map,sha256=f7D-AhE_Ca4T-cIck2V5TOHJQAVoc0GTOme1sAsUHnY,36179 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_anisotropy.DawKDrSJ.js,sha256=qbbQAFV-TO_LqtcoEtQH1xE_YAQ7Xk4fNlihRADyf5w,1158 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_anisotropy.DawKDrSJ.js.br,sha256=NrQHYXzCCdvBBOboOpvcR1FvtZK3JHoNPwBGP0wlZeM,499 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_anisotropy.DawKDrSJ.js.gz,sha256=PHuhXLECOEqWAZZMt7ZCLPz-RRVeahfHfIm5eFS3gb4,560 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_anisotropy.DawKDrSJ.js.map,sha256=rkFC6RiXJE9mUvN4zdhw9ROZBKSkDa8BXxM0OCvRbx4,4231 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_clearcoat.smUn2wvX.js,sha256=JG7vyV98Cq5gFaMURIjocCUCJ-3RsJOKcfEuKE_epzw,1984 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_clearcoat.smUn2wvX.js.br,sha256=n6LKl64-Zh0YHA176eT7tbhv-5Tbj8IuAe81owJYnak,650 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_clearcoat.smUn2wvX.js.gz,sha256=s8HkMnS0QmLjzaoi9CLAO2udBrg1swT3sqWjvUsZtN8,730 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_clearcoat.smUn2wvX.js.map,sha256=Js4NYzB7E1Q2xLCNFHTwJm_Sj0_oosje1RtCRYNZGRw,6573 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_diffuse_transmission.2rNh736n.js,sha256=9wrVw2JCFh6WdfhQLndUbzdZejJ0yFy3mou8PiW4m64,2047 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_diffuse_transmission.2rNh736n.js.br,sha256=4Umeyj8dhqilm-MNZXUX2p4u4_RgLAwffhy4jacRySo,674 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_diffuse_transmission.2rNh736n.js.gz,sha256=v70rx6QTK3ppczgBaWSL1oltWH_jrkZK-Xkzj1ElAmo,771 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_diffuse_transmission.2rNh736n.js.map,sha256=swj1qG535WthT4hBQ14XTXXZUypWk-C0HQ4K6ZArfDQ,6656 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_dispersion.Be-t9BMa.js,sha256=NODSBXLmRdzGEH_DhvXscrxx0DxjvOuBJLB3KpvlzlA,923 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_dispersion.Be-t9BMa.js.br,sha256=EUUfy8mXC3uegSr4FobMkJc2WZii0IF493eexOTkngA,428 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_dispersion.Be-t9BMa.js.gz,sha256=ox1oLwa6tiKZhtFi3w21SbVokHYBHUrVtXrVC67feJ8,495 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_dispersion.Be-t9BMa.js.map,sha256=536OCE39RjAYY7fnm6sBaRHhQP_UY5Ix5lpYMekL43Y,3846 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_emissive_strength.DEkVcEBv.js,sha256=kllim8-uoxIq1f93OrzQeSkdTWLrfLLUupL5QIQkYtk,788 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_emissive_strength.DEkVcEBv.js.br,sha256=y1macJxSPeSYW80KCOiNZq_ffLJYZmChaNfefmb7-J8,376 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_emissive_strength.DEkVcEBv.js.gz,sha256=XeuIrL5h2q8lrkeEKHKYs0jQZ2IEpRXFXb1vB24cRmc,440 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_emissive_strength.DEkVcEBv.js.map,sha256=mRr7LOnHwFc5LyTHZlDXuxl1WZ59cydhcnr6lMrmKyo,3188 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_ior.Cq60gFAz.js,sha256=O0PxPYuu6uBbuE5xEnCy291nHCJqewvk7aJib7iOwpM,855 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_ior.Cq60gFAz.js.br,sha256=v0hycta6pCSHLKjOum9TZ7gwkh6Ls_zUI5vGLOG1g-s,413 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_ior.Cq60gFAz.js.gz,sha256=zeD2DKwmZ5Hig_9-pd22KvRVldQPApQI-kHAZDPKDR4,489 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_ior.Cq60gFAz.js.map,sha256=GVIwDrU_HPCleI-FcxfM9PMc187MdRrU2Tz-ryk25wk,3531 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_iridescence.CSeeps4T.js,sha256=ptFqC1vVe547-KnkXzvqugoty207nXwyhu97rLc4FkE,1500 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_iridescence.CSeeps4T.js.br,sha256=mu0A-6DCni6cp1ZnsOUxnvLWvnEtb7yBdkuE8QZgXJM,537 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_iridescence.CSeeps4T.js.gz,sha256=w56KbGcxCOa6vsc_zhOiEX82viGNBUEbhN8VaqBBgNU,611 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_iridescence.CSeeps4T.js.map,sha256=iOwwUqxNqtPKlAoszCABtwHNiXH4YNxxFBo23dFXg2Y,5052 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_pbrSpecularGlossiness.B0g0KMo-.js,sha256=i7t1-lbZCVnKmI58SV9LOzMoC5cdjGg60cSOurKai4A,1650 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_pbrSpecularGlossiness.B0g0KMo-.js.br,sha256=Hm4xqwAOuk0urD-5HTjw6vx2YxH4avm_SW177vkiJiU,624 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_pbrSpecularGlossiness.B0g0KMo-.js.gz,sha256=OFMoSMS7rW3tCyRUBTMsKaQjZuXFEMRkmcH8jECOuAs,701 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_pbrSpecularGlossiness.B0g0KMo-.js.map,sha256=z64HXeb9DNSQFg8TGkxRsDWvZ8udUWhpNzrJaNZ6LU8,5738 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_sheen.BxK5ddN8.js,sha256=bGAIHEZbYVlLdLN49A1ZbK7jwyLgj717gN88BFnB__8,1495 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_sheen.BxK5ddN8.js.br,sha256=Pju7kQM6kQPTp1tlrhk1Z4ywzZ3EOBq7EkLgNmmzG40,582 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_sheen.BxK5ddN8.js.gz,sha256=je9m6C9GtSyB7T05NnPsik_c36nJMsVbiDhKRaF7dhQ,645 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_sheen.BxK5ddN8.js.map,sha256=8vZSRadkM4NIVcan_XfTFyoEvlqxcu9s5CXbp0kROI8,5506 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_specular.ECq9zfym.js,sha256=ezpEYibSf5kF1TsyqKo8UYnBJAV3MAC6cbnV6xiqPtg,1419 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_specular.ECq9zfym.js.br,sha256=2i44Vmqg82iBr-aCf3ESV-VFuXFnokNQLPjb_jcuH7E,544 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_specular.ECq9zfym.js.gz,sha256=YPg65xbsaVbCbVLZvusV4MqP9iCkXqwjAyp6BeuLtd8,611 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_specular.ECq9zfym.js.map,sha256=KCV846XYwjca5UnkO7KTmstVMiqEhHpwW_jAcEB0Pjk,5014 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_transmission.p_703UW5.js,sha256=nDO9IZC56KHoIr7VK29esE6LMMMsAECDFMYDEvZnyko,6197 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_transmission.p_703UW5.js.br,sha256=I2SCmFoVcyM6n3GfCtWkilD5iipuhKcW-cH2VupGjq8,1670 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_transmission.p_703UW5.js.gz,sha256=t6N_-1Yf612XQa7gQXbFXVm3vlzL0Ne56jlHlda2pxg,1880 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_transmission.p_703UW5.js.map,sha256=4fKZS3THlcehtDjEK-bwHLklAex-1-s8-0J8bcPsXVo,18842 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_unlit.I1FWdR44.js,sha256=RrwSifQPsR-iT6-Iwv7NrTLRiRk0Qx6_ySGQjoKrdXo,1117 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_unlit.I1FWdR44.js.br,sha256=nXFTtoWw-eEm7ZCXUQVKHCORJLkch_i_kSmo1rq-MhQ,543 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_unlit.I1FWdR44.js.gz,sha256=q5uBiGhL0xxnmHjZ-TJX0DHVmYlVD0EGXpqwkv-t3RA,606 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_unlit.I1FWdR44.js.map,sha256=9_qqT8DVTHTPkcMO8_1cxZvF4cbfkSMbEWaq_wllByc,4364 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_variants.Cryk6ix7.js,sha256=JhhnsMECsgeE6-hOu3pJQQqVXP055UmMSyr1DDwja8g,3950 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_variants.Cryk6ix7.js.br,sha256=iTQGUdq0L0OoYX4zpLKFbMVLYhw_IsF4aFz8Fzs0JGk,1286 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_variants.Cryk6ix7.js.gz,sha256=MJPCbCG4j3svuF6VnbvvJWVHmkktnC2Y-6K4ZoNEQkE,1409 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_variants.Cryk6ix7.js.map,sha256=b6Gfd0ov4-z2CzxCZiHFYdVUJQY8ZAMHUq2phTTsXDY,18423 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_volume.CaaTDZE1.js,sha256=gvGNtV5iyQtHZsjtwGjMqlr16HtJ9CxlmpRXdrrpzeM,1695 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_volume.CaaTDZE1.js.br,sha256=IYebOzEFmj8vUir4ocG5GFoASI7ej8eBtjuEfT1epTg,672 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_volume.CaaTDZE1.js.gz,sha256=DOszri5oo9Vg7UKJ8ZZ680ISyX6O1EhzqvTA21vCCrc,762 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_materials_volume.CaaTDZE1.js.map,sha256=naddYw2Uyob1MCRlIZmou_4yLBXphJow62adh8APrmo,5973 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_mesh_quantization.7aI80EPm.js,sha256=c1pi4a8Yqjy-KqBA74QvSwi1VRb0mnLmMAbyrfdfkQg,282 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_mesh_quantization.7aI80EPm.js.br,sha256=6Bu3Tg25yr_dyT6tQ_CbN1YhzmsD1dVAG9MIaA6S66g,195 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_mesh_quantization.7aI80EPm.js.gz,sha256=EwMHgu8ySTcHsKQF-6vZzIsbzvV1FKhTv_JEY-p5T3w,225 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_mesh_quantization.7aI80EPm.js.map,sha256=HFLHmWQFjaudtu_v5wH2a9dI1oKricobYuK9o9uyf5U,1437 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_node_hoverability.CkqDT3n3.js,sha256=GnUWhFxKBMPUe_CJr1qRwujpvd4y34uQUMGsyJn2TEM,3799 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_node_hoverability.CkqDT3n3.js.br,sha256=GrZCMbkgbjql73GDJPAKExXLJZEFv53hYHHGtOoFhaM,1019 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_node_hoverability.CkqDT3n3.js.gz,sha256=fX3lLEt-nBvqeTDpFEgUgAjEgakjt01ILeq4EcBX_EA,1156 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_node_hoverability.CkqDT3n3.js.map,sha256=iW2Y3cnmU9oSvBCbFIwyA9CwfthiKnqgsTF7zGy0OqA,11711 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_node_selectability.BLTd5yB3.js,sha256=6lfOLLecBr_OjjobImmYk-nmwnAx6418n-l6a7rXQI8,2433 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_node_selectability.BLTd5yB3.js.br,sha256=1mVEFWOGXIFsuszwaIdW67AFvi_MMtHTIO-AetLW2BU,1006 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_node_selectability.BLTd5yB3.js.gz,sha256=BdB6rx0x3UH8N2SCcXnFDUeJezZCGY2VaVCF__2v3Lo,1116 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_node_selectability.BLTd5yB3.js.map,sha256=8CfmaqdNISG-rntV_y59TbB7VQds_CFWNU3oazDgFPI,7578 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_node_visibility.DrdPfsSp.js,sha256=GFzuno7gBzokqJJkn8hZREuX-2wuUZ_8x1j0NSpbl0I,1227 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_node_visibility.DrdPfsSp.js.br,sha256=LlDlXCFng-DteD9-fpRYyd8zLgbCXCFtcnb7m-31bzY,513 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_node_visibility.DrdPfsSp.js.gz,sha256=vqoMJidj8GeBknWc2nwGHTPjuQq7TnX7-7ASfiPasEY,580 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_node_visibility.DrdPfsSp.js.map,sha256=dqH2BRIdnj1sb8kYx4-2l560CSbyLdjaA3EcpXFGM3Y,3933 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_texture_basisu.SN6A01jS.js,sha256=zKBru9GeF6ehxCwLXVy1y5JyWtualt8NNC4uKNWj9bA,772 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_texture_basisu.SN6A01jS.js.br,sha256=Fwt5CIgU5q_bhzObL3waqwKfSWl68ZqeQykMvUOW4oo,403 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_texture_basisu.SN6A01jS.js.gz,sha256=djcQ8GaJEjPqL8zClu7SENfdLtO7YAGZB5v7C2EEWYY,463 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_texture_basisu.SN6A01jS.js.map,sha256=gC80Udp0wPtw84CgQah70ddMF9bS-N9G6geHBdJ02s4,2889 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_texture_transform.DzMk5bDN.js,sha256=Xgow0E5x3c0OAOSf6BY8dp6OSaQz49pPAXoBJGllqig,816 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_texture_transform.DzMk5bDN.js.br,sha256=RYhvl0ZhXNrkwSWWymI7Q5CKppb-s0ZhyRPQIPT0O1k,413 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_texture_transform.DzMk5bDN.js.gz,sha256=-Gc6DE1vDn59twC9GFROuKZxCzZ_RiSYtHLm5_Ox5Z4,477 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_texture_transform.DzMk5bDN.js.map,sha256=95e3MrCZJ5gCbM2UcaVoiZktZ4ruYdbYsb6C7u6u3G0,3653 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_xmp_json_ld.CJKvXKm8.js,sha256=8HK1mzwonR6hS4rv9AoxcRgUvv3AksZzC4BCVlrc08M,749 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_xmp_json_ld.CJKvXKm8.js.br,sha256=TB4gSxYbHPa6Lki84_PZFTx7bHxyK9TRszq2yEglgUA,353 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_xmp_json_ld.CJKvXKm8.js.gz,sha256=LTMKXATqkqNIF3UAo2LGkfq54ayDs6fwhf7ui4YmHRU,399 +gradio/templates/node/build/client/_app/immutable/chunks/KHR_xmp_json_ld.CJKvXKm8.js.map,sha256=HUXZniqfvkW-4MvSZBF4NAnnzQ7oT3XEjKFff2-WE0s,2794 +gradio/templates/node/build/client/_app/immutable/chunks/LineChart.C8bDl53w.js,sha256=RmC0g6w2orRWWJ59g_oQ0YslIJ6mJBm2xJctQwbC1bc,1130 +gradio/templates/node/build/client/_app/immutable/chunks/LineChart.C8bDl53w.js.br,sha256=8c1Wn8tPs1wSPlC7A0T3R8wRw6om1bCZMV58uKDSEAw,596 +gradio/templates/node/build/client/_app/immutable/chunks/LineChart.C8bDl53w.js.gz,sha256=jqRR4i2eiuC7xvawd2gaoWQ6jzAKhEgbBcCEvIrxOEU,660 +gradio/templates/node/build/client/_app/immutable/chunks/LineChart.C8bDl53w.js.map,sha256=BZzjQbHjl-pi18GBK3tlNgzFqyBT46voQHbUwOBE29s,692 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_audio_emitter.BlJQZ28w.js,sha256=BF2Cz67AB4v9_KbxISk8tWwDtfMpjr5Ba3PeJg80VE4,37503 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_audio_emitter.BlJQZ28w.js.br,sha256=suGhzjPNNI-SZkkLpP4X4MYPlGhxv3dX6UbQrWoG5kQ,7408 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_audio_emitter.BlJQZ28w.js.gz,sha256=2wOHckvcFz-I_JxEVd9ggfFnhdPiVn0Pp1bg_sPietA,8225 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_audio_emitter.BlJQZ28w.js.map,sha256=R6XYaOcmT2gpKZ9BS-gjni15HGhp2gYaSqIYFUde3kU,131895 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_lod.MXkIAcKE.js,sha256=KAHZFlDUOvuJa76-SyFoFmH3ScnPAFRttM7VaNchv5Y,5836 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_lod.MXkIAcKE.js.br,sha256=WYuhEbJ7lolIv-TZLqaUUwQqXofQfPkv36rIgIw1JmM,1680 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_lod.MXkIAcKE.js.gz,sha256=be8f0Uh5SoXiNmP3mFnlPqxsQEeDjCRhvT1GVomabTQ,1837 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_lod.MXkIAcKE.js.map,sha256=eQ1IvExP6Xp4IGmbMPFYc3zslL8cQKyElxmitwa5d5g,22141 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_minecraftMesh.gCTYVD9T.js,sha256=cdke08C_mtkYm4rtUEhJI5pe_URfwwSIerw0P2VIYFI,747 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_minecraftMesh.gCTYVD9T.js.br,sha256=9t4KtuW8x07z_kAUM9u5YK60gDvzuM39_uiuzfac2jw,400 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_minecraftMesh.gCTYVD9T.js.gz,sha256=dZuNNfua0QJPwsllUIaL2qInvQz3h2oNICT4JnM6HBA,460 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_minecraftMesh.gCTYVD9T.js.map,sha256=VBJezMUW1ItR27oKI2N04z7sCyzJUn5wxzT6BAATUjs,2892 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_sRGBFactors.BReRsa1G.js,sha256=0j1LI1icj7OiHdvclGe9Kay7QffNq_qq_YFpwaGeUvA,815 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_sRGBFactors.BReRsa1G.js.br,sha256=uF8fkTzhsjYRiyLDFph5gneCi3AhHZa3QDVs8SvEjS8,416 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_sRGBFactors.BReRsa1G.js.gz,sha256=pa5SUlE5MDFm4_Ll_gQnQTiG7SyIH0bdHHbmgBEoEdE,470 +gradio/templates/node/build/client/_app/immutable/chunks/MSFT_sRGBFactors.BReRsa1G.js.map,sha256=-7C-OmYCME-jOHc3uxLlanAXyz2WVvbVp6Oz_pyDB9E,3140 +gradio/templates/node/build/client/_app/immutable/chunks/MatplotlibPlot.BqYrERW-.js,sha256=lzwuHGf8u8gxIHglZ9MDVXnLdR37VonTiAD2cSmv8Ac,1225 +gradio/templates/node/build/client/_app/immutable/chunks/MatplotlibPlot.BqYrERW-.js.br,sha256=J-xzH-_WXCAbgHbDn2hxJcA3anEoDExqvm7HpU66Khw,657 +gradio/templates/node/build/client/_app/immutable/chunks/MatplotlibPlot.BqYrERW-.js.gz,sha256=RSAOW2oPGysS2DTyB5skLT0jM4zp-sRFIVW05s0v8FE,719 +gradio/templates/node/build/client/_app/immutable/chunks/MatplotlibPlot.BqYrERW-.js.map,sha256=czS3CaVW9Fj14xMiCMBEmfyPBDLQxz-ruejWR6aj5MA,1191 +gradio/templates/node/build/client/_app/immutable/chunks/Maximize.DHMLY8eU.js,sha256=EYSmrSs66-7cnntUqZJnEZTLnkGaAaTR3MwHt_uKNbo,1125 +gradio/templates/node/build/client/_app/immutable/chunks/Maximize.DHMLY8eU.js.br,sha256=XKj1w_swSw40PxzWqeWZ44w4nZqLys6Rrn4C8cjfHSc,562 +gradio/templates/node/build/client/_app/immutable/chunks/Maximize.DHMLY8eU.js.gz,sha256=8TxDjeoOyxhcsbdV0DRtJuAIoIiQlaefyDrlp038QjU,624 +gradio/templates/node/build/client/_app/immutable/chunks/Maximize.DHMLY8eU.js.map,sha256=yhYrmtHSuP5YAc7BhfmI_OQbyxvzqE1GgJCLWQJVLA0,683 +gradio/templates/node/build/client/_app/immutable/chunks/ModifyUpload.CvD_-4A2.js,sha256=YRGu74visAR5DmibLhTKtT33DIGYGtvn22M54dbTakM,3945 +gradio/templates/node/build/client/_app/immutable/chunks/ModifyUpload.CvD_-4A2.js.br,sha256=myMNK3TNrmWzcMP6QHot-5PbTOZxkej9LYk1NOYYTxM,1267 +gradio/templates/node/build/client/_app/immutable/chunks/ModifyUpload.CvD_-4A2.js.gz,sha256=HlfHDH_MfPTXSmalbYeY9iiQva3K0qWiKm108yQ_UvE,1457 +gradio/templates/node/build/client/_app/immutable/chunks/ModifyUpload.CvD_-4A2.js.map,sha256=sfhjnCBhyOFsimsJp-47X-4PW1IoDtL5_q43mMNI46w,2398 +gradio/templates/node/build/client/_app/immutable/chunks/Music.BVFRDHso.js,sha256=WBwadFnbb5RuIDVdY_b21jjuFMfUtO5l_HeTVd42bzY,1268 +gradio/templates/node/build/client/_app/immutable/chunks/Music.BVFRDHso.js.br,sha256=8pCrnrtRT0W-YOcXM4o4bQCDlw8cJvsSRN89tBDnpK0,589 +gradio/templates/node/build/client/_app/immutable/chunks/Music.BVFRDHso.js.gz,sha256=qk8BjqEapn5IZpI_WZI9IiAwMcxPQ6g7JAuxpM87pls,657 +gradio/templates/node/build/client/_app/immutable/chunks/Music.BVFRDHso.js.map,sha256=RV3q8y0IRNGtrnEI-WFYzDxPsscDqbwjBpy0Du_Aqw4,733 +gradio/templates/node/build/client/_app/immutable/chunks/Play.DJ4h2PVY.js,sha256=747kXRqXjpxmsfgUA_D4MtEtKXweEGsnuAIVanix0t8,1015 +gradio/templates/node/build/client/_app/immutable/chunks/Play.DJ4h2PVY.js.br,sha256=__vGq14VouGc5StVx3H7cegM3P_6izQU210qu4xwUYY,508 +gradio/templates/node/build/client/_app/immutable/chunks/Play.DJ4h2PVY.js.gz,sha256=RWQQf8CEz3dI47ZeiShO3qm2BSTkMTOIlqR_Ld5s6iE,574 +gradio/templates/node/build/client/_app/immutable/chunks/Play.DJ4h2PVY.js.map,sha256=Awln5Y0mROvZvFq_A51RNW6R_JE85N0LWi9TtDi38BY,565 +gradio/templates/node/build/client/_app/immutable/chunks/Plot.U_zOHmzW.js,sha256=0Y9bJI0Xbh1cc7IB02pJ0JPKYRxoman0slZlYpRC9P8,7172 +gradio/templates/node/build/client/_app/immutable/chunks/Plot.U_zOHmzW.js.br,sha256=5xSui4c39Qt0sMpVcs8Oz1DCaF1eJKdTB822wP8xXK4,2767 +gradio/templates/node/build/client/_app/immutable/chunks/Plot.U_zOHmzW.js.gz,sha256=KqcetWerc5ND_xvvL51jgyMWcNCjFWU_0ic7t4VPeOE,3049 +gradio/templates/node/build/client/_app/immutable/chunks/Plot.U_zOHmzW.js.map,sha256=ZCtmY_iuYdZYKNFUJ_I47sfs79WgcyPOzKePlhHC9MA,4826 +gradio/templates/node/build/client/_app/immutable/chunks/PlotlyPlot.DdBOSlhv.js,sha256=I6QEltUuKl6CBpQRzYlYXRiRYMTH4iO0u4AEViyDd9c,4620031 +gradio/templates/node/build/client/_app/immutable/chunks/PlotlyPlot.DdBOSlhv.js.br,sha256=8ztWnwRBqd_d0oZoDLy2Bq1IKFVSGKsxo6ES5h_bcgw,1062494 +gradio/templates/node/build/client/_app/immutable/chunks/PlotlyPlot.DdBOSlhv.js.gz,sha256=Km07nuNnI8_WUDJkgGjaP06NKalydVNTFyFa6RUfoow,1396763 +gradio/templates/node/build/client/_app/immutable/chunks/PlotlyPlot.DdBOSlhv.js.map,sha256=gae7weS9cYWO34ozBMtQonS_o8pKNHMa2I0HpSf3PuY,10944067 +gradio/templates/node/build/client/_app/immutable/chunks/Plus.aV-xa-_T.js,sha256=hq0zP0wibcbM4RUtj-iynHhiDKykjw8X0784fke2Ni0,1007 +gradio/templates/node/build/client/_app/immutable/chunks/Plus.aV-xa-_T.js.br,sha256=EgkC0QQwjn14OQ6vv8KK9ot2s6jL6mHnpzvQT4XAYCw,501 +gradio/templates/node/build/client/_app/immutable/chunks/Plus.aV-xa-_T.js.gz,sha256=JeSQJrLiWW0Xns9BaFnK9ymCiX_ocHnpRKUGziYToSc,570 +gradio/templates/node/build/client/_app/immutable/chunks/Plus.aV-xa-_T.js.map,sha256=_LL7DkXgw3Yy8Q4o-g3OfoOWvO67dwHOTey8ETI1vZQ,581 +gradio/templates/node/build/client/_app/immutable/chunks/SelectSource.Bcc6RRAW.js,sha256=WRrUMnlqMVH4lca2Vafnaa_wEgPTgknFxEtNeUQq8FE,8080 +gradio/templates/node/build/client/_app/immutable/chunks/SelectSource.Bcc6RRAW.js.br,sha256=9y_pRD02DhxzLqf8b0zvcJ67shjk3guMmz15LilgGC8,2241 +gradio/templates/node/build/client/_app/immutable/chunks/SelectSource.Bcc6RRAW.js.gz,sha256=ysOkV579QkyMgMJ6i7U4DeUkrseBv-Yk5kSUl4B3Aew,2593 +gradio/templates/node/build/client/_app/immutable/chunks/SelectSource.Bcc6RRAW.js.map,sha256=YTRiLv5oYbE9BOSbZp1SQP7q0tFIZkK8Su8q8PGukcU,6543 +gradio/templates/node/build/client/_app/immutable/chunks/Settings.Q4E84YTL.js,sha256=_avdu29retf3SaW5MHt3n07z1SEjYZys9sdMyTfkE10,13208 +gradio/templates/node/build/client/_app/immutable/chunks/Settings.Q4E84YTL.js.br,sha256=uneKv0S6GlN0ikhYTy6arjrzzNW8PowUVBM98qm-PR0,4169 +gradio/templates/node/build/client/_app/immutable/chunks/Settings.Q4E84YTL.js.gz,sha256=ACMbNSXNW4Am2tS3bKaR0bNx5a_GP_nov2on9Zgq6sw,4918 +gradio/templates/node/build/client/_app/immutable/chunks/Settings.Q4E84YTL.js.map,sha256=OY0c1zeGHIKYD6gI7koPw8dKJOQd3taFIdTfMCCsQPM,14980 +gradio/templates/node/build/client/_app/immutable/chunks/ShareButton.DGoOl7Be.js,sha256=rFxVb9w2WJOWxMubIEa98HMl8O67fGYZj-hSv5akbHc,1265 +gradio/templates/node/build/client/_app/immutable/chunks/ShareButton.DGoOl7Be.js.br,sha256=dtfXhz0gFXQye1b7Dco7v3mNh-5_lrrImOO5uxK7hNA,641 +gradio/templates/node/build/client/_app/immutable/chunks/ShareButton.DGoOl7Be.js.gz,sha256=L5qBUioxOOwiJjYVPsQVFIJYGKziWvMkSKIzkDC7eUc,732 +gradio/templates/node/build/client/_app/immutable/chunks/ShareButton.DGoOl7Be.js.map,sha256=ykorIxUQLoExB2_ZqM3ixugM_KerTQhPMDhGxKMD2B0,1797 +gradio/templates/node/build/client/_app/immutable/chunks/SharedSystems.C7xs3BKD.js,sha256=_BhPLjB9QgQw_TE7zV4nBGjGh2Nba7JBFkxghHpq8Xw,50509 +gradio/templates/node/build/client/_app/immutable/chunks/SharedSystems.C7xs3BKD.js.br,sha256=DXQdyGli2eRNTIOPd37RY_-LEVdAPd3U7DcXmDYHJ_k,12390 +gradio/templates/node/build/client/_app/immutable/chunks/SharedSystems.C7xs3BKD.js.gz,sha256=tU_SWlupaYDZpaqDqSzgUD1tTMdc-8BuaoXeNb8wYvI,13605 +gradio/templates/node/build/client/_app/immutable/chunks/SharedSystems.C7xs3BKD.js.map,sha256=3X-OifKhfIPNY1yNvOVEpl1TR-Osq2hIiVr80ppFmPI,173374 +gradio/templates/node/build/client/_app/immutable/chunks/StaticAudio.Bekpn_j4.js,sha256=zZfVqV1BC8ePfpcGwJJbzkgfgKRfQRf2dGSz5oKsh08,6292 +gradio/templates/node/build/client/_app/immutable/chunks/StaticAudio.Bekpn_j4.js.br,sha256=Q0t8s1b9-jCcxAleIucaSW6EleYz1_TEpfS61TtnoZw,2064 +gradio/templates/node/build/client/_app/immutable/chunks/StaticAudio.Bekpn_j4.js.gz,sha256=ikYAYR1e0di0GasTjxn9jFnZXjZNS72mJs49v9yVDn0,2356 +gradio/templates/node/build/client/_app/immutable/chunks/StaticAudio.Bekpn_j4.js.map,sha256=fOc1UES0qq57ZaoYPap9U4TTKMGcrduXCw0lhfCQ24I,4466 +gradio/templates/node/build/client/_app/immutable/chunks/StreamingBar.DNa2Ucrh.js,sha256=CE1Xmsln-nD7rDHnbLeLZZtzFzfgAFXKhy5J2Vxezz4,1037 +gradio/templates/node/build/client/_app/immutable/chunks/StreamingBar.DNa2Ucrh.js.br,sha256=Iin7iRs-7A4GKO3e9tdtvy7Vw0F6WbP1G0HdzC2KNuE,566 +gradio/templates/node/build/client/_app/immutable/chunks/StreamingBar.DNa2Ucrh.js.gz,sha256=PyINdUGMyRHMpek9pVzG0uejzWvOBCshY5pi6RBbMj8,599 +gradio/templates/node/build/client/_app/immutable/chunks/StreamingBar.DNa2Ucrh.js.map,sha256=EYnauF3QeYlT4dhe6KJ9isoR6CbH9UJ5m8xGNpQFgt0,981 +gradio/templates/node/build/client/_app/immutable/chunks/Trash.D4IfxcH_.js,sha256=S_gm_ZH_7WaVcOT2lduB7lZmDy7pLBPODmWhpDhEUw4,1795 +gradio/templates/node/build/client/_app/immutable/chunks/Trash.D4IfxcH_.js.br,sha256=6JHJqbYrPhTcDqIONd7NwvBiKIU_0CrEEx_3QQNcFZE,749 +gradio/templates/node/build/client/_app/immutable/chunks/Trash.D4IfxcH_.js.gz,sha256=VQJFL7dBnn7A4tJLj36picqeF0Zx8uOqr7Zb-ceCRFw,835 +gradio/templates/node/build/client/_app/immutable/chunks/Trash.D4IfxcH_.js.map,sha256=8fLNDScDWYNeglJks9njTj1l2KB7Rc-DtxySLAPMuTg,1162 +gradio/templates/node/build/client/_app/immutable/chunks/Trim.CWFkmJwA.js,sha256=50R_IBDFKrbBvLN6bVQvoikbHK0l7RLAo1hcu5OOgL0,2490 +gradio/templates/node/build/client/_app/immutable/chunks/Trim.CWFkmJwA.js.br,sha256=jkzD6X4H8jHkn_Yo7A0q0sBUTSpFAralwICvi8Fqntg,766 +gradio/templates/node/build/client/_app/immutable/chunks/Trim.CWFkmJwA.js.gz,sha256=7Qzm-a1B3jgxJN0kVW7ib6j6GfX6BjGcWyZk0Bih_2I,863 +gradio/templates/node/build/client/_app/immutable/chunks/Trim.CWFkmJwA.js.map,sha256=2RObXvhh7eKdJx7aUSpZQXBOK9LAiEp2QA_d9wfgvLA,1465 +gradio/templates/node/build/client/_app/immutable/chunks/Undo.LhwFM5M8.js,sha256=4SqeNCWWFlFv0b5XWF_1RbPeftHK9wikJ4v3-Xd-NHA,1199 +gradio/templates/node/build/client/_app/immutable/chunks/Undo.LhwFM5M8.js.br,sha256=CS9RzfAlabuukLzGqcxUsDnh6dwjh4buy7BlaoF81m8,596 +gradio/templates/node/build/client/_app/immutable/chunks/Undo.LhwFM5M8.js.gz,sha256=Bsg4BkN4-kIvkk8Q-apfCSfL-OL4MdL-o1H1NlXLoB8,657 +gradio/templates/node/build/client/_app/immutable/chunks/Undo.LhwFM5M8.js.map,sha256=RbTYZ7Kdek13dPA_pAA_8RxuYjn2MxqO2XhfVRmuC4U,702 +gradio/templates/node/build/client/_app/immutable/chunks/Upload.BUk-D0qO.js,sha256=9AQETKdWQ6GfPjwf0dHJ69tAfh7pYNLpREBEhMsw1yM,14764 +gradio/templates/node/build/client/_app/immutable/chunks/Upload.BUk-D0qO.js.br,sha256=DlORKwzcDRb6ntYyFT71ds2VJ2jz9Tmjp3-JI-V8zHA,4985 +gradio/templates/node/build/client/_app/immutable/chunks/Upload.BUk-D0qO.js.gz,sha256=IAk7zDNUDx1xvvouptXfRmZkGwR71MMPop1UJ4DmEs4,5721 +gradio/templates/node/build/client/_app/immutable/chunks/Upload.BUk-D0qO.js.map,sha256=Wb846CANtrwz7SgcrYvddGNF98mLWMtZAkOtJSATE90,31363 +gradio/templates/node/build/client/_app/immutable/chunks/UploadText.OGQ6neng.js,sha256=6ad0MYKWxdmoWGsp-MNr-TL-y__sgrYO52-IYCfvKe8,4631 +gradio/templates/node/build/client/_app/immutable/chunks/UploadText.OGQ6neng.js.br,sha256=aQ3L3ZOxnPyKs3tVlhhRdsCwZrwwFtrcyMNDI4shF_Q,1805 +gradio/templates/node/build/client/_app/immutable/chunks/UploadText.OGQ6neng.js.gz,sha256=jVaLqcT-6PixUx8m2Mh5iWOap9w27jGTykMZ362NvJU,2024 +gradio/templates/node/build/client/_app/immutable/chunks/UploadText.OGQ6neng.js.map,sha256=viukkL07Myz6zN1aeOWwBapba3n_5Gi0sID4Z0iiqlY,5507 +gradio/templates/node/build/client/_app/immutable/chunks/Video.CE2Y9LYL.js,sha256=2MSU8k4Ov0u-71ZS7w_J_XVOi5dcidNAMQicq5G-xdU,1242 +gradio/templates/node/build/client/_app/immutable/chunks/Video.CE2Y9LYL.js.br,sha256=4KI8_yNLZAcRV1Hvi625Huv6x0x1pMdRI5RKENaTJnw,591 +gradio/templates/node/build/client/_app/immutable/chunks/Video.CE2Y9LYL.js.gz,sha256=6qwGmpl4qqNT1LYok2S3Lodil-NEsvYJdV7BQz1tl6A,653 +gradio/templates/node/build/client/_app/immutable/chunks/Video.CE2Y9LYL.js.map,sha256=BclVb-wTdOCWiJGdtUrKzyZjp7BdPYu4zHBaMxRtZJ8,702 +gradio/templates/node/build/client/_app/immutable/chunks/Video.CGJke9Z3.js,sha256=KcwmfkSmgQKrZZVw1Ux7KMBr-iYVL2mabg95NxI6Pi4,22205 +gradio/templates/node/build/client/_app/immutable/chunks/Video.CGJke9Z3.js.br,sha256=88jm42_PE-B-6lVWXRh5rNvC_mcZA-l0S4SSgZ1MWug,7118 +gradio/templates/node/build/client/_app/immutable/chunks/Video.CGJke9Z3.js.gz,sha256=8HXsA1022zr90VbRfDSD3-M2303rQnsGHJxVzOVZ-tQ,7988 +gradio/templates/node/build/client/_app/immutable/chunks/Video.CGJke9Z3.js.map,sha256=OgmMQqpY1Xc3iGme1g8P4Np1aMxnoIOgusMLQpswwfU,57471 +gradio/templates/node/build/client/_app/immutable/chunks/VideoPreview.B50aIx5n.js,sha256=QQYKdayAK1PLlPEFJuGjsDRpuqoc1d7QOzSdTydH_-8,26444 +gradio/templates/node/build/client/_app/immutable/chunks/VideoPreview.B50aIx5n.js.br,sha256=nASpudR7SweSVLQIcVxVlVDBhQPhLIvN2D86SZC9yIc,7863 +gradio/templates/node/build/client/_app/immutable/chunks/VideoPreview.B50aIx5n.js.gz,sha256=z3WT8CjsTVSfh336jxaDm3T04uPsTtoxkwkKVTIaxIg,9075 +gradio/templates/node/build/client/_app/immutable/chunks/VideoPreview.B50aIx5n.js.map,sha256=NGJoBqC_g1DyX7JTq032lmDJ-8LBNokdAukLxDzvRAc,34601 +gradio/templates/node/build/client/_app/immutable/chunks/Walkthrough.svelte_svelte_type_style_lang.CPZO0BXw.js,sha256=i2uXczX6RUhs74CQoCZxsTTHMQSgDVVLHRIl4MaS7DE,11475 +gradio/templates/node/build/client/_app/immutable/chunks/Walkthrough.svelte_svelte_type_style_lang.CPZO0BXw.js.br,sha256=1XU7Bu3NQov9vzWxjQXucaUKIdQkLTw5Tr57U_O1Sbw,3724 +gradio/templates/node/build/client/_app/immutable/chunks/Walkthrough.svelte_svelte_type_style_lang.CPZO0BXw.js.gz,sha256=jD4bOq17UYJA46sr2d37ztDH5DEgR-200_U9aNJq_Ac,4280 +gradio/templates/node/build/client/_app/immutable/chunks/Walkthrough.svelte_svelte_type_style_lang.CPZO0BXw.js.map,sha256=M-A2ZmFc-9749S7HBv13h5_CRy8u94-Dk2z1aVXozK8,18153 +gradio/templates/node/build/client/_app/immutable/chunks/WebGLRenderer.CEElA0M0.js,sha256=mKxWR-CjCRy0uy5H8wuOtTuXHMPOAC7Oo-ekYlbMaYA,62061 +gradio/templates/node/build/client/_app/immutable/chunks/WebGLRenderer.CEElA0M0.js.br,sha256=D5rAbLG2bry2AwH79VFM4folMzzlIh9LLPZQ_fmfV7o,15114 +gradio/templates/node/build/client/_app/immutable/chunks/WebGLRenderer.CEElA0M0.js.gz,sha256=aEhnp83xw7BzqPhIet4Tf8XLuXPYnjvSNgCZdKjDt0g,17041 +gradio/templates/node/build/client/_app/immutable/chunks/WebGLRenderer.CEElA0M0.js.map,sha256=E5Rsgudq3G_o4NAXhy5zTDr0yUTr1dTEM0F2vL6G9No,207652 +gradio/templates/node/build/client/_app/immutable/chunks/WebGPURenderer.BJkdAfFa.js,sha256=7hqiMSfxy6brKmETL5iCl0qX8vbFhTujjxJoUMzE5d8,36857 +gradio/templates/node/build/client/_app/immutable/chunks/WebGPURenderer.BJkdAfFa.js.br,sha256=lBMV9s4SLnv8DPQ1rJ7WTqTCFSrhjYh4WEtWNFpbq3o,9179 +gradio/templates/node/build/client/_app/immutable/chunks/WebGPURenderer.BJkdAfFa.js.gz,sha256=MpbfvmjvfO9uT3E3JA6wlo_mHIl-KdP8n4ncCL8Ooc0,10107 +gradio/templates/node/build/client/_app/immutable/chunks/WebGPURenderer.BJkdAfFa.js.map,sha256=zye_tKjH4RklOr5XCOzVTpht5PRCZEjNNdL-cRwYYts,124180 +gradio/templates/node/build/client/_app/immutable/chunks/__vite-browser-external.D7Ct-6yo.js,sha256=g0Lg8jQn30hzj74EBKeGjfMtk5Ljv6DVQreumH3ebJM,191 +gradio/templates/node/build/client/_app/immutable/chunks/__vite-browser-external.D7Ct-6yo.js.br,sha256=4IWczcLTN9kyT2pNG8tsb7smjzsSAGt0phGzM4ZeEbA,136 +gradio/templates/node/build/client/_app/immutable/chunks/__vite-browser-external.D7Ct-6yo.js.gz,sha256=6PQA8Ctthd1ILUn_BeGv3P-GNlUnedNgHnvdIJIsYrw,183 +gradio/templates/node/build/client/_app/immutable/chunks/__vite-browser-external.D7Ct-6yo.js.map,sha256=V8gVOvTzetLqdc9j_4XeFMQsNetN_PfoDwygl4N_nmk,221 +gradio/templates/node/build/client/_app/immutable/chunks/_basePickBy.BSRfEJvb.js,sha256=T0HYQpwefAHfW_xhRrExiJ6bDDgqVrYWxaRxhtYMgxA,2634 +gradio/templates/node/build/client/_app/immutable/chunks/_basePickBy.BSRfEJvb.js.br,sha256=4jT1GFHuEkxVup0qa8wSC2jyZXeki2glq39T-DKZXmE,1222 +gradio/templates/node/build/client/_app/immutable/chunks/_basePickBy.BSRfEJvb.js.gz,sha256=GyU3EHTFQk5WDe2FaNUDg7GAfm4QNHrLY1ighYRtj2A,1333 +gradio/templates/node/build/client/_app/immutable/chunks/_basePickBy.BSRfEJvb.js.map,sha256=eqx-JiUaBSUFeQdtvv7BHye-457Ex-BAx3paw7Dd3I8,26482 +gradio/templates/node/build/client/_app/immutable/chunks/_baseUniq.BvtLpZD7.js,sha256=JsyTJcWH7TxxpTl2NJNl4Y9kFxAx6yPweE1UChrUHNA,11967 +gradio/templates/node/build/client/_app/immutable/chunks/_baseUniq.BvtLpZD7.js.br,sha256=7zxj5Mi-RiLUgAR1LGiaY8XKLBx4mRz2XUCfcEO-Exc,4292 +gradio/templates/node/build/client/_app/immutable/chunks/_baseUniq.BvtLpZD7.js.gz,sha256=GCCCD0smKYgarfrQfC41bCcpiHP-C44oxdUK2MYr_xw,4675 +gradio/templates/node/build/client/_app/immutable/chunks/_baseUniq.BvtLpZD7.js.map,sha256=R3Y_mSutVFTIHJWamPiSfadSYL5899OaRamN1qVUta8,107670 +gradio/templates/node/build/client/_app/immutable/chunks/abstractEngine.cubeTexture.ELnmP5e-.js,sha256=2V5RPMixsH37Ofq0gh9_dY15U1qcavux17hxFjfWB7g,2168 +gradio/templates/node/build/client/_app/immutable/chunks/abstractEngine.cubeTexture.ELnmP5e-.js.br,sha256=Arz-y_WKig0hGDAeIqE-6XB7w_VUrc8MJiCy-Kt9-WE,969 +gradio/templates/node/build/client/_app/immutable/chunks/abstractEngine.cubeTexture.ELnmP5e-.js.gz,sha256=6ff3NLOeQcf3trJPZDlkoyn-hiwBnZ3v1b5qbFLtBAM,1090 +gradio/templates/node/build/client/_app/immutable/chunks/abstractEngine.cubeTexture.ELnmP5e-.js.map,sha256=AKub1YbUem7_tGuE3YfkUvgAw5_rgzc5hQzvxxptKX8,10096 +gradio/templates/node/build/client/_app/immutable/chunks/animationGroup.CYmPDV4x.js,sha256=rm9zfVT6VinCyWAKxdCwi-pBXxABn2Y5btf0OXAFGDk,34139 +gradio/templates/node/build/client/_app/immutable/chunks/animationGroup.CYmPDV4x.js.br,sha256=mXcHa9ZMVPCJWRaRusPPA3Z5pg7IQcFOi8WuBwBGDeA,7916 +gradio/templates/node/build/client/_app/immutable/chunks/animationGroup.CYmPDV4x.js.gz,sha256=lKiViP7IB6AFQKu09phVyIKVyax8rua65y-pjl9W-yg,8670 +gradio/templates/node/build/client/_app/immutable/chunks/animationGroup.CYmPDV4x.js.map,sha256=KbnYyADzg6zDndjsw3ESu08tPIyTrsk9A03ozSSwBLE,150676 +gradio/templates/node/build/client/_app/immutable/chunks/ar.CANZ1fin.js,sha256=DnBtIyjx6GjZvTqIjaP_S97CZTxpBB9LQixZ7F4on_o,6246 +gradio/templates/node/build/client/_app/immutable/chunks/ar.CANZ1fin.js.br,sha256=5ONRAsAKq_7ay9-JT2M6gBOqPMhrUmT9NNV8OB8Qakg,2187 +gradio/templates/node/build/client/_app/immutable/chunks/ar.CANZ1fin.js.gz,sha256=28ORJEpfdZ2Njs2X5ThYloZBISFJpF2wTG7Y4NJcshE,2636 +gradio/templates/node/build/client/_app/immutable/chunks/ar.CANZ1fin.js.map,sha256=70qwrvB3hwKbuKLUtTJfrPSKASIoTXbZYPNNkUJM3eo,95 +gradio/templates/node/build/client/_app/immutable/chunks/arc.D5BN-xhm.js,sha256=wck35hQwHip8XLJG1Xc68OrOxTE1d-IDiDHVHHOiylU,3459 +gradio/templates/node/build/client/_app/immutable/chunks/arc.D5BN-xhm.js.br,sha256=ucmQQiHeXXTzbTL8YDDnoXW_j5gY2iJvHGYRR_28sNE,1322 +gradio/templates/node/build/client/_app/immutable/chunks/arc.D5BN-xhm.js.gz,sha256=K0fNE7J8GHpB-jOjOiO3no3XOxJHZvy1UJnd80taMAA,1474 +gradio/templates/node/build/client/_app/immutable/chunks/arc.D5BN-xhm.js.map,sha256=FAq7EhuuJn3WNr4THs5nmnTxzuBHUi9lSrArBvIQYxY,17005 +gradio/templates/node/build/client/_app/immutable/chunks/architecture-O4VJ6CD3.FMkApkMd.js,sha256=l1Jwhxt5cVgP-ZiloALX5F-aArTIjOQrMzMEPVMxxME,185 +gradio/templates/node/build/client/_app/immutable/chunks/architecture-O4VJ6CD3.FMkApkMd.js.br,sha256=-K9DSYA6AQGv-HcJIGNzUxI9O5HebdxUgs6rxcJdx1I,135 +gradio/templates/node/build/client/_app/immutable/chunks/architecture-O4VJ6CD3.FMkApkMd.js.gz,sha256=OtE4hTbCAIW4trqO39QgI5hSMhiFgS96KyK_nfZfC6M,168 +gradio/templates/node/build/client/_app/immutable/chunks/architecture-O4VJ6CD3.FMkApkMd.js.map,sha256=_FibphBwChjBYMGaNrwQQuGwFpKIL6dUh7Qf6z6k_C8,114 +gradio/templates/node/build/client/_app/immutable/chunks/architectureDiagram-KFL7JDKH.Dy3ZPgt-.js,sha256=Php4Hvlart1C_RKvSdUEc1mwoAqw_mPeJ1sTAwMeU4E,148640 +gradio/templates/node/build/client/_app/immutable/chunks/architectureDiagram-KFL7JDKH.Dy3ZPgt-.js.br,sha256=p8WncSGRLoDe5bpBYFOFuVFxCOJ0K0D8CFFgpRw4CAI,36153 +gradio/templates/node/build/client/_app/immutable/chunks/architectureDiagram-KFL7JDKH.Dy3ZPgt-.js.gz,sha256=MkzdK48LMqR0I8ga4MoJJAHYXVb_71X9Vumh4wscYMc,41648 +gradio/templates/node/build/client/_app/immutable/chunks/architectureDiagram-KFL7JDKH.Dy3ZPgt-.js.map,sha256=NDMXkV5FsMXAnqzGEJ5lp--6CIDmNl4e-tGi0FRMXGY,590683 +gradio/templates/node/build/client/_app/immutable/chunks/assetContainer.w1CRG79i.js,sha256=GbOCCPZrBub97EItFB-kZGUnsKJ0ufLZm_EcqwLeW0Y,25166 +gradio/templates/node/build/client/_app/immutable/chunks/assetContainer.w1CRG79i.js.br,sha256=0gtP0OPVOd3qdivDWIgr7DR5LXcPik6xc3Fw5DymyUc,5769 +gradio/templates/node/build/client/_app/immutable/chunks/assetContainer.w1CRG79i.js.gz,sha256=oT_AOqVUJXnmP0v9PIBRh7n0HTC4geukyw2L-e_dZrs,6387 +gradio/templates/node/build/client/_app/immutable/chunks/assetContainer.w1CRG79i.js.map,sha256=4ypFTj96U17dXdvSfnKOX-OFkAEhiH7ZW4fTQs-rwl0,101697 +gradio/templates/node/build/client/_app/immutable/chunks/audioEngine.7qgWwRWJ.js,sha256=JsD3amPMAhhc9o58xdAzy4RjEyuTqNFDxfdSSQKAsEM,6043 +gradio/templates/node/build/client/_app/immutable/chunks/audioEngine.7qgWwRWJ.js.br,sha256=7DWhEuY3tVKvQxl2p-6IPKCSSE7o_5aAzm0Dm8C8tMc,1709 +gradio/templates/node/build/client/_app/immutable/chunks/audioEngine.7qgWwRWJ.js.gz,sha256=QQn_l7hGjJ_aAIgg5yHJAYntfMa_3XVKreQKSvea5gU,2013 +gradio/templates/node/build/client/_app/immutable/chunks/audioEngine.7qgWwRWJ.js.map,sha256=bbUUQIdq5M9lKIDrJ6dfw-F3ir8sy7v2Xb6Z4PMWybA,17158 +gradio/templates/node/build/client/_app/immutable/chunks/auto-render.-xYVjNAk.js,sha256=VILVLOvH01zVB5n60jUCQy15jINCH24uTwTPSXC2uNc,2663 +gradio/templates/node/build/client/_app/immutable/chunks/auto-render.-xYVjNAk.js.br,sha256=VLX-_hdmA8JscZilC2SeahjWuqiHnOZW6myyeSrLnvM,1108 +gradio/templates/node/build/client/_app/immutable/chunks/auto-render.-xYVjNAk.js.gz,sha256=z7bSyDnMIT8V3zFl71z7f-cSbBctsoXUXUEdFWqFISg,1263 +gradio/templates/node/build/client/_app/immutable/chunks/auto-render.-xYVjNAk.js.map,sha256=U1pNAjmX3aVV3M1OJW_U0lk1-7qqHb48QPG4m4d9ZAk,11164 +gradio/templates/node/build/client/_app/immutable/chunks/bakedVertexAnimation.CQvassfi.js,sha256=AkZt7BMSbJd8rvK4oTsorFB5DFLiy7GZHBYSc0arjr0,5718 +gradio/templates/node/build/client/_app/immutable/chunks/bakedVertexAnimation.CQvassfi.js.br,sha256=BrZl7zBwy-kl0BRjSSXWI45fKeMMVxAQyIhM4pOyHYg,1039 +gradio/templates/node/build/client/_app/immutable/chunks/bakedVertexAnimation.CQvassfi.js.gz,sha256=JkDkjuHMVnRvbOsxdpRZl9MsdejP36FWSHpOlgWY5ys,1181 +gradio/templates/node/build/client/_app/immutable/chunks/bakedVertexAnimation.CQvassfi.js.map,sha256=CfwLJshmfA6LalJOY5Z9woRHT9lXi4tsacHntPjBxWg,8445 +gradio/templates/node/build/client/_app/immutable/chunks/basisTextureLoader.C08JXk7e.js,sha256=sBb0FQXgJ2Hm2CrYqpgU58wXs-L7TWuapUffTwu9iNw,8416 +gradio/templates/node/build/client/_app/immutable/chunks/basisTextureLoader.C08JXk7e.js.br,sha256=dS1uBeDeKpWPWWHVSuoXOPhNlSY76qC0pDbEekaUxHI,2970 +gradio/templates/node/build/client/_app/immutable/chunks/basisTextureLoader.C08JXk7e.js.gz,sha256=gBZRaPJ6z7HeODEkar1Ti9JTGoJs0FG5I-IYzfslpLc,3315 +gradio/templates/node/build/client/_app/immutable/chunks/basisTextureLoader.C08JXk7e.js.map,sha256=C8_z86UabtMxRRfBJ93aoTSC6q9zj0qgbzgooenFU3w,38807 +gradio/templates/node/build/client/_app/immutable/chunks/blockDiagram-ZYB65J3Q.HHwW89O3.js,sha256=QVdv4iU9-PyyLDxSwFuDl_HfgNuMC6ALO7DyANY_GW0,73217 +gradio/templates/node/build/client/_app/immutable/chunks/blockDiagram-ZYB65J3Q.HHwW89O3.js.br,sha256=dg45a9K1_o6faATetYa75fj_S9bVlovJonGZbb5b6W0,18402 +gradio/templates/node/build/client/_app/immutable/chunks/blockDiagram-ZYB65J3Q.HHwW89O3.js.gz,sha256=aLk-4mXglJj-xXOh1shB5V7X4rhtKAksjzxqL5a5PYE,20614 +gradio/templates/node/build/client/_app/immutable/chunks/blockDiagram-ZYB65J3Q.HHwW89O3.js.map,sha256=4xA2Hkj6Ol2oF_j5lEuQLq95uoDKH7hXWk1AlN4r9YY,247921 +gradio/templates/node/build/client/_app/immutable/chunks/bone.F-7hGbXp.js,sha256=V147sTCLJ1u7sE6i2oCZ9-uZEPeWqPJKEhBdUdkt_Ys,12091 +gradio/templates/node/build/client/_app/immutable/chunks/bone.F-7hGbXp.js.br,sha256=-zu2_3aDd51AF4EWzuVtwYMfxD11DHKNHk0zo8KzjYQ,2497 +gradio/templates/node/build/client/_app/immutable/chunks/bone.F-7hGbXp.js.gz,sha256=Qq0WdNMy0B4l2iHJ0u0fJZnCw_g6BLXuY_mVjd5Lsxo,2721 +gradio/templates/node/build/client/_app/immutable/chunks/bone.F-7hGbXp.js.map,sha256=8Lsm_jrB7Vi-Yg9y4pfH8_g2r1UfX3noSwz7tGKKuZI,56890 +gradio/templates/node/build/client/_app/immutable/chunks/browser.DUWpyp6K.js,sha256=Q__MO0xtkRAQ_qbZZl2LOsWljJFY5cuQz4Tz8uA_xiA,611 +gradio/templates/node/build/client/_app/immutable/chunks/browser.DUWpyp6K.js.br,sha256=jQCnrzS8idxMNl0GVQp1fNPDUaKXv7RiBYj4LmOsqOc,367 +gradio/templates/node/build/client/_app/immutable/chunks/browser.DUWpyp6K.js.gz,sha256=0PkxEVBLS_AgAKQ_J-PnAGPfkhlwWJ8o32u699qIsxM,435 +gradio/templates/node/build/client/_app/immutable/chunks/browser.DUWpyp6K.js.map,sha256=srtP_04SSagBx0bvR8xQB_0FdpK0K5RCdbrDhwlvJfA,473 +gradio/templates/node/build/client/_app/immutable/chunks/browserAll.D-bwoqhk.js,sha256=3ek4ajzw3FRkhH5CRM7ItGJMSuQyF59qZl1h4G7vP4I,39330 +gradio/templates/node/build/client/_app/immutable/chunks/browserAll.D-bwoqhk.js.br,sha256=DbmIPuTLM3ZKLGH4qvBLlFW7OJO6iA3Hn8cg3U1Ag8s,9101 +gradio/templates/node/build/client/_app/immutable/chunks/browserAll.D-bwoqhk.js.gz,sha256=e7xsx80DshXp9A1VN-uCDzMh9rraQ2O05azP1mkOKgU,10315 +gradio/templates/node/build/client/_app/immutable/chunks/browserAll.D-bwoqhk.js.map,sha256=sFeo_xDY9T-5KSQNRAZmLKFmZ3VcFvUcIh95KcLOncM,155745 +gradio/templates/node/build/client/_app/immutable/chunks/c4Diagram-AAMF2YG6.DheyfHD2.js,sha256=_F7pFYzwHuzB-YRzPzX_g1eNU8x8V0q5XpgEjCbRD5M,70206 +gradio/templates/node/build/client/_app/immutable/chunks/c4Diagram-AAMF2YG6.DheyfHD2.js.br,sha256=kQITVQmc2Ix4LLQjkKSN9AGGEv6LCuFaTz04sJl8Uqg,15898 +gradio/templates/node/build/client/_app/immutable/chunks/c4Diagram-AAMF2YG6.DheyfHD2.js.gz,sha256=Uta0NqXsu81Hc6jqD3SsZsyZbJs7-pdp6dqvPt9php0,19527 +gradio/templates/node/build/client/_app/immutable/chunks/c4Diagram-AAMF2YG6.DheyfHD2.js.map,sha256=QYvUQX51uVLINJAwDkvPTT2QqVE9Z_I9yrs8I-P-2Cs,203869 +gradio/templates/node/build/client/_app/immutable/chunks/ca.BawhR5IW.js,sha256=Bm039suQ2MdXV3iAzy7F_P1Yyd0Rypr0ke1mhvcMBL4,4816 +gradio/templates/node/build/client/_app/immutable/chunks/ca.BawhR5IW.js.br,sha256=_RDEqKh40_D4F2rbAmY3-Sya-3JxXmlwjyHzwMM3Niw,2090 +gradio/templates/node/build/client/_app/immutable/chunks/ca.BawhR5IW.js.gz,sha256=bBNzGuxxgCrZja-3LLuYritY3Vknm5EuYIbahHeU4RY,2282 +gradio/templates/node/build/client/_app/immutable/chunks/ca.BawhR5IW.js.map,sha256=3cTJ7FOfa27B1P0e5wwV0S32yPJ2WKptr4w-OcSRK-8,95 +gradio/templates/node/build/client/_app/immutable/chunks/channel.rvlSQJk_.js,sha256=MDzTHeoIlYaqLodXJkM5Id1rWmXJhF5rynDa6yXtUKA,158 +gradio/templates/node/build/client/_app/immutable/chunks/channel.rvlSQJk_.js.br,sha256=ah6gvrM0FsuwZDj3jQ_2symbDCe9WuFwmUhVms5K-iA,156 +gradio/templates/node/build/client/_app/immutable/chunks/channel.rvlSQJk_.js.gz,sha256=XR6yIDH0N66IEFlQ5fKRdmWmLWoTDopTBo_q_w1OFOM,163 +gradio/templates/node/build/client/_app/immutable/chunks/channel.rvlSQJk_.js.map,sha256=G22nw5zBlb6v4O3W9Ymbgsk5KnW8LIIYew5FZsDFKN8,579 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-ANTBXLJU.C7o1p9v-.js,sha256=7Io0_Gjyam3BzLAmivHGVWfRz_kl9t7Ezcp7G-3oDT4,349 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-ANTBXLJU.C7o1p9v-.js.br,sha256=BQ0N2tWh3FCHSCGChkU-h2ZvLcA442Zgh0MYYGAFFmM,214 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-ANTBXLJU.C7o1p9v-.js.gz,sha256=YGNZL28qm_y57fM9KtxMK1v-60EoGEcg1IDwQTVgw2g,250 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-ANTBXLJU.C7o1p9v-.js.map,sha256=fcW8QCN1NeWiz-RSpHh0Jlnt5aWTTTY2F46a0K6JQSs,989 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-FHKO5MBM.DI5oLZlu.js,sha256=GmLSP8Ye1HiSbWkKwkOvAszInEu4dYmFQssW8XdYUx8,245 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-FHKO5MBM.DI5oLZlu.js.br,sha256=v7IDgk_LkDmxyQuoHaQcmYAVcYqEtmGre2mnwGayNm8,178 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-FHKO5MBM.DI5oLZlu.js.gz,sha256=ViU8WZdu9NaNPNPLv7H9vG2ddAGRo5JcvYZAV4J5AuQ,211 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-FHKO5MBM.DI5oLZlu.js.map,sha256=qpOPSpSSFfWUQ0H3xNbVugcTirePLoNFhuxtqZGm02I,878 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-GLLZNHP4.C5cUCvXL.js,sha256=OLenB-H7y7joh2cTHm4XnSWPB-K5pjlt1ly7vC9wQEg,418 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-GLLZNHP4.C5cUCvXL.js.br,sha256=JsFLt0JyXJLsqCWYfRgjXkYguOUbWr0iPTOjVxqNHSI,247 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-GLLZNHP4.C5cUCvXL.js.gz,sha256=Mf98sef01DUIASrrefWuemWx9W5r1ED3HF3Ic7z5BKM,319 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-GLLZNHP4.C5cUCvXL.js.map,sha256=_0uV1M-bLY1OaVQy9TUwXLBjGv4ElbVPQ9oVHXDQI3M,874 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-JBRWN2VN.CYZYINHs.js,sha256=ZkX85iMCc0Gbqi1azySA0gV2UY7C-mEX1eBQ21SqMm8,45388 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-JBRWN2VN.CYZYINHs.js.br,sha256=uAcIydyE8g9JTg4kRaR84LNkzsRrPSKYRy4U5jgz2xg,12233 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-JBRWN2VN.CYZYINHs.js.gz,sha256=8JT-44B3ELQ6xxt_dquSxjNRTIER9GAXO_zId1HmBac,14577 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-JBRWN2VN.CYZYINHs.js.map,sha256=LEEd56tMSckF4S9gtQMW1t_kj8arKlSOTA32Fi55N1M,139820 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-LXBSTHXV.B9gaZ9rb.js,sha256=q3y0RhNHWvY6zeEQBvQsrkL5unPBd7990OC4yIIt6cE,36850 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-LXBSTHXV.B9gaZ9rb.js.br,sha256=595OqzPR3QmtwxZwb_I0UUEA2GtBXzgtMImXr_pyQ8M,10531 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-LXBSTHXV.B9gaZ9rb.js.gz,sha256=ih-WwVnSv4FbBX2DY55-zhsVPXPBUjK-Mcc2iRmjckY,11884 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-LXBSTHXV.B9gaZ9rb.js.map,sha256=PHh6Xxeg01NmPSqfjttRJQKfFWQExgKfIpaaWJV2FwI,121823 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-NRVI72HA.BEyn9hui.js,sha256=3u64B02S36nmZP0ofNw8ndPOAh8Jsu-ZgTYk34nj5xw,584 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-NRVI72HA.BEyn9hui.js.br,sha256=Tvl-Hg4PjLoQ2CBOug-zYqVvxbsMGBwUzQCPMnAyM4w,374 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-NRVI72HA.BEyn9hui.js.gz,sha256=ImO7o8FXXW1KS0nhJa1Agroqg_iSEQ4HpNIrr9qvuZU,419 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-NRVI72HA.BEyn9hui.js.map,sha256=FkVW9KhQEkitldszKWF-3Mhg72wVNBBYEAgS1FYI4T8,2325 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-OMD6QJNC.CVGejw4R.js,sha256=qwlpHRJhIlKP30nEezMJ5mS7NbwQKD_bi67shG-vD0I,1465 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-OMD6QJNC.CVGejw4R.js.br,sha256=x0W1a5QO-qlZ21ess9KMWk2t0CdsbGZHbJ4IEQ4reJM,611 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-OMD6QJNC.CVGejw4R.js.gz,sha256=uYtK2NxZTuAml1kqYvZk2xwxTguk3wR_ZEKQ8jakTfs,674 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-OMD6QJNC.CVGejw4R.js.map,sha256=kcZT37rmvlECIuR_Hce9xQtDa-utJeJ4RStcdBto8Mk,5834 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-WVR4S24B.CJYggihH.js,sha256=6pSi6sefrw_gg0zwH_aCgGxsgVgdTdXZ3ewuLWxbg8c,321 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-WVR4S24B.CJYggihH.js.br,sha256=rQpWWDpzRXjII0LP9LcDE0DtT1ZdQJ6-CEnqLHWEn0s,240 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-WVR4S24B.CJYggihH.js.gz,sha256=omsSaCWyDZHsuDSaxEkCQBZdpIjtOuue3-CQH-J-INc,274 +gradio/templates/node/build/client/_app/immutable/chunks/chunk-WVR4S24B.CJYggihH.js.map,sha256=IXjkbQuyXZKnnyCymHxcFajg-VfRUbp9vt5XqmRsXL4,1127 +gradio/templates/node/build/client/_app/immutable/chunks/ckb.DJglGH6y.js,sha256=ujbiKyWYNRry69EmBP-gC3l69sWq9-6NVPq5ayFkwjY,6680 +gradio/templates/node/build/client/_app/immutable/chunks/ckb.DJglGH6y.js.br,sha256=LAUJi04YE7-0HE7xv0NHmRmJCNr5i7gjBmFG7Jngc78,2305 +gradio/templates/node/build/client/_app/immutable/chunks/ckb.DJglGH6y.js.gz,sha256=D71ezC3wz8bXa3BsP_osMCSI9Kit7z6GgjagSQ6vefk,2667 +gradio/templates/node/build/client/_app/immutable/chunks/ckb.DJglGH6y.js.map,sha256=DlYrq2XWy94zYjeSGgE-BxF6R2nrklsnZMdfSMXbhKw,96 +gradio/templates/node/build/client/_app/immutable/chunks/classDiagram-3BZAVTQC.CgO9vedN.js,sha256=2d6qlkFAdWKHnN4DKg2mt3sLuqKw2lHGJMSuQtSq2pw,350 +gradio/templates/node/build/client/_app/immutable/chunks/classDiagram-3BZAVTQC.CgO9vedN.js.br,sha256=YLQPTDXndydE2T5WwKp3CmYVUJ4ahrMJY8lK_ZfRrec,239 +gradio/templates/node/build/client/_app/immutable/chunks/classDiagram-3BZAVTQC.CgO9vedN.js.gz,sha256=jePioQiN3DQinFZc_t-eMNNI31wSBEtfgzoGnxj0me0,276 +gradio/templates/node/build/client/_app/immutable/chunks/classDiagram-3BZAVTQC.CgO9vedN.js.map,sha256=bN4iEoOBIeBz6Z5Pj8M3gCdq6mIcYOe8ZyiwW0v1bbQ,1550 +gradio/templates/node/build/client/_app/immutable/chunks/classDiagram-v2-QTMF73CY.CgO9vedN.js,sha256=aqevJvLYYwjNlq5hCXNBennQzLxF0xxjJ710KhQRtxQ,353 +gradio/templates/node/build/client/_app/immutable/chunks/classDiagram-v2-QTMF73CY.CgO9vedN.js.br,sha256=ZTDGRUIZ77SCSaYU8r6j3vthU2f3L9r2UTcLLcuj3Kk,242 +gradio/templates/node/build/client/_app/immutable/chunks/classDiagram-v2-QTMF73CY.CgO9vedN.js.gz,sha256=BgVTWRaXqVT9tqEcW_NsWYvGALIHZ6codOrEAQrqGTs,279 +gradio/templates/node/build/client/_app/immutable/chunks/classDiagram-v2-QTMF73CY.CgO9vedN.js.map,sha256=jfmlqsEH-sbmrCiGUVdhOpne9vfugzKjOAIBPskAGxo,1559 +gradio/templates/node/build/client/_app/immutable/chunks/clear.D_TEXRKD.js,sha256=6eK4XAbhfXUOMEK7E02thsR9AJvzyfV_McMkBBRY_Ew,1604 +gradio/templates/node/build/client/_app/immutable/chunks/clear.D_TEXRKD.js.br,sha256=SKRyGHSBmtwYZMp11Se-kx_s1_eeckt4T_wC8SkivTY,751 +gradio/templates/node/build/client/_app/immutable/chunks/clear.D_TEXRKD.js.gz,sha256=tYo4bhG9XtHz3nYHoo66VA_JXuD9p6kPlyXX3I9g0PY,834 +gradio/templates/node/build/client/_app/immutable/chunks/clear.D_TEXRKD.js.map,sha256=_pxxun7PeG0fz3mfLJtfh_IXa26tFTotAUKtBM-SlqA,1150 +gradio/templates/node/build/client/_app/immutable/chunks/client.CZs4mqb7.js,sha256=7VTXWvJ8bCRDghaPtlegBJoa4PWogZKbG4H2J_kdY3E,27120 +gradio/templates/node/build/client/_app/immutable/chunks/client.CZs4mqb7.js.br,sha256=Qd6F_IvwhjvEQknHMyLf8u0HeTNoXwm4LvAcqkZChmk,9704 +gradio/templates/node/build/client/_app/immutable/chunks/client.CZs4mqb7.js.gz,sha256=ARTJNqE-sDaxSnKOtpIb9MUZ-Man5uKtA3tju6P9tQ0,10702 +gradio/templates/node/build/client/_app/immutable/chunks/client.CZs4mqb7.js.map,sha256=PWOGN_Fle4NHgnRKE5ukEMX_0Qy6f3snJnbfoj1Adus,173315 +gradio/templates/node/build/client/_app/immutable/chunks/clike.wD8xDpL-.js,sha256=_3KW4KQkJWqqt1Xz-ZdMVUf6jffRTwKM5oPyLg72IbY,22363 +gradio/templates/node/build/client/_app/immutable/chunks/clike.wD8xDpL-.js.br,sha256=mN0L-nypOh0C1mv0qof11M3G5uZxQ-ZCtsVcusM7neo,6962 +gradio/templates/node/build/client/_app/immutable/chunks/clike.wD8xDpL-.js.gz,sha256=GUX5qtZpihF63EgJJbU4ne5DLkHW_1rlvMDzatX7B5k,7828 +gradio/templates/node/build/client/_app/immutable/chunks/clike.wD8xDpL-.js.map,sha256=Paj5qEpH6kOqFCyO7OzHG471EWcCVzrkNZCg-04-pV0,59705 +gradio/templates/node/build/client/_app/immutable/chunks/clone.BCkqZCIj.js,sha256=Tl24xknX59cCGnJU8vnJBjdt9Uqp24-dKrt2Xc5V3MU,139 +gradio/templates/node/build/client/_app/immutable/chunks/clone.BCkqZCIj.js.br,sha256=zClBlzK3t10J__JRxTRQ5N3ISmvNIDIGhOOIexWaWZ0,118 +gradio/templates/node/build/client/_app/immutable/chunks/clone.BCkqZCIj.js.gz,sha256=I80hRCPMLl3sejEz7XQldt4mnAqgcS5X6PtagCKfj5A,151 +gradio/templates/node/build/client/_app/immutable/chunks/clone.BCkqZCIj.js.map,sha256=aYru34GYwU5L6YLtWrSFEqLUXkCereht5BdO2MVtNfM,1444 +gradio/templates/node/build/client/_app/immutable/chunks/color.4zi1K3jK.js,sha256=pA6lM4P1WN_4gV2XhH-iDP6JJJQIHY_tRMSw4ebXUTE,115 +gradio/templates/node/build/client/_app/immutable/chunks/color.4zi1K3jK.js.br,sha256=rB2J0l8y_5nnOKLFwG4ECpXKFL3RDgYiKRrathJFiek,101 +gradio/templates/node/build/client/_app/immutable/chunks/color.4zi1K3jK.js.gz,sha256=wkxTEMSxJbuWFKImjUJlKWZqPJmUmgR5__tK820OOSo,131 +gradio/templates/node/build/client/_app/immutable/chunks/color.4zi1K3jK.js.map,sha256=ttkpPWyP9yzCRVDeWwZkDK10DoN6wRFVDdUkkVvnixw,424 +gradio/templates/node/build/client/_app/immutable/chunks/colorToUniform.KTpA7KSL.js,sha256=103RqjEA90KELxAumq2LyJrFzkoAPanxQSdxAhHC4-Q,1737 +gradio/templates/node/build/client/_app/immutable/chunks/colorToUniform.KTpA7KSL.js.br,sha256=TI0RIZZZhh9QKwD2KFO-8XI7MZqR7-ZymxOxT0gtCzI,600 +gradio/templates/node/build/client/_app/immutable/chunks/colorToUniform.KTpA7KSL.js.gz,sha256=DUZYKh8bCZWIMT5FBGrbJmMcHvPK-C7iBgmEcv5R2CQ,683 +gradio/templates/node/build/client/_app/immutable/chunks/colorToUniform.KTpA7KSL.js.map,sha256=wzfjNI0Tz1bY_uEOFFIAxQ2cZnuPKOR4gPCUkOrQEnY,4725 +gradio/templates/node/build/client/_app/immutable/chunks/cubeTexture.CrR7pXZF.js,sha256=XRZGsaf8GgEz2SPqFtBpWf7JjOphaqUyjHKk23KDMxc,6085 +gradio/templates/node/build/client/_app/immutable/chunks/cubeTexture.CrR7pXZF.js.br,sha256=lqgHe4UkL0af7z49DvUP-3saHJi-8XHLUICp2fqQNcs,1969 +gradio/templates/node/build/client/_app/immutable/chunks/cubeTexture.CrR7pXZF.js.gz,sha256=nwqD--ntHTCeI_EfoU1zKgaCCdGTw4Jj4iVG26k9CDY,2157 +gradio/templates/node/build/client/_app/immutable/chunks/cubeTexture.CrR7pXZF.js.map,sha256=RKeZIXfrxlvjoSxPEpeUPx-p50-VKhLpKF7oF1GKsRw,26236 +gradio/templates/node/build/client/_app/immutable/chunks/cytoscape.esm.BlEmlE64.js,sha256=BCr-GykT-zomKO-rOfxy1m7vPqHpuz6y5v3WGaZKIxA,425656 +gradio/templates/node/build/client/_app/immutable/chunks/cytoscape.esm.BlEmlE64.js.br,sha256=Rp7P7tRSWbgMnjj1aOaHhY6WsyUSNcVFHYJ6uK4ykzE,114825 +gradio/templates/node/build/client/_app/immutable/chunks/cytoscape.esm.BlEmlE64.js.gz,sha256=Mrhh6v_Xv6pIEIrYHR_-8Qd_zV4gnJh2dxoJiTqURF4,135391 +gradio/templates/node/build/client/_app/immutable/chunks/cytoscape.esm.BlEmlE64.js.map,sha256=2A5INq6DmjZlgZmtFDoQYWC7rgFp1ou7QnseqP-zDrM,1798360 +gradio/templates/node/build/client/_app/immutable/chunks/dagre-2BBEFEWP.c6K8ovLW.js,sha256=irFVrXqN_shAiCaa5svhHhfjJ8fJ6xNzeGokFO6AZaI,11292 +gradio/templates/node/build/client/_app/immutable/chunks/dagre-2BBEFEWP.c6K8ovLW.js.br,sha256=rAFh3bHyqOChJqG5xO-KE1lI4_Wkuv1GXkhflQWGWXI,3834 +gradio/templates/node/build/client/_app/immutable/chunks/dagre-2BBEFEWP.c6K8ovLW.js.gz,sha256=qF8kfKVfW0GQZVcmQyHE9eXPjRUxu1ixZ-CS1VtOWUE,4228 +gradio/templates/node/build/client/_app/immutable/chunks/dagre-2BBEFEWP.c6K8ovLW.js.map,sha256=7ZLWcMVG4hnjVDj10AS_7BxtLbvmn-4CiyMnOXmliO0,41948 +gradio/templates/node/build/client/_app/immutable/chunks/dds.BuwPYcco.js,sha256=4gqeoAs1x42fbEYbNfS7PVYhMv4NUNWF7I7r7L_zzKA,7092 +gradio/templates/node/build/client/_app/immutable/chunks/dds.BuwPYcco.js.br,sha256=I2XVyCo7JOxvJSw7LmA44PEa3W9fK7dwfITm0Cld888,2244 +gradio/templates/node/build/client/_app/immutable/chunks/dds.BuwPYcco.js.gz,sha256=Uh-ed4EtU45VWF4_zJOV8aWxx-QG3xE83zzLd8h_MM8,2489 +gradio/templates/node/build/client/_app/immutable/chunks/dds.BuwPYcco.js.map,sha256=iDwl97KsIGNbN6Yg-TRivZidL1MyH9SWDMykW90nP9U,38590 +gradio/templates/node/build/client/_app/immutable/chunks/ddsTextureLoader.CMsOIwCf.js,sha256=-wv96KFF6_YOhLd_iUJ0ZEb3pCCCc7kqs1iUNHPhCbI,1316 +gradio/templates/node/build/client/_app/immutable/chunks/ddsTextureLoader.CMsOIwCf.js.br,sha256=EVLtPZfItfQQUm5or1s6nKh4BCD7kovP8_rIkI1sWyY,596 +gradio/templates/node/build/client/_app/immutable/chunks/ddsTextureLoader.CMsOIwCf.js.gz,sha256=yaMsav3zHrGpKKFF5mx5hYGtHi8tMcEXDNPXSkxslwA,645 +gradio/templates/node/build/client/_app/immutable/chunks/ddsTextureLoader.CMsOIwCf.js.map,sha256=0rB76g-b6iRdRsHoqSq-4XpU8cDoj0WhP4T9rvcys8E,5762 +gradio/templates/node/build/client/_app/immutable/chunks/de.1aCSmaRd.js,sha256=k6TT14FZ7-TJ9jqL6HqLJiLKQLLPJLUk3V2AlFbcHU4,4905 +gradio/templates/node/build/client/_app/immutable/chunks/de.1aCSmaRd.js.br,sha256=_Z4b-Euf7KPWfjEIk8A15G5G8qC0jsw-sedycXCNLb4,2095 +gradio/templates/node/build/client/_app/immutable/chunks/de.1aCSmaRd.js.gz,sha256=XD4YaazXHUebezwZBlfdkUWDCwszU0wZULkh2vbogPM,2298 +gradio/templates/node/build/client/_app/immutable/chunks/de.1aCSmaRd.js.map,sha256=4dKNn4ZzqoQeVhr3C2BQHiRq-fIYKSOXZmFo3LD_we0,95 +gradio/templates/node/build/client/_app/immutable/chunks/decalFragment.gy9apl3R.js,sha256=Tn1_N5-vZS9zSFotlYjiUqTtXLqEDPT-L4FBO32JihE,490 +gradio/templates/node/build/client/_app/immutable/chunks/decalFragment.gy9apl3R.js.br,sha256=ENoB_qhPcqbQy_dUU9Q5eT-ftAZ5xtj4D9zMDnNB2j8,259 +gradio/templates/node/build/client/_app/immutable/chunks/decalFragment.gy9apl3R.js.gz,sha256=He19LWcTQ0XYL9ufqp1jt3T8Skd69NOUNWCztiyxBMI,289 +gradio/templates/node/build/client/_app/immutable/chunks/decalFragment.gy9apl3R.js.map,sha256=IlxsVbyCHkCG7hCrvrDdczbdDQg41RAunsg8kUbPM5E,1121 +gradio/templates/node/build/client/_app/immutable/chunks/declarationMapper.UBCwU7BT.js,sha256=CS5RQnGrCcc0fnwgqZV53OTIW_tFIl-rzhGvVtW-_Cw,32457 +gradio/templates/node/build/client/_app/immutable/chunks/declarationMapper.UBCwU7BT.js.br,sha256=nfpbhqTt1zceaLVX9YD2zkiigUKJLkvVGw6Gng1dByQ,5599 +gradio/templates/node/build/client/_app/immutable/chunks/declarationMapper.UBCwU7BT.js.gz,sha256=6UVMmBsxG_kNnKlMXXrxojV43lnQkVLlRwDzmaaN4eE,6376 +gradio/templates/node/build/client/_app/immutable/chunks/declarationMapper.UBCwU7BT.js.map,sha256=owXOBtI44JNd6WlONg40ExxrTGsS0lEv5_463CI0JhU,136195 +gradio/templates/node/build/client/_app/immutable/chunks/default.fragment.DyEtCaQY.js,sha256=_uIzJOmgUiBW_ZXIqjFgr3FepzcqIfN5HC3qGSQuxnE,20638 +gradio/templates/node/build/client/_app/immutable/chunks/default.fragment.DyEtCaQY.js.br,sha256=UZvUXimAgMlAeNxcfr-K02sU-alEXoqm0_uR3b6PHiw,4422 +gradio/templates/node/build/client/_app/immutable/chunks/default.fragment.DyEtCaQY.js.gz,sha256=Ba6HmIk8E3JysvYCIOlA2ijqfopxDEyWshK-vvKI7CI,4876 +gradio/templates/node/build/client/_app/immutable/chunks/default.fragment.DyEtCaQY.js.map,sha256=7d5MnhMlEef-L4irK73Ri-jL1Cp4F61Z6jh81G48d0w,27052 +gradio/templates/node/build/client/_app/immutable/chunks/default.fragment.XGnFGBs5.js,sha256=wXKI1l-g7-oUpDRJfkMJ2ZuBXp36z4OAjKilev0uduk,21773 +gradio/templates/node/build/client/_app/immutable/chunks/default.fragment.XGnFGBs5.js.br,sha256=ACjAjhmoqUFDSZzqCbkOEtwNzqMcqsdDaU0NswPllK8,4336 +gradio/templates/node/build/client/_app/immutable/chunks/default.fragment.XGnFGBs5.js.gz,sha256=In4RoL2haNzZfrXoxNrIJnrnMv15qsLzYLx7cdEtL9Q,4758 +gradio/templates/node/build/client/_app/immutable/chunks/default.fragment.XGnFGBs5.js.map,sha256=Yqmwhi6zSppbPi07rdPUodpXHZUmfyUPolMZ6VuNY_U,26554 +gradio/templates/node/build/client/_app/immutable/chunks/default.vertex.CTF58pFh.js,sha256=Pk1jISVqYjVYYQrtCXm6yOxhZ8RQU0CC3gBlG2y7Qkk,7504 +gradio/templates/node/build/client/_app/immutable/chunks/default.vertex.CTF58pFh.js.br,sha256=LBwHVnLurNqFVkejnw802Xd_3N8QjJb3ae0dHsWcyCA,1781 +gradio/templates/node/build/client/_app/immutable/chunks/default.vertex.CTF58pFh.js.gz,sha256=k2uRh-Pp26h3qP8belv9WO0LtxDeYZ078C0osP4L48k,1965 +gradio/templates/node/build/client/_app/immutable/chunks/default.vertex.CTF58pFh.js.map,sha256=pctsQTf-IBNNggp4N_w8HP0sYuThGYJ0xwNmdymIE7E,11025 +gradio/templates/node/build/client/_app/immutable/chunks/default.vertex.DZ0mQRmM.js,sha256=1XOigAR37o86i2fRVGqVpGZiynzF3-7Mfuwsl0E1x4Q,7118 +gradio/templates/node/build/client/_app/immutable/chunks/default.vertex.DZ0mQRmM.js.br,sha256=brROWldAyGSQpJrcubJ1Xtme2hmOqAn7zKBjAQTntbM,1688 +gradio/templates/node/build/client/_app/immutable/chunks/default.vertex.DZ0mQRmM.js.gz,sha256=JltZgJ1rlWmk4DrByl9gA4eLSZWjKTrrjlZBPggFisc,1893 +gradio/templates/node/build/client/_app/immutable/chunks/default.vertex.DZ0mQRmM.js.map,sha256=jaPcGVxDppUWwsJt49CaFrvOpUU01VjVELSR27lRv-Y,11399 +gradio/templates/node/build/client/_app/immutable/chunks/defaultEnvironment-C15qoIsh.DPUnnTO0.js,sha256=Ae3AaK8uPBtc64H-ZdLw0lulxF-MMct2482-PMYLtgM,83859 +gradio/templates/node/build/client/_app/immutable/chunks/defaultEnvironment-C15qoIsh.DPUnnTO0.js.br,sha256=0K1Pf4pJ4rvgISc7E7zKntssszD_0nCBuLXsRcKnfzU,59217 +gradio/templates/node/build/client/_app/immutable/chunks/defaultEnvironment-C15qoIsh.DPUnnTO0.js.gz,sha256=0BpQMvwkyU5_yQbveGcSaSh6F6HVq4nq4GmlNXAwhyk,60039 +gradio/templates/node/build/client/_app/immutable/chunks/defaultEnvironment-C15qoIsh.DPUnnTO0.js.map,sha256=T4x76tiaAAK6duSwR5yvjldg289QlDSTKWVGMRHnD_E,84312 +gradio/templates/node/build/client/_app/immutable/chunks/defaultLocale.CNpUPyHh.js,sha256=FHnAtLcHYn-IvRh18T_l3YiG2siRkY1vpaCblpmAuQg,4605 +gradio/templates/node/build/client/_app/immutable/chunks/defaultLocale.CNpUPyHh.js.br,sha256=o1dYaIH0Gw68olGR5Ozf7mNWTuRRKqTxMh6C6Edde5M,1997 +gradio/templates/node/build/client/_app/immutable/chunks/defaultLocale.CNpUPyHh.js.gz,sha256=iOu4GJwscmxg-8DGJrAzuEIWxL49Qg-AwLrRy3u2e3I,2153 +gradio/templates/node/build/client/_app/immutable/chunks/defaultLocale.CNpUPyHh.js.map,sha256=yWxrqYBPCLGdekFrDlQ6otgcF1RamqIkYlcIsZ9PaM4,22274 +gradio/templates/node/build/client/_app/immutable/chunks/defaultUboDeclaration.M8PpIcZp.js,sha256=VxNCO96luvz0StvDjP04IbtNu7dYATIBVAmJDzV0XZE,1183 +gradio/templates/node/build/client/_app/immutable/chunks/defaultUboDeclaration.M8PpIcZp.js.br,sha256=19E4DrFFer-jDBMxkdt5lpuQLAClk1nwsReH2UcSDVk,449 +gradio/templates/node/build/client/_app/immutable/chunks/defaultUboDeclaration.M8PpIcZp.js.gz,sha256=p0gJA9NeTcgGWR2F6eAtUVSntmw0sYsFHh09o7i4_QI,524 +gradio/templates/node/build/client/_app/immutable/chunks/defaultUboDeclaration.M8PpIcZp.js.map,sha256=ImembSFtMcEzBuBQZTA3e8J9tUNOFpAyPr1YE-fTeXg,1839 +gradio/templates/node/build/client/_app/immutable/chunks/defaultUboDeclaration.yhOcdVd2.js,sha256=HYvxy0SNiApczPUs5mGr7bq1RcBP3ZfgJHHgnxz30xs,1525 +gradio/templates/node/build/client/_app/immutable/chunks/defaultUboDeclaration.yhOcdVd2.js.br,sha256=m0zfTc6L0QbaJcgQufYimzWEZzTgt1dm8VpL5AroZUU,441 +gradio/templates/node/build/client/_app/immutable/chunks/defaultUboDeclaration.yhOcdVd2.js.gz,sha256=FO0RZAHQux09LpPTVAjueGIr0TUzlJwDJOw0jqn-6jw,505 +gradio/templates/node/build/client/_app/immutable/chunks/defaultUboDeclaration.yhOcdVd2.js.map,sha256=2Y-3uqD4QQVpHmiHa3-RlFEVYG6Mtvy4guV9TMn3LOE,2178 +gradio/templates/node/build/client/_app/immutable/chunks/diagram-4IRLE6MV.BlyYFIbh.js,sha256=3ffDChGZ_eaVFhzgboOv_Qa9g5Y5t5IxudfOXxRjCqw,11196 +gradio/templates/node/build/client/_app/immutable/chunks/diagram-4IRLE6MV.BlyYFIbh.js.br,sha256=O92iOmZdJcZoMD2cFA25U3sI-_Dh05dumukvbWnB6TM,3554 +gradio/templates/node/build/client/_app/immutable/chunks/diagram-4IRLE6MV.BlyYFIbh.js.gz,sha256=3tXIUJOURl7kNJEmdZyuGfamsO0-zNWv6qkbedjvarU,3945 +gradio/templates/node/build/client/_app/immutable/chunks/diagram-4IRLE6MV.BlyYFIbh.js.map,sha256=oo3ORq7TYl7RPkkKv6PnOWKo32ZPQhPrjR8hr7QAnE0,37836 +gradio/templates/node/build/client/_app/immutable/chunks/diagram-GUPCWM2R.Aimpg5ho.js,sha256=HvOEqxV8B4fpP88QOPtWhpSSAuMG4MDjRRRw8HYCots,4273 +gradio/templates/node/build/client/_app/immutable/chunks/diagram-GUPCWM2R.Aimpg5ho.js.br,sha256=f3tbaIkUPuivcpm-LPHvEs-rT_PbSj0IJJO4zPyLTSU,1690 +gradio/templates/node/build/client/_app/immutable/chunks/diagram-GUPCWM2R.Aimpg5ho.js.gz,sha256=ajO5dB6YJdPA8tozRvC60RegORJU8yKZ9UbZTiCBOjk,1858 +gradio/templates/node/build/client/_app/immutable/chunks/diagram-GUPCWM2R.Aimpg5ho.js.map,sha256=GD61HoLff2NewXmMYPTbk5PAkBiVbg-kkWQF0OwcHPQ,13616 +gradio/templates/node/build/client/_app/immutable/chunks/diagram-RP2FKANI.d1gaqwPs.js,sha256=d7FCdu2Jcp_Q0FsISlo0WvVN7oCY1axPAGm3Uej23LU,5993 +gradio/templates/node/build/client/_app/immutable/chunks/diagram-RP2FKANI.d1gaqwPs.js.br,sha256=8zzzK3gQPijRrXyxS3mlBJqrcCKnjTrUW3PnGa7ymOU,2274 +gradio/templates/node/build/client/_app/immutable/chunks/diagram-RP2FKANI.d1gaqwPs.js.gz,sha256=ZqJ0g744HmDWrkr6nzUzxjQu4_R-GLTDUwd-7T-pwUc,2507 +gradio/templates/node/build/client/_app/immutable/chunks/diagram-RP2FKANI.d1gaqwPs.js.map,sha256=M6yU-M3QP-7DZEQs61UdhIT1ao0x7aQCFxHKQ-iyDEQ,20824 +gradio/templates/node/build/client/_app/immutable/chunks/dispatch.kxCwF96_.js,sha256=Hp7-JSD87cVJi_tN5tU10KTsQ2DF_xXkYDwtEgh7ngY,1586 +gradio/templates/node/build/client/_app/immutable/chunks/dispatch.kxCwF96_.js.br,sha256=pjHVn7esCw1EqtCPpq_0KMRt1j37fjnj-nPvssu3ML0,687 +gradio/templates/node/build/client/_app/immutable/chunks/dispatch.kxCwF96_.js.gz,sha256=eWAdqP1as5677MOn9oulHd2Z5BkoIqban05WhSoqcpY,776 +gradio/templates/node/build/client/_app/immutable/chunks/dispatch.kxCwF96_.js.map,sha256=TlwY-0qj5EF3mtaqu3xXfe3iytfatxwXq-O_KAmfWXw,5760 +gradio/templates/node/build/client/_app/immutable/chunks/dockerfile.D3l6Kuvz.js,sha256=cJT0YOVDfpKXU4w9xMUo7dxQLAQtKSCq9pOCm8GxUAc,4166 +gradio/templates/node/build/client/_app/immutable/chunks/dockerfile.D3l6Kuvz.js.br,sha256=4zbu_MBikd9hJIL9kCWbZYpiI3rJRfxVycH67mOoKJM,1550 +gradio/templates/node/build/client/_app/immutable/chunks/dockerfile.D3l6Kuvz.js.gz,sha256=aT_8oB_mboc3ZI1tlToT60d43y3wmfs5WIb4Tc64MRU,1668 +gradio/templates/node/build/client/_app/immutable/chunks/dockerfile.D3l6Kuvz.js.map,sha256=A7b4MwAQQZ7bshfoPZMEID5s1Vv4t38BcXEaRbYI6mg,14888 +gradio/templates/node/build/client/_app/immutable/chunks/dsv.DB8NKgIY.js,sha256=5RdZE461aMrwMQTIm4mD2K-SnHynJhJVsSNdqFtL8Qg,2189 +gradio/templates/node/build/client/_app/immutable/chunks/dsv.DB8NKgIY.js.br,sha256=WMV0_5B7N3Be5tG76AtWtIjGmX2i3gaNyrRTZ_x0kZU,960 +gradio/templates/node/build/client/_app/immutable/chunks/dsv.DB8NKgIY.js.gz,sha256=ydJ0mzwmiyxire9xe3SDwoVbv83tq7HBNF3AjhsdNnY,1044 +gradio/templates/node/build/client/_app/immutable/chunks/dsv.DB8NKgIY.js.map,sha256=2CFkZsy3-pB4kxYzlKSEi9P1t3l2e0IPqWuKvc81OyI,9575 +gradio/templates/node/build/client/_app/immutable/chunks/dumpTools.DaNYYVzh.js,sha256=NQ6z69_JlCPd11cjKksdjdhrCEtcMpk_n16p5oyzoIs,2556 +gradio/templates/node/build/client/_app/immutable/chunks/dumpTools.DaNYYVzh.js.br,sha256=2qOf5bhRoMgWZkcMI01NekoSNU-vaq-KWlAKFTT8Q-8,1174 +gradio/templates/node/build/client/_app/immutable/chunks/dumpTools.DaNYYVzh.js.gz,sha256=z66ZvrfLYvvAGZKyjGTLX1OWUYkOXJTR_Q38QRdA4kE,1276 +gradio/templates/node/build/client/_app/immutable/chunks/dumpTools.DaNYYVzh.js.map,sha256=ZsF0zsuHrR7FibMWVLhgTqj9FahFIULHId7nBDhf71o,13422 +gradio/templates/node/build/client/_app/immutable/chunks/envTextureLoader.BhqyU474.js,sha256=YuBse7YNuN4dnHobOgZVImljFugleT4zWi-0nAMc2Jc,639 +gradio/templates/node/build/client/_app/immutable/chunks/envTextureLoader.BhqyU474.js.br,sha256=F9u85gN7iixwtj5HtNDCZpIMq-lgKZ4c_pNCWyiSKkw,358 +gradio/templates/node/build/client/_app/immutable/chunks/envTextureLoader.BhqyU474.js.gz,sha256=qi2frHmQQUBX8rushEuHzhT_xCYCIZMIQYlvjI8voiY,410 +gradio/templates/node/build/client/_app/immutable/chunks/envTextureLoader.BhqyU474.js.map,sha256=EBrccV6uVuHKjeYKC1B3gJG-fSSXbrllRebA3oMqAwo,3273 +gradio/templates/node/build/client/_app/immutable/chunks/environmentTextureTools.DZJEvUsQ.js,sha256=4i6Kymfaq1mZ7dgiXq34vCKptTr6nNQMKFmULWz9aD8,6653 +gradio/templates/node/build/client/_app/immutable/chunks/environmentTextureTools.DZJEvUsQ.js.br,sha256=9xHxBkXIzlVJsppj6Mr0pwkgEDGuqrMj8AW3OqlGBHk,2566 +gradio/templates/node/build/client/_app/immutable/chunks/environmentTextureTools.DZJEvUsQ.js.gz,sha256=TrJUUn8E2XA4YTrBdNTMEoVpnq_mVh-CAuUgDCYtTMs,2824 +gradio/templates/node/build/client/_app/immutable/chunks/environmentTextureTools.DZJEvUsQ.js.map,sha256=29S6xd8LpB8jV-i6_D78e7O7BVnmmz3OfEmyDHms8Sk,42455 +gradio/templates/node/build/client/_app/immutable/chunks/erDiagram-HZWUO2LU.Bk-YGJi-.js,sha256=hK4BvkxKwrB7JLOHq9HMWDXjT5lfIjQBN74KRPeUv90,25400 +gradio/templates/node/build/client/_app/immutable/chunks/erDiagram-HZWUO2LU.Bk-YGJi-.js.br,sha256=sYRQbk6dRkjA-Wag4CPv-BFIpn0TCX71ewz6ORoWbDE,7661 +gradio/templates/node/build/client/_app/immutable/chunks/erDiagram-HZWUO2LU.Bk-YGJi-.js.gz,sha256=Hf4FRhAKJ5-WOgjMBH98wdb2gu7nIN8dTic2NnFtVnw,8814 +gradio/templates/node/build/client/_app/immutable/chunks/erDiagram-HZWUO2LU.Bk-YGJi-.js.map,sha256=I1ozoVoO4fPhLWnuAgj_aIk-LmW9v5qHkc_DzluMpmM,85608 +gradio/templates/node/build/client/_app/immutable/chunks/es.DnL3K9UL.js,sha256=wOqtiTBP0NwG3xQnihEb4CfdtzbNweUko9pUHFFIW44,4910 +gradio/templates/node/build/client/_app/immutable/chunks/es.DnL3K9UL.js.br,sha256=ejdh1yY_HGUwbOOtivjJfG5fr5boOyY9SkwY9XIP07Y,2034 +gradio/templates/node/build/client/_app/immutable/chunks/es.DnL3K9UL.js.gz,sha256=rfCTn_NkDuBtdwFysOuZPsArew0DZPv_grr6uUMdcc0,2285 +gradio/templates/node/build/client/_app/immutable/chunks/es.DnL3K9UL.js.map,sha256=xIQynUZjdCn7D2r_hoFMG-C_DVlygamLx-3USN2HB7Y,95 +gradio/templates/node/build/client/_app/immutable/chunks/eu.CVD4vzPg.js,sha256=Pv8622ofc4JcToaOD1aqaM8BOGbTSjWjIpCHb8a1Nhs,4680 +gradio/templates/node/build/client/_app/immutable/chunks/eu.CVD4vzPg.js.br,sha256=IWSq0Risx6OQx6airipAtXvwzXXV63AYBQmapThAr70,2031 +gradio/templates/node/build/client/_app/immutable/chunks/eu.CVD4vzPg.js.gz,sha256=cMLkAmy9ntrNmSPs-Zd-Z9OOe4JJQS4Kj0gZQG68wx8,2203 +gradio/templates/node/build/client/_app/immutable/chunks/eu.CVD4vzPg.js.map,sha256=rMZSuUnkF5BasQctAxKAOYbJQbugeRBylwf1RWLrPto,95 +gradio/templates/node/build/client/_app/immutable/chunks/exrTextureLoader.BnLJw0AM.js,sha256=TzfX_VrRIflh8KzUGg2Y7rRP_jFD0L1oI-5r6VqwlIo,14830 +gradio/templates/node/build/client/_app/immutable/chunks/exrTextureLoader.BnLJw0AM.js.br,sha256=HxkJTuUqEgCgOGzZoN39h_Dpeen6l6-JvY5uYPw-nAk,5111 +gradio/templates/node/build/client/_app/immutable/chunks/exrTextureLoader.BnLJw0AM.js.gz,sha256=PqI_uC3S2shC6v85LtMb9VlyCdyX0e3OtzDpR4UR1DQ,5601 +gradio/templates/node/build/client/_app/immutable/chunks/exrTextureLoader.BnLJw0AM.js.map,sha256=yEqoerMRd8rfiH_vzaAZTsCF0UIeGaG3B49xnC5NiPA,101553 +gradio/templates/node/build/client/_app/immutable/chunks/fa.EPplD9mS.js,sha256=F72Dp8x3EaBAOi7Gwfw5imsbFDGPXdh-h0D6k9PE71Q,6189 +gradio/templates/node/build/client/_app/immutable/chunks/fa.EPplD9mS.js.br,sha256=yCQ2Ij7Ty5SSVyn5WAXSutWykw3cXyNUCAjP921CDAw,2165 +gradio/templates/node/build/client/_app/immutable/chunks/fa.EPplD9mS.js.gz,sha256=-_ZMT_79N1gpNZx3jc-hmiHMu8bOhDTQBRoF-Eakv3w,2551 +gradio/templates/node/build/client/_app/immutable/chunks/fa.EPplD9mS.js.map,sha256=Vfk5zh-VXDO7VMHybboClDWKO4j5GR4qiUA49Nrwozk,95 +gradio/templates/node/build/client/_app/immutable/chunks/fi.B30SrT2N.js,sha256=91E65d5nUBnv2mH7gOmEV4c2BId8V3HND-PmiAsLMJ8,4683 +gradio/templates/node/build/client/_app/immutable/chunks/fi.B30SrT2N.js.br,sha256=93mdPjROVq8FYyXcFjPUM14MXf7gmitnz_7iI73-3Fc,2048 +gradio/templates/node/build/client/_app/immutable/chunks/fi.B30SrT2N.js.gz,sha256=Oisv5o3DeNgVoKfADn27veUWHCjnAMg6SJ0UNAtw4jw,2232 +gradio/templates/node/build/client/_app/immutable/chunks/fi.B30SrT2N.js.map,sha256=aBVYteDynQzDC-uK0bdcbuzvOZLnGknfrfPFy56QEzA,95 +gradio/templates/node/build/client/_app/immutable/chunks/flowDiagram-THRYKUMA.BpQNIPHh.js,sha256=NkeEfg5Wt3PGP4M7RItIX40TJlft0-s33w_7puB_9dQ,61174 +gradio/templates/node/build/client/_app/immutable/chunks/flowDiagram-THRYKUMA.BpQNIPHh.js.br,sha256=IBfL82Lef5zRxflmpG3tJDdUGyg2fJ9nATI6RD-D3wM,16201 +gradio/templates/node/build/client/_app/immutable/chunks/flowDiagram-THRYKUMA.BpQNIPHh.js.gz,sha256=U9zb0761rdWoIfPYwm3659UGME9sJ-YArwJt3PSAypY,19350 +gradio/templates/node/build/client/_app/immutable/chunks/flowDiagram-THRYKUMA.BpQNIPHh.js.map,sha256=8KlJB55BLrHgdErTqvt1Ghxh5XYuXPFp7CetgT3PZQo,190163 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphArrayIndexBlock.B03sfcvL.js,sha256=Gb0wFT06eCoC_iEqvlm0f2GcdQTZ6d7W-LwsdhJeCaw,727 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphArrayIndexBlock.B03sfcvL.js.br,sha256=hDmru2n2t3r-XIVRRVBkxEc5AmzPyEMukW76jA3pyzk,362 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphArrayIndexBlock.B03sfcvL.js.gz,sha256=ANlr2E1Ob_pOfHX82gPAdDP19_m_Kf1NtQCkbQ1t5ZQ,411 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphArrayIndexBlock.B03sfcvL.js.map,sha256=qtNkhAXDPAh599FPlBE22kWNxyvsJMqIpw65Dymv5uU,2807 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphBezierCurveEasingBlock.BqfcWA2V.js,sha256=Xf4_ki64M1xxiINCQ4laS-JxeYwcWaUlG8lveykYDVM,1020 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphBezierCurveEasingBlock.BqfcWA2V.js.br,sha256=wC_-Kz3OonffzwyZbdzkGple9UJ_yYXEdgJh5wZsqew,429 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphBezierCurveEasingBlock.BqfcWA2V.js.gz,sha256=65DQnXJ-WpDIhUiHvx6SNongPSClJh7wogRB-hQ2emY,491 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphBezierCurveEasingBlock.BqfcWA2V.js.map,sha256=mzIwjQlzi3-jPz3OJu7U35yLtUZF-39_Sg6n2vw7_mA,3495 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphBinaryOperationBlock.CI0NxKdM.js,sha256=9_ZCUMTUYUu9GGyTARFAk3PFjZ8AkLYiXxo_dMhLMLo,442 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphBinaryOperationBlock.CI0NxKdM.js.br,sha256=gpuq0v0BOhh37xSETo3ej2_Us5_gARF1vUEhLqV3AQ4,235 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphBinaryOperationBlock.CI0NxKdM.js.gz,sha256=t1CfJXQokbqkqoxBXBX7mii63FqOJeOKld5OpXvcRsc,283 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphBinaryOperationBlock.CI0NxKdM.js.map,sha256=BhTNaOTV81KUpIPmnD5d6b8-M2xqw90gAIQYb5npdvM,2037 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphBranchBlock.B5KPMpSk.js,sha256=eUXz2RdpZeCF72tqLeDIB3QvZPSxcSyi-W_gKwS3oFU,607 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphBranchBlock.B5KPMpSk.js.br,sha256=lcAlHWBPT-XYLe9fczbPJZf1hVUvotXpTcCu6Kiih5s,287 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphBranchBlock.B5KPMpSk.js.gz,sha256=G8HCCG6RCAUY1X2BXGKqvnvk-78a21pFv-EOimMXFh8,350 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphBranchBlock.B5KPMpSk.js.map,sha256=EUIjknwudhh7YsnKv_CFbVIy1FX5P7CpuNdEm0ma_jg,1902 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCachedOperationBlock.CtP7sxiu.js,sha256=ieAov9amQ4D_0pVAXwfo7jnmnXmd8mad5PG6hZ1z_vM,812 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCachedOperationBlock.CtP7sxiu.js.br,sha256=6C6GLHjkcCKJf9Jw0ZCXaP7TM-AcTXpIith-P7V0PFY,388 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCachedOperationBlock.CtP7sxiu.js.gz,sha256=gWEtZg5Uhm5YVJR4kcLS70sgHAgPts0eXOUMdkdtXko,416 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCachedOperationBlock.CtP7sxiu.js.map,sha256=BaiQa8wOMGolY26EuHvTtIZKiZ0ma74T1qPGMe7Lepg,3003 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCancelDelayBlock.Bo445-z6.js,sha256=cjrghqc6FdjbyQyGEG3jN7d3uvHAHRqI93avSaSCpRo,662 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCancelDelayBlock.Bo445-z6.js.br,sha256=0sYm9ZbNeeoXsqMdPROOQRg4SFOWa7HWPHOF4bDL1Pk,380 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCancelDelayBlock.Bo445-z6.js.gz,sha256=Klv1FytNemM_f8Hb_U1FCgj-jFBQ8mihd5NRsK_VJw0,428 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCancelDelayBlock.Bo445-z6.js.map,sha256=h1hL5z3PTHvCoKqBzCP26jJdxhxKpF1JoKmj3v2Z0BM,2359 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCodeExecutionBlock.BITVoFWe.js,sha256=NBcZgXGx4HLskaeLWYtk56KPh_elXwiAXEnIoetQVJ0,592 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCodeExecutionBlock.BITVoFWe.js.br,sha256=CyeOC7tYRILYs-3lpUGxHLnbbWrGKoES2LBuo4F0kZs,279 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCodeExecutionBlock.BITVoFWe.js.gz,sha256=MJuSaqnMPCkrfwTnSYjeKngnzscbxIbo3_MFoTQ1Xhk,339 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCodeExecutionBlock.BITVoFWe.js.map,sha256=ICTBBIZ_rrddf4Ey0b3F25KreqoAmPCd4fDhI7Ph1WU,2179 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphConditionalDataBlock.BpscsBV2.js,sha256=8kTOIFuqA7lzsFAF7jVRSGOWF2AG5nWv1AF34GyIUpg,712 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphConditionalDataBlock.BpscsBV2.js.br,sha256=DuuCbu6KIMZ9NEatjzxIaOrociRAEwsQXz2ggRYlGAE,315 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphConditionalDataBlock.BpscsBV2.js.gz,sha256=wmETlw9jIZ8eN3il9iUbi2OpibRLk6ip01ceCIXZCxg,368 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphConditionalDataBlock.BpscsBV2.js.map,sha256=6qfM4Tw6G-aO92o9KhA3c9wLM_cCLrrH3oNSZesjgnU,2399 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphConsoleLogBlock.cIadvORr.js,sha256=z8_dqBl_nnKg9FJeBSsZgoNYtc5RdUVidXMLHqweSfs,1203 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphConsoleLogBlock.cIadvORr.js.br,sha256=nqQ5T5m0JTq1Dpf5j9FwE5Mxn_HjvtSPzKYvdAoaN0M,526 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphConsoleLogBlock.cIadvORr.js.gz,sha256=uQ4x4FHpLP4q_p3Mjk2kvScNa8PhVeaE6fay4BlEhB4,620 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphConsoleLogBlock.cIadvORr.js.map,sha256=01q6S8iV7ew-Lx1FNQnI6N9zE1PgqNN5_aZs1ogBiSs,4239 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphConstantBlock.Cf9AYaf0.js,sha256=B-iEV7JutYVl9OhkCNEo457RObiOQFRdjsw4TyvCMeA,575 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphConstantBlock.Cf9AYaf0.js.br,sha256=RcUHRZh8Y5-wEpmBdHPVJvoSfSA-Xqkv0hyLZxTiv8A,302 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphConstantBlock.Cf9AYaf0.js.gz,sha256=XTiGHPXy73pOaY5Cq4vaUsa6xxELcvnYtLAOUDzlm1I,352 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphConstantBlock.Cf9AYaf0.js.map,sha256=irHgsLg1RUlaz3Tj3Jo7Xf1-GOyqy47qTap28-1Bf44,2358 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphContextBlock.DHb7kEHn.js,sha256=0U7CwrmZajhluaNWXU-y_nZldEuGZjJa0EOd2BbQPAA,623 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphContextBlock.DHb7kEHn.js.br,sha256=sMaeI6RjCY51d6cWm64EcIYaSqhpif4TZtdk0m68iXg,293 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphContextBlock.DHb7kEHn.js.gz,sha256=0MKhu8Wu1uPqvZdjbDUDnxmOVQtPKazxyRXtPwg9Qec,349 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphContextBlock.DHb7kEHn.js.map,sha256=qbe8Dqdlx7ws98r38SExTDEULdooch4lcr9noVvat04,1849 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCounterBlock.B4fjt7HE.js,sha256=t2SrPfoSi8-DhNvOgRjBdaTZFs0AUaslKeYMEgiWsCQ,708 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCounterBlock.B4fjt7HE.js.br,sha256=PXML3m1VvOJdHOOQKEct4_LXG3lWY4FQRGQslq3lK_o,349 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCounterBlock.B4fjt7HE.js.gz,sha256=8Uw8mOVDd0gsoQwSHULiq-IxypI2BEnS5WWAWr1rKlA,392 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphCounterBlock.B4fjt7HE.js.map,sha256=A4weiEhTjwjj2VLqnFuJz37yOjQtzjuKd84io-HIYfw,2376 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphDataSwitchBlock.CRZGNJmJ.js,sha256=2ai4nwUVcdkuLunkAvDTBRWPyT1luUdwP0QUKe4gAZI,982 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphDataSwitchBlock.CRZGNJmJ.js.br,sha256=3tPGq5U5GfMEgsvUwCm2pRRykZKV3QFRrzsZ2F0ns8A,460 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphDataSwitchBlock.CRZGNJmJ.js.gz,sha256=GLuLIg1b8TMHMJdkURmAD2h8mPSLsacgi0jQluR9Usg,519 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphDataSwitchBlock.CRZGNJmJ.js.map,sha256=K3mXg8e2O6Rcl6OYVR_hOF5Er5J7pRfq930b_N6tCvY,3549 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphDebounceBlock.BBFhWo9P.js,sha256=g1sAudjQhGecJWpTWGBqABxrDdMGamtxHitOo2uWaBg,846 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphDebounceBlock.BBFhWo9P.js.br,sha256=O0fT4Vs5S1VDkIOYqhFwxa_iQj2a9_YFz0ADyKGn8Y8,363 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphDebounceBlock.BBFhWo9P.js.gz,sha256=HScR9gwUUl7JL5n-N7gXJEfYiw_-Vha6ovEJtNgDxII,425 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphDebounceBlock.BBFhWo9P.js.map,sha256=7c5FgXRIwccB2Rn7Kv0IohW7F3YaSiomB7oClP6qHig,2751 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphDoNBlock.DCMR9_vT.js,sha256=qBDBPExeyTNdNZtshMkFF1i70ijHvhYy9bO9FjVxnz0,848 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphDoNBlock.DCMR9_vT.js.br,sha256=4raDTnjPnvJknK0wS1W1OSEYAK04Xdc2oDzVlftzDEo,380 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphDoNBlock.DCMR9_vT.js.gz,sha256=L_o1Py0EFmyIsOR5et5QKVkh5sdLtW_SAO3rXGjOuzY,447 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphDoNBlock.DCMR9_vT.js.map,sha256=M5l84z0CDri02wMwJX5jINt5JHfYYBikiG_7-aLrK2U,2930 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphEasingBlock.1niIOCug.js,sha256=DgLS3DhUavXnAogcTEA0gVdprxxAEm_tfAF5QUQNiIw,1705 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphEasingBlock.1niIOCug.js.br,sha256=dTLRdllDHX9dlUVELzxwMgAI3Av6dr8S0Qxtyz7-ld8,704 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphEasingBlock.1niIOCug.js.gz,sha256=9729WJGFvFMPZ9sopmiIqhLMaVyQzblpsE0RbYBRa-U,787 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphEasingBlock.1niIOCug.js.map,sha256=_rPxtPhUHyW4TsQeNnQXGtO5XjE51RSk8ZSpBLam44A,6767 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphFlipFlopBlock.CA4_-zai.js,sha256=TEzaza9kxfjPw9BETVkXkbwkm7WpiI-MZahFhzZr0TI,781 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphFlipFlopBlock.CA4_-zai.js.br,sha256=Hw5Juc6x0XNLKwYmt_1uXG-Xmqz40gIYbpZm5cTFY18,374 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphFlipFlopBlock.CA4_-zai.js.gz,sha256=Syfw_3PMWuVT9a-3XPQUlweMWhm0115fkNFXIzpyWW4,439 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphFlipFlopBlock.CA4_-zai.js.map,sha256=CcNX6nnDXwAy3sx4uU6UspBZnAmeeQ-JwAoJwVKreeY,2360 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphForLoopBlock.BWvb8YvA.js,sha256=p7uzIPyFxb86A-kGAgVJTIndXYWO760C34T12Rah-_U,1101 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphForLoopBlock.BWvb8YvA.js.br,sha256=smX5rWp68qXZxylI0Z1qbbIFdSmBOYFnQwnHowj9gGw,466 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphForLoopBlock.BWvb8YvA.js.gz,sha256=ikhTJVcJmLoOkKjsoE_bjN2v5W7wcRwPcneMrMaVA_k,522 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphForLoopBlock.BWvb8YvA.js.map,sha256=lH0e6nj6nIKR5uI2aG_V-nYw7p6JiTlDGuQyEGVpf9E,3774 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphFunctionReferenceBlock.DYL4rOb8.js,sha256=koOJkHzrJk_rTT3_r7NGuAiBJPEbrAH131uYJexx6-0,792 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphFunctionReferenceBlock.DYL4rOb8.js.br,sha256=zUklNJFhTe4yoX90t3CTJZoM0plLd9tjpdRINkyBqqg,347 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphFunctionReferenceBlock.DYL4rOb8.js.gz,sha256=_d3TafnXA7hcGoVKjgSIyQ1h-oIx_IPlKm-a7tQjRVI,417 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphFunctionReferenceBlock.DYL4rOb8.js.map,sha256=asL-CIcees4fUJaEBs6rxy3Jy7YrG3orwrzFkCaHuhc,2637 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGLTFDataProvider.BfhrUZfi.js,sha256=tShoHxkHwHqwt4bqr8tyTWfnVkboL19BaqpHDxB0bt0,583 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGLTFDataProvider.BfhrUZfi.js.br,sha256=27DED9fh29sb2IwWvlNU7qHfR4iLdVo74gZTI6zguDk,301 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGLTFDataProvider.BfhrUZfi.js.gz,sha256=sqw3WAK0M8acUWesuf2XuDfusw6caaBxnPMFI4hBflw,360 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGLTFDataProvider.BfhrUZfi.js.map,sha256=9JKxsBogo9P1sCdqGaMyZH4nzeVs7SM-9fDrVMbSn34,1807 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGetAssetBlock.B9sydsa6.js,sha256=fDM9RE05jVV95qLOAJWvO3004nfE48vXd8XS5hXn73M,715 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGetAssetBlock.B9sydsa6.js.br,sha256=vJPFmQITEUbX-CRbRveFqwxC8-xzj-MvxJWf5Wd-_1s,372 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGetAssetBlock.B9sydsa6.js.gz,sha256=Ubb8z4EorRqO8AtQDv-42AT3v8_grL6HHXuqnt3HePk,411 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGetAssetBlock.B9sydsa6.js.map,sha256=BKFULlalnmeBhxopX8_oK1yWg9yar7R8U77CNkYa464,2942 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGetPropertyBlock.CvJub6Jr.js,sha256=0twoeBcvjHQF8mJgD4fI64A3cDjgmmlVqOmietdETQw,956 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGetPropertyBlock.CvJub6Jr.js.br,sha256=fJy-Fw9fIZou1i95AXqErsDyT2XlnB11tFNUQ8EjYi4,390 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGetPropertyBlock.CvJub6Jr.js.gz,sha256=dGmYXgkfMiHeM2jBMpKY4l5uBYo9N8uDMcQVQmE9RjA,462 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGetPropertyBlock.CvJub6Jr.js.map,sha256=S-ek755h6DS7_t4u5UclGbu5R2Tcm-f290Is4WzHq-I,3617 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGetVariableBlock.C49Sb2GW.js,sha256=3RqU_hW7jtuk0wxc_jJzdRy7HcBDx-ThKHJWX2oZi5E,623 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGetVariableBlock.C49Sb2GW.js.br,sha256=B46PA_T6y6ZvcMvnJXzgTLlYnnsqnA03QeRDoGk6aEw,298 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGetVariableBlock.C49Sb2GW.js.gz,sha256=RxzjgszVmMBVYLjlk1XOHEeSJZbAnxjEqsAcewbc9tM,362 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphGetVariableBlock.C49Sb2GW.js.map,sha256=P7s6K0YzOegR_IkR2LsOFunh5zDOYvuJrErawQQ2tYU,2381 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphIndexOfBlock.cBkAYfIL.js,sha256=GcTfO8azFFrUi8m1PCzEvpvUw0YZ93O45bpBAX_OJmw,685 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphIndexOfBlock.cBkAYfIL.js.br,sha256=rJYktN4SGvTzeK64DEFeYcUkYjCxkRnBngOTVM06M9w,357 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphIndexOfBlock.cBkAYfIL.js.gz,sha256=2cRiQJLe5odeoKEqKo0UYE0VXg-TOLLxi0YL2scL3eg,388 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphIndexOfBlock.cBkAYfIL.js.map,sha256=H1BKQW_Ew88k8v5AsFUrjMt9qg41CthoHTFB6aRla68,2635 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphInterpolationBlock.Clp4-F7o.js,sha256=zXiuVcbKrMerF9v3z7MkdLogWJgiAyrCbmsD3sm55JY,2309 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphInterpolationBlock.Clp4-F7o.js.br,sha256=GS85FgtV78-_kqHOTRU1J09THA59CkEUVVz5tL72wc8,835 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphInterpolationBlock.Clp4-F7o.js.gz,sha256=O0Ux-kD6xNpVRPvB3sVWAjWVLE7Ygt1OMuhNrIMmaMk,950 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphInterpolationBlock.Clp4-F7o.js.map,sha256=B7Dr7rkQ8wO7QyQLDBBCrW1sSjrUo4rdV4lqQ5vIodw,8438 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphJsonPointerParserBlock.B04B8uAV.js,sha256=9ip19duByU7ob-1rflnVKnNEFCH0gRi-F2Er57cZ914,2967 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphJsonPointerParserBlock.B04B8uAV.js.br,sha256=05VN1Fg5_ELFfCNfQi2aZcv0HLJHF0DZ24ztLL3KOoA,1079 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphJsonPointerParserBlock.B04B8uAV.js.gz,sha256=xzik35B6UYpI-U3Vrmjlzg2b9qZU6nz7EFJPojQwfsU,1228 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphJsonPointerParserBlock.B04B8uAV.js.map,sha256=v-ECj_0aTbZQ6JZ6QZmmYqULwKyfF5Fv2O5r-_Jwmu4,11668 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMathBlocks.BgQ6jpID.js,sha256=I4ODDw_-_aO64wAdYW2fzYYpgXbF57t0AsVWzGIsJMo,17801 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMathBlocks.BgQ6jpID.js.br,sha256=wy8LdiHx9eaGYYAAdoFWBTLMlLxM1ByF_ipkAb1I5dk,3235 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMathBlocks.BgQ6jpID.js.gz,sha256=lD2Yf_-4eJEX9VdtWROgyE0Dr3c7gnWyScFa558-CAY,3697 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMathBlocks.BgQ6jpID.js.map,sha256=Xon-2I9m5OjZeLZn6yl7EF0x4T-jwg0CWOEGxO8t7JE,70455 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMathCombineExtractBlocks.DpvecDoq.js,sha256=pGrMiZ7GQJbYkKUvkm1J09AB5O1lak26Yty7mbfAFR8,8235 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMathCombineExtractBlocks.DpvecDoq.js.br,sha256=czDYo_WhvD9IZACnEPOOUogQVkq65IxpUdPtmR_vSdc,998 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMathCombineExtractBlocks.DpvecDoq.js.gz,sha256=CKQN1IipwcWEBVGtRv4W2EuvKY4r-lc3bF5ePVP210M,1187 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMathCombineExtractBlocks.DpvecDoq.js.map,sha256=TtDGXrdMG75UEZ8CgtHBu0FqUObjhZPb_y53vO_cV3o,24841 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMatrixMathBlocks.DxazJ9N_.js,sha256=IdAq0SwJuRe-YzyGczRgRrdjhOLA4a4s1nAeVtB45xU,3724 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMatrixMathBlocks.DxazJ9N_.js.br,sha256=qE9kkBzrPu8fBIBBI7fR5Fw_F5jnFfc2TkqE-6wNU-I,926 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMatrixMathBlocks.DxazJ9N_.js.gz,sha256=MIFOw57Ircj2PUbhSmEDPNLh2LX9RLPc2GnwkI-dGKU,1038 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMatrixMathBlocks.DxazJ9N_.js.map,sha256=HWIoZ4ZlZVJF1b_H8SFhQwCmM5DeB9EiOxhSEFbL4HA,12378 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMeshPickEventBlock.Bkgm0TYl.js,sha256=rTSjTSqKiymoWQZF_97knrxWibDSIhyVAHznSCAv8eY,1615 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMeshPickEventBlock.Bkgm0TYl.js.br,sha256=Qnv_HCw3ASxo9iALsd26p24O_oulrfL9ac8QGUNqcaw,581 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMeshPickEventBlock.Bkgm0TYl.js.gz,sha256=pZ_dqfXS4q0zQe8XMvJBy-9A4CJta_a_NxxAm6-ihW0,672 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMeshPickEventBlock.Bkgm0TYl.js.map,sha256=eCNP3Y5rmG5zks_R24SgyNEXc6UtNWbPd-yvSOT5e0Y,5077 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMultiGateBlock.KML6_2T-.js,sha256=BtqR0ofwD5qWRD5wHvSaw20csRBh6tAQ2sDtwh5ux3E,1752 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMultiGateBlock.KML6_2T-.js.br,sha256=lXkVAjIS9f0MrJQONNucZyk5USM4cZetZ114vEv-QLE,668 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMultiGateBlock.KML6_2T-.js.gz,sha256=_F6GdjQ5pLpMpfjf8yXfcC4BbrHU5ydA8hW64PoP204,777 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphMultiGateBlock.KML6_2T-.js.map,sha256=WiKoKuxFL1539yy2hVCQubmp4OvehlBrsCFwOj69Vc0,6345 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPauseAnimationBlock.tGoUJuwx.js,sha256=LCoBlOFR3IKVUGSXU8kr8H4TNUm-U0QtbrHMA9TyKtw,533 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPauseAnimationBlock.tGoUJuwx.js.br,sha256=fc2zrQ-ahM8Yqd33i1ne6w2qZANxoo-38amXdcGYeJo,261 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPauseAnimationBlock.tGoUJuwx.js.gz,sha256=Wm9N_1cwOeEVxyaE0eZ9AZxR6EHlsQkGfrIxveIdprM,322 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPauseAnimationBlock.tGoUJuwx.js.map,sha256=nsf3GJO5LE8sH_-dWzLy5V6xiZ9TL0VmMUksdZzCxFU,1789 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPlayAnimationBlock.DMpd9AzC.js,sha256=mf8M6tf-EXmZQ-c9yltwKpuIB1tbl6-EBKe3dvmHSBE,3807 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPlayAnimationBlock.DMpd9AzC.js.br,sha256=qUdIDIhAhyB4qEdlQV0lI-Lco9x2Gp9mZ9t6E8kUTPc,1146 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPlayAnimationBlock.DMpd9AzC.js.gz,sha256=r5Fke8iC5nkTQXyRrggGx_5eN-kRFT8NVQ3Ls85zUk4,1273 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPlayAnimationBlock.DMpd9AzC.js.map,sha256=JepdkOxKFv69AVcAZQMhtiNkeCB4upqVIkqBG-NGMiQ,12775 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPointerOutEventBlock.B3OaQD4T.js,sha256=byviyGlcgFIiAVJlnCFgjZGCdtov_EGehvoy0xSE2_0,943 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPointerOutEventBlock.B3OaQD4T.js.br,sha256=psReLN8p-iLZAPJ98tq_wWucNIxtm-Er4Ynm9CH3KZE,416 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPointerOutEventBlock.B3OaQD4T.js.gz,sha256=qDq_9AkwwKpDgGnxzN39m6EtoRMq2WJh6pzJ4wAYKms,494 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPointerOutEventBlock.B3OaQD4T.js.map,sha256=dUQ59ybzzhD1ALCSFWqsfxIRSL_LLBqjnI-oSyle9HU,2945 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPointerOverEventBlock.I7XsC6gG.js,sha256=QVaRxj2aBo8Dmp20U4mLaBYh4WAlZGrXDXR1-hP15wI,954 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPointerOverEventBlock.I7XsC6gG.js.br,sha256=ZYF1NpbNc_oeD-pqMjm50wYfiWx6t3-gBGIcR6u6DJU,432 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPointerOverEventBlock.I7XsC6gG.js.gz,sha256=h9Aa-veKiVj_LTDO1mdbKprhdPgjeEN4GoBGgNx-uS8,506 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphPointerOverEventBlock.I7XsC6gG.js.map,sha256=qFQWchJgJb0qUtb9FOI2TONAm-UJ2xEafzt-KugXxNo,3072 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphReceiveCustomEventBlock.Zl1e7Elp.js,sha256=XkO912NfCvU3nfY1SK7qv3_lovuWtaX0gswGa439eOY,1291 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphReceiveCustomEventBlock.Zl1e7Elp.js.br,sha256=sh6ZJEwy-i5-5bvZGQw6D6zlsPpGZKA2rqZnVIaE2_Y,521 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphReceiveCustomEventBlock.Zl1e7Elp.js.gz,sha256=p6UujAje4YBRoJiZsKOSLZ-k5RZOJL8sWRaFpnQvN6I,614 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphReceiveCustomEventBlock.Zl1e7Elp.js.map,sha256=h3QLElljZmEqPsNtTKae5emaGXL2JBFII3CtGVU8DY0,4275 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSceneReadyEventBlock.D16NDYdp.js,sha256=CtsYWstZoyk1Imu_rYEdcaxu50tDAQEJ_nS4Yz_Usl0,485 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSceneReadyEventBlock.D16NDYdp.js.br,sha256=bD0h9wFJT3gJirWmyy7fHHW6PBSmqoFpKVrPsfi2KTY,244 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSceneReadyEventBlock.D16NDYdp.js.gz,sha256=PLQocCmbddHjlNnwIQPcwd35tP2v_OEaCk_hvj6mZT8,314 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSceneReadyEventBlock.D16NDYdp.js.map,sha256=gzp0SyVjr_kJmrz-2jc1GyXBLovV5puQa7hCNHqLDIE,1661 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSceneTickEventBlock.Bwibrsmg.js,sha256=TZQnOku6E40SEX6RZ2QZJkixldS47DeTV9CqoUFPTMg,713 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSceneTickEventBlock.Bwibrsmg.js.br,sha256=b1dKX0ePrvPYQNiE3SbgwtYfuGYLiLuhOrIZpgA84i4,320 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSceneTickEventBlock.Bwibrsmg.js.gz,sha256=4VZBSSlLjv17ZUuF9f103cunjEU5OaOuiQ2c42fFxc0,383 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSceneTickEventBlock.Bwibrsmg.js.map,sha256=dcagT_g8WWfhJIPNrjN7s6UfS5WOiRWw-KK1aIk7ptU,2269 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSendCustomEventBlock.ChWfcsQb.js,sha256=i6owILi0xqgYIsgIMEhHUGVQ7DfiTlbEhq4SALjDtz8,658 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSendCustomEventBlock.ChWfcsQb.js.br,sha256=K1bDM2Gixgdr1HNiDNJ08Lk2hiGXJrc0TKE2vs2i1Sw,341 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSendCustomEventBlock.ChWfcsQb.js.gz,sha256=C4FdfkOvMuRyiaEKEUJ7lHITo4aV__DihOzkNBZx8oI,390 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSendCustomEventBlock.ChWfcsQb.js.map,sha256=em-yEmt0GnSWmFm5tkBnsyEZ-l2oELlz9n93d5moodE,2592 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSequenceBlock.CEbTwj2T.js,sha256=NyxgLg2hUeg9KRd-8ZCzF9mOCUJviwf4bJ1zwwXiTiM,810 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSequenceBlock.CEbTwj2T.js.br,sha256=Q4w8vwOfgTX-OaSTNd0q-83Pyph4Bx2gNv1BTz9QO0s,341 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSequenceBlock.CEbTwj2T.js.gz,sha256=-GSJvUd5OaSjnxSxIfOUCy1xWFGFN0TK4W_9aehddVk,414 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSequenceBlock.CEbTwj2T.js.map,sha256=yHx9oKOEmC0GQ64CD3G9nnnivOhiEZB6eo9helyyOYA,2869 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSetDelayBlock.NAhfwlgz.js,sha256=K77Zs863CVu4Ty8Ve-QIQocvxmlv06yrDPlYbTJ3jWE,3803 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSetDelayBlock.NAhfwlgz.js.br,sha256=khn6u6Igt5ZvARpZXyoKb_u_1MPQK4lZCZ6TKkOQgmc,1266 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSetDelayBlock.NAhfwlgz.js.gz,sha256=j7oF6RfEKPJHjF9FFhzHqi1t2ab1eZWfNm2WMlM9hlg,1429 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSetDelayBlock.NAhfwlgz.js.map,sha256=wr_y0Q4YM7-8w3FdFIA_1d_YQ1a_oxNSIxl1NYnF6lc,14028 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSetPropertyBlock.BrAMshGe.js,sha256=h4xGSAxd1yMMzii-BiBwEFpwhRbW-td9U07PGC81rx4,1049 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSetPropertyBlock.BrAMshGe.js.br,sha256=L2sNCZajKxV-0CZcoHPqHzbnKR1xKUK_rPUrBdE7_GY,440 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSetPropertyBlock.BrAMshGe.js.gz,sha256=gc99_Fyg2vtprYnm0G6JOMeU2WDgE-2-IHKZefAdSiw,520 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSetPropertyBlock.BrAMshGe.js.map,sha256=eNkKQOJxW6PQDJp2-TNTJp2WdND3kqcKo3zOgjALcms,4209 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSetVariableBlock.CWwy6I9C.js,sha256=bUvMuQITiiHm3cIq0spYgkPPQ4KafHxI_fZy5ouWCOM,1488 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSetVariableBlock.CWwy6I9C.js.br,sha256=8uTVR6QugmZFZIoFKCjKLsunC7yrPyFBpGvuYbqJQLE,589 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSetVariableBlock.CWwy6I9C.js.gz,sha256=KufJkMNAAv8SdIKNmVLh5gUrexetb-8fb_J5pbH98Z8,687 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSetVariableBlock.CWwy6I9C.js.map,sha256=u_5fwHUeZJFMhQ-d1mBcodIvc2AyUWNxyXM8JLC4RvU,5640 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphStopAnimationBlock.DRdSCS1A.js,sha256=4g0FD0hyCigyb_HbrwrVra06hZmC0N8DBHbZMrDKVQc,1967 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphStopAnimationBlock.DRdSCS1A.js.br,sha256=i6OjdM50lL262Vz2tcXl0I7UAN79waUvGs7Pe9Fcm5U,623 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphStopAnimationBlock.DRdSCS1A.js.gz,sha256=TqKmmGcfIniPB82j6Z2xIk8Mm0SpZP7-nnan_NLsgXQ,722 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphStopAnimationBlock.DRdSCS1A.js.map,sha256=qGKmqtQytZJX4Mm9c9D8NeZtyZ4zmcrGX8vc6bCzSWI,7276 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSwitchBlock.rlj1f3Pb.js,sha256=D4EUA_692e_2TBnG3Zd6Sn9tia5L8r_B3i5nyffx9Q4,1203 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSwitchBlock.rlj1f3Pb.js.br,sha256=hLy-piJcuScdrwT3XKHUrUGxgAcRK8guar6VvQFaMTY,491 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSwitchBlock.rlj1f3Pb.js.gz,sha256=bQ0a9_Y-3v179MuBgarY70cvnl8qdqLhyYnaMM14VNQ,558 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphSwitchBlock.rlj1f3Pb.js.map,sha256=SHGrNbncytW53y_6Uo-Ksxe3RC5LIcz1g4IDh6GtV-w,4657 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphTernaryOperationBlock.DiGI0Nsv.js,sha256=ueHwX-rVEzHoWcKSbr_GPJtqSZmCvIIy30ZtlJu8SJ0,487 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphTernaryOperationBlock.DiGI0Nsv.js.br,sha256=BKUJUSv1tyKwjpW510CIvfzTAwluaar5VXALPQNTK6Q,239 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphTernaryOperationBlock.DiGI0Nsv.js.gz,sha256=SiniO-nsOjfK0HHWwnwCt0-kJaIaUsO-AAMeOLWiMs0,286 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphTernaryOperationBlock.DiGI0Nsv.js.map,sha256=Vn65nbyIVN_RJm7eXDc7XB1WRpu5M-HAzM63Oj2ootk,2018 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphThrottleBlock.D9nMlAUr.js,sha256=9Z1X3S-IbRXnD1TYTIgcu3bYTInqN40p2g8pRPrTDnU,1441 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphThrottleBlock.D9nMlAUr.js.br,sha256=6eNLgZTCm3tz7d73JvhlzLnsPYlN8Xmn8rFHHx8RTk0,493 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphThrottleBlock.D9nMlAUr.js.gz,sha256=BEg69rpme74EaL0jZIL3l54HF1ge3vjNmDe0HPK_8KU,559 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphThrottleBlock.D9nMlAUr.js.map,sha256=_E6uA5agmmCs3p1B1BUZ8P1xS-5EIkfBYYFUlMErZXY,4812 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphTransformCoordinatesSystemBlock.DdG5wdid.js,sha256=gN-nB1eCAgtMslaQQwfu1TNDwSIIerG78PDE_brxFCA,1040 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphTransformCoordinatesSystemBlock.DdG5wdid.js.br,sha256=Kn2f46BLQPSozGjF5-u4q3c81zyw2I01sl-wQlEPfE8,419 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphTransformCoordinatesSystemBlock.DdG5wdid.js.gz,sha256=puoTV3qPJ0YsHHxhsXyJkQtW0YvVJqOh179fQeaMgVk,467 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphTransformCoordinatesSystemBlock.DdG5wdid.js.map,sha256=IPjGpLQuq__tpZuy03zc3FwGkqNY9I6EQWx1pH4fnVY,3956 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphTypeToTypeBlocks.DFY5E9Xa.js,sha256=m7F60Nc1AwGI8HWOsq242PGa3nIUo-48rU3gYLrlb_k,1276 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphTypeToTypeBlocks.DFY5E9Xa.js.br,sha256=SjZSGMig8VpLF01KLxK60-1hMH2a9N038SLQ5uhd9Ic,423 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphTypeToTypeBlocks.DFY5E9Xa.js.gz,sha256=us0P6z4upCVfMkqQE1GpFgIuwjYUN1SvckNcQgypneQ,485 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphTypeToTypeBlocks.DFY5E9Xa.js.map,sha256=YTIrylmblporrCmiMrbQMafjwkhT4-4vh4b-uEUbJwI,5083 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphUnaryOperationBlock.ZI1fHq8c.js,sha256=70eo5OdSDB43fDKZKtwwQJd9Rw_EH6Bksr3hXz7MZd4,369 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphUnaryOperationBlock.ZI1fHq8c.js.br,sha256=3a5CZCaw5tt4FCQnmfeVmKrf_QTA7wqGV1VMgrQjCF0,215 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphUnaryOperationBlock.ZI1fHq8c.js.gz,sha256=ckPacP-py1eS37TQn4QM8YQsTNJGlxv-jvyeGf_mLog,260 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphUnaryOperationBlock.ZI1fHq8c.js.map,sha256=mknKzr4LTDfbeze-UJlIAvnhwXFXXWwG4IknTOc0xtg,1756 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphVectorMathBlocks.B5YfnEFA.js,sha256=xXtVQGANWNYcN7goiflKqMwZDSwkNWl1XCRmersxqbg,2923 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphVectorMathBlocks.B5YfnEFA.js.br,sha256=8DYyBijPo66DGht50I6Y0LwdWqzOf_2nABoMIE_Cp_Y,911 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphVectorMathBlocks.B5YfnEFA.js.gz,sha256=zW7AF-wbnzqqmSDuw7lSnkEKE9mSvgwa0Yi1s3WKsm0,1017 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphVectorMathBlocks.B5YfnEFA.js.map,sha256=eCfUIoOEA1p9FTnkk4tdGyrhyJBTOrfWIqxzBd_TOb8,11060 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphWaitAllBlock.Bj0x3SHG.js,sha256=UgZTa7h6TiZSNvPlqbyJMKqsFSn8yW_yUkeLxVUUVmE,1588 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphWaitAllBlock.Bj0x3SHG.js.br,sha256=rH_fR1wNRfu0ldn2H9UcRd5ZbtAOSOY-7yImSdkAbLo,585 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphWaitAllBlock.Bj0x3SHG.js.gz,sha256=JaGlOEvTUkX5cKIccugl73_SNuyWNQlUZOF73iz6I7M,676 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphWaitAllBlock.Bj0x3SHG.js.map,sha256=tIWkrMKMujkSMfox_L9F5Q2QF3auUOCooxwh2vy0s_A,5476 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphWhileLoopBlock.CE8CW0jy.js,sha256=IRM9IAakZeHgLGpo4piGGGekDFuDO8ECzBVbUAyqT2Y,959 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphWhileLoopBlock.CE8CW0jy.js.br,sha256=11c5FBi4q547JDV_Xk0rzl7Wb27Jh6-XLxduqF9fhm0,425 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphWhileLoopBlock.CE8CW0jy.js.gz,sha256=HGuZtI74g-bvXI9oG244kz1u0xC9hL8HjHp0WoGdcdc,489 +gradio/templates/node/build/client/_app/immutable/chunks/flowGraphWhileLoopBlock.CE8CW0jy.js.map,sha256=KsZ1iOwZyc-t7tYmJJNf7SXPW83NVEyi3RB5ZcjtKPs,3197 +gradio/templates/node/build/client/_app/immutable/chunks/fogFragment.BUxLzITE.js,sha256=BrPG3n0mIoteiTLAVDZ636yNHfaE_fp37oxuckXjjPs,2591 +gradio/templates/node/build/client/_app/immutable/chunks/fogFragment.BUxLzITE.js.br,sha256=Rs3viFvcY58NyJbG82FhYrA-f892Eyx9eR92FHccfD4,699 +gradio/templates/node/build/client/_app/immutable/chunks/fogFragment.BUxLzITE.js.gz,sha256=FTjReXMiD9xjEl_jR-T29BdsfbOZdNPivkWeZDSeGiA,804 +gradio/templates/node/build/client/_app/immutable/chunks/fogFragment.BUxLzITE.js.map,sha256=YTtJJBOEQVClngmssIszzal7QyegNDihjXA1d7dzgSY,5696 +gradio/templates/node/build/client/_app/immutable/chunks/fogFragment.D2zFd_lI.js,sha256=QFFxnbJeJ5LAjqTPmllRuk9b80hZEIuxEGGBDLj7ln8,2319 +gradio/templates/node/build/client/_app/immutable/chunks/fogFragment.D2zFd_lI.js.br,sha256=9k_-zcFD8vhfXOn2P5TxWwulFeaKqXJaxvJU9fMJX9E,642 +gradio/templates/node/build/client/_app/immutable/chunks/fogFragment.D2zFd_lI.js.gz,sha256=_kWo2mR1JWRrRAHRzNepIRsNQDfhKdR8h5nWkVWqd9o,749 +gradio/templates/node/build/client/_app/immutable/chunks/fogFragment.D2zFd_lI.js.map,sha256=jc7qaWw2Sqh4QLsoKAB3DHbkrcdbdMUqa-vJSBD4S7Y,5390 +gradio/templates/node/build/client/_app/immutable/chunks/fr.BtMjEOuI.js,sha256=ZmXRUEx2iArGjom2tRXMzBc1V9rA8NUSsvplwq_q6a4,5065 +gradio/templates/node/build/client/_app/immutable/chunks/fr.BtMjEOuI.js.br,sha256=w8w76IoXNQ4Y3yKIXbL0O9YF9PDfpYVMR17BbqufOek,2077 +gradio/templates/node/build/client/_app/immutable/chunks/fr.BtMjEOuI.js.gz,sha256=PB_3zpgxyIIB3w7ySvfeXFk-vyE11WDTk6BctNqS1Gs,2292 +gradio/templates/node/build/client/_app/immutable/chunks/fr.BtMjEOuI.js.map,sha256=0_0SrxAl49FJvMmQ9MItlscefGcKrF8pcI--oHiUMk8,95 +gradio/templates/node/build/client/_app/immutable/chunks/fresnelFunction.PQckb9nj.js,sha256=LLOeqnOgp2hbibAEHY79OOCG1rVTJ1bE46o4-dXGQ0g,409 +gradio/templates/node/build/client/_app/immutable/chunks/fresnelFunction.PQckb9nj.js.br,sha256=XFq_GFjr1aE8J3JhJhKwHG2HXrkv2aA87Tst0OsQMkM,249 +gradio/templates/node/build/client/_app/immutable/chunks/fresnelFunction.PQckb9nj.js.gz,sha256=kg0pOF6H39MRFbG0peqzfbMc_ewAdY6ph4dC1boqrC4,292 +gradio/templates/node/build/client/_app/immutable/chunks/fresnelFunction.PQckb9nj.js.map,sha256=BE_8YPy2RCHNXa1sF6DZZ1nV5VzGqiyna02JRfV-ed4,1010 +gradio/templates/node/build/client/_app/immutable/chunks/frontmatter.BNFpjisB.js,sha256=CmSfFqKhptaQzKsnssM2SG5TEE300n8s3X5P6WcehBg,884 +gradio/templates/node/build/client/_app/immutable/chunks/frontmatter.BNFpjisB.js.br,sha256=gaO7rU5c0M0GGvttXGv7TuIpJckcHI_OFhzzW81J3Sg,460 +gradio/templates/node/build/client/_app/immutable/chunks/frontmatter.BNFpjisB.js.gz,sha256=QL7xuzI6ZEoCM3HL1zM5Cq2FWx6Op1DAyJ61hMwaVeo,522 +gradio/templates/node/build/client/_app/immutable/chunks/frontmatter.BNFpjisB.js.map,sha256=ljT-vSlzze1AHIjhTkp8l2bmm3OgCBPRKQnwAzyWlMU,3072 +gradio/templates/node/build/client/_app/immutable/chunks/ganttDiagram-WV7ZQ7D5.CDkbSQZN.js,sha256=ljphjAlqoxd5h9Uh8hETenB-1NbeMukMtmA9EpyQc5Y,45380 +gradio/templates/node/build/client/_app/immutable/chunks/ganttDiagram-WV7ZQ7D5.CDkbSQZN.js.br,sha256=g68Q1JE9lv5WvWjPv0MtJERxBXZDYhOlu9HeWFiiy8U,13830 +gradio/templates/node/build/client/_app/immutable/chunks/ganttDiagram-WV7ZQ7D5.CDkbSQZN.js.gz,sha256=sdkRojQrYDfuOwdGZ2Ra5MxJ10eQpHr8QHuvZegEjQU,15495 +gradio/templates/node/build/client/_app/immutable/chunks/ganttDiagram-WV7ZQ7D5.CDkbSQZN.js.map,sha256=18OzZnbZyi4K7jgdJ8LKC_FGW7RspOS5YmWNgzqyWec,151852 +gradio/templates/node/build/client/_app/immutable/chunks/gitGraph-ZV4HHKMB.B8c4G3FH.js,sha256=aU_gL1yNpsTHjcyNtLiEzd_0KHmFhU_zMEAxbd_R248,173 +gradio/templates/node/build/client/_app/immutable/chunks/gitGraph-ZV4HHKMB.B8c4G3FH.js.br,sha256=voDOVDRayKhERjDK9qi9BNeZnpuO0g5OkkOEEl_32CA,141 +gradio/templates/node/build/client/_app/immutable/chunks/gitGraph-ZV4HHKMB.B8c4G3FH.js.gz,sha256=5jEMi_d05V77mQb7AVrc1EJuYem3QbDQqeHyeu3J86k,166 +gradio/templates/node/build/client/_app/immutable/chunks/gitGraph-ZV4HHKMB.B8c4G3FH.js.map,sha256=pdnDLNcaUlPHKvVL-hukVIbbw2t_DxU7CbrgbXNgNGg,110 +gradio/templates/node/build/client/_app/immutable/chunks/gitGraphDiagram-OJR772UL.DPGyrqJS.js,sha256=6RYwxziZDensGzqketmaCKZKl8f-YlDWsT7gP6qfcHU,24706 +gradio/templates/node/build/client/_app/immutable/chunks/gitGraphDiagram-OJR772UL.DPGyrqJS.js.br,sha256=fQMmIyJfrOzsWfLnH66m4TlArTIjdFGJ33S_l46hZF4,6796 +gradio/templates/node/build/client/_app/immutable/chunks/gitGraphDiagram-OJR772UL.DPGyrqJS.js.gz,sha256=wC-CSzdoHA47MTmN3TMG3HtT6zOV4ymfvroEkdrhkA8,7555 +gradio/templates/node/build/client/_app/immutable/chunks/gitGraphDiagram-OJR772UL.DPGyrqJS.js.map,sha256=U0QCYAEBeMzKZJxdGc2hh8uxy504KLsKeiqJ4TiGbss,102771 +gradio/templates/node/build/client/_app/immutable/chunks/glTFLoader.BetPWe9U.js,sha256=X8_gGz99MNLUQFpu7wjkXCc67fEQ5OO9uFHuzh7QuRc,107769 +gradio/templates/node/build/client/_app/immutable/chunks/glTFLoader.BetPWe9U.js.br,sha256=azyv8Bs_Xx5f2fZ7jpGZqKmk0wfc3Z63V75wd0gBvxw,23543 +gradio/templates/node/build/client/_app/immutable/chunks/glTFLoader.BetPWe9U.js.gz,sha256=QN3h8Iy5fwcTedwaX1N8-rqzk8PCSzcE78HFf8maJU4,26390 +gradio/templates/node/build/client/_app/immutable/chunks/glTFLoader.BetPWe9U.js.map,sha256=V4HCFjgTX6IWsw44Y2eNtnTZBXt-n-WSJPspg0TqSYw,417304 +gradio/templates/node/build/client/_app/immutable/chunks/glTFLoaderAnimation.CKms7EUf.js,sha256=xmBB1BeWK3UNQ1nqDi_X22mC9hwYMWRCzJVEjgDlErE,1787 +gradio/templates/node/build/client/_app/immutable/chunks/glTFLoaderAnimation.CKms7EUf.js.br,sha256=FaWzRKTDdOYScQVUKpJC_FkOxOeG9AWJK-uc6OjSfkY,718 +gradio/templates/node/build/client/_app/immutable/chunks/glTFLoaderAnimation.CKms7EUf.js.gz,sha256=J2i1u4pBWehsHfAqkSpoGEz6ersp-TCQIinO0MSxQRQ,817 +gradio/templates/node/build/client/_app/immutable/chunks/glTFLoaderAnimation.CKms7EUf.js.map,sha256=Dg6PyartVk6_7B-YJ2UjsEp4Er3OSWGNtT0llhnJUww,6518 +gradio/templates/node/build/client/_app/immutable/chunks/graph.CEmC0eCk.js,sha256=4iGYrvwCNooO83SwIxcCiaIlr2k7LcMmXbI_98ilCq8,5963 +gradio/templates/node/build/client/_app/immutable/chunks/graph.CEmC0eCk.js.br,sha256=FN0re5rxrSQ6VfqeuzZP268gY-xMGKIEnIthy0Mg-HA,1765 +gradio/templates/node/build/client/_app/immutable/chunks/graph.CEmC0eCk.js.gz,sha256=ISx0H-fgC9NLoAHIUkqb2A-7aCyIgpsc-jHKUEJYaP8,1908 +gradio/templates/node/build/client/_app/immutable/chunks/graph.CEmC0eCk.js.map,sha256=QpQMJrhKvD2leIKcqptjGfCHGWzEQ5IHJxpe-Yif1DE,22974 +gradio/templates/node/build/client/_app/immutable/chunks/harmonicsFunctions.C1UVinys.js,sha256=yhwIQSfUJKGf0HyIOU99IchDONA2uBh0blxg117PeAk,3470 +gradio/templates/node/build/client/_app/immutable/chunks/harmonicsFunctions.C1UVinys.js.br,sha256=hWMGvCCL__rHVRloaxRvNsqVmQO3KmdFwATwBa3yOLY,872 +gradio/templates/node/build/client/_app/immutable/chunks/harmonicsFunctions.C1UVinys.js.gz,sha256=Axvb6iDf7OzuGKsjpAYZBSs5GiXlVkfqmOtLBqrW34k,974 +gradio/templates/node/build/client/_app/immutable/chunks/harmonicsFunctions.C1UVinys.js.map,sha256=ToJ6VcFkxTCzjjkBjOuiBTstwB1w5-zXAscOVMCJq18,4724 +gradio/templates/node/build/client/_app/immutable/chunks/harmonicsFunctions.ab_68Deg.js,sha256=l8bCvvHCeQix3ibX3XLPcQMBe9XoBx_bvwS8QokrXW0,2637 +gradio/templates/node/build/client/_app/immutable/chunks/harmonicsFunctions.ab_68Deg.js.br,sha256=S45iXaWVS5WbG8ZKg_sqvOoOIrS70I5pIg8k6W1VvD8,884 +gradio/templates/node/build/client/_app/immutable/chunks/harmonicsFunctions.ab_68Deg.js.gz,sha256=mH5liSJdDDdG86_4Lm_NSmg7V4OQ2-PHtlmG8xeMMRM,969 +gradio/templates/node/build/client/_app/immutable/chunks/harmonicsFunctions.ab_68Deg.js.map,sha256=qpbhSOMgCsnXE7b2MwoSE1UVDODJfaA7ij2dkjWTrX8,3880 +gradio/templates/node/build/client/_app/immutable/chunks/hdr.BtQBZSUD.js,sha256=YPqfUtUkMXjrrLF4EJcYvKC0gGbB4bGmgWzDWZH3MUc,4077 +gradio/templates/node/build/client/_app/immutable/chunks/hdr.BtQBZSUD.js.br,sha256=2OfjwYf3pZuW564oSyYBW7GH9CmNXd61BeciwjuTFeY,1564 +gradio/templates/node/build/client/_app/immutable/chunks/hdr.BtQBZSUD.js.gz,sha256=5gJkskOioxue9KTl6_axVcCIq17WjbcvrxpBUW-aaQA,1728 +gradio/templates/node/build/client/_app/immutable/chunks/hdr.BtQBZSUD.js.map,sha256=Fh3ocIFdDgJInq0usuSskIlg5_37idogCYG3_QZclS0,23631 +gradio/templates/node/build/client/_app/immutable/chunks/hdrCubeTexture.DjwBvdn7.js,sha256=QmmXPk7OhFDbdJT3lLbZ1F6S9pEt9lZ4agzhL6JXpyQ,30268 +gradio/templates/node/build/client/_app/immutable/chunks/hdrCubeTexture.DjwBvdn7.js.br,sha256=fVDKR3iSKm3nXy7N_T8ztXl3oU3jrOV9_x3k_Iqb8j8,6918 +gradio/templates/node/build/client/_app/immutable/chunks/hdrCubeTexture.DjwBvdn7.js.gz,sha256=POlKInbGUp1JEto8F8OzSQbSMz1-BJxC7VeMGTNoLzo,7609 +gradio/templates/node/build/client/_app/immutable/chunks/hdrCubeTexture.DjwBvdn7.js.map,sha256=fAHW5Io1yNyo7pHMnwOiSkdi6DkTgKBObaKl-Bbod94,103643 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.fragment.DSxmCFFd.js,sha256=X4OFlQTFSk4aSWyfdVMFvZ-fTrf20BJd4a0ulIHT128,851 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.fragment.DSxmCFFd.js.br,sha256=li3atPmYmNz551xZuG6eK7sihN7y19Qa16XcHAYdOJk,440 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.fragment.DSxmCFFd.js.gz,sha256=ZRxzdJ2cWBKAI-cNp-yZKY4lJxBWRyBBFCo92Z_M878,451 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.fragment.DSxmCFFd.js.map,sha256=hI_YZmrkIPOOg6Xiv-yKXe7JAlMfK5owfUNK-xLg1Dw,1593 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.fragment.xc7pfRic.js,sha256=v69hD1YVp00jvP77K8wqxrs1NqwmJO-37EhRvY3v5tg,685 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.fragment.xc7pfRic.js.br,sha256=jtmL71gDC0kDBNhibEcQMpO96UFyw7uUK7_E7B-0ypM,343 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.fragment.xc7pfRic.js.gz,sha256=su5oDOkgmMlmTE4Vc4O5VPBj9re39uzOXIVwYn7uyeE,397 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.fragment.xc7pfRic.js.map,sha256=B4bAQ-WarkE8NveBo7Lx2gjxsWAsJE_jOu7voWn9RBQ,1409 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.vertex.Dfq7Bl_B.js,sha256=84jxgfzt8_HQjDMktKJH01i7Uwn7-YGcJpACTubm748,563 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.vertex.Dfq7Bl_B.js.br,sha256=eQ3q10yWV9aIJujIwFr_TK0BsUDwNWtO8ObgRod2lPY,301 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.vertex.Dfq7Bl_B.js.gz,sha256=lXzfVjb8YEAlCU_6jpRU1dSOfZwEZM07elifUPOYtuE,357 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.vertex.Dfq7Bl_B.js.map,sha256=KQIeHtI1rPQxQFZeUipvOpGSEmnjVvjS7t9HxoLyHRM,1171 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.vertex.Do7UVsNP.js,sha256=HtDww1ZCorm2zhvArPgHxzD3xz-N0Zi2NKG5PMbYO1g,702 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.vertex.Do7UVsNP.js.br,sha256=shob06BJ2I0S6rPd0ai9RthMtKtCZL_wRVeEnCQFVho,366 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.vertex.Do7UVsNP.js.gz,sha256=shiPaYwB7G61ArPBaX-N4-93fUbvJRkQs_bZPpJOfq4,403 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFiltering.vertex.Do7UVsNP.js.map,sha256=PykrfIVQQqbALqWdUmjfH40SMYieyHBtq8_QCoUCEWM,1328 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFilteringFunctions.5uiW-V2V.js,sha256=1QLHewgzDVP84VEOFZZjAqfwi2Z8MqxSaYZ-5yVHEcY,14042 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFilteringFunctions.5uiW-V2V.js.br,sha256=yF6vxKZkX6szra-y9TZ1obDOJbBpmxz0ylRentK-rak,4210 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFilteringFunctions.5uiW-V2V.js.gz,sha256=nPYGa7JT9iGcoZKHGgdKZWtQ7_jLe5XY5riolUNIPOY,4545 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFilteringFunctions.5uiW-V2V.js.map,sha256=NWNlZg4pgGlK8l4eIHdza1L_Nywgebu0zbasYkN-lcM,16945 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFilteringFunctions.BAMmBZk2.js,sha256=1doDEhDmA0jCcXojrVYqGvTynPzeLhfXrLOdv_0gcq4,14544 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFilteringFunctions.BAMmBZk2.js.br,sha256=xaKjYGjNUFe0vdwoeXUhKPhAerjwqtXdfMl1YEkmKgQ,4208 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFilteringFunctions.BAMmBZk2.js.gz,sha256=HAgBt3fUJSEsG7W-1IZ9oFGZXzmhUB0-TnBmUGgCOW4,4571 +gradio/templates/node/build/client/_app/immutable/chunks/hdrFilteringFunctions.BAMmBZk2.js.map,sha256=7piXBMerBqvk3RVWowxQXWgDDuDtZEB5-u9RwZCOtuA,17363 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.fragment.D-vL2gMK.js,sha256=cLP-KjwunytkoKAJn6wFnm2JaxXU0HlvwAV4eiUihTY,799 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.fragment.D-vL2gMK.js.br,sha256=VKG5n3ORCkUpBDx5YSL0385tgSejqfQ64FmE0irElkc,384 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.fragment.D-vL2gMK.js.gz,sha256=pAFzQS4M_tnX_TCtBvIqDy7Zc81A9fQpQEn0tqESPic,436 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.fragment.D-vL2gMK.js.map,sha256=EoAGCUpxDovTsDyRkVDY3cMd4E_oOdCqtbZiinG9aec,1601 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.fragment.DficRESK.js,sha256=aP1TI3H_1r3Z_O9gj_-eNe90MVFqMLrhxPBHiWhSHvs,1011 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.fragment.DficRESK.js.br,sha256=OKl9YTpBNI87vaTCX5NcwUOdR1Ne8w60TRzMRirW0Pg,451 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.fragment.DficRESK.js.gz,sha256=gVXuCfSEI12S0bFdsj-byrEImWA16H_U9-n2ap4ttFI,499 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.fragment.DficRESK.js.map,sha256=sLd2hmsv_bWivZvCotXKWWIYv2oUX_4NbnEf3wjF-vc,1831 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.vertex.CeoFqdbB.js,sha256=xPxbD7ECgJhJPLBN7v6YCKPoc75SY1TEnsBwUU2iTCQ,593 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.vertex.CeoFqdbB.js.br,sha256=de2RVCKLic2J2ADcSQSZ2Nkz0LUpJw5VNcblXj6J-Yk,306 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.vertex.CeoFqdbB.js.gz,sha256=9GZ8CsavFpEFTB-xUfOz6FavvnGCaWShuJYeTvvPxgM,360 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.vertex.CeoFqdbB.js.map,sha256=7B01mJh1sBqhwXcEKKlqst4ZtZLMWYikV6GKAwFgdoY,1231 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.vertex.NhQXm8kI.js,sha256=hSovRm10p-cTWrTTUY-k7TRuSeBLUY4jy2hgncEiG3o,732 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.vertex.NhQXm8kI.js.br,sha256=GMwHcQa67YXihXJJ7pvLF9F2Y5fyVRN5VkfOmQcw1zc,355 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.vertex.NhQXm8kI.js.gz,sha256=2NZTrtm35k1LVYB0r5E80czbTxgTkB6McIeHHQifrAw,411 +gradio/templates/node/build/client/_app/immutable/chunks/hdrIrradianceFiltering.vertex.NhQXm8kI.js.map,sha256=JlSbzt2nXhRe3Y3VFxzDlx2G7IvTNWenZrjP9zNsPEY,1388 +gradio/templates/node/build/client/_app/immutable/chunks/hdrTextureLoader.R27R0mBk.js,sha256=kJTW0eAg22AvKZ6o5L-VyAHLR9Sln8IOg6_pxmO3AMc,586 +gradio/templates/node/build/client/_app/immutable/chunks/hdrTextureLoader.R27R0mBk.js.br,sha256=uI0xca8ouwwFZV0va7MylCJenOBLQvorQNdYLwG7psw,375 +gradio/templates/node/build/client/_app/immutable/chunks/hdrTextureLoader.R27R0mBk.js.gz,sha256=je-7OiJWjupBr6aHgVLni44MLKtJwpS2bUT_vhDy-uo,416 +gradio/templates/node/build/client/_app/immutable/chunks/hdrTextureLoader.R27R0mBk.js.map,sha256=gDG9xk5KZQetVL5ZQfpl0Vt_4OvGuT8ln7t4X3tKFp0,3257 +gradio/templates/node/build/client/_app/immutable/chunks/he.C03Xfbr8.js,sha256=5845TL7zpldYGA4JinrNQOA3StrdNpHZEvWRiw44-r0,5159 +gradio/templates/node/build/client/_app/immutable/chunks/he.C03Xfbr8.js.br,sha256=LC21yVqN8nEqee4MMN79nwxRxabwect1XXJymL9KZyQ,1907 +gradio/templates/node/build/client/_app/immutable/chunks/he.C03Xfbr8.js.gz,sha256=a-ezykRkBGuPB-Ml5YOp4WlM2aKTgXiZKp7i_KauPBg,2283 +gradio/templates/node/build/client/_app/immutable/chunks/he.C03Xfbr8.js.map,sha256=W_Ax0L38fraJZYnNxO0zYUsLkHRGme2GWHKYCWFuhEQ,95 +gradio/templates/node/build/client/_app/immutable/chunks/helperFunctions.BZ696Q10.js,sha256=3FTFfcQts9HoBqX7pVYtDNJcUJ9xMd_2NCa9HLpIOXk,5520 +gradio/templates/node/build/client/_app/immutable/chunks/helperFunctions.BZ696Q10.js.br,sha256=cs9gl8aCatlBTDT7xHfDnnUlYfJMj0wvNjYeiO96y0A,1650 +gradio/templates/node/build/client/_app/immutable/chunks/helperFunctions.BZ696Q10.js.gz,sha256=P8qPKCmxZmk50Wv0y_B4VfNBserI-RqumUjm6BPNIUA,1811 +gradio/templates/node/build/client/_app/immutable/chunks/helperFunctions.BZ696Q10.js.map,sha256=qFUMPiI3nFk3Opp7zGYMEpC_lpk1yQb251Ax1xP8vEo,6703 +gradio/templates/node/build/client/_app/immutable/chunks/helperFunctions.Ck4K-qjq.js,sha256=eU5CI-PzYRnUSBIBeQTonUTMWsPxb1zPcpLt99xuJdA,5357 +gradio/templates/node/build/client/_app/immutable/chunks/helperFunctions.Ck4K-qjq.js.br,sha256=lYVXSr8yNxZPVu86WUH6SklNQOQih2sO1X18NKR_-sQ,1657 +gradio/templates/node/build/client/_app/immutable/chunks/helperFunctions.Ck4K-qjq.js.gz,sha256=i2kwcW-hNnif2HBXDHVm1U7JW1IDU0GMH2FR6sTMNOc,1794 +gradio/templates/node/build/client/_app/immutable/chunks/helperFunctions.Ck4K-qjq.js.map,sha256=mHdVjCdZvqwFY03WQVKggdbUOr6bMIlTy6isGBAVIh0,6385 +gradio/templates/node/build/client/_app/immutable/chunks/hi.DaWfWT5u.js,sha256=-IQn4nDWDAolFIUmIJb5qyTagPI_4l133hBes7FNxAo,8360 +gradio/templates/node/build/client/_app/immutable/chunks/hi.DaWfWT5u.js.br,sha256=JbZtd0cfhwOX-9PgxWkCFGQPnmpzrCwvh-Ch9HJD3ow,2254 +gradio/templates/node/build/client/_app/immutable/chunks/hi.DaWfWT5u.js.gz,sha256=dy1dA10ZKrrcMP5RH1u61mg0JnXmyXm31T7mDMdB16Y,2733 +gradio/templates/node/build/client/_app/immutable/chunks/hi.DaWfWT5u.js.map,sha256=Jz5U-fNwIkbV-5coJH8qw5-FBNEESeP5vpeo9nze-rA,95 +gradio/templates/node/build/client/_app/immutable/chunks/hls.C_AVPmGC.js,sha256=fhcHWdYDiIzWjHo0RvT1T3Ww6DH_3lheEBEWT_dofx4,397084 +gradio/templates/node/build/client/_app/immutable/chunks/hls.C_AVPmGC.js.br,sha256=-fLYOWkrBtWYe7jcw0KkrKE07zcE03snGOTeXJJe5Is,102194 +gradio/templates/node/build/client/_app/immutable/chunks/hls.C_AVPmGC.js.gz,sha256=ZTSlL3GVVVrZkksCdphSZL04TtTtuznEsrLKXzpJXJo,122475 +gradio/templates/node/build/client/_app/immutable/chunks/hls.C_AVPmGC.js.map,sha256=FOBhErmyrscE13Wn4-TakP-CQmdFl2GePbbfwVozKo8,1558556 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfDebug.fragment.6eeToOmw.js,sha256=FL6-sXSNo2DHCHkY0ZRxpIvZFSzbVtrUALAgvvpWMew,3108 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfDebug.fragment.6eeToOmw.js.br,sha256=3yH51KFpEfMw-Uup05K7KPH_uEqJ0m7MgkFaDfg0nG4,921 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfDebug.fragment.6eeToOmw.js.gz,sha256=00cJ3uFJM2LfkCv4c09Wth2595c8iOdr6wWXk2jgUIM,1027 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfDebug.fragment.6eeToOmw.js.map,sha256=5UlMgYuw-BzuVgF7hTasyHo8FQnNLanS1lAH8FHbZbM,3892 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfDebug.fragment.CAG_w1Es.js,sha256=svrb4GxEdjkYeuysgfmZYGvb3b-jv1bSInC1RsXLX2w,2733 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfDebug.fragment.CAG_w1Es.js.br,sha256=E7E3s2J4XyP9KaH-soWQCHWSTUBC4-6S0Rd_7SkZJqw,904 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfDebug.fragment.CAG_w1Es.js.gz,sha256=EmobPP6pkL0LQLRWu7UQxYWElGtfPbWv_WF6kRSrIIY,991 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfDebug.fragment.CAG_w1Es.js.map,sha256=yVc4OcLBjgFR8Onea8fNz2Yw67Llb8Rh3CWDAWG-MTg,3552 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfx.fragment.DOqZcU35.js,sha256=jiEFcyAxsG9ML9Oee9d-ISGdO2qjyjQpxtlkxxzPYvw,550 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfx.fragment.DOqZcU35.js.br,sha256=QQZnmCeqKsN4swlOfOGAU73QodDvzncFep17QABX7VE,357 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfx.fragment.DOqZcU35.js.gz,sha256=fN1AAIlXXQxtKpasD8JvjxCzMnfkY_BJYVW_pZu1ffs,392 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfx.fragment.DOqZcU35.js.map,sha256=-XeWZwPPIGwVE-Obk5Q8orW0VLKyvbWJ85vSpOPazVQ,1129 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfx.fragment.Z-_-ltMr.js,sha256=BwAU9xp-ovibgHie0FMSZRRqj7UeBod_qFTcVcKzWhc,618 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfx.fragment.Z-_-ltMr.js.br,sha256=EfLA4wdPlqLZoFbOxoZYeRPwxpoCL2UVAotVfp_sYzA,365 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfx.fragment.Z-_-ltMr.js.gz,sha256=CDAmKWpWEodNJSmnwsjD83vuWuJjdsMx8uXPeUda4q0,410 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfx.fragment.Z-_-ltMr.js.map,sha256=TicT89s7GQSwAcO2OPRJ7MMG9YBWnCwsK7Y35xxwU20,1209 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfy.fragment.CTCeNoOz.js,sha256=Fos1RBiyfVr96vpABLizqA3YlLFK-FNKmQ8f3V1Jlx0,1216 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfy.fragment.CTCeNoOz.js.br,sha256=i4S5sx4peC1LKsDZ471h2xr-wF76T8e3s0eUZFCjn4w,622 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfy.fragment.CTCeNoOz.js.gz,sha256=7u4tZr_oe4I9MQqCIwwtUGSMzv8CMHBufG8wVUidu8Q,648 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfy.fragment.CTCeNoOz.js.map,sha256=HKr6gF1VsY7PFHuAYG624GUWnXLdEePyZPZ2pgTDKxE,1927 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfy.fragment.xBjBk7L0.js,sha256=ebTU9GHX3uEHV_K17Oj5yMGWFzTafJ8VA9bp56QxXgk,1312 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfy.fragment.xBjBk7L0.js.br,sha256=NKiCq99cPtcbyyZa5tJ4pD7ancuCUUdNVUrGrBACvjI,614 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfy.fragment.xBjBk7L0.js.gz,sha256=D3u1kFlOgI74Sv7Bh0ZR3TaFIMVD7kkTMc0m4TCRH54,670 +gradio/templates/node/build/client/_app/immutable/chunks/iblCdfy.fragment.xBjBk7L0.js.map,sha256=ulFlFSs8lkVKiSux1Au3M77WaIfmH5scu_ZB5Cmt7WY,2036 +gradio/templates/node/build/client/_app/immutable/chunks/iblIcdf.fragment.12bprPG9.js,sha256=y0trbbxIqn5olZhtqRS_v9vQAfZPZfLO38PI0ssSeRs,2894 +gradio/templates/node/build/client/_app/immutable/chunks/iblIcdf.fragment.12bprPG9.js.br,sha256=Tto2SXHLFhhH7pjTsegtDpcrLqrwrFDXgKKiXQcknCY,949 +gradio/templates/node/build/client/_app/immutable/chunks/iblIcdf.fragment.12bprPG9.js.gz,sha256=B84sMCf4NHEbbGGLhIuBdrLKCsU_cx1VjZ_toxgAGg4,1046 +gradio/templates/node/build/client/_app/immutable/chunks/iblIcdf.fragment.12bprPG9.js.map,sha256=2ZKFNkp1tUkuKewGHGi9udr57t3ODAqZs0lntHysD9o,3677 +gradio/templates/node/build/client/_app/immutable/chunks/iblIcdf.fragment.BdMnGfSD.js,sha256=2MdNIUG74t_PpDYWYA_013FA1mJjHkgueIvG4u2VRbM,2512 +gradio/templates/node/build/client/_app/immutable/chunks/iblIcdf.fragment.BdMnGfSD.js.br,sha256=OTt3SMD7cVwz9CEnr_LafhTF54-Fv-WsEYJRT8WMoyI,902 +gradio/templates/node/build/client/_app/immutable/chunks/iblIcdf.fragment.BdMnGfSD.js.gz,sha256=gcRnGqx0eCBFt4ZEk5Bq-6BjQLCMWS5oNT_jqRQHD1k,987 +gradio/templates/node/build/client/_app/immutable/chunks/iblIcdf.fragment.BdMnGfSD.js.map,sha256=OhOY5YRxLzsSMjjP0M8XpIlsTW0XpF-bURCRgFUC-PY,3282 +gradio/templates/node/build/client/_app/immutable/chunks/iblScaledLuminance.fragment.Bok6c6yO.js,sha256=IScYsHHH0wqb3iSwpZweWlOl3xpoBPsOzpp4HzqelA0,1088 +gradio/templates/node/build/client/_app/immutable/chunks/iblScaledLuminance.fragment.Bok6c6yO.js.br,sha256=toY-O2ckzJy3GZG0B3ygyYzcGtkuVwO3WPdeiGY6cWw,498 +gradio/templates/node/build/client/_app/immutable/chunks/iblScaledLuminance.fragment.Bok6c6yO.js.gz,sha256=ouXhh5-GHAcA5HPKoOsMeFFbDvZh8cB71ExpB-9BpkA,551 +gradio/templates/node/build/client/_app/immutable/chunks/iblScaledLuminance.fragment.Bok6c6yO.js.map,sha256=KKOq-QbFJ3tLtMMU0i1EAsxVM_JC7AmmdSZs5ok6RB4,1790 +gradio/templates/node/build/client/_app/immutable/chunks/iblScaledLuminance.fragment.CSkzw7tw.js,sha256=1ybGkvAk362zR58wWykKsjOFCnLYlCHDoZ_dcrYbfAc,945 +gradio/templates/node/build/client/_app/immutable/chunks/iblScaledLuminance.fragment.CSkzw7tw.js.br,sha256=KXzsdoX9kStoWrN2DszA6fG5H0_irdTQumtiN_kwxy0,470 +gradio/templates/node/build/client/_app/immutable/chunks/iblScaledLuminance.fragment.CSkzw7tw.js.gz,sha256=IcBSn5yj44nzeQQk0kpyxe5wRkPazSMMsbUFxac0zL0,527 +gradio/templates/node/build/client/_app/immutable/chunks/iblScaledLuminance.fragment.CSkzw7tw.js.map,sha256=wwQozOGOo-3lhBBu2pXocS_5HAR0dlIpZy9RWfrAxMI,1641 +gradio/templates/node/build/client/_app/immutable/chunks/id.DT7UMZdQ.js,sha256=0LlOTRiMW9ZrZFWOahxpYRvzpllbv3IBAlKEJIRlI-4,4599 +gradio/templates/node/build/client/_app/immutable/chunks/id.DT7UMZdQ.js.br,sha256=lcdnKmXWdyv1PCBLj6WDb-Ff2YzG5eCSCwoIAnqo_Vo,1941 +gradio/templates/node/build/client/_app/immutable/chunks/id.DT7UMZdQ.js.gz,sha256=6-DPeff8krDiGupUiRWMQuSFVpIYGQVaDd89Ap0iumA,2132 +gradio/templates/node/build/client/_app/immutable/chunks/id.DT7UMZdQ.js.map,sha256=KpLFEoGrq0K71rNi42X2H53z9NIpNv78lEwyuJlafTY,95 +gradio/templates/node/build/client/_app/immutable/chunks/iesTextureLoader.SVutdS56.js,sha256=RzsL7W3fCsQVf-GvnuyeTnKrg6xQYJLtLxbGudnYdgc,2744 +gradio/templates/node/build/client/_app/immutable/chunks/iesTextureLoader.SVutdS56.js.br,sha256=IX1Lz6S_iuyE1csMvwR-Rm0fp4mL7mNNA7FBYrHM8AM,1070 +gradio/templates/node/build/client/_app/immutable/chunks/iesTextureLoader.SVutdS56.js.gz,sha256=HuqzO1Yf3l-QuhIlp4cyucZtQpjHSsIFlkOQLM9ZlXU,1181 +gradio/templates/node/build/client/_app/immutable/chunks/iesTextureLoader.SVutdS56.js.map,sha256=YF2IgyyXQAkKzFZ-ox7yXc1bwS2W4LuPsGl8KEi-6Y8,12350 +gradio/templates/node/build/client/_app/immutable/chunks/index.7c3XF4Mn.js,sha256=wJfHDCQMLcjmgTF9a1cA9DFHtsOqqrzZWnlDjYMKaYI,14341 +gradio/templates/node/build/client/_app/immutable/chunks/index.7c3XF4Mn.js.br,sha256=KhRDNLX6ja14FxfsT0RcfQbPt6P2OFwiLZppWCa6FQI,4087 +gradio/templates/node/build/client/_app/immutable/chunks/index.7c3XF4Mn.js.gz,sha256=UPjHuoG0KQlcWzrvKjGPEyQLYUPx3-Ka7oiI-VVnKLY,4762 +gradio/templates/node/build/client/_app/immutable/chunks/index.7c3XF4Mn.js.map,sha256=H4yqd7wK7dDMCxZ_dwRAmms9xH6alWHMSSQjBdizHKk,13135 +gradio/templates/node/build/client/_app/immutable/chunks/index.B6DhgMUy.js,sha256=l8o2CIL2R4Vk2wp7kBAh2mqLuoyTsvZP9LaW1rl7Tgs,22991 +gradio/templates/node/build/client/_app/immutable/chunks/index.B6DhgMUy.js.br,sha256=_4NsCvdcIw9UiFqYL92J2Plh1nBHM_WZ0fS5AKgzONY,8816 +gradio/templates/node/build/client/_app/immutable/chunks/index.B6DhgMUy.js.gz,sha256=a8uJmbe8AF6vctkn0b6GLrlMS6HVeYm8xaQURNOIyPc,9993 +gradio/templates/node/build/client/_app/immutable/chunks/index.B6DhgMUy.js.map,sha256=JR3MPgRuLIpG27M8ZtVKMBkG-iwVlB14RKgDHCvHKbI,44089 +gradio/templates/node/build/client/_app/immutable/chunks/index.BaEKf4N4.js,sha256=QbvHSGrd994wd39J7Dr0zemqdDpP-CiEQBJwx2slp5I,26097 +gradio/templates/node/build/client/_app/immutable/chunks/index.BaEKf4N4.js.br,sha256=YzIprEbM4AVPH7iWsOnaW2_AghDzyYUpCH8O-sNiiwI,8001 +gradio/templates/node/build/client/_app/immutable/chunks/index.BaEKf4N4.js.gz,sha256=lWwyt1lqfOY-OmsvDWBtbGv1E3HzSahyoY97hIaZLAs,8716 +gradio/templates/node/build/client/_app/immutable/chunks/index.BaEKf4N4.js.map,sha256=nxcR_8NyGgCYFFgnW8dblDvGfhZHKGnHvf4U22_LJ8o,110266 +gradio/templates/node/build/client/_app/immutable/chunks/index.Bi7T_FA4.js,sha256=rgN9Sud078bl-OEjfuBHSBO89_kR8l_gf6Gtijt8tBs,4901 +gradio/templates/node/build/client/_app/immutable/chunks/index.Bi7T_FA4.js.br,sha256=Tf9dKbmB4Kp9l_Db-UpdKmy_IaikJUbQpLJ8kym2qsc,1791 +gradio/templates/node/build/client/_app/immutable/chunks/index.Bi7T_FA4.js.gz,sha256=LzmtX9qVCItL5ZSlWsywIjVTdVXjcF0k29_9DaHPgKc,1979 +gradio/templates/node/build/client/_app/immutable/chunks/index.Bi7T_FA4.js.map,sha256=kWGcwRZDN5ml_ZfV9rCwv222oh4uUvmzSa8j_WUBdDk,23774 +gradio/templates/node/build/client/_app/immutable/chunks/index.BoI39RQH.js,sha256=hFj6ig_1Ver_yunPGxEBfBm0KLiuOSMJcdIyHjtcDk4,1222090 +gradio/templates/node/build/client/_app/immutable/chunks/index.BoI39RQH.js.br,sha256=VzfU2FZUMp04bZCkxnHYPDu2IvKLJSWB7-Ll07mGUfU,249612 +gradio/templates/node/build/client/_app/immutable/chunks/index.BoI39RQH.js.gz,sha256=IR7TK8iqoBKU2MhahDCP3ZvH9TV4fMyJ1zd7S2jn1B0,307233 +gradio/templates/node/build/client/_app/immutable/chunks/index.BoI39RQH.js.map,sha256=R5TAFnJpYeqAn8NXANNR92zz-g40NsKOzxgZ00aX6W4,5113122 +gradio/templates/node/build/client/_app/immutable/chunks/index.CDfa8EaJ.js,sha256=DGZNHQbY_Vsf6MlvsbCTVISTjiQqYZG11BxCq2ruVX0,56085 +gradio/templates/node/build/client/_app/immutable/chunks/index.CDfa8EaJ.js.br,sha256=vUZ6hDRi9RFIeHJ3cAWAHMZasi2t3LtW-RGG-5bDirk,17063 +gradio/templates/node/build/client/_app/immutable/chunks/index.CDfa8EaJ.js.gz,sha256=-1JyCnyO6iMW-9xZQj6evb2_6SUc2Z-VlnGNS-Ordys,20369 +gradio/templates/node/build/client/_app/immutable/chunks/index.CDfa8EaJ.js.map,sha256=Juz4lpMZFcPC3LjGZLJPCR2G97FpW-AoVESKZD5kcYw,82349 +gradio/templates/node/build/client/_app/immutable/chunks/index.CTLtmS8V.js,sha256=VdOhi1h89D8D7galbMU3hqTUYSwfjYexecwVgkbdNRc,2436 +gradio/templates/node/build/client/_app/immutable/chunks/index.CTLtmS8V.js.br,sha256=BdUNOh5ja7ry-3fEBE8g6528HhUXHG_wWZ04-uRIMiI,1370 +gradio/templates/node/build/client/_app/immutable/chunks/index.CTLtmS8V.js.gz,sha256=7o5RBX1bqwCkazrmTE7M570tCVNRilSn1HgyLKjuF88,1492 +gradio/templates/node/build/client/_app/immutable/chunks/index.CTLtmS8V.js.map,sha256=75Ep9nQp_GHLjZ8rFA1P42Z96jQhI-uMSBPvETu7Kno,5958 +gradio/templates/node/build/client/_app/immutable/chunks/index.CkUWgvGJ.js,sha256=m-qYz5esUn8Qz60FUiSW1HFfqXAWPWsOICU88pPzEbo,229 +gradio/templates/node/build/client/_app/immutable/chunks/index.CkUWgvGJ.js.br,sha256=V45txM9fJp8S9h8QqF0kBZsg7R8UrtL0Iem7TFFRGtU,161 +gradio/templates/node/build/client/_app/immutable/chunks/index.CkUWgvGJ.js.gz,sha256=By-e5C-5XoRmkyug0s79qYj855KAk6NzINLlPOjdVm4,187 +gradio/templates/node/build/client/_app/immutable/chunks/index.CkUWgvGJ.js.map,sha256=kJLS3eelo1VpQ9ptTdoQWxqeHeZHUBC5lmJHpxFypks,98 +gradio/templates/node/build/client/_app/immutable/chunks/index.CnqicUFC.js,sha256=jxcCKlBwVber3OEzO4FTIPpEqJIq1Qfd5yS33-bqiUo,522 +gradio/templates/node/build/client/_app/immutable/chunks/index.CnqicUFC.js.br,sha256=de719dT9GJSZpfGm4SKtDMpuUGmjg9QmTlhMYX7UdK4,294 +gradio/templates/node/build/client/_app/immutable/chunks/index.CnqicUFC.js.gz,sha256=pWGgCVkIiwSBkyVIS8Dy8HZ0OA3vyTZNpWH4CkjQu8o,343 +gradio/templates/node/build/client/_app/immutable/chunks/index.CnqicUFC.js.map,sha256=LJY3B3V_663sF-r5wtWzUL3epK5Rbcwy9RQYkmVkXK0,1804 +gradio/templates/node/build/client/_app/immutable/chunks/index.DEEZiz47.js,sha256=V-ixeqyMKvnLxB7p1F0DkSjc09XFWmiupKSpzmAMyh0,42945 +gradio/templates/node/build/client/_app/immutable/chunks/index.DEEZiz47.js.br,sha256=bCbW-nVfODAt1tGZQB_idSsr4P-SBClXv1qs3Z3p0mI,13583 +gradio/templates/node/build/client/_app/immutable/chunks/index.DEEZiz47.js.gz,sha256=esBlmrFFFrVqivI10ZxSi2RuNk8upnZ1S0F7t99P6Bc,14799 +gradio/templates/node/build/client/_app/immutable/chunks/index.DEEZiz47.js.map,sha256=EbnnyjkHffH0IcZvQhtLNdVucALhYeCbocDh6gJJr7Y,174673 +gradio/templates/node/build/client/_app/immutable/chunks/index.Dw5vV_fe.js,sha256=m5PncsrOG7u-u1thrzpnXWFQSCNzRbKi43llqiIJ3wM,28786 +gradio/templates/node/build/client/_app/immutable/chunks/index.Dw5vV_fe.js.br,sha256=8EPm_9aWZq7OWWYxqERM292611okAYoYPacGMlF9xa4,10238 +gradio/templates/node/build/client/_app/immutable/chunks/index.Dw5vV_fe.js.gz,sha256=RU-qXFL_fYkBaSwzNT5o39yoNcxzFeI96FT-iVKfBBM,11445 +gradio/templates/node/build/client/_app/immutable/chunks/index.Dw5vV_fe.js.map,sha256=upZXceYGT-JxnnPWw_EAv12FVo1s64xszxefvQZm-RI,76795 +gradio/templates/node/build/client/_app/immutable/chunks/index.R_oaT30q.js,sha256=XAOqRCqDT9kcQcwhVKutp-FAbBtrZ-4DJXyQyiz1_nI,20399 +gradio/templates/node/build/client/_app/immutable/chunks/index.R_oaT30q.js.br,sha256=AEQG4zSkUs5b-kNF8Ziq3egKNc2AXWLUiroi_x4_BYw,5779 +gradio/templates/node/build/client/_app/immutable/chunks/index.R_oaT30q.js.gz,sha256=MdRO4_6TTkrIUjgDAMqGldNhVyfw8L-RpMiDogHJ3WI,6673 +gradio/templates/node/build/client/_app/immutable/chunks/index.R_oaT30q.js.map,sha256=GDrOwMqN1XjKy9k345i5U7US2iZjvm2yHLr3ZhAbfbI,18127 +gradio/templates/node/build/client/_app/immutable/chunks/index.Vrc5Br-P.js,sha256=DLsNUU2jdq7edzuojZmv4Ir7x7MvltNlq7pWXA0ivv4,452 +gradio/templates/node/build/client/_app/immutable/chunks/index.Vrc5Br-P.js.br,sha256=Q6hMloHWTCz6Snd0aAqvR1D6IMpsf0npfOhsypTt7AE,254 +gradio/templates/node/build/client/_app/immutable/chunks/index.Vrc5Br-P.js.gz,sha256=tpY5SBVxHjYQ65VMD2znyw5Vxb-j4Q5yVAijhtUSxQk,298 +gradio/templates/node/build/client/_app/immutable/chunks/index.Vrc5Br-P.js.map,sha256=x9unihf9UBUo8c95Rc6XdhbBKP_Q5AabmRbXydwqsgQ,98 +gradio/templates/node/build/client/_app/immutable/chunks/index.tFQomdd2.js,sha256=tDfewTB8aOGzc2WDsBbpxhTS-_RINS66Ru94A-UpbtY,1107 +gradio/templates/node/build/client/_app/immutable/chunks/index.tFQomdd2.js.br,sha256=lyubagvp08DM54jRt2E9LCGRpPcxYPitW2chMYDxRxE,467 +gradio/templates/node/build/client/_app/immutable/chunks/index.tFQomdd2.js.gz,sha256=OxcJCanYemHr1s3firBzEUAppkQeqYLoq9Od4MyOv_w,529 +gradio/templates/node/build/client/_app/immutable/chunks/index.tFQomdd2.js.map,sha256=Z0s10ZEyVwV3ong4sGQmFmAx1A06vdGiFO9yuz7mrEI,4080 +gradio/templates/node/build/client/_app/immutable/chunks/index.wTkntGrF.js,sha256=J6fm47X69N9Mr5JRsHSaosu_AP0Pcsf4aaUnuqgOYDA,78607 +gradio/templates/node/build/client/_app/immutable/chunks/index.wTkntGrF.js.br,sha256=ns6Y3MloueIihf5QhIRxRmmhsnCmZYg7XA2l7NHYoaM,25645 +gradio/templates/node/build/client/_app/immutable/chunks/index.wTkntGrF.js.gz,sha256=p1_2_0F3SLUndt0lOyDd4JoCy_mhMdUiKu9IhhicNlI,30316 +gradio/templates/node/build/client/_app/immutable/chunks/index.wTkntGrF.js.map,sha256=TbGchNmOBmRWDSJnJXaVdx0Up4wfbM7dKwvhUqV2-ZM,109795 +gradio/templates/node/build/client/_app/immutable/chunks/info-63CPKGFF.DxN3w2iD.js,sha256=EPpsez4vbG_sf_-ewggWfGrSn967Ku-jsON-FmN9g8A,161 +gradio/templates/node/build/client/_app/immutable/chunks/info-63CPKGFF.DxN3w2iD.js.br,sha256=mVQxa-H9gcamDaGSexZXu9ZuL3_grt5Z8oF6Ptq9zVE,131 +gradio/templates/node/build/client/_app/immutable/chunks/info-63CPKGFF.DxN3w2iD.js.gz,sha256=iXzNI0QhwEsC-aDBWFYev-duNfq5-5e10dZu274lAos,162 +gradio/templates/node/build/client/_app/immutable/chunks/info-63CPKGFF.DxN3w2iD.js.map,sha256=pYLy8Yh5pFzouKzconjNZ2F_2b6KpJvs41tzLbZgJxk,106 +gradio/templates/node/build/client/_app/immutable/chunks/infoDiagram-DDUCL6P7.B5gMWncv.js,sha256=ki1GWi5mHz95nCpiXOMRpnbpHyD5EUtDwqyZZ_Dfrp4,625 +gradio/templates/node/build/client/_app/immutable/chunks/infoDiagram-DDUCL6P7.B5gMWncv.js.br,sha256=Pcs3ulfyXwWQkvzqcL0FBgBZwYDLmP9LRR4yMJvxvKo,367 +gradio/templates/node/build/client/_app/immutable/chunks/infoDiagram-DDUCL6P7.B5gMWncv.js.gz,sha256=skbUEftJ_2dWf2-WFQHa2mfGIuP6Uc0KShAnZXYvzxw,423 +gradio/templates/node/build/client/_app/immutable/chunks/infoDiagram-DDUCL6P7.B5gMWncv.js.map,sha256=Vq5VT9qS37VMTgpmcB86V2KljhAYvDb5qsSpJrExF2Q,2381 +gradio/templates/node/build/client/_app/immutable/chunks/init.DGTL8PSK.js,sha256=KLjaOnNGjn3QWYdnDEjhD8kfw5bAjzjmJok6X99kUYo,62423 +gradio/templates/node/build/client/_app/immutable/chunks/init.DGTL8PSK.js.br,sha256=D0HmDPsY2J5k02FrNidtfT2d4CK-ZPanzOENRIpQdJg,15212 +gradio/templates/node/build/client/_app/immutable/chunks/init.DGTL8PSK.js.gz,sha256=usCm-M4ZJyBOhuzNRiDiGUiFiAcvtRSw4BDKTSOBjXI,17089 +gradio/templates/node/build/client/_app/immutable/chunks/init.DGTL8PSK.js.map,sha256=LJG1xz5rdgoiTQg-3gnpwEDIYijrlW1vOnnGcSJHvDM,213741 +gradio/templates/node/build/client/_app/immutable/chunks/init.Dmth1JHB.js,sha256=sY8EHEt-SVPskDgHJhL8aiGSFebp5HXAfUahbeqG7oQ,419 +gradio/templates/node/build/client/_app/immutable/chunks/init.Dmth1JHB.js.br,sha256=DAZZwfFkD2-fFKGkOww9ZpyR9EEPwnj4c5MXeLbbHJs,173 +gradio/templates/node/build/client/_app/immutable/chunks/init.Dmth1JHB.js.gz,sha256=RDMdM2lbRmuLSqxcH72tYLjSm-4yI3hSvu6yOiNBYNQ,234 +gradio/templates/node/build/client/_app/immutable/chunks/init.Dmth1JHB.js.map,sha256=KYopb4kZaVEWw0P3nwIBVbTnXYM-QH-TlCuUKlR2FKQ,1394 +gradio/templates/node/build/client/_app/immutable/chunks/ja.BTBiRAkN.js,sha256=mHPAGOr__UblbInsksfUCT2w1TtI_q4Vf2BzcA0La9E,5673 +gradio/templates/node/build/client/_app/immutable/chunks/ja.BTBiRAkN.js.br,sha256=PGgcm5B8fu9VqYgaYaJOr3-q3cbiXVYvjT7KPm1fG4o,2189 +gradio/templates/node/build/client/_app/immutable/chunks/ja.BTBiRAkN.js.gz,sha256=Con77CG5EGShBekIynoSx2tbX5E53GxxNCeBQV8Wdh0,2604 +gradio/templates/node/build/client/_app/immutable/chunks/ja.BTBiRAkN.js.map,sha256=MDNOoxtVIRK5xMuDrLEKZIR-5noRIGtPzZk6AH6Ewe0,95 +gradio/templates/node/build/client/_app/immutable/chunks/jinja2.C4DGRd-O.js,sha256=wg1xfUyEI4b2KgCN_l1-7nmyZneDMGGcCrcwqmwyUqQ,2660 +gradio/templates/node/build/client/_app/immutable/chunks/jinja2.C4DGRd-O.js.br,sha256=POr59KX7qZCLsUW7uYtUs_suIJ9MkIR1lBn0EyK8d_U,952 +gradio/templates/node/build/client/_app/immutable/chunks/jinja2.C4DGRd-O.js.gz,sha256=vHBzjmo-QHRG4Ppu2hixADs_eEQNc6wzjkM-knw365A,1077 +gradio/templates/node/build/client/_app/immutable/chunks/jinja2.C4DGRd-O.js.map,sha256=zGymelHLnAMjgybvB3uqP0SO_uuKuaHIEbgbNziyPJE,8369 +gradio/templates/node/build/client/_app/immutable/chunks/journeyDiagram-FFXJYRFH.Di_Wav3K.js,sha256=wld7ZVA7MYxiU1yqnCIg9hbny8ChuBNEnzXxpiiMaoc,23622 +gradio/templates/node/build/client/_app/immutable/chunks/journeyDiagram-FFXJYRFH.Di_Wav3K.js.br,sha256=liNzDobD-_SFFXuXIbBgEK-od-2vSTinSd5IXtJzU1s,7555 +gradio/templates/node/build/client/_app/immutable/chunks/journeyDiagram-FFXJYRFH.Di_Wav3K.js.gz,sha256=2LSB1BnPRiaQfHRgUnSFqvdJQ-wbEQ6c5TNdkrC07pc,8317 +gradio/templates/node/build/client/_app/immutable/chunks/journeyDiagram-FFXJYRFH.Di_Wav3K.js.map,sha256=-mxfj_XmCgycrouEhwujGnZ4ea03sAE5YGCys1LbUfM,80411 +gradio/templates/node/build/client/_app/immutable/chunks/kanban-definition-KOZQBZVT.DR4HyZ5P.js,sha256=eRSGtQk9YIs_sxAcs5TznNjAtMSCBR5cCPUwv0J3fHQ,20634 +gradio/templates/node/build/client/_app/immutable/chunks/kanban-definition-KOZQBZVT.DR4HyZ5P.js.br,sha256=GImWAbgTY-5IQMXpJ7_p5glCNMU0JEPimvjXzjxRjGg,6476 +gradio/templates/node/build/client/_app/immutable/chunks/kanban-definition-KOZQBZVT.DR4HyZ5P.js.gz,sha256=KF1Fl_O-ri6WHJi2yNqItoNNZC2dozaWVkyFCKNan44,7213 +gradio/templates/node/build/client/_app/immutable/chunks/kanban-definition-KOZQBZVT.DR4HyZ5P.js.map,sha256=IjI1DLrZcwQIKms6hmSbozh1TaAnBo-yiO4dHCJvfaM,68295 +gradio/templates/node/build/client/_app/immutable/chunks/katex.ChWnQ-fc.js,sha256=NkTNCkYkne5j2FcvagiBCecnNVH5LQJs18KNDH79S6g,265489 +gradio/templates/node/build/client/_app/immutable/chunks/katex.ChWnQ-fc.js.br,sha256=ubLiKiYVi52t3g7hrAXgD_pJY93LWwH8mMKcYjNKyWI,63757 +gradio/templates/node/build/client/_app/immutable/chunks/katex.ChWnQ-fc.js.gz,sha256=yZjtZtFVQ7OFBm9oSqxKXx6fMMtRQbyPsvvFnLxZZYU,76867 +gradio/templates/node/build/client/_app/immutable/chunks/katex.ChWnQ-fc.js.map,sha256=cng7lHGd8i2KHLkLSIwc9SEvl7y6cD1eOs9zY5oE1kU,987819 +gradio/templates/node/build/client/_app/immutable/chunks/ko.C9Hiv2KW.js,sha256=5NX3JKOxQ2ApKPGlhArcDMnnysciYL23SUnnyTkl6Ko,5070 +gradio/templates/node/build/client/_app/immutable/chunks/ko.C9Hiv2KW.js.br,sha256=-9qZTGzTMRitktwRaNr_k8w3jU9OfnWMTzFsqZ3ClTY,2132 +gradio/templates/node/build/client/_app/immutable/chunks/ko.C9Hiv2KW.js.gz,sha256=0ZayvXbNsT52XPABJq7a8btiDWlBi6FCuW9qOazK-G8,2507 +gradio/templates/node/build/client/_app/immutable/chunks/ko.C9Hiv2KW.js.map,sha256=8cT_blkiDGxeQ-rSJeAluO3Y_rNJQjfYKrmHAZ5bTEA,95 +gradio/templates/node/build/client/_app/immutable/chunks/ktxTextureLoader.CYBfYmpx.js,sha256=wkMJeZLuKME1uz_fsGtD5ScilfyBftNoD-C2mMbvsA8,14307 +gradio/templates/node/build/client/_app/immutable/chunks/ktxTextureLoader.CYBfYmpx.js.br,sha256=bxXQ8q0uNJ4PyL-12GSm_mwYNP7cxaZZmkLVxyr4DAU,3763 +gradio/templates/node/build/client/_app/immutable/chunks/ktxTextureLoader.CYBfYmpx.js.gz,sha256=nYgrmIOq3AKENpFlFC6oK4iQOLAyoQe0wmqeFKz-M8A,4197 +gradio/templates/node/build/client/_app/immutable/chunks/ktxTextureLoader.CYBfYmpx.js.map,sha256=LzMr9SBB5H6aprUjP-XwfRpWNVp-I7CoXGl2EvnVZ00,54994 +gradio/templates/node/build/client/_app/immutable/chunks/layout.Bcpteh_H.js,sha256=uoC-yCphXoYAoHlUTFpKTIfhEDoymp0Y8RYYIQTjAjY,27250 +gradio/templates/node/build/client/_app/immutable/chunks/layout.Bcpteh_H.js.br,sha256=TdNfVl8Bsy4eKbb4r1rnXc7bsBG9L6dHnFPqkQtQqMI,8852 +gradio/templates/node/build/client/_app/immutable/chunks/layout.Bcpteh_H.js.gz,sha256=6_k9h_cACkg6fXQsWbaxP1wo3Hs5pb_zfaVGvb-bO_4,9700 +gradio/templates/node/build/client/_app/immutable/chunks/layout.Bcpteh_H.js.map,sha256=5a2jh_ZXfszz4mcnqcKpqo8LZzlZiSCQ_q4sPRZviSE,163344 +gradio/templates/node/build/client/_app/immutable/chunks/linear.BQxp-PJv.js,sha256=xxqRLySwkLYMB2XllPNnYjh-0zcnlBkjHlR7cODfVl8,6036 +gradio/templates/node/build/client/_app/immutable/chunks/linear.BQxp-PJv.js.br,sha256=Q5BBhlMvw26mjsGEAWVIIB4vY9TZ1LS9tfYQ5CkfnjI,2283 +gradio/templates/node/build/client/_app/immutable/chunks/linear.BQxp-PJv.js.gz,sha256=o3lVZC4uEzTC3iw45lBq_I6hXRIJbvu6ZfdecLLRFKc,2498 +gradio/templates/node/build/client/_app/immutable/chunks/linear.BQxp-PJv.js.map,sha256=OUD97DrIJhp3sDXpWDgnLsvn2t1aWBWfdvM93tCkjEY,28667 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthDeclaration.B72K0fi0.js,sha256=cjX437MagUtRnPYPseaIito9TJZeVkS4WCdQePDLp9o,810 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthDeclaration.B72K0fi0.js.br,sha256=0V8WfuImyr4c0hadxakGQW5BUhWEMRddqcEzHB5iUYk,385 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthDeclaration.B72K0fi0.js.gz,sha256=KLVBNQtagX1zXPM0MD2ixeMNXS_TcEP0umzG5LgpgIQ,425 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthDeclaration.B72K0fi0.js.map,sha256=pVdFdvoUKCQDCO4xt7HuPWzoylnR0JpZhQPtMy8jhdo,2512 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthDeclaration.DiRgFK2Q.js,sha256=nQrGwCy4LrMipUOdnlKZjVJJLSlH79mRgcE95U5D9qo,296 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthDeclaration.DiRgFK2Q.js.br,sha256=ppZlDr7auQoj7xjWIvGDfhESQRLFen3PLd0QPxCwCnQ,204 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthDeclaration.DiRgFK2Q.js.gz,sha256=F7Ve4S6Agi8-k5jGjXPKTSdp_10DxT7_8qVzxm8HlIA,240 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthDeclaration.DiRgFK2Q.js.map,sha256=kdycOQidCYaHQroMfZ6L0JYtSeBSNDPNRxcypOsGHWc,903 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthVertex.CcEiEiyg.js,sha256=LLJ8jlS-gexoF8__EbcQtSLiA1BislwwHg1SOH_heW4,1654 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthVertex.CcEiEiyg.js.br,sha256=Tyrge7dJQUlooIYuJg3LYnBcbd6QLkes59t_d9HwTBY,428 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthVertex.CcEiEiyg.js.gz,sha256=sOYYlLVh59VdpjSscBZIMuH1ypVoCR0HDRpW17I8pBQ,515 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthVertex.CcEiEiyg.js.map,sha256=067E30qwP9vJ5EamT301lN_X9Su9o8EDBvJohVcyuAI,4543 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthVertex.MGj6XVNz.js,sha256=nebXMLOUHyVunulhvrbn46oXD12Nw2hAI96K1aQ8Jqw,2030 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthVertex.MGj6XVNz.js.br,sha256=Ahud7D94M8dGtB_7CZkqNhNZ4_PL-YgYI2XxCiZFTEQ,476 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthVertex.MGj6XVNz.js.gz,sha256=5uc3-1SLk_1K99HjyiNFJGYaRscsXxXGyndAq_TfCw0,579 +gradio/templates/node/build/client/_app/immutable/chunks/logDepthVertex.MGj6XVNz.js.map,sha256=fsu0gH6mbOteuGjSnntJFHz_ORO-vxILirTMtlpVm3E,4983 +gradio/templates/node/build/client/_app/immutable/chunks/lt.Z_MxAT26.js,sha256=RrqeDjYfYG7oIE22fy5q6LwY_Yr3U1aLbAqW3UiRFvQ,4896 +gradio/templates/node/build/client/_app/immutable/chunks/lt.Z_MxAT26.js.br,sha256=hKleWDKzN_GZJ84HE51zSE3qM15F8e4GIFw2PjZe8B4,2141 +gradio/templates/node/build/client/_app/immutable/chunks/lt.Z_MxAT26.js.gz,sha256=gVDSvMwMD-NnEhYc1t0PaFnOJwnCtmgqaD4_rQ2XUjU,2345 +gradio/templates/node/build/client/_app/immutable/chunks/lt.Z_MxAT26.js.map,sha256=QPpiUxmi56G5e0XSVxUrfMOQuN2eIOGSA3vmE_PNuiE,95 +gradio/templates/node/build/client/_app/immutable/chunks/mainUVVaryingDeclaration.CVndCKVJ.js,sha256=aeGjNA21hxSF9CDO14TGv--ahmEyer0yxr0dHV415rs,249 +gradio/templates/node/build/client/_app/immutable/chunks/mainUVVaryingDeclaration.CVndCKVJ.js.br,sha256=nVWO8FBKNEgQuoe-5TrpimzZ2rAebrxcGWXtMuOast4,188 +gradio/templates/node/build/client/_app/immutable/chunks/mainUVVaryingDeclaration.CVndCKVJ.js.gz,sha256=zrtoePnp6h5hMMxGOWzQI7g6eNgd6n1Trctfa3IIZAQ,204 +gradio/templates/node/build/client/_app/immutable/chunks/mainUVVaryingDeclaration.CVndCKVJ.js.map,sha256=PChvicJTRD6d2W40v4k1_NUz0HdTWxYFl5f6bkaE5i8,863 +gradio/templates/node/build/client/_app/immutable/chunks/mainUVVaryingDeclaration.SDCC3qCc.js,sha256=6mNBo8Fa_u_uCblhacNNfJchTJ_ZDL5Uay71_jhCT4M,259 +gradio/templates/node/build/client/_app/immutable/chunks/mainUVVaryingDeclaration.SDCC3qCc.js.br,sha256=cugwsgsaUwy4FRl1m3t9ojrGqxpu3B0Cx_sqxhA_DwA,174 +gradio/templates/node/build/client/_app/immutable/chunks/mainUVVaryingDeclaration.SDCC3qCc.js.gz,sha256=dI7Yg2fxKkgE8OAyfmIG5Z0T-47LoQSJrExEe9phUWc,214 +gradio/templates/node/build/client/_app/immutable/chunks/mainUVVaryingDeclaration.SDCC3qCc.js.map,sha256=UAEUuq0XJZAtzyj-dKgQRHh7ci2L7BKXcoe_Mc3LzW4,881 +gradio/templates/node/build/client/_app/immutable/chunks/mermaid-parser.core.BcwwbwyI.js,sha256=3YfOHPH-CKzbkNRho9ksHtVfeEdErfeaMA5hoMISihk,328395 +gradio/templates/node/build/client/_app/immutable/chunks/mermaid-parser.core.BcwwbwyI.js.br,sha256=R0Fjos8QVqt0HUIvVoTIt9Zray2M7dRZXGy-ordY_ws,68767 +gradio/templates/node/build/client/_app/immutable/chunks/mermaid-parser.core.BcwwbwyI.js.gz,sha256=XWUtV_4KrJRP81AZA8d5dcQlNCPGff0A5WeUCZqP5MY,80110 +gradio/templates/node/build/client/_app/immutable/chunks/mermaid-parser.core.BcwwbwyI.js.map,sha256=tkDMZ4zKCK9Zmx0Nnkh8BXiQMpIFMY7iRbg8E3NjepA,1358157 +gradio/templates/node/build/client/_app/immutable/chunks/mermaid.core.DTNv8IuU.js,sha256=Wprs24k85859fd5DoOTD44kvcITtS78TMMENaac_rNU,445699 +gradio/templates/node/build/client/_app/immutable/chunks/mermaid.core.DTNv8IuU.js.br,sha256=dxunrnza8PsceiXYeDinyHF4veAO2Y9snvnKdj0RWq4,106437 +gradio/templates/node/build/client/_app/immutable/chunks/mermaid.core.DTNv8IuU.js.gz,sha256=DlUutWk4-cFr0I09X9TI8znnuAg14lHLmo7YY5sg8So,124383 +gradio/templates/node/build/client/_app/immutable/chunks/mermaid.core.DTNv8IuU.js.map,sha256=WKyLL3lvE3gfwn4sVWAzLtl6XuiqWcvp4l4McYdKTP8,1509724 +gradio/templates/node/build/client/_app/immutable/chunks/mesh.vertexData.functions.BYooUupK.js,sha256=WQSWEvv4mu4aSCFw3XqGOQg8EuGqsX6Z2P_0CbohQPI,981 +gradio/templates/node/build/client/_app/immutable/chunks/mesh.vertexData.functions.BYooUupK.js.br,sha256=vaI0PqDQzmF_cF08kQwOshUsBFr-bhZHLBGlxZi6AY0,478 +gradio/templates/node/build/client/_app/immutable/chunks/mesh.vertexData.functions.BYooUupK.js.gz,sha256=ljmjot4oxb8hJVSXgg_XJ2lVNMT8QrAJqAoYkBzlioA,536 +gradio/templates/node/build/client/_app/immutable/chunks/mesh.vertexData.functions.BYooUupK.js.map,sha256=ZrEShXnmNVyT_8dEdXzyemg10VHIJmifMNoT1AOiskc,6524 +gradio/templates/node/build/client/_app/immutable/chunks/meshUboDeclaration.Bq7Ie8G6.js,sha256=wht7m0tLyGOE3ju9Vt9DUFQ_xIsJijxrGqhx0lLkf_k,613 +gradio/templates/node/build/client/_app/immutable/chunks/meshUboDeclaration.Bq7Ie8G6.js.br,sha256=naPHli8f0EU6_m50PqgJoEtXG8GoWRYrUBPblCoMV5c,294 +gradio/templates/node/build/client/_app/immutable/chunks/meshUboDeclaration.Bq7Ie8G6.js.gz,sha256=ANwwAgJI0ss_2b6LsqjdzKxegDVKbKfsl78AyPKt2zc,342 +gradio/templates/node/build/client/_app/immutable/chunks/meshUboDeclaration.Bq7Ie8G6.js.map,sha256=nWis2bs436cDfteYRJEXsMMSvORmYEX3u1kpzuxdiGA,1796 +gradio/templates/node/build/client/_app/immutable/chunks/mindmap-definition-LNHGMQRG.DE9syxZS.js,sha256=DyvEFVHS_VufuZUwmpZ1WLscNTtbkxrWROIdhUmkDdU,101643 +gradio/templates/node/build/client/_app/immutable/chunks/mindmap-definition-LNHGMQRG.DE9syxZS.js.br,sha256=ASOI7Twrh1qm2QPDynHK_B-xOpRGQbPUsTGvD-DqXcw,25026 +gradio/templates/node/build/client/_app/immutable/chunks/mindmap-definition-LNHGMQRG.DE9syxZS.js.gz,sha256=Krs1hcu93SjKxef3uEezmeaWehYnRFB-iW27aWUPd_Q,28345 +gradio/templates/node/build/client/_app/immutable/chunks/mindmap-definition-LNHGMQRG.DE9syxZS.js.map,sha256=mZyHCD10nHdxf3GPgnOORw8hXL7PoXNSr3AidzGEj-s,367428 +gradio/templates/node/build/client/_app/immutable/chunks/module.BkdQaKeM.js,sha256=KJKurm8XOaYbIZgl98AWwG4sT3sALvP-LuokgPIzofE,92320 +gradio/templates/node/build/client/_app/immutable/chunks/module.BkdQaKeM.js.br,sha256=B5S7nlg8bbyR_hRr6fUYJnm9ev5nvOV9JY54ML7XwfM,24619 +gradio/templates/node/build/client/_app/immutable/chunks/module.BkdQaKeM.js.gz,sha256=-S7TsOu8V9VKkjDjwpC51xHjaNVVKqMaJfUAOFlfdgs,27902 +gradio/templates/node/build/client/_app/immutable/chunks/module.BkdQaKeM.js.map,sha256=03e87sWAKgY8GBK1uNFW7Yfz-3DVS_jDyvdkEO0ejBQ,576358 +gradio/templates/node/build/client/_app/immutable/chunks/module.C-VadMaF.js,sha256=KDyQPSfp1UAuDdWTgdj8hCX4NFDqI5UlH_3GNUHD-wU,1670 +gradio/templates/node/build/client/_app/immutable/chunks/module.C-VadMaF.js.br,sha256=hfyioxjODD9IGZutKZfjz-fnHCMsS-7QosaPS9Up8ig,790 +gradio/templates/node/build/client/_app/immutable/chunks/module.C-VadMaF.js.gz,sha256=5EM717qCfCeg474DxulsdHF3Q8hOVJNe6uSLpTVbMBY,901 +gradio/templates/node/build/client/_app/immutable/chunks/module.C-VadMaF.js.map,sha256=65qZmTTVsk4_bhAEDpMvF8cm4RiDaUGLzBBc1qMUpp8,11792 +gradio/templates/node/build/client/_app/immutable/chunks/module.niXGEr8P.js,sha256=L3LmDc2Zn-_6xA7E0m-5a-wWqKpwpvg_n6dLKE6qtUg,10074 +gradio/templates/node/build/client/_app/immutable/chunks/module.niXGEr8P.js.br,sha256=XAAe5gWtX0cJfpv3u2YwzZbC9NF7TRGTlKv9uoCYyk8,3693 +gradio/templates/node/build/client/_app/immutable/chunks/module.niXGEr8P.js.gz,sha256=mor6DKGWN_wbM4mOIjsi-6_Y9e7tezWp5Z-OJaD7YDc,4161 +gradio/templates/node/build/client/_app/immutable/chunks/module.niXGEr8P.js.map,sha256=FbHaEIR5HicIqdGNDYKcC4pAwY4nr9ZLeoNWQzgHAAc,13049 +gradio/templates/node/build/client/_app/immutable/chunks/nb.CGxYPyHM.js,sha256=QzSEqXFO3rrzCLa3ZIiNk5RM7dtgtT1T45lKoX_1Rc0,4490 +gradio/templates/node/build/client/_app/immutable/chunks/nb.CGxYPyHM.js.br,sha256=xwWBJFmSI7H4GLdHDe559H5rhDg24JgsmXWJYCxDG3M,1948 +gradio/templates/node/build/client/_app/immutable/chunks/nb.CGxYPyHM.js.gz,sha256=t51-TM27v1GsHZRsWzU7J7LwU3e9efAv02ZvXCmdmIk,2130 +gradio/templates/node/build/client/_app/immutable/chunks/nb.CGxYPyHM.js.map,sha256=GfYGkpKP2NA9CKGtPKw77OMjBOtIJPGiVn7sPNPFCaI,95 +gradio/templates/node/build/client/_app/immutable/chunks/nl.Dw1IiFHs.js,sha256=wXI9rkxZ5jQfm3ja_Vz2Jc8vY-IWxosIsazrXwfROkk,4811 +gradio/templates/node/build/client/_app/immutable/chunks/nl.Dw1IiFHs.js.br,sha256=Li2uQ9CUeH2G_1Zgaz5C6F8TjSHdBOifBl2BzVJEUbM,2020 +gradio/templates/node/build/client/_app/immutable/chunks/nl.Dw1IiFHs.js.gz,sha256=kBrbsnPQqNYrT52TpYbmF6W1AwcsntLv2kMTxYf2u2k,2211 +gradio/templates/node/build/client/_app/immutable/chunks/nl.Dw1IiFHs.js.map,sha256=yFHAK8rxeNpFw8B0CjG2tsL3KXz-TgXg8PazOOIJJE0,95 +gradio/templates/node/build/client/_app/immutable/chunks/objFileLoader.D_EDW7od.js,sha256=91d45iqvyIbVNO8qXti7cNJsvmH5k9j_yeeKjhdET7E,18755 +gradio/templates/node/build/client/_app/immutable/chunks/objFileLoader.D_EDW7od.js.br,sha256=QpZzvudXLIbmLVwdDY2ri6NnGyCtImbYDBWpZ37I7TY,4683 +gradio/templates/node/build/client/_app/immutable/chunks/objFileLoader.D_EDW7od.js.gz,sha256=4ENrDriRx5HUYWoo6qusXCJqGA4pfykkVvzuDvTjUy8,5144 +gradio/templates/node/build/client/_app/immutable/chunks/objFileLoader.D_EDW7od.js.map,sha256=-Vgl5B0PlW6JyQTFtUGWj35RVT26YPYXfvEBsDGXhB8,89999 +gradio/templates/node/build/client/_app/immutable/chunks/objectModelMapping.ha_8hIyl.js,sha256=OtOvTU2HIZrCQq0Lo37UNvnXvOW3eurJd-odFwxARhs,38095 +gradio/templates/node/build/client/_app/immutable/chunks/objectModelMapping.ha_8hIyl.js.br,sha256=x88xvvJ2bqRt7LSYQ1QDWdKtofJZXGiPyxPPyiOJlQQ,7669 +gradio/templates/node/build/client/_app/immutable/chunks/objectModelMapping.ha_8hIyl.js.gz,sha256=qYEa6madU8rPFpBW-tYrtMvxWALz465TpHnD83r1wdQ,8639 +gradio/templates/node/build/client/_app/immutable/chunks/objectModelMapping.ha_8hIyl.js.map,sha256=gAFZ0zKo-_Tif4RBeOx5JYuP2seviQa53eJWM-v_PMY,144449 +gradio/templates/node/build/client/_app/immutable/chunks/oitFragment.4aBUoMbS.js,sha256=lWyd2rrvH9mQ1inA0XRbvV0EuLsNySYeWWSFEoOye-Y,68702 +gradio/templates/node/build/client/_app/immutable/chunks/oitFragment.4aBUoMbS.js.br,sha256=bHHmB_Lf8YV8D81MMPfYFPZZ7Ba6v94pwQopGAKiEmY,11169 +gradio/templates/node/build/client/_app/immutable/chunks/oitFragment.4aBUoMbS.js.gz,sha256=Lhu49AUP1V-OlYy8cVsT6de7mWj83BRA0Lx7Ta3vkfY,12957 +gradio/templates/node/build/client/_app/immutable/chunks/oitFragment.4aBUoMbS.js.map,sha256=m2sie-AnH5nZcOHAbg0YU6p6G5W-Gcg-9VLO0STaC6M,85320 +gradio/templates/node/build/client/_app/immutable/chunks/oitFragment.y--lkChi.js,sha256=q8jsWbQ-v9QoB2zXKhc6AXkChhmxGtu3cI9puEtuUD8,73148 +gradio/templates/node/build/client/_app/immutable/chunks/oitFragment.y--lkChi.js.br,sha256=2ZiazG5T1IkEKZI2pqwyUGvfpFanKrYALXuL94yBGUc,11218 +gradio/templates/node/build/client/_app/immutable/chunks/oitFragment.y--lkChi.js.gz,sha256=Xa7r3vAC7KA1-D1rA-Ae7WYhrY0VnNxB6dPnHO3kM0I,12944 +gradio/templates/node/build/client/_app/immutable/chunks/oitFragment.y--lkChi.js.map,sha256=dERBgKkNXd5THslSCBWbai4r7sVfF-dU8aNMQJMk564,87465 +gradio/templates/node/build/client/_app/immutable/chunks/ordinal.BJp8kCrd.js,sha256=WcrYJ1uH3oBLLYTln40wllTdubwxqpH1B6Pyt5J8S1M,1518 +gradio/templates/node/build/client/_app/immutable/chunks/ordinal.BJp8kCrd.js.br,sha256=L2uxIZvP-e_Sc2rJbq-wdncwcflI18rd0FZAXI_hKGU,575 +gradio/templates/node/build/client/_app/immutable/chunks/ordinal.BJp8kCrd.js.gz,sha256=UwCxjLNAKXmbLqcc4I1pqNHG65xi_T-y89iDQre6rVA,649 +gradio/templates/node/build/client/_app/immutable/chunks/ordinal.BJp8kCrd.js.map,sha256=iC0SgRQucuOyC3MB-wdyjTW2J0TgCSwWTLrThBVdXoM,5598 +gradio/templates/node/build/client/_app/immutable/chunks/packet-HUATNLJX.WVsYeykk.js,sha256=Oq-BN1iLOWbNHrqvcEPWRe_S2UI5k21IXbjbsiD95No,167 +gradio/templates/node/build/client/_app/immutable/chunks/packet-HUATNLJX.WVsYeykk.js.br,sha256=DCqcvD8s1p_sbbCz6l_sUu0POAnZUs6Uz0ruvuVKyUg,140 +gradio/templates/node/build/client/_app/immutable/chunks/packet-HUATNLJX.WVsYeykk.js.gz,sha256=9N7mziM-E2iOcHN6H36oRD7vixxgqRpGlrvB2X6sPz4,163 +gradio/templates/node/build/client/_app/immutable/chunks/packet-HUATNLJX.WVsYeykk.js.map,sha256=hWRw2yvpWFCPlNZxljtxt2zCyD4HyPScFDTYv2brniw,108 +gradio/templates/node/build/client/_app/immutable/chunks/pass.fragment.DAWzS7VX.js,sha256=f8d8Dm4jP6J0mBCzrHiHFjKHB6p_e71TR11Ehe73N-g,502 +gradio/templates/node/build/client/_app/immutable/chunks/pass.fragment.DAWzS7VX.js.br,sha256=WZsN0tVFQvBvj4pFvi10KCQWY1j_Tof5b37d6B2NOjQ,277 +gradio/templates/node/build/client/_app/immutable/chunks/pass.fragment.DAWzS7VX.js.gz,sha256=lKHdFFsNkv8g7PrquZrUEapGCf2a2RmLdiOFsUHlgdQ,331 +gradio/templates/node/build/client/_app/immutable/chunks/pass.fragment.DAWzS7VX.js.map,sha256=POBW0ewR9CcCvEVVEIUIdfDugNhiRqlx3Fsbnn0W1-I,1084 +gradio/templates/node/build/client/_app/immutable/chunks/pass.fragment.DRSohf02.js,sha256=2KfLb-QPeDssrOH4h3120kqEkkRya_Bd0gN4B8n_tKQ,368 +gradio/templates/node/build/client/_app/immutable/chunks/pass.fragment.DRSohf02.js.br,sha256=fuB0x1ylpNcnSJ96iiX5OnGVbrLh1iKCcPYWiNcm_Ds,239 +gradio/templates/node/build/client/_app/immutable/chunks/pass.fragment.DRSohf02.js.gz,sha256=zbpX23XuxX7VcZlR1IoFXMS9g3sD_NFIpMTykNAcl_M,289 +gradio/templates/node/build/client/_app/immutable/chunks/pass.fragment.DRSohf02.js.map,sha256=SIPlHOurmb6CTTxDHTOpzOzK-XXTkr3nSf1RNMgNrSQ,938 +gradio/templates/node/build/client/_app/immutable/chunks/passCube.fragment.CP-kl7JH.js,sha256=k9tMhKp8rpkSlgXK9Dckn29rze20y9rzt9GNbP8GXs8,1186 +gradio/templates/node/build/client/_app/immutable/chunks/passCube.fragment.CP-kl7JH.js.br,sha256=yNbTJRCvZO4I_3SHgtLQg0KNV6jCygZjweA6KgWVuvs,382 +gradio/templates/node/build/client/_app/immutable/chunks/passCube.fragment.CP-kl7JH.js.gz,sha256=tyYmLJO4C3sic8pjSVGYtIKsd-yxDStDkm_sNxZIza4,435 +gradio/templates/node/build/client/_app/immutable/chunks/passCube.fragment.CP-kl7JH.js.map,sha256=a6yGCGGl-VGNlxWN3Z0AynmRQEnTXhiQAxaGb-NUZQg,1894 +gradio/templates/node/build/client/_app/immutable/chunks/passCube.fragment.DCGbgrrH.js,sha256=v3BUANwSEPf47fOm-cnFT0S04H4L_rRtELFRQImP4Jc,877 +gradio/templates/node/build/client/_app/immutable/chunks/passCube.fragment.DCGbgrrH.js.br,sha256=_2qc0ZODKKKLlE3jlhjpCmEOnP8lGLKWEl3lZiJB4nA,345 +gradio/templates/node/build/client/_app/immutable/chunks/passCube.fragment.DCGbgrrH.js.gz,sha256=risLSvrLkXdLzLdpxr9ArRl3QyK_JMn7M-QtDUjzax0,385 +gradio/templates/node/build/client/_app/immutable/chunks/passCube.fragment.DCGbgrrH.js.map,sha256=r8d8s9l26m6xsqtfVUHkhWIo-rmM-8LssndR8RJpO0s,1573 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.fragment.CBkNxON-.js,sha256=ZG7NUPns8BfJxxGGDLQ1txUXnnmvOot050bUzg3T99Y,112935 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.fragment.CBkNxON-.js.br,sha256=2kB3-KGci4cwQpzALyN9Vk99NCA6xAo2BVtkVPgXg-0,17069 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.fragment.CBkNxON-.js.gz,sha256=kBUGMI5hL7kI7G1mx9iMbXI9GPUxswHWocYIWVphDeo,19732 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.fragment.CBkNxON-.js.map,sha256=qiHISF0JZEOwyjtwdUQd-nrEvV33eMmh6YTM_e-N_cs,150907 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.fragment.z3Egf0of.js,sha256=Tu3H2XtnUOQeT-pOUyU1YY7yeaHgNBuvhrTI6BB8Nt4,108720 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.fragment.z3Egf0of.js.br,sha256=RW-7NH_qnZ8KWxVZ3qCkjhjyvF4-z11jIPgyNweZzgA,16805 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.fragment.z3Egf0of.js.gz,sha256=nKeW3DrTAFXv678NuCPL1B85hmnBnJuZ7Ol5Z0Db8Zs,19527 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.fragment.z3Egf0of.js.map,sha256=HuAA4cWYKFp8M5XoONoF4IaTqdZID-S6TW54bbkPoYw,147298 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.vertex.BfyoZ2Uu.js,sha256=YKtDSAmtc25oT4_DVaQ_HTgXOlGFar15DpUC3c4YLd4,11660 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.vertex.BfyoZ2Uu.js.br,sha256=olPjFQylJEZnPATugzVqt-ckWUcpbhK96W1qJk3Y0BY,2198 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.vertex.BfyoZ2Uu.js.gz,sha256=54ZaUHaSAi3F2ElkHTTWmxzh-f_4_R9PHg-QOdsGGWI,2425 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.vertex.BfyoZ2Uu.js.map,sha256=gmytSEmALbWeM-jgY5jK9m4TuNyds5z2YzaIoFcQxy0,14842 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.vertex.D_M17hKk.js,sha256=JmMWIiX4eeat_yDWByeX-dQTPRG5qM0mlC4PUhG51hY,14992 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.vertex.D_M17hKk.js.br,sha256=81GU8NZXQKZz60kympd4qe4LNdnLZyqcch_v8a2Lf9Y,2665 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.vertex.D_M17hKk.js.gz,sha256=u-plL0rQiKIEDgXglydiA5eg3MfHIc0ksr5sEcX-P8s,2984 +gradio/templates/node/build/client/_app/immutable/chunks/pbr.vertex.D_M17hKk.js.map,sha256=AQhuHzCr9WRDoXIoJ3WrImV9GTntvldwNShZ2QraohA,19625 +gradio/templates/node/build/client/_app/immutable/chunks/pie-WTHONI2E.DbugBi9m.js,sha256=KKW6JefmmCu5a8wAmoGTf6PK6lMPEhKfh91BXmuouVc,158 +gradio/templates/node/build/client/_app/immutable/chunks/pie-WTHONI2E.DbugBi9m.js.br,sha256=mMnPLps6ZARyTM1Ez943UIfRnt97FAbuVFlPKfFM-TM,147 +gradio/templates/node/build/client/_app/immutable/chunks/pie-WTHONI2E.DbugBi9m.js.gz,sha256=dXf7zwt-W8Rp3QeP6ea3WwPgH4zo7uV_-btx_IV6pKU,160 +gradio/templates/node/build/client/_app/immutable/chunks/pie-WTHONI2E.DbugBi9m.js.map,sha256=jRyBP5D4Jx2AsghN8zfVePLtpcaIS2MW3WpoOqQ5l2M,105 +gradio/templates/node/build/client/_app/immutable/chunks/pieDiagram-DBDJKBY4.OmMTxEV-.js,sha256=twVdKc1S3pq3UHA8LWlzkIdlHu82pFey6TVqmiVjM4A,5215 +gradio/templates/node/build/client/_app/immutable/chunks/pieDiagram-DBDJKBY4.OmMTxEV-.js.br,sha256=SDCaEvDf0RjiG80ekeYHm7bh3djN5BXfEIOUTvpF00c,2119 +gradio/templates/node/build/client/_app/immutable/chunks/pieDiagram-DBDJKBY4.OmMTxEV-.js.gz,sha256=0_ljVRbJT54W3mRDacREY77_4zskX_dj-Y-9SBgXSs8,2322 +gradio/templates/node/build/client/_app/immutable/chunks/pieDiagram-DBDJKBY4.OmMTxEV-.js.map,sha256=Maw4kW_WVFMv47wVt-F616tYoNjoO1IH5BbgfvuQzJ8,18828 +gradio/templates/node/build/client/_app/immutable/chunks/pl.CewrFAug.js,sha256=zH1WOjYeluAHHUuvktWtCrlArrt0Q0kal4YhNVoUI7U,4849 +gradio/templates/node/build/client/_app/immutable/chunks/pl.CewrFAug.js.br,sha256=6uAv0xvrkXdlvldKDGUovXho24LVrikPZ7zza1H-GtA,2154 +gradio/templates/node/build/client/_app/immutable/chunks/pl.CewrFAug.js.gz,sha256=Y24108QCFSkVAFyJn5G48xTryutx2xzrTiLyj58hSE4,2338 +gradio/templates/node/build/client/_app/immutable/chunks/pl.CewrFAug.js.map,sha256=j3SyGrgX1joaCan-mcpYhwuPBSbds4i8mTWbuODhxRo,95 +gradio/templates/node/build/client/_app/immutable/chunks/postprocess.vertex.BZnoc_l3.js,sha256=ZzcOg8h7CdDkvc2JMGRKng-7q5ZU9_9T7PXohAiXDMU,639 +gradio/templates/node/build/client/_app/immutable/chunks/postprocess.vertex.BZnoc_l3.js.br,sha256=WmarBulBoo4iUvCGV85T6u8NaeQTrkPQ5T7PletaSTY,372 +gradio/templates/node/build/client/_app/immutable/chunks/postprocess.vertex.BZnoc_l3.js.gz,sha256=Jzxbh_M8PbEgoBAn75izqR97DCia5DjqNVtYTSA_vwc,389 +gradio/templates/node/build/client/_app/immutable/chunks/postprocess.vertex.BZnoc_l3.js.map,sha256=ui1WcAw4NMW5IL8irw2esZ5mCKJFpfR6mGRq5HCpi0o,1268 +gradio/templates/node/build/client/_app/immutable/chunks/preload-helper.D6kgxu3v.js,sha256=PjOywJR4qUP-gyhVgiutJMQ0sdFnWvU7KWDDOFfAZ80,1111 +gradio/templates/node/build/client/_app/immutable/chunks/preload-helper.D6kgxu3v.js.br,sha256=iv7VKhJVtWvq6utHPB6J18M5Btwkcd9QSb7ekWZNcaA,570 +gradio/templates/node/build/client/_app/immutable/chunks/preload-helper.D6kgxu3v.js.gz,sha256=mXxx13yXxus6jmavKXWfwQtjEUtP2sMvBEv6KDqIa74,673 +gradio/templates/node/build/client/_app/immutable/chunks/preload-helper.D6kgxu3v.js.map,sha256=FuOh1MaB8sqALV_eDlkzgYr8Gb0mFyZuD0osDF1bWzg,107 +gradio/templates/node/build/client/_app/immutable/chunks/procedural.vertex.CxsRyA3g.js,sha256=AzBj7z0Y4bIXiH7Nqb2hI5p7mc3F4W5Wv3zYB2QIE8Y,527 +gradio/templates/node/build/client/_app/immutable/chunks/procedural.vertex.CxsRyA3g.js.br,sha256=RWXrARlmgmOuuEYa_5YSm5tn_jfssOVzRK6k-9XoBoc,285 +gradio/templates/node/build/client/_app/immutable/chunks/procedural.vertex.CxsRyA3g.js.gz,sha256=l8qa_bz0XEZaEDaXM9yQFE9oMoOoPJ7EBdY9tSIpgbA,335 +gradio/templates/node/build/client/_app/immutable/chunks/procedural.vertex.CxsRyA3g.js.map,sha256=10Pmtx4KHhemEUovwA6a4E5VSur2N20NO-XchLzB66Q,1129 +gradio/templates/node/build/client/_app/immutable/chunks/procedural.vertex.DjpJn_HM.js,sha256=M1rXcPuM9B6xy3IG5pQ0VcNPP-BNLf_cFH788BJCc30,646 +gradio/templates/node/build/client/_app/immutable/chunks/procedural.vertex.DjpJn_HM.js.br,sha256=FYte5eJ8weZfrVcHc30HLVK1t1mCP1VxAcY8ZFn7Hig,355 +gradio/templates/node/build/client/_app/immutable/chunks/procedural.vertex.DjpJn_HM.js.gz,sha256=SsS1VSAPhh7dhVzOuwpSfzABhlNQiga2CunyoV8mnCg,378 +gradio/templates/node/build/client/_app/immutable/chunks/procedural.vertex.DjpJn_HM.js.map,sha256=55DnlJaBPr9KK7S19zSKvh98pz4a0Pehcf-PCL49gCI,1266 +gradio/templates/node/build/client/_app/immutable/chunks/pt-BR.DZjK3tkX.js,sha256=Q59xGYldxWclvnLXpP__LrwlwNTS_ACwWvNHtF-w9Aw,5007 +gradio/templates/node/build/client/_app/immutable/chunks/pt-BR.DZjK3tkX.js.br,sha256=aUn3-2QlwbbpyvW6FffkoPUc334F3LxnnUGoHiHPtgk,2125 +gradio/templates/node/build/client/_app/immutable/chunks/pt-BR.DZjK3tkX.js.gz,sha256=GhP3X1mXXZ_BHxLOmF5LBUJKT0dsSjL9W5E56-FInQw,2350 +gradio/templates/node/build/client/_app/immutable/chunks/pt-BR.DZjK3tkX.js.map,sha256=SoXE5cakW4GObXysnsEagU5JTlD5wCCiuDtmC2Rz5eU,98 +gradio/templates/node/build/client/_app/immutable/chunks/pt.DH1R3DI2.js,sha256=Ir5gnyU8UDqu7s94J3sqqH3VYxQOo8myUsf1Cj0FmYg,4969 +gradio/templates/node/build/client/_app/immutable/chunks/pt.DH1R3DI2.js.br,sha256=uJIU90fSNWSe5D0ZKyKePD-cgCTzT-i2NlyDIz6ToKQ,2102 +gradio/templates/node/build/client/_app/immutable/chunks/pt.DH1R3DI2.js.gz,sha256=T-FLpaTj9YULyNVUujfn2Ca4bS3DdP0E2zKBtsG1XGo,2312 +gradio/templates/node/build/client/_app/immutable/chunks/pt.DH1R3DI2.js.map,sha256=esFxvD8-ylOOTR-avvay7GkZWtxl4D0-80Oa3bn4MN8,95 +gradio/templates/node/build/client/_app/immutable/chunks/quadrantDiagram-YPSRARAO.D2XuIncn.js,sha256=nG9mogjU_KYnaqp7Ht9rw3yz1LaCE2sS8F4NOrM8V7A,34320 +gradio/templates/node/build/client/_app/immutable/chunks/quadrantDiagram-YPSRARAO.D2XuIncn.js.br,sha256=t1SF2GbkxsqXfZwPFwrDFzAddWKcTVOSddofs-JNLMo,8647 +gradio/templates/node/build/client/_app/immutable/chunks/quadrantDiagram-YPSRARAO.D2XuIncn.js.gz,sha256=ymMUFQnzIRyhEdnTeHieB3E_W5QWxtePyQ8R7r9biA0,9975 +gradio/templates/node/build/client/_app/immutable/chunks/quadrantDiagram-YPSRARAO.D2XuIncn.js.map,sha256=t-DwmbKi9qYfrEU0r1m2aqxBTEB-wJFK6G_APM0J26g,110980 +gradio/templates/node/build/client/_app/immutable/chunks/r.DUYO_cvP.js,sha256=5ow44d3mrl5TSGYZVE78n-k7jMkwxT645E_5QwtcTF4,2974 +gradio/templates/node/build/client/_app/immutable/chunks/r.DUYO_cvP.js.br,sha256=bwHYb8W3iabpfPLnZP0n2C-qjXa-IHVcax_R6Syc0gk,1281 +gradio/templates/node/build/client/_app/immutable/chunks/r.DUYO_cvP.js.gz,sha256=SEgu1k-_sYak5XcyQARBE2RzIAb6EprP4wQw0draONE,1393 +gradio/templates/node/build/client/_app/immutable/chunks/r.DUYO_cvP.js.map,sha256=gZyXnQ3_I28mbNX5sDU8P0_bR9Mh3Z8dSRn3Hd4kiaE,10635 +gradio/templates/node/build/client/_app/immutable/chunks/radar-NJJJXTRR.Dc7_qcxs.js,sha256=P0VDc702eJ2C8BNpRFKQqQYtWk79gItOsXE5mSl9uUw,164 +gradio/templates/node/build/client/_app/immutable/chunks/radar-NJJJXTRR.Dc7_qcxs.js.br,sha256=iBV7ZyJH3olKE2oYgIKV5HFLHves69WMybMHeccSrMA,140 +gradio/templates/node/build/client/_app/immutable/chunks/radar-NJJJXTRR.Dc7_qcxs.js.gz,sha256=2ZSMsuw-GNl-9uKn4AMduyaE3MAaqZ96duaEKOoKuSg,160 +gradio/templates/node/build/client/_app/immutable/chunks/radar-NJJJXTRR.Dc7_qcxs.js.map,sha256=dUMzax2M-_Cg-0A95R-qn7ya9199hoBP9Q2aTfSojXE,107 +gradio/templates/node/build/client/_app/immutable/chunks/range.OtVwhkKS.js,sha256=D1006cQUTeTjCYYnkf1KwKQrmtCAAIcqwDWnff1s12w,223 +gradio/templates/node/build/client/_app/immutable/chunks/range.OtVwhkKS.js.br,sha256=J2mHHqsnDvlUDzmPORY0pYvqgDlLrvz1VEvR8TPdLpQ,177 +gradio/templates/node/build/client/_app/immutable/chunks/range.OtVwhkKS.js.gz,sha256=iVt90f2T9eAGTp5gKNflrjCCcGv7TE8ff0yBWBfS-3Y,210 +gradio/templates/node/build/client/_app/immutable/chunks/range.OtVwhkKS.js.map,sha256=Iva9qTPcMYz49nz0AZxpdQ56y1EVlDqVnQhiF8FrAv8,949 +gradio/templates/node/build/client/_app/immutable/chunks/rawTexture.CJKlnpAh.js,sha256=TSsvYwqCau3BuIREcEHy8E4Psy2y1yPsF-f3qK-AcEw,1916 +gradio/templates/node/build/client/_app/immutable/chunks/rawTexture.CJKlnpAh.js.br,sha256=iE7mL-Ww1agM-TwbHGQWEA6F4ya9KWRLyin_OlUsfvA,620 +gradio/templates/node/build/client/_app/immutable/chunks/rawTexture.CJKlnpAh.js.gz,sha256=9_ApJ2mJ_T2ZBDs9DwdqDLHT5Gjv7bSq68F26c49yoc,692 +gradio/templates/node/build/client/_app/immutable/chunks/rawTexture.CJKlnpAh.js.map,sha256=Z6uOBxu9PzZ9F8fi77H-4XSgIbTu5-rrY1SakccPhXo,15101 +gradio/templates/node/build/client/_app/immutable/chunks/ray.sJZVblPT.js,sha256=kuNN49RtLw5aCdxMqIdpyZ3jZJqC6v9Q4AaSTM6sX74,11023 +gradio/templates/node/build/client/_app/immutable/chunks/ray.sJZVblPT.js.br,sha256=VvHIzH20oTucEw8bAIaHj2otUE5Rh5O1z9x7lhG6rHQ,3222 +gradio/templates/node/build/client/_app/immutable/chunks/ray.sJZVblPT.js.gz,sha256=PvolUoieLKk2Ft0Kof61qPsafKlDbBt2k87Vfizu6jc,3627 +gradio/templates/node/build/client/_app/immutable/chunks/ray.sJZVblPT.js.map,sha256=RpTBI_Ye4ccsTxA7mfCfYUKYxShR9vugEWZCFEM47i8,61888 +gradio/templates/node/build/client/_app/immutable/chunks/requirementDiagram-EGVEC5DT.CLGp8Oya.js,sha256=B9Jl813Gsl-NYOBYS3_toAAu4ayZqx_iCwb2MSr_NJ0,30298 +gradio/templates/node/build/client/_app/immutable/chunks/requirementDiagram-EGVEC5DT.CLGp8Oya.js.br,sha256=JVuvgiui-TVBVKs-7bbB8eRGFksLx4Jb8SD-LRVCE9w,8067 +gradio/templates/node/build/client/_app/immutable/chunks/requirementDiagram-EGVEC5DT.CLGp8Oya.js.gz,sha256=t2UhFeOJMjzIhwTdpZg83yENr1W9ygXKDfUkypptUuU,9397 +gradio/templates/node/build/client/_app/immutable/chunks/requirementDiagram-EGVEC5DT.CLGp8Oya.js.map,sha256=l1sJ72PaC_aJ6QsP0Fus-CI9jvasWg8WrBmwKbGip0s,96697 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdDecode.fragment.CpYe6Awb.js,sha256=cRzhaHxs9elU-ap0vf2-On_x1IU8ZX41-QRaro1LzeY,470 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdDecode.fragment.CpYe6Awb.js.br,sha256=qibGTWjI-kflHxJYf3dXCJgtRM1lSo0Ma3R9lJZZui8,313 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdDecode.fragment.CpYe6Awb.js.gz,sha256=AnabdKUTqzT08gFp3HeMIlpPlQGYZc26Ifze0ycQobg,349 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdDecode.fragment.CpYe6Awb.js.map,sha256=PO4ACqZKgn91JWOom2nGuo9P5eCLYDphoAAXjPMU2IM,1075 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdDecode.fragment.CzHiO_Z5.js,sha256=twSLnBbMcs7Sb6_5vEcfIMwXVCX_7RWkMlnir2sLk84,605 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdDecode.fragment.CzHiO_Z5.js.br,sha256=43BrlGl-ZLeEKtzV4SMccx0R1OOi2SrbeSUZjuiJkt4,331 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdDecode.fragment.CzHiO_Z5.js.gz,sha256=HQiKBQk5SWMRMOVOJzWC5NHrQC-x7QUYMNk-Wc7l56g,388 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdDecode.fragment.CzHiO_Z5.js.map,sha256=FwC6uaTgnsx6OwuURot7DYRYTzH_ej-yCQsECboLOQI,1222 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdEncode.fragment.B5LpBaEr.js,sha256=EwSUUUSpwLT7R4HxyDUv5oB44lcP495pHoqk1GrWDeE,596 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdEncode.fragment.B5LpBaEr.js.br,sha256=cbLYExjjkpNU-VRmsjC02xVynRytFBJZhB-puqKGNng,364 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdEncode.fragment.B5LpBaEr.js.gz,sha256=NmEHLVZ4MZx6ZVhJOCkGPDUJnD4zH-IPdsIMEw8eAxs,380 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdEncode.fragment.B5LpBaEr.js.map,sha256=gWO8oAGdoPpLG2Lv-HD4D8IQLV4ZAX9qxdIyOmptuDE,1213 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdEncode.fragment.Wd02zsF7.js,sha256=yTKab5Zvx1c6jajj9PQ3l9i4PGTlRw3ILj5YXLOigAQ,462 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdEncode.fragment.Wd02zsF7.js.br,sha256=I3iTmXsrdA-SEia7rL64Y3rxP-Ghsq2LgFUSs5OF4_g,282 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdEncode.fragment.Wd02zsF7.js.gz,sha256=c1R49ajXZonSja3LnNCYpZ5Xa3p74jXiKpmC_PzcI0k,342 +gradio/templates/node/build/client/_app/immutable/chunks/rgbdEncode.fragment.Wd02zsF7.js.map,sha256=k5AYCjPlkmnYgYxufpAtz9hmou1lt6w3AZ_3vqIIh3g,1067 +gradio/templates/node/build/client/_app/immutable/chunks/ro.boSZHd3M.js,sha256=3OQ0KSjWA_bzxLM804WlTTe9aPGy69tjbA2heZEFllg,4995 +gradio/templates/node/build/client/_app/immutable/chunks/ro.boSZHd3M.js.br,sha256=N4S4EFDypUYz_dhYhVuPMieqIjNKpX9b-mfWHWKnNhU,2079 +gradio/templates/node/build/client/_app/immutable/chunks/ro.boSZHd3M.js.gz,sha256=3r2YZSnWPuQgTlFFwvLs3CTC5vRG5DqZ3XiOx9i4DJ0,2270 +gradio/templates/node/build/client/_app/immutable/chunks/ro.boSZHd3M.js.map,sha256=YER5YnUTt5s7jWBSi2XSMgoFPKLIe2bI5pPHHYBV7DI,95 +gradio/templates/node/build/client/_app/immutable/chunks/ru.BgQGKwpu.js,sha256=fuODdE6zr2Xj_SnaOUXVSfLCzoYY7xd0XuUjdAr8BdQ,6940 +gradio/templates/node/build/client/_app/immutable/chunks/ru.BgQGKwpu.js.br,sha256=Y5Ev9ut2jADtpZW_ECzj7N-al7g8Ge3UDNEe6F8afpM,2292 +gradio/templates/node/build/client/_app/immutable/chunks/ru.BgQGKwpu.js.gz,sha256=V7q-8AF-Soh-ecXg83kOBcMQp7x9G8Lry61GuED-1HM,2761 +gradio/templates/node/build/client/_app/immutable/chunks/ru.BgQGKwpu.js.map,sha256=Mvay1yoWYbhQyFMKrPI9U6-l0dHcF-0gyJ2JDcnZW3o,95 +gradio/templates/node/build/client/_app/immutable/chunks/sankeyDiagram-HRAUVNP4.CcqAxuZr.js,sha256=LWEkcVCFpEIr-M8kO2uGOJNT5MtW0CUOLX0NC5so9C0,22272 +gradio/templates/node/build/client/_app/immutable/chunks/sankeyDiagram-HRAUVNP4.CcqAxuZr.js.br,sha256=79TGLn2iBNNWn8km-QZIMIGJ86tvMROdTz-FYzTqO-8,7473 +gradio/templates/node/build/client/_app/immutable/chunks/sankeyDiagram-HRAUVNP4.CcqAxuZr.js.gz,sha256=bGkLq9559gwXQVzbzikk18OqhEgKLc4q5qGwfWmcbO8,8142 +gradio/templates/node/build/client/_app/immutable/chunks/sankeyDiagram-HRAUVNP4.CcqAxuZr.js.map,sha256=V7dfn0Nrf7ikSjdS72ZFROj-4Oca8N3jMpGIjzOJt08,85619 +gradio/templates/node/build/client/_app/immutable/chunks/select.BigU4G0v.js,sha256=rV7JohB9tP1K_jtiXQGVezaLJBWfFlZW6wIxHy2DGhg,12222 +gradio/templates/node/build/client/_app/immutable/chunks/select.BigU4G0v.js.br,sha256=9-jdmVsdi9No-YmEEje6DvmEMpFEgylXPqnRGyjiWXk,3464 +gradio/templates/node/build/client/_app/immutable/chunks/select.BigU4G0v.js.gz,sha256=viGkzqSRHRu8eDXXfn2_4_xyJmj4usA1szjf3S8KJFs,3866 +gradio/templates/node/build/client/_app/immutable/chunks/select.BigU4G0v.js.map,sha256=by59q9sSAEIl-pQrS-6ViIz8_qimhXQaMPVMVadBYcM,54982 +gradio/templates/node/build/client/_app/immutable/chunks/sequenceDiagram-4MX5Z3NR.ewdC-TIV.js,sha256=J3eGXF7obmohzRPPyC8ccp5rf1EXDLiqG_fmao218xk,88755 +gradio/templates/node/build/client/_app/immutable/chunks/sequenceDiagram-4MX5Z3NR.ewdC-TIV.js.br,sha256=L1uIwV4H9M8H2w7tevR8NVBbULbvbHklScYnF49Wotc,21171 +gradio/templates/node/build/client/_app/immutable/chunks/sequenceDiagram-4MX5Z3NR.ewdC-TIV.js.gz,sha256=Ye-72dtklZ9fVRuyc31oG6jit9XHMrfNS1USIzX-f20,25152 +gradio/templates/node/build/client/_app/immutable/chunks/sequenceDiagram-4MX5Z3NR.ewdC-TIV.js.map,sha256=iw94iIwxDO6G48Ut0bB7LBpLjO-DFfxKDwh7gR-5yN8,262193 +gradio/templates/node/build/client/_app/immutable/chunks/shell.CjFT_Tl9.js,sha256=tzd3o_NHe9V6fS5wDo0x-1H1NaunvCb_0Z_7li0bExM,2614 +gradio/templates/node/build/client/_app/immutable/chunks/shell.CjFT_Tl9.js.br,sha256=LZRWNkLaZVz6UL4R0TJlmOsV5NJvBQtI7eij2kjz3Bg,1154 +gradio/templates/node/build/client/_app/immutable/chunks/shell.CjFT_Tl9.js.gz,sha256=-OqWDWoG9yVMeDGHQDZ4-Y6LJuNtfhzx5pnEeCRpeE8,1243 +gradio/templates/node/build/client/_app/immutable/chunks/shell.CjFT_Tl9.js.map,sha256=dAV9iqGIoNgXGHE4bO3kfVJONEKKUo0nP4LyC_w4_fA,8803 +gradio/templates/node/build/client/_app/immutable/chunks/splatFileLoader.DiNDmZCz.js,sha256=BjrpoHLVSXy3NugHn8gKhTC28Ptb9Hhgxh-eCtqbANo,61578 +gradio/templates/node/build/client/_app/immutable/chunks/splatFileLoader.DiNDmZCz.js.br,sha256=lU630kBO4uJf7faAVnZrxPF0nSsJuVNGUACn_m_nMYo,16818 +gradio/templates/node/build/client/_app/immutable/chunks/splatFileLoader.DiNDmZCz.js.gz,sha256=8yjmuPlv1AzcCtKP8nBLVhBECZ0GtCfmzp3rGta3kak,19311 +gradio/templates/node/build/client/_app/immutable/chunks/splatFileLoader.DiNDmZCz.js.map,sha256=sE6qIoWAL_Sv6ge8L_kij31EJn1dEUSZxfFn18M7RLI,243128 +gradio/templates/node/build/client/_app/immutable/chunks/sql.C4g8LzGK.js,sha256=QwXlt1oobepETdinvu0s0CD6tjj0ane3n6tQf_lvHeQ,37113 +gradio/templates/node/build/client/_app/immutable/chunks/sql.C4g8LzGK.js.br,sha256=2MqS-GhMhYPTQvEyH8hghyKv2DG8QC0n49Vq0tpHYnA,9614 +gradio/templates/node/build/client/_app/immutable/chunks/sql.C4g8LzGK.js.gz,sha256=f0ttZlwuyRndcvFj2wN4Lb6xltmr5ZUSxeJ_sVooWrI,10948 +gradio/templates/node/build/client/_app/immutable/chunks/sql.C4g8LzGK.js.map,sha256=eQh0iVDSauDts1cvDne-i7PJn3SbU87aCbP9DtTwHzY,56037 +gradio/templates/node/build/client/_app/immutable/chunks/standardMaterial.Cnq1RvLI.js,sha256=wcI9PbS_q3hjC3aLGftZf4PPBtf3Y4PT2gap2RktaoE,41691 +gradio/templates/node/build/client/_app/immutable/chunks/standardMaterial.Cnq1RvLI.js.br,sha256=Wir3hOfdLENYzEC7K0dRHQMOfwFDAGHZGvaPaFKnJLo,8038 +gradio/templates/node/build/client/_app/immutable/chunks/standardMaterial.Cnq1RvLI.js.gz,sha256=2_fDL5S91gTaQnVZlxENq9Jh3F8i74bC6d1rbO6teTY,9074 +gradio/templates/node/build/client/_app/immutable/chunks/standardMaterial.Cnq1RvLI.js.map,sha256=JO0qxJ3YriBxnUPRwLwRNAS6uLcMcdPiJNNvNVFYEaQ,117515 +gradio/templates/node/build/client/_app/immutable/chunks/stateDiagram-UUKSUZ4H.9W6wWDtn.js,sha256=-G8vyCSvoprs8ZrHaoqGkdGINI5cae1zhXWIcanrxBA,10343 +gradio/templates/node/build/client/_app/immutable/chunks/stateDiagram-UUKSUZ4H.9W6wWDtn.js.br,sha256=zGFQZzpS6-GybqtBj0oOwZpeERKQVNQ5LDF9m3bgtH8,3333 +gradio/templates/node/build/client/_app/immutable/chunks/stateDiagram-UUKSUZ4H.9W6wWDtn.js.gz,sha256=mxWGWDP86sG-Px7yVaiAa7KnYU6_wkKSXP3VmwKrUOw,3619 +gradio/templates/node/build/client/_app/immutable/chunks/stateDiagram-UUKSUZ4H.9W6wWDtn.js.map,sha256=2pIxtig6SLZpbmw6Lt2Ly6ce7RBYrTtS1xBt-B-BMVg,35692 +gradio/templates/node/build/client/_app/immutable/chunks/stateDiagram-v2-EYPG3UTE.r2UB7ZWP.js,sha256=4-GvPz6U7481zc4yjWIZWz1hGBXL6wqI9vggFw6kQJY,356 +gradio/templates/node/build/client/_app/immutable/chunks/stateDiagram-v2-EYPG3UTE.r2UB7ZWP.js.br,sha256=l4Pbp6rP-cqLa2YW9E-tinLx89XsiYeavFh3esa-VRQ,238 +gradio/templates/node/build/client/_app/immutable/chunks/stateDiagram-v2-EYPG3UTE.r2UB7ZWP.js.gz,sha256=KVLKOr69vQuT4ut0bFIn9FA1MNqRaRjFcWkE2INUdVY,279 +gradio/templates/node/build/client/_app/immutable/chunks/stateDiagram-v2-EYPG3UTE.r2UB7ZWP.js.map,sha256=DqiuNeQPY5nptyeadSciSuft5M3b6T5WSbUt0oARnGY,1537 +gradio/templates/node/build/client/_app/immutable/chunks/step.5RfL8DsB.js,sha256=bGF2MMJQii4iY8AL_QCJ8-YMa0ByARDwhRx6adb1erE,30754 +gradio/templates/node/build/client/_app/immutable/chunks/step.5RfL8DsB.js.br,sha256=dCUEebCW1urznXnHTzeu9WGbZYKynz7c7W5Y3N6lpWc,8022 +gradio/templates/node/build/client/_app/immutable/chunks/step.5RfL8DsB.js.gz,sha256=DodoW7b3Hurh35MvjxiCIttvYrVJhWJhR9oAG_n-hEY,9060 +gradio/templates/node/build/client/_app/immutable/chunks/step.5RfL8DsB.js.map,sha256=_Agsu4nX7aFOWyiuKBynF-IOxH-oQDHu8vXJzyhwvJI,107089 +gradio/templates/node/build/client/_app/immutable/chunks/stex.C3f8Ysf7.js,sha256=w-ig-ltxD3Pp3uLMQ77Ump-0tODsiBDzkRskgKRvBc0,3166 +gradio/templates/node/build/client/_app/immutable/chunks/stex.C3f8Ysf7.js.br,sha256=6OFgVtALdHORRh6-BqjEc3-MK7u4IDl6OD2XlodggwU,1104 +gradio/templates/node/build/client/_app/immutable/chunks/stex.C3f8Ysf7.js.gz,sha256=gpNdNvFaWwpuzpc7wtWOxSGxGos1BkHTD2-JBah1p_Y,1236 +gradio/templates/node/build/client/_app/immutable/chunks/stex.C3f8Ysf7.js.map,sha256=XbCGvm--S47c71WxoPRyOCM4quaBqIfZ3-i5FgPpWlI,11935 +gradio/templates/node/build/client/_app/immutable/chunks/stlFileLoader.CK3vorYO.js,sha256=4k-DNedcdHYTnFE5bTOX8z5CaSYo3mqom02xbykhfF8,3152 +gradio/templates/node/build/client/_app/immutable/chunks/stlFileLoader.CK3vorYO.js.br,sha256=nsL5O4FMRLR8ZLP9-pmMoqkWq5_DbOnJ89UiPibWuI4,1190 +gradio/templates/node/build/client/_app/immutable/chunks/stlFileLoader.CK3vorYO.js.gz,sha256=pox5YdS_qMFP7TErdHx3MGBvvj0C6u0jeWxt7M_mwMA,1310 +gradio/templates/node/build/client/_app/immutable/chunks/stlFileLoader.CK3vorYO.js.map,sha256=b-6nqOz5J65EzYrvuWcuvhOb3rgw6bltwsJUjcSZgBY,15141 +gradio/templates/node/build/client/_app/immutable/chunks/stores.CAUBlXQ3.js,sha256=CyYLguLfJXiGlKHVQ_hCfM1l7AtJ5tyzEd7jByDjch4,312 +gradio/templates/node/build/client/_app/immutable/chunks/stores.CAUBlXQ3.js.br,sha256=hu1l-7-pVvuNhqjnMplPqxTOzpUhbGX2B5_mk5mZPzc,197 +gradio/templates/node/build/client/_app/immutable/chunks/stores.CAUBlXQ3.js.gz,sha256=UG39awOlmIAJyz0HCOS0bEAfKEuJiswK9VWswcmwGcs,222 +gradio/templates/node/build/client/_app/immutable/chunks/stores.CAUBlXQ3.js.map,sha256=UIZ2WzLMOCi1UTJ5Qrayhld37yUNTebEGqOiidYzlkI,4075 +gradio/templates/node/build/client/_app/immutable/chunks/sv.D1nuPeJf.js,sha256=kt7u1Xm-AmHnLmBTvx55K6kMO_UpWydi56weB7ywcYk,4591 +gradio/templates/node/build/client/_app/immutable/chunks/sv.D1nuPeJf.js.br,sha256=8LjPIkqfyvXFVhmAXGt1ewyhH9KxoEjgLAR0FUs8oDk,1962 +gradio/templates/node/build/client/_app/immutable/chunks/sv.D1nuPeJf.js.gz,sha256=0VJT5pJsUPI60sUjcEhuAQVzGHXI_xcCJAFFj4snpWQ,2160 +gradio/templates/node/build/client/_app/immutable/chunks/sv.D1nuPeJf.js.map,sha256=jeP00brtXym5F8zArnWl8q0ADpHdOpQK9zVQdRKmeQ0,95 +gradio/templates/node/build/client/_app/immutable/chunks/ta.Ex4E4CrJ.js,sha256=78z2WicNA70B2XgdwYHxCzasIswH-B8u5oli2aa9kK0,9758 +gradio/templates/node/build/client/_app/immutable/chunks/ta.Ex4E4CrJ.js.br,sha256=pfNYORNwTflGbWQl7ZjGgBt8MyvlRJZNphkbjyIlhS4,2397 +gradio/templates/node/build/client/_app/immutable/chunks/ta.Ex4E4CrJ.js.gz,sha256=cdC_JjzsAgAVOj0GbdhVb3kL4AxFQnTnvC28SfYerR0,2727 +gradio/templates/node/build/client/_app/immutable/chunks/ta.Ex4E4CrJ.js.map,sha256=Z8vN4W5hcleXXse3Ip8gK2tdcKP3HtZEMdITz2KyKTU,95 +gradio/templates/node/build/client/_app/immutable/chunks/tgaTextureLoader.CHYuKu0j.js,sha256=95VlWOTXGwAxcdVd_bFymhF8D5PqBVhTndpd6hknxBA,3582 +gradio/templates/node/build/client/_app/immutable/chunks/tgaTextureLoader.CHYuKu0j.js.br,sha256=ucAPU_O3g7-ZTMtDZy-0ydcWMm8JkkAQjMZBopiAIuI,1253 +gradio/templates/node/build/client/_app/immutable/chunks/tgaTextureLoader.CHYuKu0j.js.gz,sha256=wBbCXqKCdJe6UhVayUm687oaUOAOpX3TZpANiXQ1xGo,1407 +gradio/templates/node/build/client/_app/immutable/chunks/tgaTextureLoader.CHYuKu0j.js.map,sha256=GwWR2utjUKEmN34rDaLMMDCS76TSHSNOH_dM3X6Gybo,19747 +gradio/templates/node/build/client/_app/immutable/chunks/th.DGNowuDO.js,sha256=cTW5pOImTiWg8M75fAZfhKNNfLoyCCXkiSpM4psuIHU,7972 +gradio/templates/node/build/client/_app/immutable/chunks/th.DGNowuDO.js.br,sha256=7XmXE7IwxAKMUUkzHjKqoNmAjvvH9-pmqwRvZEZkBJc,2245 +gradio/templates/node/build/client/_app/immutable/chunks/th.DGNowuDO.js.gz,sha256=7ukgy6sk6HEhZ3f52CQSse-i0CEoTl-QJDTqUbtzHus,2603 +gradio/templates/node/build/client/_app/immutable/chunks/th.DGNowuDO.js.map,sha256=UWWf6GpSYCSAn0U0stAWyPIESdeecK2OmINazwGlEOE,95 +gradio/templates/node/build/client/_app/immutable/chunks/thinInstanceMesh.BW3MxSeP.js,sha256=yfg9BB4mSqZYhjkPNt_llz8q9d-_d2VcYjxyVva8QN0,10668 +gradio/templates/node/build/client/_app/immutable/chunks/thinInstanceMesh.BW3MxSeP.js.br,sha256=OtJK7IlRywzebw5LMWxlRKS_6pAL2ZKAcbf2Q-isKRA,1912 +gradio/templates/node/build/client/_app/immutable/chunks/thinInstanceMesh.BW3MxSeP.js.gz,sha256=VbpGZmTz_5WE9BcLIwci1eb5B0psHmrX5NdOzMZ-1vA,2131 +gradio/templates/node/build/client/_app/immutable/chunks/thinInstanceMesh.BW3MxSeP.js.map,sha256=gu_Uo-O7az9k8rOO0_Gwwc5Ruy0gZ_qOas203LJnPmY,24697 +gradio/templates/node/build/client/_app/immutable/chunks/time.Be8aEIgQ.js,sha256=Q2Antv4TFSBrv5Q3DUsnQAP2CxHrTrHnpRMjUrTIemU,17611 +gradio/templates/node/build/client/_app/immutable/chunks/time.Be8aEIgQ.js.br,sha256=PNxpyWZOb3AP_Ir0xSy50ak8towjXH-OxLOSBHnnUvg,5281 +gradio/templates/node/build/client/_app/immutable/chunks/time.Be8aEIgQ.js.gz,sha256=xFCz0E64ZUJSgSa9afcj0Cjl7RIfxwhOBFrqgMhX0bc,5936 +gradio/templates/node/build/client/_app/immutable/chunks/time.Be8aEIgQ.js.map,sha256=Qw4hUg_PSHXlnGUcu4Y_mlkplh1_IS0K_MQW0DfY_-Q,79939 +gradio/templates/node/build/client/_app/immutable/chunks/timeline-definition-3HZDQTIS.CcM8VM1T.js,sha256=ufnFgsRVY98wXbsLT6f5rH9c-yEuooocn4PWlMZ479Y,23794 +gradio/templates/node/build/client/_app/immutable/chunks/timeline-definition-3HZDQTIS.CcM8VM1T.js.br,sha256=AU5sbGtNQfzv2vRlsBPTrBUL6bINsO6icj4QmvQWqB8,7581 +gradio/templates/node/build/client/_app/immutable/chunks/timeline-definition-3HZDQTIS.CcM8VM1T.js.gz,sha256=Huk12gXbbMG5YxBWnfJsCh6-s2bAaseQbQOTm5uuPCo,8285 +gradio/templates/node/build/client/_app/immutable/chunks/timeline-definition-3HZDQTIS.CcM8VM1T.js.map,sha256=kQVc1q3fp36mfAHFp_awh26KRyAUXJQRodIBuqs_9UM,82225 +gradio/templates/node/build/client/_app/immutable/chunks/tinycolor.CowIdatr.js,sha256=0MeJd-IuLLC3GpNvBzKp6-WFS1B9uyMVrF7EqBsuj0Q,16698 +gradio/templates/node/build/client/_app/immutable/chunks/tinycolor.CowIdatr.js.br,sha256=N3J_wVR1yWEuHczr4ANXeIgBCBV0DixeNFGYuyyj798,5370 +gradio/templates/node/build/client/_app/immutable/chunks/tinycolor.CowIdatr.js.gz,sha256=ErWmdeXed6Stk5UOBdLNEEMQuLuWPGiA7DnETRFreus,6005 +gradio/templates/node/build/client/_app/immutable/chunks/tinycolor.CowIdatr.js.map,sha256=Ja2RXM8pT3DvF29fVjqOydINuGCdsKFxYKLyzHQO1dg,61043 +gradio/templates/node/build/client/_app/immutable/chunks/tr.Cez09yqM.js,sha256=1suJEZtmCnQj5kaIrsY1oqYp8BPDIffQ_WRipTSWdvA,4915 +gradio/templates/node/build/client/_app/immutable/chunks/tr.Cez09yqM.js.br,sha256=6_YQjbc8eAKJeL2dakXeJe6NswmWBCZx9LnJD0bJRmY,2153 +gradio/templates/node/build/client/_app/immutable/chunks/tr.Cez09yqM.js.gz,sha256=JfAP6MfaT28EmfC8dv2hFrygb0GA26b5Y7zRy-x8emU,2346 +gradio/templates/node/build/client/_app/immutable/chunks/tr.Cez09yqM.js.map,sha256=mlX3As5WYaP-kP1l3vcFtk2M6LUq4l-dhW9A6oUxY54,95 +gradio/templates/node/build/client/_app/immutable/chunks/treemap-75Q7IDZK.pD2smaOq.js,sha256=pKE9I1b186XQeb8cYuPiS4jSOLmdPdU_SH2kc3_9ivc,170 +gradio/templates/node/build/client/_app/immutable/chunks/treemap-75Q7IDZK.pD2smaOq.js.br,sha256=74Hsr9W7Z7MOV-GyBfGKs7UwdORB-6RwpU3PIG6jeBM,157 +gradio/templates/node/build/client/_app/immutable/chunks/treemap-75Q7IDZK.pD2smaOq.js.gz,sha256=dEMuOG4nPHJMya3oXstjbEbkKN3J7BYGVEPGfR7VYfA,165 +gradio/templates/node/build/client/_app/immutable/chunks/treemap-75Q7IDZK.pD2smaOq.js.map,sha256=34b20Q611CvY87u7xBVy9bYkslN0nYh88FM_6bL1xtM,109 +gradio/templates/node/build/client/_app/immutable/chunks/uk.C_6kyB1E.js,sha256=Cx7azjkDHTJZI4lI8oQSS1i2cthGe7ZXhLmE84tcQLs,6893 +gradio/templates/node/build/client/_app/immutable/chunks/uk.C_6kyB1E.js.br,sha256=R65abYYzBTWB1uDM_gJQRlHitaq7bD8AsQ5OCnLArgQ,2343 +gradio/templates/node/build/client/_app/immutable/chunks/uk.C_6kyB1E.js.gz,sha256=a-W-HIuPL1zOFose0HtgrcjvTsJrqydBYCtxlE8g69k,2762 +gradio/templates/node/build/client/_app/immutable/chunks/uk.C_6kyB1E.js.map,sha256=-8g3fh8dnt5oIC5-ZlNLhaVGqMRD0tLSVTE2njpzeW4,95 +gradio/templates/node/build/client/_app/immutable/chunks/ur.1gg1Zkwj.js,sha256=v1fkdRCBTh1S-YD0pnloqQWXz_M1HybI5lHMGqjcLII,6498 +gradio/templates/node/build/client/_app/immutable/chunks/ur.1gg1Zkwj.js.br,sha256=b6Q0YIlNQh68bYU5qcOxXJ4OWa0s3IE_6lujqxvDtM0,2220 +gradio/templates/node/build/client/_app/immutable/chunks/ur.1gg1Zkwj.js.gz,sha256=7SSn_wPvXy5LB3odP5N2HfQQPk74n_kJj9jn4CUzqgw,2597 +gradio/templates/node/build/client/_app/immutable/chunks/ur.1gg1Zkwj.js.map,sha256=wiBNhIMlLy8WtSlBlG_bMw8DRFcS-KK-oJ1EoMnJaE0,95 +gradio/templates/node/build/client/_app/immutable/chunks/utils.Gtzs_Zla.js,sha256=8M_q-tZDzBlmVTeMFF-OoA7yud7Yt7FrUBTCPyDMISU,575 +gradio/templates/node/build/client/_app/immutable/chunks/utils.Gtzs_Zla.js.br,sha256=711ROeoM-MBhS_ExPZVzDRFdCBo_0K_0TVX6kn1RaNA,288 +gradio/templates/node/build/client/_app/immutable/chunks/utils.Gtzs_Zla.js.gz,sha256=uVV1V0Zschxehp7hGXVLk-QmLjxsnGgc4BpmvhCGBnQ,331 +gradio/templates/node/build/client/_app/immutable/chunks/utils.Gtzs_Zla.js.map,sha256=U1hulXTYbNM-WNu7va2ZmCabyFBaOdWY9ks3uItVjMo,2109 +gradio/templates/node/build/client/_app/immutable/chunks/uz.CVKNjEjc.js,sha256=XW3ndsw28faiJemMbRc6verW0cuKoe62DOf8TUMgUS0,4919 +gradio/templates/node/build/client/_app/immutable/chunks/uz.CVKNjEjc.js.br,sha256=atVVoyqR9JuaC5xl8lYDOfB3JCOct74h-lCbzD08bMk,2064 +gradio/templates/node/build/client/_app/immutable/chunks/uz.CVKNjEjc.js.gz,sha256=XdpQp358eQLsQG0J7oscQmQLJ3H5XtNn9xaP9JplOKY,2256 +gradio/templates/node/build/client/_app/immutable/chunks/uz.CVKNjEjc.js.map,sha256=ETWXQw6OWZ2nbrYFzHoMA1d6-dDTI6iJDvBwW5cgxcU,95 +gradio/templates/node/build/client/_app/immutable/chunks/vega-embed.module.BlLW9pYO.js,sha256=FsnvHqOXcxdkb12FN7UW35uFfk7iuxAQWTGEh1Y8iKY,300676 +gradio/templates/node/build/client/_app/immutable/chunks/vega-embed.module.BlLW9pYO.js.br,sha256=SF0Mpoj1LE_2RiVQa0SzRAFnwspdcTzsNXOOwW4av38,84988 +gradio/templates/node/build/client/_app/immutable/chunks/vega-embed.module.BlLW9pYO.js.gz,sha256=CpzKc6sGH_WvijPrq0T6aR6wteky_P06onmMgC7X0Nw,98326 +gradio/templates/node/build/client/_app/immutable/chunks/vega-embed.module.BlLW9pYO.js.map,sha256=2edVm65fDA9qwbUOM9Uit1sVfIu1pWJ7FUde4iUpXw4,1422907 +gradio/templates/node/build/client/_app/immutable/chunks/vega-tooltip.module.DSC9NprE.js,sha256=8CpuPJutqbdjd0KFBar1yQKPOyrDsFHWPakoZZ9DED0,498972 +gradio/templates/node/build/client/_app/immutable/chunks/vega-tooltip.module.DSC9NprE.js.br,sha256=3VNuvhJTNfQWdtU_hSF3wSt2ogevwEKQxjFfMClGebE,145744 +gradio/templates/node/build/client/_app/immutable/chunks/vega-tooltip.module.DSC9NprE.js.gz,sha256=00NQGSQHsV8dhsXElTciHFFV4qbtTJTONJeuuLZguic,179303 +gradio/templates/node/build/client/_app/immutable/chunks/vega-tooltip.module.DSC9NprE.js.map,sha256=rdsBplQAh793Ai8XGYwsFlCimLVdBi7gg69Z9c6xpq8,2174347 +gradio/templates/node/build/client/_app/immutable/chunks/vertexColorMixing.g3ZfyMX2.js,sha256=lc_gULtyrZavu6MfHdbVw_mPt_qQXempX7n96hrjXBo,16674 +gradio/templates/node/build/client/_app/immutable/chunks/vertexColorMixing.g3ZfyMX2.js.br,sha256=dCVGDUByOzVzILZQSedMESN6Lf7adFXhJh_casuwum4,2656 +gradio/templates/node/build/client/_app/immutable/chunks/vertexColorMixing.g3ZfyMX2.js.gz,sha256=jya6Wne4zqgLIZoVBC3rKMZo4-jSO4vy1qar4yaEqfQ,3048 +gradio/templates/node/build/client/_app/immutable/chunks/vertexColorMixing.g3ZfyMX2.js.map,sha256=_okd-7hMW3c_LS5FR-YUTL7n86C6N5wTR-gi6RkEwls,27847 +gradio/templates/node/build/client/_app/immutable/chunks/vertexColorMixing.oNIyIizS.js,sha256=aUcJE7c-EnFTMxvQP4F39XLKMUpdzbrmaVXdqkH01aQ,18434 +gradio/templates/node/build/client/_app/immutable/chunks/vertexColorMixing.oNIyIizS.js.br,sha256=7SVvc-5f2nwXCPVjB9EJ9apcZ7n0Lc06u9rIkZ-2O3c,3044 +gradio/templates/node/build/client/_app/immutable/chunks/vertexColorMixing.oNIyIizS.js.gz,sha256=tgjWfJn5SHwmG0tVlVO_QLV06Sxoc4dXOuJRYNvoWXI,3466 +gradio/templates/node/build/client/_app/immutable/chunks/vertexColorMixing.oNIyIizS.js.map,sha256=ihfuJOLBM_elFgoAFwgwWjzjK1ND5WJuLDYWaoIZKrI,33121 +gradio/templates/node/build/client/_app/immutable/chunks/webgpuEngine.BexmqO75.js,sha256=u3ADc6-A9e_iFSnbaOFgSJTr3PFbF-4DDLOkFQQrYys,217669 +gradio/templates/node/build/client/_app/immutable/chunks/webgpuEngine.BexmqO75.js.br,sha256=jOrddW7fb4SFRVwrQ9kKRYQtlISV1JZyS43HiZLrU8A,45241 +gradio/templates/node/build/client/_app/immutable/chunks/webgpuEngine.BexmqO75.js.gz,sha256=OFqc0wTXNoRy__9YtAyoNPBqsOItsGya-5B7SwaxSlI,53202 +gradio/templates/node/build/client/_app/immutable/chunks/webgpuEngine.BexmqO75.js.map,sha256=2iIBo_9Vq0oLhT0y50BmujJ56R0fc3cNBeZoazR-SSA,794958 +gradio/templates/node/build/client/_app/immutable/chunks/webworkerAll.Crh1EAch.js,sha256=dd7gpuavdCTz5iaX1O4LVXOJE6Q4xR3d3cxhPCJRcLQ,106 +gradio/templates/node/build/client/_app/immutable/chunks/webworkerAll.Crh1EAch.js.br,sha256=0-6H99doXdft1lOv_BOz_kTDk5_WZ6fRiKTcobB-1Kg,93 +gradio/templates/node/build/client/_app/immutable/chunks/webworkerAll.Crh1EAch.js.gz,sha256=cqsWwRGVXE7xBjsrKwzrpqW4_Koe_EY7Gm1MN8knOE0,115 +gradio/templates/node/build/client/_app/immutable/chunks/webworkerAll.Crh1EAch.js.map,sha256=vYr9qrzgU4mFEM7egoEztm-b5bVIUpycjJQVu5StAao,105 +gradio/templates/node/build/client/_app/immutable/chunks/workerPool.CfMXSLnf.js,sha256=hsZ8ry0dXSjgTkC-YLeOa63PpTLHOQrIVmnzqau7gKM,1352 +gradio/templates/node/build/client/_app/immutable/chunks/workerPool.CfMXSLnf.js.br,sha256=g0up2chw8JGNSkcIUGhTQCs1XCBW4kloyXjFu_jok-8,504 +gradio/templates/node/build/client/_app/immutable/chunks/workerPool.CfMXSLnf.js.gz,sha256=lIr7026METiJyB0guTOMjetg2BRLiL84L3X99lz208E,571 +gradio/templates/node/build/client/_app/immutable/chunks/workerPool.CfMXSLnf.js.map,sha256=Um_Hxy6w4OmiK2WAGoKjr8tO7V2ObQJKAL2cGlboezw,6066 +gradio/templates/node/build/client/_app/immutable/chunks/xychartDiagram-FDP5SA34.B-mTF9qf.js,sha256=XXjTHobB5pnR-zi2YNFAZRLEhihVkrrIwgO6gFexj2I,40103 +gradio/templates/node/build/client/_app/immutable/chunks/xychartDiagram-FDP5SA34.B-mTF9qf.js.br,sha256=L6TpOZWSOdXb6pdccKCnIXB1AtEb-ttSVKxFqRX8LH0,10009 +gradio/templates/node/build/client/_app/immutable/chunks/xychartDiagram-FDP5SA34.B-mTF9qf.js.gz,sha256=TB-yVRjlnQxx2dyN4gKqR1NUnlYwbSkTwWQI55aTFss,11286 +gradio/templates/node/build/client/_app/immutable/chunks/xychartDiagram-FDP5SA34.B-mTF9qf.js.map,sha256=8nsC72xudsYlrf7zLY-FLLwuj5jVwb9FRD4egETCPgc,132256 +gradio/templates/node/build/client/_app/immutable/chunks/yaml.DsCXHVTH.js,sha256=O1a31AoNVAiPpWBgz6IkgdlaqISQ5xVQm2mD0GR1MGg,1564 +gradio/templates/node/build/client/_app/immutable/chunks/yaml.DsCXHVTH.js.br,sha256=UEW3acMzI-FILquHo93xWZXypEJeZ0GrmlqwK-VqZqw,689 +gradio/templates/node/build/client/_app/immutable/chunks/yaml.DsCXHVTH.js.gz,sha256=3m5UnkSr6SYXNRAZP6opjwpc1_yUEyf9qZc5UBobueI,760 +gradio/templates/node/build/client/_app/immutable/chunks/yaml.DsCXHVTH.js.map,sha256=UwiYvw5BYqMmRhk8pv19hVfjsdkc-2xQXhz0aHep-4g,5030 +gradio/templates/node/build/client/_app/immutable/chunks/zh-CN.C4t77Jdq.js,sha256=WRuVVcc5pj-_P2WdkY2Wis-KdP2o0O5NTD1HySEOOuw,4396 +gradio/templates/node/build/client/_app/immutable/chunks/zh-CN.C4t77Jdq.js.br,sha256=2N8CBHl4hMYf_kYrUch4rBGxQ1o6x9mZcq9qneCrA1c,1865 +gradio/templates/node/build/client/_app/immutable/chunks/zh-CN.C4t77Jdq.js.gz,sha256=h0CP2-cqeRZeU9Hsc1rSVH3-jsJmWbVIS2-accdcgsE,2413 +gradio/templates/node/build/client/_app/immutable/chunks/zh-CN.C4t77Jdq.js.map,sha256=XZa5bMdI3TXTkS_ehkz4XKppMT5GzONaEVD4N882M3s,98 +gradio/templates/node/build/client/_app/immutable/chunks/zh-TW.DnQkjK12.js,sha256=m5yC0tzGX3FtOTvUWqf2BSvIvODe1Ff9XLLIBhbsPkQ,4374 +gradio/templates/node/build/client/_app/immutable/chunks/zh-TW.DnQkjK12.js.br,sha256=nkuT3HaSV5twCD9-6NxF-epwUeMjR7dNfrshzFaZtIM,1961 +gradio/templates/node/build/client/_app/immutable/chunks/zh-TW.DnQkjK12.js.gz,sha256=4MJhjUVfd2P6Vg_zuHg-wA0OnSbto5VGL0TFLszopTg,2416 +gradio/templates/node/build/client/_app/immutable/chunks/zh-TW.DnQkjK12.js.map,sha256=BeUsqbdo-Cp1AjPUuBx4REH13OijBJvBvPEb3lVYxC4,98 +gradio/templates/node/build/client/_app/immutable/entry/app.CEv0s9UE.js,sha256=8J2Heo0wQLwtsFM9_NTh5Ana1DnPfFnr_-PexUA-4Oo,5461 +gradio/templates/node/build/client/_app/immutable/entry/app.CEv0s9UE.js.br,sha256=OwFQFNvqYRD-1wsaxJl1hEOT1Re2KQP1nBXuhHTcUbc,1941 +gradio/templates/node/build/client/_app/immutable/entry/app.CEv0s9UE.js.gz,sha256=BygrH-lYJoshpLoxgc_Ga8XwtW0JtTtBJMfjWLHIv88,2140 +gradio/templates/node/build/client/_app/immutable/entry/app.CEv0s9UE.js.map,sha256=V35qk14JGpPds7zJVmzdpf9T-4M_YnzRIZ_2EdGsXMA,3913 +gradio/templates/node/build/client/_app/immutable/entry/start.bFX3RwUH.js,sha256=YJtntF3UtG5hk_MpGWC_3UNKHH0Y57qT1ss0d21g-jY,112 +gradio/templates/node/build/client/_app/immutable/entry/start.bFX3RwUH.js.br,sha256=xPvgAGhSabFx-d1b0LOzG_63TIZtotutTBGteuLFEoc,104 +gradio/templates/node/build/client/_app/immutable/entry/start.bFX3RwUH.js.gz,sha256=M7x6vZ9MR0uiITtIJFsWTfeYWfkL1jLPp5ixF5j4z6o,123 +gradio/templates/node/build/client/_app/immutable/entry/start.bFX3RwUH.js.map,sha256=cSvgLLVRdeagIkFi2Fq3CWTGR-M96I3sFNC0gc0fsno,98 +gradio/templates/node/build/client/_app/immutable/nodes/0.GBrUGmfb.js,sha256=MoaQXL1lqjPgEVECkn__xNfSU8yMRB8WG0QGus6g4J0,1073 +gradio/templates/node/build/client/_app/immutable/nodes/0.GBrUGmfb.js.br,sha256=xK7-mTFBEVirOB6VM3OtFeuVB-CFQ9cEUvFD0sKX8oI,521 +gradio/templates/node/build/client/_app/immutable/nodes/0.GBrUGmfb.js.gz,sha256=f5iA1eK81HbE_XPwmHAYhxgMRgut00kLaP-qngrB558,579 +gradio/templates/node/build/client/_app/immutable/nodes/0.GBrUGmfb.js.map,sha256=94eTecKYXajR385GGEocCoVQBVbioNIZECI90ZNVtYc,984 +gradio/templates/node/build/client/_app/immutable/nodes/1.4azl2JiR.js,sha256=vVpKcNKYeoh7UmVyEn3V7Zb6TA7tK2kO5GpTXMvNzVU,1022 +gradio/templates/node/build/client/_app/immutable/nodes/1.4azl2JiR.js.br,sha256=fjX_ppqhBCmB01AsZ4syk4ykQ_KzMnY-F9xHwv40gmI,572 +gradio/templates/node/build/client/_app/immutable/nodes/1.4azl2JiR.js.gz,sha256=ImgNeH6tAq7tUiulnIkUqkq3su_uToAfPWF1gkVQSr4,614 +gradio/templates/node/build/client/_app/immutable/nodes/1.4azl2JiR.js.map,sha256=HFQEEMrg2jLfZmbC3wYe4sAsGx8Ol35uXW6x5DFvoj8,845 +gradio/templates/node/build/client/_app/immutable/nodes/2.44jw4EI1.js,sha256=byK5UUYww767bextQuWqBVMq0JSP3kOh7wo72lf5IQs,129 +gradio/templates/node/build/client/_app/immutable/nodes/2.44jw4EI1.js.br,sha256=4xosuKW_NmAWndeMlZyNN1hujCGptJQumM8zXH1yewM,133 +gradio/templates/node/build/client/_app/immutable/nodes/2.44jw4EI1.js.gz,sha256=0wPSDE3bgUhbvSkmzYM9TKtcTC3YhxxKA3rtI89bsT0,137 +gradio/templates/node/build/client/_app/immutable/nodes/2.44jw4EI1.js.map,sha256=2ZsOlMxHDPaE1IcoIpgWBciO4Nt1Fn1NwBt7CaZXlGc,94 +gradio/templates/node/build/client/_app/immutable/workers/worker-DJ3jufjD.js,sha256=8etal0e46Ik7GYt93q3Boakxg8_gI06CcDywv_L8AXo,2369 +gradio/templates/node/build/client/_app/immutable/workers/worker-DJ3jufjD.js.br,sha256=R3SUV3xdrDM0js-Do7cQ7NRSfG6OE6l5G4J0677poM8,1018 +gradio/templates/node/build/client/_app/immutable/workers/worker-DJ3jufjD.js.gz,sha256=SvGMTIDzdw9CuZrPcMCAuoL6a_MEcgUizAcW8oJrBUQ,1138 +gradio/templates/node/build/client/_app/immutable/workers/worker-DJ3jufjD.js.map,sha256=nhZnbtJSlLt1z-THVlu2QtTsqP-d7L0zrkGYqHHsm1I,10204 +gradio/templates/node/build/client/_app/svelte-submodules.js,sha256=78HYJ6tO9J2ZiNtF_5jpdC15Rqw6rS9ZeyN6RAIr8lk,9830 +gradio/templates/node/build/client/_app/svelte.js,sha256=NKrr42KwGhtVr3aElC9anChGzNq_M7FdehvPjfBCjJk,35081 +gradio/templates/node/build/client/_app/version.json,sha256=Y5-6tiPvRld_h1HLfO7OUoJDvfX_ZIh1ha3qUQkcTg4,27 +gradio/templates/node/build/client/_app/version.json.br,sha256=s73fgfqQH93CNfNO4dFLcuFYgE82vBWWINKSavMx6gg,29 +gradio/templates/node/build/client/_app/version.json.gz,sha256=G-M_rHulEu-OJl8NC8bocfuU_WkvjkNH9nEByhBuA1w,47 +gradio/templates/node/build/env.js,sha256=HWkgdy8wE3KURrZWJrZgdIhFqoa4lfm-7pQO8PcALAs,894 +gradio/templates/node/build/handler.js,sha256=BxqcARMD3cq22VuP0j8ayspYMy6LFquPLHisD4gfI0U,36667 +gradio/templates/node/build/index.js,sha256=4Bf8IF-QGVNOFON_CYp2s82IlHDEAyNl26oaWmo5KNo,9456 +gradio/templates/node/build/package.json,sha256=Ryxo71GjcRpC60BvsILf3nso9g85FKt9nU7Q5oREAb8,53 +gradio/templates/node/build/server/chunks/0-DijfUwFQ.js,sha256=si7gloBQx89ykDPy7sh4P7dPlOdMHmdQyGMo4DCgMOU,608 +gradio/templates/node/build/server/chunks/0-DijfUwFQ.js.map,sha256=1-2HMYKNquS93yiOSVlTKU0RxZO7gpmKr7NV3fjgB5M,1154 +gradio/templates/node/build/server/chunks/1-BSUGQSKm.js,sha256=8UTkQQFSvhNjxCytIh0ml9O2qOBSxsQuorRUAaXCCVg,424 +gradio/templates/node/build/server/chunks/1-BSUGQSKm.js.map,sha256=REOLPFgjQrLPET7HPpFUUviWL5RIWpR20TjmZrEhsVY,775 +gradio/templates/node/build/server/chunks/2-2QjpS3e7.js,sha256=nQ1FQmIpOhp-GbvB0phH_vQ5Jbp_D3gK3LZRNBxSIB4,897455 +gradio/templates/node/build/server/chunks/2-2QjpS3e7.js.map,sha256=XKk7Vn0rO4AXYZSWi3UfCmfm8S9sh2MR2Rpn2LKm718,1847413 +gradio/templates/node/build/server/chunks/AltairPlot-7YM1R3ND.js,sha256=Nbr_CdI9FvR9R3JdISjDCxMpTdnlJUazqRJYSDX-hQk,297800 +gradio/templates/node/build/server/chunks/AltairPlot-7YM1R3ND.js.map,sha256=vghnqRV5ZSQeGIRIBV3YpLIyV48KzkR5DyvVkWFQQEU,902432 +gradio/templates/node/build/server/chunks/AudioPlayer-BodTRsY3.js,sha256=YuBvYHw6kugtCvmoTNwV8Nk2TfrWb9yscazWc6bCZDM,79672 +gradio/templates/node/build/server/chunks/AudioPlayer-BodTRsY3.js.map,sha256=G7-wx5BD3rdhkG5khDmI1klsSy1Owcy4ku8esqP7p9w,160622 +gradio/templates/node/build/server/chunks/BokehPlot-DrxknxTG.js,sha256=lOXlXpAeB6W0mMD6p-8lSt3p5midA_mEoFCo7obZFzM,4610 +gradio/templates/node/build/server/chunks/BokehPlot-DrxknxTG.js.map,sha256=jLQ7anHZq_fNE0UDYZz8rOV1xcP3S9kVUQsOKMpKw64,7439 +gradio/templates/node/build/server/chunks/Canvas3D-B_jcxqUB.js,sha256=h8IpP6uTFw6oXi7904nhGjdBAwNA7-f_4VOii_gXW6Q,1248 +gradio/templates/node/build/server/chunks/Canvas3D-B_jcxqUB.js.map,sha256=I_nz1L4oVs9Rip1SEKdLx2kCAnC4BR8le-e8Ml3vSjw,4000 +gradio/templates/node/build/server/chunks/Canvas3DGS-DveDxqQS.js,sha256=E2prn_BFyC7ia9Iclc6hnEzK9NzT5iZGfijmH7RzxvM,51926 +gradio/templates/node/build/server/chunks/Canvas3DGS-DveDxqQS.js.map,sha256=MUBmf9QVmgD_koc3xo3BcSJVWxkuGatL7ICCnHz__w0,133598 +gradio/templates/node/build/server/chunks/Component-NmRBwSfF.js,sha256=yw-SlsLk6NHHzL4A2bV0xiYTmneOHptuCrxqk8QY3Xc,6265 +gradio/templates/node/build/server/chunks/Component-NmRBwSfF.js.map,sha256=8ue6uARLnT9zxuuU9VYLzzPZVFRERhn3K6uiQK-NaA8,25795 +gradio/templates/node/build/server/chunks/Example-CmZTmcbg.js,sha256=ToxZUtE8ZUh4qXsBWXbDx76g48B-FNeOwrK9rYGZepM,283 +gradio/templates/node/build/server/chunks/Example-CmZTmcbg.js.map,sha256=1e_j8lp4TRJGdtiyl0JPvO0KqRbLbpfLXTKkFy1OQhU,728 +gradio/templates/node/build/server/chunks/Example10-DUw5ngWN.js,sha256=sc-oebTwtMNJzk0q9NAE9cJFu9NFLbGJdcUie2mWSlA,1381 +gradio/templates/node/build/server/chunks/Example10-DUw5ngWN.js.map,sha256=mkiY5-UcwvddqWBGOJ5oNeGJunQ41Ea5Jt5kpD5kLmM,2673 +gradio/templates/node/build/server/chunks/Example11-DbSY_4re.js,sha256=REFAvZ_j4LqD4-EEuYrhLn4kEiCcjANgb8QgMOYdWEY,6117 +gradio/templates/node/build/server/chunks/Example11-DbSY_4re.js.map,sha256=vMdcnzdENOPI1D0pO2oL_A0nYcRuXk1b-b5a-vJaP34,9097 +gradio/templates/node/build/server/chunks/Example12-_jhlwqC-.js,sha256=2ZIDZDyjv7V3dvnM1OC-VMsxt__36bdSDpLQUY7BGzU,2887 +gradio/templates/node/build/server/chunks/Example12-_jhlwqC-.js.map,sha256=vb32isV5bLx1SWS66V8hWSUB1mEqxKp7oy6yr4Dvjjw,4349 +gradio/templates/node/build/server/chunks/Example13-DKMNurZL.js,sha256=5cPqMTth8UxAxsBMQAo2I2xLpvqtygQcKDoq49MGexM,1156 +gradio/templates/node/build/server/chunks/Example13-DKMNurZL.js.map,sha256=CRsAfcqJ9YCC3tjTgrWAGz4R8TdVV554jLz78wESUhw,2371 +gradio/templates/node/build/server/chunks/Example14-Dm_QueAJ.js,sha256=Ybi7kLTSnjDyZgLluvUEiemkZ8X0Cf3Upo3e-3Kuypk,1590 +gradio/templates/node/build/server/chunks/Example14-Dm_QueAJ.js.map,sha256=_3n6P-U1_uVaun6EmsF-LC4tEsF5WW9ISqkKEV4b32A,3263 +gradio/templates/node/build/server/chunks/Example15-QUrFCQ6n.js,sha256=4MQ68MzQgDoUXrtWDHOGa_bKdFQPvcnVjVLMIbPtHKk,1756 +gradio/templates/node/build/server/chunks/Example15-QUrFCQ6n.js.map,sha256=vhvqhX9tVSF_Sy36hYDst-_tB6dZhhwCHCyECya9s-Y,3127 +gradio/templates/node/build/server/chunks/Example16-DvaAOKL5.js,sha256=xTBtlOfxMfIcX__KhqzckKxiGRA_hPhvQ6DCsaJwhq4,2262 +gradio/templates/node/build/server/chunks/Example16-DvaAOKL5.js.map,sha256=_nYsh5cglqBcGd_VBZggJuruo1LWhDZsdNsKUDxJNuE,3902 +gradio/templates/node/build/server/chunks/Example17-BX_Nds0Q.js,sha256=WFPRWxQKzcdPd4v8d78y7vMlsVJurgrTFBrpMJjVXdc,1164 +gradio/templates/node/build/server/chunks/Example17-BX_Nds0Q.js.map,sha256=bT4xg7gCKSlu2-jmOvzh413duLdnHM2bXLiApw5basw,2379 +gradio/templates/node/build/server/chunks/Example18-DsisKUSa.js,sha256=pmkDiskW4rnPFLUIYoOhPAWNmz5RhohyMwoFgKQU8iA,2897 +gradio/templates/node/build/server/chunks/Example18-DsisKUSa.js.map,sha256=YjdMN61zFcf1KbR7Z-EgoWUGIGHHR9sEDq-H6olERPo,4307 +gradio/templates/node/build/server/chunks/Example19-BSaUMSck.js,sha256=RAm0X-pg5kK-P088j2CMWP3lhQiN4eQ3LeG9v0kHlnA,4307 +gradio/templates/node/build/server/chunks/Example19-BSaUMSck.js.map,sha256=DuFhQiprfFE4taBxdAmeoBi7u9-SRrzf-E59bOZuooM,6042 +gradio/templates/node/build/server/chunks/Example2-DF9c7LSI.js,sha256=TCrTFD88f2UtamN-jmu_yJoYK03QscIjkYAtiIe7ucw,9107 +gradio/templates/node/build/server/chunks/Example2-DF9c7LSI.js.map,sha256=iw571UNXC07Nut_3SIlZXHtAZ6fYRrS3Z4l6l1NxtbM,11978 +gradio/templates/node/build/server/chunks/Example20-CFDouFEG.js,sha256=RyuiQuuTxohKKqurgM_0fMQJkR3yIu4qByMWvjI0RY4,3659 +gradio/templates/node/build/server/chunks/Example20-CFDouFEG.js.map,sha256=g-xhqBz4KWBrsyiYiKmWmr8wzmSjVMb97JEd3WV-NKo,5524 +gradio/templates/node/build/server/chunks/Example21-uz6Wj3xI.js,sha256=QrCRhI4z2QBHHdt5703-o7D8y28T_aGy2uSbPAkY9l0,2385 +gradio/templates/node/build/server/chunks/Example21-uz6Wj3xI.js.map,sha256=1Mfzpv2Fj4rNuC_hR0_DqWVJ6yHQcu1DOGwBGaYmpdc,4473 +gradio/templates/node/build/server/chunks/Example22-7u--UOCG.js,sha256=kKaqhv_-wgg166tc-RkAZdnvNin4odmoL6csHhI6JO4,1177 +gradio/templates/node/build/server/chunks/Example22-7u--UOCG.js.map,sha256=FJamN5S-yCzntH3cx2znY4tdWMylf4NLLkvjQU3-9Bw,2412 +gradio/templates/node/build/server/chunks/Example23-JmT8Yk3A.js,sha256=SU0ItOd5OcQxx3VouEHtPwgvKyiJhQDRsKJBuaPHARU,5355 +gradio/templates/node/build/server/chunks/Example23-JmT8Yk3A.js.map,sha256=gOCBl3cxBeFdFTjtCGnl3B2Cs8FVjkuqiudVlJiEYZY,8023 +gradio/templates/node/build/server/chunks/Example24-C9X-oh6t.js,sha256=8ZURGNw7f9jbOOrBFau3T3jZ9jKofqcgKUarzhXpxUU,1194 +gradio/templates/node/build/server/chunks/Example24-C9X-oh6t.js.map,sha256=n1LC2r62LUtk8Q4OkuMoaSph4dPbvkbyTyysZ25W_lM,2449 +gradio/templates/node/build/server/chunks/Example25-DUXZ9Y7A.js,sha256=aBp4kyrkb7R4Ab3dva8jKWyo2IhxwQv6f_yL384PWvY,1226 +gradio/templates/node/build/server/chunks/Example25-DUXZ9Y7A.js.map,sha256=_-hH-f1ViVfnJwqIFGg2nMB0jXWF0upaR1aoNfximpQ,2488 +gradio/templates/node/build/server/chunks/Example26-DpqwuJHm.js,sha256=AnIWWObViX1xcrbLNF6FO-fPzT6xpLpmPK1H3k--ixQ,1512 +gradio/templates/node/build/server/chunks/Example26-DpqwuJHm.js.map,sha256=MTwVSj9V9x9B-5y3UrQBHIssGGJ9P0vaeKmCoBfiaW4,3121 +gradio/templates/node/build/server/chunks/Example27-DKMNurZL.js,sha256=-l2MwkLW3k-O_tjzlhF_0fk9yMM_5ZCA-a5_7HCwgGk,1156 +gradio/templates/node/build/server/chunks/Example27-DKMNurZL.js.map,sha256=Ez2eK-EPD0BfZQ3QtQihyO34t4L8J_RqdvdmY7Fn5Dc,2371 +gradio/templates/node/build/server/chunks/Example28-DrLN6-P6.js,sha256=Tgihu2mS-v9HIVezTUOY4_yHHSnsrhT88EVNbw9ZEwI,4127 +gradio/templates/node/build/server/chunks/Example28-DrLN6-P6.js.map,sha256=JkyDSQ63V_bUIcxeILAz1cmppONpk1Hgiz-gi1cR08w,6228 +gradio/templates/node/build/server/chunks/Example29-DKMNurZL.js,sha256=fI6uuOlPYUYF4eG5DEb3EuB_ZoVlCLNojhkFdsAmdto,1156 +gradio/templates/node/build/server/chunks/Example29-DKMNurZL.js.map,sha256=W_Gs5TSZ3-PsogsfLsqha9DdG-93pegW8pwQwOzft9Y,2371 +gradio/templates/node/build/server/chunks/Example3-Biy8EGGC.js,sha256=JZuqNo21hLND7VaRPuByEx3wUnkZ-6WtdpDeOE_Yat0,409 +gradio/templates/node/build/server/chunks/Example3-Biy8EGGC.js.map,sha256=D6uODx33mjnBGoVVTtAXK_rNei8J7VLJNNAQ-JH7nO8,1256 +gradio/templates/node/build/server/chunks/Example4-BB_DQ8Ql.js,sha256=JIoUmpQn1GVHO0pfg4_Xmes_HjwmvYY9vSwK2_HHM2E,440 +gradio/templates/node/build/server/chunks/Example4-BB_DQ8Ql.js.map,sha256=A4MGwH7XuT_PW19DXyUSs4mJc3don7EdJ0mz7aO6ciQ,999 +gradio/templates/node/build/server/chunks/Example6-7u--UOCG.js,sha256=O7URM4NkykE-RKslHe5fVXm1UO4PBCtBvmdDRyPWrT8,1176 +gradio/templates/node/build/server/chunks/Example6-7u--UOCG.js.map,sha256=-CQuZTxsprXGYoi4WvTbXkegCxgj_g-odPrFOPvXWyI,2409 +gradio/templates/node/build/server/chunks/Example7-BY36bKUd.js,sha256=jep67yniFG4FlZQS9pHEgMQStDwgT6fQIjBsXTBcpt0,1227 +gradio/templates/node/build/server/chunks/Example7-BY36bKUd.js.map,sha256=abv6yN7qBdYkIhzrfarq2FIpDyIt1LeZ9c0C-_oyrbo,2495 +gradio/templates/node/build/server/chunks/Example8-CtF03CXA.js,sha256=_MttYooNu8rvMrVtPJHLEMElHrOnwIoktybsOX-mFe4,1482 +gradio/templates/node/build/server/chunks/Example8-CtF03CXA.js.map,sha256=Fjbxi5l-h2vZnoZEHVT013dGVZHVUHgQsHq8o77WzE4,3071 +gradio/templates/node/build/server/chunks/Example9-BgAxc6bX.js,sha256=ZmSQXZBHbCxy-cR_gRHUaiqZorcFey2eb3ptpFHGyKI,1604 +gradio/templates/node/build/server/chunks/Example9-BgAxc6bX.js.map,sha256=DL7TYuYppJy9V10kulRKr6Zhm8tFFZ_z-znxwSVDuD8,3099 +gradio/templates/node/build/server/chunks/Gallery-DwewYNOL.js,sha256=X3EZMfpu_iVOeSSXc0ZvK5Yan_e6zEzBTMi_iHiJaqs,42589 +gradio/templates/node/build/server/chunks/Gallery-DwewYNOL.js.map,sha256=d260ePDV4j9MxtQdKSf77vxu-dNVTRvjlRsxi0jtHOI,62303 +gradio/templates/node/build/server/chunks/ImagePreview-CkivoaK1.js,sha256=9_VsnkgzX4IgJueaLIoXI4RrWOkGKRKXVvOBAbUNEPM,8092 +gradio/templates/node/build/server/chunks/ImagePreview-CkivoaK1.js.map,sha256=h4kLRN3Hxzqi83vhMGg56r-Eyg4n4l7SnrcXyYfBwEw,12759 +gradio/templates/node/build/server/chunks/Index10-Bco55gHe.js,sha256=xh8h5m13jdwtQ5JAQ5vbkY_esEeuVRruN0Jua0pvrL8,21544 +gradio/templates/node/build/server/chunks/Index10-Bco55gHe.js.map,sha256=nsbErgacDCX5Xj1uZLzBFP6gBDj0pbtsPf6-Ufja8xk,38646 +gradio/templates/node/build/server/chunks/Index11-CiflBTUp.js,sha256=lATuDHa9DKHPi2HCgZ2NLWEV5UN59E1c8kicBNRz5eA,2398 +gradio/templates/node/build/server/chunks/Index11-CiflBTUp.js.map,sha256=kcWsWm1Snh3cW62fS3-_5FsdYv1ddeUqvII9ObEhvGk,6451 +gradio/templates/node/build/server/chunks/Index12-Bu5WKBZZ.js,sha256=mrzfPnLmYa47J_IHf3K0SIKCRCmyV00dG1CRQ7oFLR0,926 +gradio/templates/node/build/server/chunks/Index12-Bu5WKBZZ.js.map,sha256=m2WFHfqu7DeQvxs2c-S5p-iGPE6Nx2_dyM42xXXF9uI,2251 +gradio/templates/node/build/server/chunks/Index13-CVAomUgM.js,sha256=eByGIhVKIfNovpjS4zFum4O1ldUk0VfABrP1B5C82rw,2785 +gradio/templates/node/build/server/chunks/Index13-CVAomUgM.js.map,sha256=2XK5JULU5pnmaaYvoQ3BBBpo8dqTx3A0yP0GguexaF8,7395 +gradio/templates/node/build/server/chunks/Index14-D3zgy-z7.js,sha256=I29bMd_Qq7Yok6T-iGFcEe_w2OieSxz3M_7892Cb11g,180 +gradio/templates/node/build/server/chunks/Index14-D3zgy-z7.js.map,sha256=MZAd2MAFdMAAxcAvfu4LX7J8nkMLd_P5VRDmyJqD9eo,406 +gradio/templates/node/build/server/chunks/Index15-DFvG43KK.js,sha256=YT18jBywv6MU_TOw-3Jvk1HnIXqfeEX-qtjQFg5TzaI,587 +gradio/templates/node/build/server/chunks/Index15-DFvG43KK.js.map,sha256=XVYhMI8N7EGh_w2ZPkEEmAZ1-_vqEIQtdQHcWby0Fso,1703 +gradio/templates/node/build/server/chunks/Index17-BN-GAMZQ.js,sha256=hW6O3hoGvuCAREXJ05bNfD1O2PO0vMw2tmEt6qpOrlQ,392669 +gradio/templates/node/build/server/chunks/Index17-BN-GAMZQ.js.map,sha256=dX1mGef91Ut9E5-Tl8g2R5KGtryzGy9Kvl6vnets4BU,1214895 +gradio/templates/node/build/server/chunks/Index21-dm_cbYH_.js,sha256=1SDuM3cOPl1TkbSwttdqxfdoO5HRpwxtA0tt5KrGVG8,12222 +gradio/templates/node/build/server/chunks/Index21-dm_cbYH_.js.map,sha256=2w57rcoBwlYyXTmwL0IszCN0isFbKatDFyPEQvaKMR0,20041 +gradio/templates/node/build/server/chunks/Index23-I-jXs_Pm.js,sha256=HQaXY9Dpy7UumbNFefMgsK9pdblLK-Kpzbv_UVB7ZXw,19426 +gradio/templates/node/build/server/chunks/Index23-I-jXs_Pm.js.map,sha256=SmQ4tB9MX-FJJnuviaP5Zf7nUeAFfO8T_sXmZ2Xf3dU,26100 +gradio/templates/node/build/server/chunks/Index24-DpKxUqly.js,sha256=HYWUGjRKz3CiwNKVphhqO7GT8HSp62dQh9o8Wi1YQpQ,20085 +gradio/templates/node/build/server/chunks/Index24-DpKxUqly.js.map,sha256=RwkdE4Oiid8RdIPqg3IVlalBS4JDPjY61Zsb-A_fDbI,30550 +gradio/templates/node/build/server/chunks/Index26-CK4B0gSY.js,sha256=HWH6rrTOAz8_4DYrrAKhlKviBWectwZWYcbrvuhKUrM,16413 +gradio/templates/node/build/server/chunks/Index26-CK4B0gSY.js.map,sha256=dCjgb5GfPx2GMZllRHCt0eTzucdhzmgBTZHmUY7CH-E,22295 +gradio/templates/node/build/server/chunks/Index27-yqg76A6k.js,sha256=3V-CJbYku2kg92DtTfBAzfsrHx7m2syTwvFOCwbdLrA,2771 +gradio/templates/node/build/server/chunks/Index27-yqg76A6k.js.map,sha256=THLiQ2fthHCZEaU3M2z8RXx7qaBNpqstzG1WB421IBQ,4449 +gradio/templates/node/build/server/chunks/Index28-DJN_cVP2.js,sha256=d1x7prUEs-7YuFAxyjGd-wLqmD3kLLMm5GxexFIlwjo,44920 +gradio/templates/node/build/server/chunks/Index28-DJN_cVP2.js.map,sha256=_uiQ4wx03-2bYeVtllPN0-nd73rS8Q8rLvaKFnnCLuw,74011 +gradio/templates/node/build/server/chunks/Index29-B7uK_Jl3.js,sha256=3gjj5DAJvB8vUJnx-PxQBLxvZHfkT0iC57kpMdFr-eA,35648 +gradio/templates/node/build/server/chunks/Index29-B7uK_Jl3.js.map,sha256=5elTPIMUUJKeLj3BuhmVL6CHPjr9Jm8HPqsP4Wcnxww,59709 +gradio/templates/node/build/server/chunks/Index3-DezoQBCD.js,sha256=43KkydtXWZqkAQxwTZFjr1q5G-Tpik4jG8Hvfn_KK_U,326844 +gradio/templates/node/build/server/chunks/Index3-DezoQBCD.js.map,sha256=YDfs0eWzFuYi6ZnQXRcY4dhWTBIzK6chYe61JTDJiDs,1086501 +gradio/templates/node/build/server/chunks/Index30-CTzNUBZk.js,sha256=SRbHE8vewWY0xAMT6m0_8DVz0TfH9H28iSgNbKXpPrQ,9758 +gradio/templates/node/build/server/chunks/Index30-CTzNUBZk.js.map,sha256=3rojkSPmX-r3iCOzCt_2UEx5yFI8Aeb4uZWp6bMcC-E,15490 +gradio/templates/node/build/server/chunks/Index31-g7Qq22JS.js,sha256=blEwnidXdZGL-9tVQ-Z6Jd5n0ABPS1aUAUJUrD8rdqc,6303 +gradio/templates/node/build/server/chunks/Index31-g7Qq22JS.js.map,sha256=5lqfL9ZV8WBJ3JjwZ_9GiuKVjUVrJ2mvvY0k-lCxMVA,10403 +gradio/templates/node/build/server/chunks/Index32-7_fo2y5l.js,sha256=2fDIvEYXFBnWlttvR8N0UWUQSJOS36VXa8OEGHfamFE,15420 +gradio/templates/node/build/server/chunks/Index32-7_fo2y5l.js.map,sha256=QpnrJ8M81uSml9D32iJknINrMTcuJAjMNtc4J0zdztc,20322 +gradio/templates/node/build/server/chunks/Index33-BRRWgmb1.js,sha256=auUkGbtcA957CRKmgDqiFxbMQP5SRZPxREAjvYYPIsg,23546 +gradio/templates/node/build/server/chunks/Index33-BRRWgmb1.js.map,sha256=Kz2P2s1HYfkDRbyOQDFyorUQsOz43ttsXh1uCr69bpE,31194 +gradio/templates/node/build/server/chunks/Index34-Do-wGrBJ.js,sha256=zlTK7cu5KpUgW-lzjZfnIUBqFOPtEHqzND1c_BHIfGI,38767 +gradio/templates/node/build/server/chunks/Index34-Do-wGrBJ.js.map,sha256=ajqF07X5yhlENOyWKImLs44GvW_V_efZMjS7FyYmgvY,46953 +gradio/templates/node/build/server/chunks/Index35-BdTDRCom.js,sha256=x9rwn06VJl2ecXmtCcctImZmAVHQzj5cfZ7TtrZf41w,10391 +gradio/templates/node/build/server/chunks/Index35-BdTDRCom.js.map,sha256=-fu1mZNRaFL2qhlsneJUnI3ElJPE89Xs4aY2OINo5BE,19157 +gradio/templates/node/build/server/chunks/Index43-ChjjuSzg.js,sha256=t-OXTzjTXnHAXPefE-EVo280N5gcr6ld7nx1PHYlU1k,3879 +gradio/templates/node/build/server/chunks/Index43-ChjjuSzg.js.map,sha256=vqXXPWaSq51EDYrPuuJu2Laz5HKN4I3WWN_HXB6QH24,7381 +gradio/templates/node/build/server/chunks/Index44-Bn1tFeA3.js,sha256=zjVaIMl6LGBvD0SsPYKwvR_1xz0toD7Myb2x59OvM9c,10643 +gradio/templates/node/build/server/chunks/Index44-Bn1tFeA3.js.map,sha256=3AIkYYVfwdnKsAOVwy_S1rRiN9nhgq3qGRjyTJ_4f8s,15860 +gradio/templates/node/build/server/chunks/Index45-Du2TAant.js,sha256=KV_vFNPqdfBfGgBy0HZobgClv3lmKChKSE2zlFxmSRk,4588 +gradio/templates/node/build/server/chunks/Index45-Du2TAant.js.map,sha256=--eDQW-xeYeQl9h2jAOrXQzf2JSsQahnf_GLyiY4LTU,9777 +gradio/templates/node/build/server/chunks/Index46-DWMPmKH6.js,sha256=JQUGds0HtqA7rzwv4ERGdTNmMX9-rpelpfVvlA-SECI,13470 +gradio/templates/node/build/server/chunks/Index46-DWMPmKH6.js.map,sha256=Ng9u8x44lEqgHlI4tjRryWjefcWbhZCaqAgxCh0DYVc,21000 +gradio/templates/node/build/server/chunks/Index47-4e3cSZs8.js,sha256=PiWpbATwya-JXDdqgCrYTsrGuvCER7za7h0yaigr3JM,40356 +gradio/templates/node/build/server/chunks/Index47-4e3cSZs8.js.map,sha256=9fIlGBNzL_0y_vDqAnhtBN4QNxSFOuWwfhYG7ms_dvo,63366 +gradio/templates/node/build/server/chunks/Index48-Dyg47yOt.js,sha256=VOnl1IKA28K7uid-YOkjzPlHRRyJtxljDZgcU--vQxk,15818 +gradio/templates/node/build/server/chunks/Index48-Dyg47yOt.js.map,sha256=-vwOAOyVP13z18mABI2sOa41YCg1mOJcXN-9b2xyzJM,22021 +gradio/templates/node/build/server/chunks/Index49-9fG8c8Wg.js,sha256=yGRDezd1quyLaWx3pWLJ-6O6l9PIgi7UYfvS5OCZx2k,4705 +gradio/templates/node/build/server/chunks/Index49-9fG8c8Wg.js.map,sha256=GDm79huiDSSGZpWB90FXygLy8t1qMikavTa_1EMU4jA,9704 +gradio/templates/node/build/server/chunks/Index50-GZfrLJcs.js,sha256=gGwfMWoiB5tvA3OAKzRzhcAPKtT6lIRgVIHXp4XgiDc,44390 +gradio/templates/node/build/server/chunks/Index50-GZfrLJcs.js.map,sha256=Z-R0KfGIso4l1-N1JWZXO_TxG9Eqb3XlKA-8M2-AHvU,62394 +gradio/templates/node/build/server/chunks/Index51-C9z37drs.js,sha256=0U_lmAI8ehok5eTFSjt38m9sFhLCzwmaXAGioFE0Uho,7223 +gradio/templates/node/build/server/chunks/Index51-C9z37drs.js.map,sha256=s02KqnbDYSUs6hZMgoiLGCj87MHRqd73O8rcMGVNOsE,14783 +gradio/templates/node/build/server/chunks/Index52-ZpJ-z0Q3.js,sha256=ZMN_R-rYRWN5T5S9xXr7oALEpxjwRemvR6tuihrgV2A,8522 +gradio/templates/node/build/server/chunks/Index52-ZpJ-z0Q3.js.map,sha256=5tY5OlDQlfW9sX0MYImhMulp8hmbjxHVkY1KYpFDC6E,14482 +gradio/templates/node/build/server/chunks/Index53-B_iLe6EW.js,sha256=F5FFf72ASnsNlHKPiF9yY0T8FyBEK8hv0lOLZBwvh34,22550 +gradio/templates/node/build/server/chunks/Index53-B_iLe6EW.js.map,sha256=Yufn_SI6xOkhfpwODwJEqpBBqqk4juPSVZyW0KIt1iw,31843 +gradio/templates/node/build/server/chunks/Index54-CnLpc1YV.js,sha256=5SyOyTheUZOWWgPCzXU7RxYlcHQZp81dNI6fbJwf0pA,7833 +gradio/templates/node/build/server/chunks/Index54-CnLpc1YV.js.map,sha256=0LcAzzngdy4Ijvq2iUOsZwy_aSg93c1teSYJKhI2nJo,14023 +gradio/templates/node/build/server/chunks/Index55-D9T9fC57.js,sha256=t27w_myH0ufpQKxxFsQZZ7R_E1ilcyRXem75Mzj-D4E,14159 +gradio/templates/node/build/server/chunks/Index55-D9T9fC57.js.map,sha256=tbRygzjsMEdcDiKWRFtUs3bbIjdUc4KeYhVzdoCjR04,21155 +gradio/templates/node/build/server/chunks/Index57-Bca_UpPh.js,sha256=Mgf7uN_y-Z2CWTdFVUzoecXrTUpdJHoIa4VfDPzWaYs,15672 +gradio/templates/node/build/server/chunks/Index57-Bca_UpPh.js.map,sha256=j0FOwPLnxm0c24dNUYrcmJ_yivhbtOY8GMZZBG-OsOo,50726 +gradio/templates/node/build/server/chunks/Index58-Lq6UQMA_.js,sha256=AYgEt0sDZLtwEP3e_bjHwcqodQLMAN9nFmej1LKqF2o,56515 +gradio/templates/node/build/server/chunks/Index58-Lq6UQMA_.js.map,sha256=oyb3zgrC9D0i2DBFNleKGqsr4h_0PUShi-c_UZ12EME,78365 +gradio/templates/node/build/server/chunks/Index59-87V3dxMW.js,sha256=oYn8UWgZzycfC2ABr9QaqdVYSmC5lQO5k0-jz3smaec,45534 +gradio/templates/node/build/server/chunks/Index59-87V3dxMW.js.map,sha256=KdPnGWfl0tjgGnuiXlFkwNLABBmAVtaHWZoNfoaOFqQ,69406 +gradio/templates/node/build/server/chunks/Index6-BQIkyqu7.js,sha256=UmatbwIjMEvtAnq4_OzeDkV7RWe6qHKKVbBykioKiu4,746 +gradio/templates/node/build/server/chunks/Index6-BQIkyqu7.js.map,sha256=eb473kOAJCQA3Y5BDlszmP6TdBThKU_jdt0wfQoPcI0,1650 +gradio/templates/node/build/server/chunks/Index60-TLxCPky9.js,sha256=gKOsnjlvr8KnAcr636XYayXNqSXu4KkH0vJuw4Q9vjk,17413 +gradio/templates/node/build/server/chunks/Index60-TLxCPky9.js.map,sha256=2bzk4FvP3cz5SId3t6SwBt5YecMFmuwkN_EJfwSLtrs,34131 +gradio/templates/node/build/server/chunks/Index61-BBRZRllP.js,sha256=GCbusY7nJB3V1B9gmgu2H8rIjo47jI3sE6htQS_X-rI,20578 +gradio/templates/node/build/server/chunks/Index61-BBRZRllP.js.map,sha256=MQH8E3sSJmpmY0FE5DCwCNR0rqgyMs91tJN9QQZ5Uac,28874 +gradio/templates/node/build/server/chunks/Index62-DPL7i5i_.js,sha256=iXba4AU9YEb8phB9bsXqRMLW54kB5AQo6SCKDTvKgmc,51589 +gradio/templates/node/build/server/chunks/Index62-DPL7i5i_.js.map,sha256=xd2nzdPiynSnfvNRWpDDmYALmaBoiqtVEWy34P--t3U,79045 +gradio/templates/node/build/server/chunks/Index63-CCGS6IKs.js,sha256=Nk-e6iAsCs_Fts57ZxkLd81KsWC7nJiX5JsRdfQ3C_A,24326 +gradio/templates/node/build/server/chunks/Index63-CCGS6IKs.js.map,sha256=mCEmzRVwGfQj0aQ9-X5LmLs_atP7TGW41YDtLuAppf8,37200 +gradio/templates/node/build/server/chunks/Index64-dK3pb0Ha.js,sha256=vW4LMoYne3JeMqFWNtSF3keQH7Ts64u0qLvLZwTwdO8,153702 +gradio/templates/node/build/server/chunks/Index64-dK3pb0Ha.js.map,sha256=JzWMpnINL4H-OaGXX2OHWXJ2VB4nmgbmv8tx54UTr10,241442 +gradio/templates/node/build/server/chunks/Index65-Dp12pKmz.js,sha256=GhkJOnDmZqjnVlLUCr4XKWtgSfUfyzrKHGvNZpmNiAU,191445 +gradio/templates/node/build/server/chunks/Index65-Dp12pKmz.js.map,sha256=jHoT0quLPyTF52p5xBfyl2m3AwuEYnaJQ-fbWzqR5b8,337544 +gradio/templates/node/build/server/chunks/Index66-BT_wCfAY.js,sha256=ASJaKMYqXJw8_XcHpgY_HXYll6plAyGFLDDt8kNKVtY,71392 +gradio/templates/node/build/server/chunks/Index66-BT_wCfAY.js.map,sha256=HstpI5z8Z7_GsoK-zol36ubLotH3ZX8SeVDUtTemR6g,227444 +gradio/templates/node/build/server/chunks/Index67-C2nyfLhf.js,sha256=1naeM1bbwju_Bro33AbytdQNp6AXR_5v47USdnPMkuE,66131 +gradio/templates/node/build/server/chunks/Index67-C2nyfLhf.js.map,sha256=aampblLGruapUJ9IUgBHkI9bTqJXktqQ2leLTiKOlhw,147102 +gradio/templates/node/build/server/chunks/Index9-D7555p8a.js,sha256=4yLT3-T9Nog-P5JYIFk2IITcORmmOe3QWmhLxQppK84,4244 +gradio/templates/node/build/server/chunks/Index9-D7555p8a.js.map,sha256=kTlq78YmI4JGidpXYUfCLnYiof_ZEJNJzwl-69hjJF0,10921 +gradio/templates/node/build/server/chunks/InteractiveAudio-Da1uh9B9.js,sha256=nXlmbLl4oRCcRnERhP0L23AnHzY6agXCYO4WOLVdIzA,46260 +gradio/templates/node/build/server/chunks/InteractiveAudio-Da1uh9B9.js.map,sha256=3ez5_ooyuctNJG-KPmM8ZR_MFUe9u7miqW7MAHQZsKQ,92276 +gradio/templates/node/build/server/chunks/JSON-DqGnZuFO.js,sha256=ABrtirdeuMBzWbrj9iIf1EUmOJDsw197bNGF7puDEV4,20708 +gradio/templates/node/build/server/chunks/JSON-DqGnZuFO.js.map,sha256=SxxjMTABDnsLVHEy6GEHxgjsUX_hNftvyf453EJBol8,31429 +gradio/templates/node/build/server/chunks/MatplotlibPlot-DZTjkRT7.js,sha256=hcrWdncM_NYBzpAamId-O08UyhVbgQSHh8Qk_inodNw,1757 +gradio/templates/node/build/server/chunks/MatplotlibPlot-DZTjkRT7.js.map,sha256=ZQQ_Ms84Z2qRBJzrjlb3PO8TLlZgU0MIx_Y7Ej6_yhY,2661 +gradio/templates/node/build/server/chunks/ModifyUpload-D3TChhFo.js,sha256=nFuZ_cWBa8_pWK7rK6GXCtIZWp16Dl_AcL_raywrpmQ,27900 +gradio/templates/node/build/server/chunks/ModifyUpload-D3TChhFo.js.map,sha256=kSV3iMjAV5zl8wofTE9Yj-_LLqdR3lUYjR49ybS1EnA,46780 +gradio/templates/node/build/server/chunks/Plot-D4xKcFIN.js,sha256=KpdRJJd1qD9z6wZjQDmzVhCADVVZb-Q1aidzfpjyx30,2104 +gradio/templates/node/build/server/chunks/Plot-D4xKcFIN.js.map,sha256=jN8nDx6b6_ADZ6HGL8OK_3dYu1GrjJxw98Rddz5MW8o,5411 +gradio/templates/node/build/server/chunks/PlotlyPlot-D4ZO-WDo.js,sha256=FEgxgMtc12mQINX4Jd8iEYdKbEJShhE-wYBit1IsHK4,4554669 +gradio/templates/node/build/server/chunks/PlotlyPlot-D4ZO-WDo.js.map,sha256=Cas5ocFgO-GxIUBj0YQmpCEx3JQMDuWye9y6lvQ7k8k,14179294 +gradio/templates/node/build/server/chunks/SharedSystems-B_SV4B1h.js,sha256=8patveZWoaZiKNpLNeGHmzA4EvtKZlOK2LmUR6kWEko,50831 +gradio/templates/node/build/server/chunks/SharedSystems-B_SV4B1h.js.map,sha256=cx1g7MDrIRyN81Ykd1vkWToCYf-bCnzQGQ7R44KBsv4,120998 +gradio/templates/node/build/server/chunks/StaticAudio-6eyiqKRV.js,sha256=ZIpoWfODfQeSXMQwberylWj-ksfKgCukLJ0xY27W1x8,2756 +gradio/templates/node/build/server/chunks/StaticAudio-6eyiqKRV.js.map,sha256=jNhc_QH4IumvfvK60GSG5doZsy-zF0O4WfWNfRvdEB8,6733 +gradio/templates/node/build/server/chunks/Video-BOxlhE7M.js,sha256=JSFNy30GSYKDd3CDRt2YdTHzi-Xxd-91B1gTaSCRdEg,9844 +gradio/templates/node/build/server/chunks/Video-BOxlhE7M.js.map,sha256=QJ6dqoQXdSqr3t3pPJIwYtuI9I6zBepxyASKBnOIQSc,15003 +gradio/templates/node/build/server/chunks/VideoPreview-L9YlhEoC.js,sha256=4unuPiX0balCijxb7aCGJRAxePh4UCGLy_HwvVuZueg,40498 +gradio/templates/node/build/server/chunks/VideoPreview-L9YlhEoC.js.map,sha256=JuA2A_uGCPOAKeOk1Y_EbYn6xy0agC1oMyCjD0HRGNk,64057 +gradio/templates/node/build/server/chunks/WebGLRenderer-D6K9dX3W.js,sha256=E9F6y8wL_PpbtvYYXecG4CcIb5yfvAxgODrBMKZVgOY,62556 +gradio/templates/node/build/server/chunks/WebGLRenderer-D6K9dX3W.js.map,sha256=BgJxRwTwIdzIfLcBWe2NULoGAkkj7q9dq6Lb9Coeycs,155298 +gradio/templates/node/build/server/chunks/WebGPURenderer-DnylRHBM.js,sha256=e-brd2NaXnAt4vIZsl9RZOn50SDa6LKcrS3wwoW07Ss,37337 +gradio/templates/node/build/server/chunks/WebGPURenderer-DnylRHBM.js.map,sha256=cf5xR_OibdwpWdWrNceRYp49tooHKVoD_ks7ACfK3sk,95270 +gradio/templates/node/build/server/chunks/_commonjs-dynamic-modules-DX_xVkta.js,sha256=DiYDZXqUtTfvfowOGe-gn-PK0S1tZBgH372Hxje5hIg,302 +gradio/templates/node/build/server/chunks/_commonjs-dynamic-modules-DX_xVkta.js.map,sha256=eUXjTOUeOYf7ieJNRnqg0ab_pzMmVK2MwVs327DLHAA,596 +gradio/templates/node/build/server/chunks/_layout.svelte-DtUVntm9.js,sha256=aIlNC-7pVIwjMvNzmHtTIY5F6VPzwnK1un0kZbFjusw,1598 +gradio/templates/node/build/server/chunks/_layout.svelte-DtUVntm9.js.map,sha256=FhKE3nwDOn9plJpOATe1UunthKe6yF96TyL3fuhbBe4,2512 +gradio/templates/node/build/server/chunks/_page.svelte-rjY2KN1w.js,sha256=WU-pyrL90grj85EJiShabacq5gMoFBi1ftJttIx8A20,11747 +gradio/templates/node/build/server/chunks/_page.svelte-rjY2KN1w.js.map,sha256=QAxSKiuOdWxJlA4kX5WKRcVr9O37Wdj-TeU_FMwwUrI,29338 +gradio/templates/node/build/server/chunks/ar-Cwk59jlo.js,sha256=R4djsD4azBhlBFCDadAf5Rf4xXXqiCxce4haofvTVs0,6274 +gradio/templates/node/build/server/chunks/ar-Cwk59jlo.js.map,sha256=O-Qp_Guot6lqOxH0QrhzlFNJNMhw4U2CVTV-z_FxVkE,9981 +gradio/templates/node/build/server/chunks/browserAll-BQSmeIQU.js,sha256=g08I5bY3Q29p-PHF5v1dSg1DFhgmlcdBuFS8cX-JkQQ,39668 +gradio/templates/node/build/server/chunks/browserAll-BQSmeIQU.js.map,sha256=Jik8FxGqcpNk-3heAFor0PS5xOqRM7ko8pD7hglVzag,100944 +gradio/templates/node/build/server/chunks/ca-BvH50zSS.js,sha256=rJVOeMew0im3lHNmtjm_pbmxV3pDU55EhwLFLjh63Cg,4844 +gradio/templates/node/build/server/chunks/ca-BvH50zSS.js.map,sha256=glpw4ziNyiq4VvGMbE6kKXVRhfI9DV56y2L0F5nQHjQ,8417 +gradio/templates/node/build/server/chunks/ckb-l7nR8ql7.js,sha256=KhtbTjU3dL9lIMuxDlEeSIR60Ue058wxMusTZsFcRnI,6708 +gradio/templates/node/build/server/chunks/ckb-l7nR8ql7.js.map,sha256=ILE4FN87tpTL1FcWU9eXQJmsh6w7ZiwpDuUI1pIuPEY,10271 +gradio/templates/node/build/server/chunks/clike-BmyQvQnm.js,sha256=IKJy1Ak198mgg4HuDbOsn2kFoHA6OqLwt1nuOMJVtnM,22419 +gradio/templates/node/build/server/chunks/clike-BmyQvQnm.js.map,sha256=2U3iiGTTE_iGTlQKFQVe7ebYsytu0IkyApooGFHyPUg,49268 +gradio/templates/node/build/server/chunks/color-BxRWE_zS.js,sha256=o2cCKs2-jYa3PkfnGP3uDXq7ua8VncMB8p-uu92Nrv0,131 +gradio/templates/node/build/server/chunks/color-BxRWE_zS.js.map,sha256=PABBngcEKKzzVPAbhDat9KY6oHpaB-m2txHBmGnW6dY,349 +gradio/templates/node/build/server/chunks/colorToUniform-BWqj7xWF.js,sha256=Tkyqg4K-yV8nG2sGGyVGJtsdJwszXQL07vLQEV8gWHc,1724 +gradio/templates/node/build/server/chunks/colorToUniform-BWqj7xWF.js.map,sha256=gOeKC8scIDPHOsxwgjciyKErCnSiT4tOdFrZ-sH_r7U,3553 +gradio/templates/node/build/server/chunks/de-B1wU7-Ch.js,sha256=4XVn9_Q2vEP7U3tK7LigE-48xuIbOeOTj1eGmufnOfo,4933 +gradio/templates/node/build/server/chunks/de-B1wU7-Ch.js.map,sha256=1PAUbEL10y0GJiVCJ7aSEKK2zKcOh5FebEVX3Eqkmhs,8480 +gradio/templates/node/build/server/chunks/dispatch-DGVRt-1i.js,sha256=No9rg5Er-xVwUAmfjQtDuWH4v0qYqWzxHemvBoYDZrI,1591 +gradio/templates/node/build/server/chunks/dispatch-DGVRt-1i.js.map,sha256=-3dnSuAXPBmt8BYMaT9W6hlNs0gBTRMyf8utPT0tIK4,5607 +gradio/templates/node/build/server/chunks/dockerfile-BYGRaj2s.js,sha256=61YsyMmm8Pm0ACMedzrqkRwxTvGQUCZEzlcA0q5-xVI,4176 +gradio/templates/node/build/server/chunks/dockerfile-BYGRaj2s.js.map,sha256=iz2qh-Q8_qUu2NXtZia4f2MnEj4cOtSIqWQg8IyIJQ4,13070 +gradio/templates/node/build/server/chunks/error.svelte-uehjnFTh.js,sha256=kCpx-WOcMl2cNDjL5jWky1TXknAF8HsqTdxxRF7U_So,403 +gradio/templates/node/build/server/chunks/error.svelte-uehjnFTh.js.map,sha256=Vj2kgpO0UWdypU_2RyhXdEs69f1FyqjPRQgh3ltqiK8,838 +gradio/templates/node/build/server/chunks/es-B2LmZtQQ.js,sha256=1pm2Pic2O8EYx2xLlfgmXgNaW0NyN_5o9MtU-WxD93s,4938 +gradio/templates/node/build/server/chunks/es-B2LmZtQQ.js.map,sha256=egVRpau2ql426LMUdC1y5NjW1BRCd3MYU3bE-UqVgUw,8543 +gradio/templates/node/build/server/chunks/eu-DQN2mBJJ.js,sha256=VscB1F7mSpwSoD6E1wZbbkeswZw1VF4OijH_ZLtcLL4,4708 +gradio/templates/node/build/server/chunks/eu-DQN2mBJJ.js.map,sha256=Nr5LdM4Z6zSxzc6tDFTDXDvdnX1BhHlKwsMyD4i-cXY,8275 +gradio/templates/node/build/server/chunks/exports-Cu4i9J_Z.js,sha256=eUk39KgRVdIdvyTthrKgZfz1SG8gotAyPFOqyLi_Dmo,1908 +gradio/templates/node/build/server/chunks/exports-Cu4i9J_Z.js.map,sha256=dQT4Gm8DD_NnahunF8zqyh0f2zwCPBXoMMkU3862zSE,6424 +gradio/templates/node/build/server/chunks/fa-DJTEw8mO.js,sha256=Yk5Axkjxxd0TuIPJW3JkWq3Ms1Pi8ToZ8YkPSIdR9l8,6217 +gradio/templates/node/build/server/chunks/fa-DJTEw8mO.js.map,sha256=ZIHEpCaW7wnj35yBeerq9g8_x-4wFJxgLYA8AG5f6QA,9758 +gradio/templates/node/build/server/chunks/fi-BJkPVS_L.js,sha256=0W2WZHjI4l6TD8LDTK-nT8OWitJ5LlNaRRrabSCwDq0,4711 +gradio/templates/node/build/server/chunks/fi-BJkPVS_L.js.map,sha256=LkLE2iJ00hbcIy9JfxkQsfvT4Xj27m22VEwO35-o1WI,8262 +gradio/templates/node/build/server/chunks/fr-Doonyoep.js,sha256=-Bz3CpdGG2dodORiSqrjPA36nSfk2o9hgLBeMaqbAYA,5093 +gradio/templates/node/build/server/chunks/fr-Doonyoep.js.map,sha256=JtnZa62HGfRkfddtYMAXIsfc9N3_PYgf6aQMjaFTjlI,8726 +gradio/templates/node/build/server/chunks/frontmatter-DxvS_zut.js,sha256=ve_thPnsJxPzNLVWfHq2EZAgcLCzwBqJOczOFl5n8Qs,1119 +gradio/templates/node/build/server/chunks/frontmatter-DxvS_zut.js.map,sha256=QppvhWL5kPZDkyB7lZJpaPfYMOT67QuM8gYUCy2CkjM,2483 +gradio/templates/node/build/server/chunks/he-C5xAKd5S.js,sha256=AcDAe_fyUkkFs0bvCvFkSP8x0q_Yf1ELapI5OXm2lBw,5187 +gradio/templates/node/build/server/chunks/he-C5xAKd5S.js.map,sha256=5YlCuW5DhDW_uW7_ryOMobzLaunRsh_VL2Ll0Gb3o4A,8696 +gradio/templates/node/build/server/chunks/hi-DKgm37B9.js,sha256=awzPu-cHweDYfjx0JiCstw6ZRhNS7F1GY335Sd7NnkA,8388 +gradio/templates/node/build/server/chunks/hi-DKgm37B9.js.map,sha256=GQ52x-_6ppv8l4Yj6tqJTIm7Jf0LJ9C-7GKnLOHQmTU,11937 +gradio/templates/node/build/server/chunks/hls-DpKhbIaL.js,sha256=n2GfQCwO-wAjqQO5NCyr2uUIvrMWqnHmcjuwMeeX0Vk,397375 +gradio/templates/node/build/server/chunks/hls-DpKhbIaL.js.map,sha256=FKarYBTmkoUuX8ONatpv2aLPvEWzTwV_RJ_owAWKp84,1143171 +gradio/templates/node/build/server/chunks/id-CeonQf4M.js,sha256=81huk9OGTuuUJ6Ywul_2b6s4M2XghHnBzMVH9d2ff6c,4627 +gradio/templates/node/build/server/chunks/id-CeonQf4M.js.map,sha256=_NKkflxwNq3puXOZgE8_cBFnlQTuSpNuNPoZ_7_kSto,8166 +gradio/templates/node/build/server/chunks/index-C94nxEv_.js,sha256=IuyoKQnEFA8hY9N0QYOxSA8NmO44iTaDoEYFPs7ipT4,503 +gradio/templates/node/build/server/chunks/index-C94nxEv_.js.map,sha256=7ClHhjDcMXZhZy-VeDcer48runRd9seWHc4YTadjkwc,104 +gradio/templates/node/build/server/chunks/index-ClteBeTX.js,sha256=qNTkxQAmJ2X4gTdSqLwpCq9QNMixzvxsF_p-hDokkFU,5089 +gradio/templates/node/build/server/chunks/index-ClteBeTX.js.map,sha256=p0d-l6AMsi2IYlsjPTOe6X9SiXrqRinPmSD0C_SDwFA,9710 +gradio/templates/node/build/server/chunks/index16-Db6Z8zRY.js,sha256=oTM8JGIV9mrEhZh4MktkPNzVtCbG_epkapz-eBLSObM,26251 +gradio/templates/node/build/server/chunks/index16-Db6Z8zRY.js.map,sha256=rZE3U0czx8JPNbQ4oscSk7qnJ9Ow27O3woxq2c0aLmQ,83305 +gradio/templates/node/build/server/chunks/index2-ihSmwCiq.js,sha256=tHNv0ztnKXRO8WEEFQOdKwuNdg6ixsCQBrd2NHFneGM,290 +gradio/templates/node/build/server/chunks/index2-ihSmwCiq.js.map,sha256=4u-ILj3C4uh7xbc5rdgU3IgTxEgvupKTh4ER_4HDy_o,105 +gradio/templates/node/build/server/chunks/index22-Bu3XhRRH.js,sha256=ehizgr29xrw0LQr24PvQ74vxZGvcUTX_So3gFQmuuzc,5363 +gradio/templates/node/build/server/chunks/index22-Bu3XhRRH.js.map,sha256=w1GBpIdoi9R5W1WIyYuw_2zcz9xWkW8zRokJVjzQxS0,14727 +gradio/templates/node/build/server/chunks/index37-Bbrbn6Kl.js,sha256=zPpHgKWj9BIOCbNZ6w1IuLDyyxj_gHZDNHeKNtVt-h4,56472 +gradio/templates/node/build/server/chunks/index37-Bbrbn6Kl.js.map,sha256=gVWHfIrNreROerZzcUV4lyjPZnZORp4ZvlNpjvtc1JQ,76777 +gradio/templates/node/build/server/chunks/index38-C6u3TLsu.js,sha256=BDD5-txQA-ILy66ZO47T9sdNgGrSip66ZQx0ZSgq9xY,43552 +gradio/templates/node/build/server/chunks/index38-C6u3TLsu.js.map,sha256=fLxBonpzi5vYeeaLhkOp7-_8i83yFZeWBYLssSqR3PI,139387 +gradio/templates/node/build/server/chunks/index39-CroaAz3c.js,sha256=CYvOeIalhTO8yNtQ5rbRfAgxMu0AP2DxyNHEsW_Fo-4,29073 +gradio/templates/node/build/server/chunks/index39-CroaAz3c.js.map,sha256=DcNoemixNM-Wa46wdjc2GNE_W5BKhKU6yzyYzRK3D1g,69562 +gradio/templates/node/build/server/chunks/index4-HDyePXPv.js,sha256=hfUhPzkrB41Z4ydekzJSRVCZ0MiMFlAvnL4YJIG4IqA,567 +gradio/templates/node/build/server/chunks/index4-HDyePXPv.js.map,sha256=tF9rwujzA8RY0jfTb4qV8eb9-Clrdx6UHRzQbnrsvok,1645 +gradio/templates/node/build/server/chunks/index40-yeMbQYW6.js,sha256=Ux9rizi_YIsN4glGfyDYLgDBiloiODFI5ZXgew21yek,23244 +gradio/templates/node/build/server/chunks/index40-yeMbQYW6.js.map,sha256=gjeN3gbh0Hrvb30UvZ8bBI6WI2Vo2yy6KnIwWaT5fBE,43403 +gradio/templates/node/build/server/chunks/index41-C3eLAb-q.js,sha256=P68MAeBWhM5TSt4Ee8RXsdudOn0bjzTKflrKdesqCYA,78866 +gradio/templates/node/build/server/chunks/index41-C3eLAb-q.js.map,sha256=MhHSfg_hRmjESJp0FNwVtboJPNgX2yBh9wYlS9QqLxU,103187 +gradio/templates/node/build/server/chunks/index42-B7jJ44rA.js,sha256=6u6r75XXmo_4uPikbcv4rPdfHv7Pbh2XWJl5gO8mY-Q,2677 +gradio/templates/node/build/server/chunks/index42-B7jJ44rA.js.map,sha256=XOc-mhzoe1L4sW8iG25lan5PN2R7d3mCNfbEuvIW9DA,4812 +gradio/templates/node/build/server/chunks/index56-DRAeGH6H.js,sha256=JAKDANVxz4if9bTMKJKwfA-qvyr305QwTgN0wjC_ZkI,12935 +gradio/templates/node/build/server/chunks/index56-DRAeGH6H.js.map,sha256=iHnU5bK3s_u-kWAAzfkBnm5VD45RgwFWGDdYC60llQ8,26811 +gradio/templates/node/build/server/chunks/index7-DcVoQjit.js,sha256=6Z05MTvgm4CEMP2FSjAyKncF1RIAU_aibA_mwNCc3Ek,525 +gradio/templates/node/build/server/chunks/index7-DcVoQjit.js.map,sha256=n5iF7vXx_ssl4y9UsCympia8DtjUo1YntCZKr7fciwI,1740 +gradio/templates/node/build/server/chunks/index8-DWEiEAhs.js,sha256=K3Qza35w8W9LQY5s5FbheSmxGg0vXKANLgWqcyNIQhM,1116 +gradio/templates/node/build/server/chunks/index8-DWEiEAhs.js.map,sha256=F1NpgWNYUflK2Q7qWK4TI48mEgqqJcJrXGlg12Ptrys,3724 +gradio/templates/node/build/server/chunks/init-Dm1OEjUU.js,sha256=j9wrrf8fPc7KM0TLWT2SyPe8tjr0V5Fsb7jnLSCHDxw,62705 +gradio/templates/node/build/server/chunks/init-Dm1OEjUU.js.map,sha256=1AXrTLylLBC7HAAV2U7ZRuyxvrjqoCxxa5SqX-noLyM,158612 +gradio/templates/node/build/server/chunks/ja-IeX0ScdE.js,sha256=Heb7R6vG91KD6NNdaFHFS7uEXo_mBVN3C9ZTbeyLaYU,5701 +gradio/templates/node/build/server/chunks/ja-IeX0ScdE.js.map,sha256=8dfPNMJFZM8uhiLfggZTTPAxXDsFe41jySBy8UER4qo,9200 +gradio/templates/node/build/server/chunks/jinja2-BOu_N3FT.js,sha256=Xq5vHM0fzSVLKYH1ZOhE9Q5Md7mu3BSaC-vdd8o5siI,2680 +gradio/templates/node/build/server/chunks/jinja2-BOu_N3FT.js.map,sha256=BS6FeQRhEzvBd0D2nFQWp6wr7aMKEBMbUXjrPXszNGI,7623 +gradio/templates/node/build/server/chunks/ko-CWBcxRwV.js,sha256=F_yfwnhHOqw5cEGl4X14bsQ1HlWAc4zoey_PYfByXNs,5098 +gradio/templates/node/build/server/chunks/ko-CWBcxRwV.js.map,sha256=IZ94QyiQD1iXcu1aKp9yWLdrPxndGGtLKkGc_osD2Xg,8597 +gradio/templates/node/build/server/chunks/lt-DuVbsrrG.js,sha256=vyCsEGVLuUUp-cKBN1RpVNzndkXGBJCdcxRmM7YuaQc,4924 +gradio/templates/node/build/server/chunks/lt-DuVbsrrG.js.map,sha256=yWywnJbGev0mky1NmR8dJs__jFZ_Va93_Khx1EqmcV8,8513 +gradio/templates/node/build/server/chunks/module-CipkLjW5.js,sha256=qsbBm5PIP4l6ojAVtanHfyqrPInncpAYvLjLZ7bmEHA,10004 +gradio/templates/node/build/server/chunks/module-CipkLjW5.js.map,sha256=IHmxCPX25NooTdwvDTMFk4Dg29Pbn_jOSVMNkJSK6n8,11350 +gradio/templates/node/build/server/chunks/module2-CbBHh9zs.js,sha256=8x0BfshPcblOHdhQ0clut6LNa2fVul5LuHmEfM1hi54,1668 +gradio/templates/node/build/server/chunks/module2-CbBHh9zs.js.map,sha256=pyqFTh4IB1_f1m2rd6OjJmrNvhQELlDSfCli1f9f2kU,5544 +gradio/templates/node/build/server/chunks/module3-DE6WvkeL.js,sha256=2ucV0rWq2923WMi_VTrqdBL11W4jb7buMTAwn3EGJbQ,91757 +gradio/templates/node/build/server/chunks/module3-DE6WvkeL.js.map,sha256=Fc4deh8BXlhu9QUz7Tj3lHRwtYaVKENNnUKATAQstpU,257675 +gradio/templates/node/build/server/chunks/nb-D08346Tf.js,sha256=WrJTJv5vgsT96fTFfbQn8hPR0X8MgJfrugRE5lQCG50,4518 +gradio/templates/node/build/server/chunks/nb-D08346Tf.js.map,sha256=ifmcegq4ORHwRaVs6NW6yJl4CCHtS1Rhrtu-EsuS1MI,8073 +gradio/templates/node/build/server/chunks/nl-C9vqu2l6.js,sha256=PkOOHjOky7L9TTbXRrlKKeDQj2FfRzfd0nRnvUEmDWk,4839 +gradio/templates/node/build/server/chunks/nl-C9vqu2l6.js.map,sha256=IQSQ995bYDswjNcYnCmSrTlp9cGE7LiMfpjlXUJDxNs,8428 +gradio/templates/node/build/server/chunks/pl-CCZ3iBe5.js,sha256=k4NpkH7z13kkylCkzd_GqKvJTrY_2-Z7bzNXc0ZEYZ0,4877 +gradio/templates/node/build/server/chunks/pl-CCZ3iBe5.js.map,sha256=l56pft6SS3hz_Z5U5_xlChevKO-wDds2mSMGz0cjSUQ,8456 +gradio/templates/node/build/server/chunks/pt-BR-DPuva9n4.js,sha256=AsbUALW8XU27Wy5wpQVLn9rQmhcXauFl7t_9zOOFLIQ,5035 +gradio/templates/node/build/server/chunks/pt-BR-DPuva9n4.js.map,sha256=RYBURzPFapgs57XV84O5SPzYUbk9ws215aLKbuvkqDs,8698 +gradio/templates/node/build/server/chunks/pt-B_nt5bpZ.js,sha256=kf0BCWvypbP3kb_xrGGs_U5S1DyGeQOw6UCnBPfklQk,4997 +gradio/templates/node/build/server/chunks/pt-B_nt5bpZ.js.map,sha256=lRWaRmHU2Ow86gVkCXKCrWaji1oOtw13bAKRxOVHkiM,8636 +gradio/templates/node/build/server/chunks/r-CxMAnsBX.js,sha256=zhRG--K-FyAKdHmTuhCDKUe73fGBcjLkWWmTHqvErx0,2986 +gradio/templates/node/build/server/chunks/r-CxMAnsBX.js.map,sha256=qDpkJID_mg2lWQRUWWGdmD-qH2DKuJgN_e_1Vy_HLuo,9387 +gradio/templates/node/build/server/chunks/ro-Ddw_SWeO.js,sha256=aBHzy8snlumzgDfH6nAKAPFbLiCZTeek6GXKsrySR_A,5023 +gradio/templates/node/build/server/chunks/ro-Ddw_SWeO.js.map,sha256=Z4PWo_58hnvKCfOkcTuz0Xe6r0MdWj3ti1qmtVTgZbA,8612 +gradio/templates/node/build/server/chunks/ru-hxtnGKGc.js,sha256=Kvvxa3CumbIHbZx3Mdc6m6ikx4tkJ9qqgIJsdLF1hWg,6968 +gradio/templates/node/build/server/chunks/ru-hxtnGKGc.js.map,sha256=kNOSBBVCN0WUTweRj9lqlwbU7dP8RnHTj05RKYJeK2M,10549 +gradio/templates/node/build/server/chunks/shell-fOTMLIXC.js,sha256=XjonQW3I3tAIHqVvUbclFi5RzpnuJ3gJqUz_E6Im-N0,2628 +gradio/templates/node/build/server/chunks/shell-fOTMLIXC.js.map,sha256=qWzEwHoqHmBspDy7ps-8mRA46iywL5z_QlwM5lPvMUo,8312 +gradio/templates/node/build/server/chunks/sql-CrwZCygc.js,sha256=0U3dojI0VuId2-vOxtych7q9PoJkH42WpPayjTVMh6A,37149 +gradio/templates/node/build/server/chunks/sql-CrwZCygc.js.map,sha256=lcVWU7LT4jQCZFEYM8aHuEK8yewP3W1kcIF88DyUSoM,49359 +gradio/templates/node/build/server/chunks/ssr-BO6k2UBO.js,sha256=a-4GgLKRdAtiukwPeZKq0BLOgWsGaYuuZYdcyA2rIXM,3281 +gradio/templates/node/build/server/chunks/ssr-BO6k2UBO.js.map,sha256=u6AtxygOIc0EL0E5jOCwTc8joTWGvDv_KMw6VxfNISc,11532 +gradio/templates/node/build/server/chunks/ssr-C3HYbsxA.js,sha256=HKZ3bXe1rvLVXgrwPcPRwcuvvorvM7uEpzzng_LATgQ,13985 +gradio/templates/node/build/server/chunks/ssr-C3HYbsxA.js.map,sha256=oLaE9-N_v5GUpGZcjqIVePIgHHGjSqG64nAtnutGy3o,71307 +gradio/templates/node/build/server/chunks/stex-DE2_jxrP.js,sha256=V2ipyfEQk5clOkPDIXDm0fDnaLUEADMeyU-XQ_cSGOA,3189 +gradio/templates/node/build/server/chunks/stex-DE2_jxrP.js.map,sha256=dvasz-HNebTouyN8yZUam4CjhBppUwUZubSY8bWST8w,9627 +gradio/templates/node/build/server/chunks/stores-D_Cz4lHU.js,sha256=9Q90eVMFrO35Y5bvpxeaob0_HPaWLeYvnggKu8YCSO8,474 +gradio/templates/node/build/server/chunks/stores-D_Cz4lHU.js.map,sha256=BsSIJ1JOpAxMQgpBRtKsHI_djhU8QUCDOLax-MdHlgM,1205 +gradio/templates/node/build/server/chunks/sv-CBaAzwhi.js,sha256=3PGEMVheaaSLWyn33UnX7vDnUW5gvfJldmCYZkLGk8A,4619 +gradio/templates/node/build/server/chunks/sv-CBaAzwhi.js.map,sha256=7mE9WzdqtSLhTEVRzL3_6bnavmkBf7OcqyW43W50X28,8178 +gradio/templates/node/build/server/chunks/ta-CIRcMeU1.js,sha256=M_0A3XPzeQmzSDxeDg1NJKqOisx97jKQYbrdzkawdRU,9786 +gradio/templates/node/build/server/chunks/ta-CIRcMeU1.js.map,sha256=CTDH6D-bSLq5bQPa1DTKoDl8TLIr37KtvtEUToYqJlA,13381 +gradio/templates/node/build/server/chunks/th-CWKCe4yc.js,sha256=SLmbeOnNGlVNhoPRWacmma2WvKgQDQLapMe-JqiaKYU,8000 +gradio/templates/node/build/server/chunks/th-CWKCe4yc.js.map,sha256=FnWz9SXHERliq91ENlipfwJTiZLvJOVVE4E3tnQyIHg,11553 +gradio/templates/node/build/server/chunks/tinycolor-BAU9cgwS.js,sha256=CdN4rWfBA5m61X3fNapr1O9-6AJVXN-kXV6eursi6-w,15325 +gradio/templates/node/build/server/chunks/tinycolor-BAU9cgwS.js.map,sha256=Dk4QrUoP5wnOblPQsbfqywuTNX38R2qTy8IKQImiIuY,50205 +gradio/templates/node/build/server/chunks/tr-BjNdPtGX.js,sha256=u05FCDXMbgGIHB4nbNoemzt5pRpVtqaR3zdxThDJGWY,4943 +gradio/templates/node/build/server/chunks/tr-BjNdPtGX.js.map,sha256=aDNBdBw4ssE-ErZXOz7Ji9ow6p650TuFpTmSlg3dvYw,8506 +gradio/templates/node/build/server/chunks/uk-DxkC9TjY.js,sha256=dMOQAwFXDNkOBtWNJViexqlfVQEy0k_hBZTUoyctyAQ,6921 +gradio/templates/node/build/server/chunks/uk-DxkC9TjY.js.map,sha256=eJ7qF9xWMRGwh9AY3kXxifBOkVHX1O7MaQglhDJ0ZmE,10502 +gradio/templates/node/build/server/chunks/ur-DPrEFG9j.js,sha256=N6fd0JVcHAaLaNzeKOw9ZyO2LOQ5Kv5NVqDDTsfKa9w,6526 +gradio/templates/node/build/server/chunks/ur-DPrEFG9j.js.map,sha256=5Ljd9ul0evpG0E-1y45rSnbvvuSYTfyDofciRCUpH9o,10103 +gradio/templates/node/build/server/chunks/uz-BUySSN8V.js,sha256=pOk-KR-DBCak_MOeHmeyeYnHKMrBZi-zOUxkYmvG6mA,4947 +gradio/templates/node/build/server/chunks/uz-BUySSN8V.js.map,sha256=7KqkGoIHJGTAgXBXJ_VT335m00RYS-UalLyhPe97gcI,8540 +gradio/templates/node/build/server/chunks/vega-embed.module-DsI9BZ1D.js,sha256=6gmHZ7G6Wel7ASiSN8nPeA9HbglIzcYG7pu8ex-lODE,301713 +gradio/templates/node/build/server/chunks/vega-embed.module-DsI9BZ1D.js.map,sha256=wwkT5_smJTt59YniAlLPtG7oCnweaTDnLQ_zJhGbW50,919195 +gradio/templates/node/build/server/chunks/vega-interpreter.module-D8ONVnUK.js,sha256=8nJJN5oO_hAiA80fJYuEYa_lojHG1jI4G7B8wToTPuc,565702 +gradio/templates/node/build/server/chunks/vega-interpreter.module-D8ONVnUK.js.map,sha256=jeJIM3uZe6dWlu4eVEmY8Wjk9suKH-P2RbR3ieFNJTk,1949484 +gradio/templates/node/build/server/chunks/webworkerAll-COumIYOS.js,sha256=Zn3d0DAaDWz9usAlQPL8ihrBZgRBUnM2EMu3jA0I3Ec,417 +gradio/templates/node/build/server/chunks/webworkerAll-COumIYOS.js.map,sha256=B-AD4H8p17HmKwPTzWwubNhQWC_TkVxIMtHLc32-Iec,117 +gradio/templates/node/build/server/chunks/wrapper-CYei9jbK.js,sha256=Ugi5dJ2h4BcAzcZCGfkQvr6uShAwoGyqR-8NoMA-fF8,47573 +gradio/templates/node/build/server/chunks/wrapper-CYei9jbK.js.map,sha256=I0xVdgmdXVU8XGR_jTPMSt8hFsDBoMmnxgDdg-mlL40,134472 +gradio/templates/node/build/server/chunks/yaml-C6fZICTl.js,sha256=8F5Uz7DatCgWjXNTHH8uDtHxHHNpblDd__p0Q-mIjwg,1577 +gradio/templates/node/build/server/chunks/yaml-C6fZICTl.js.map,sha256=nvVioI6ThJS3mF-uDX3DSbz4ph1komkgWCqtwRss6bM,4466 +gradio/templates/node/build/server/chunks/zh-CN-CPutFXEq.js,sha256=9Zv-PA6FwfkNbdW-rtx2lfvnXaPZvsSHdpE-8D8H2cU,4424 +gradio/templates/node/build/server/chunks/zh-CN-CPutFXEq.js.map,sha256=R4qoHwBRSiOQLvRJMYceVCmFQKbZANP2oP2vm49QzAA,7919 +gradio/templates/node/build/server/chunks/zh-TW-CFo1-iyM.js,sha256=FFHKhslz91pco04fwTKwpixlktygawaC8Ows423Cx0A,4402 +gradio/templates/node/build/server/chunks/zh-TW-CFo1-iyM.js.map,sha256=5iwjpXyADyt1WV_gw0RVtQyvqZJCak31z3lnX9r8bJs,7897 +gradio/templates/node/build/server/index.js,sha256=AK4m_yYSEfERgRbHvnIvdkdQYkQNuvZU4-4J78eErxo,56984 +gradio/templates/node/build/server/index.js.map,sha256=LElKIzh0Bn2XnWhZZzoUl7EESGG3zmA1yR85NDOzX1M,166662 +gradio/templates/node/build/server/manifest.js,sha256=5a8kwApEul6J25eddwK1Snc9o1hg5OOkW0zMfkXq6LY,1196 +gradio/templates/node/build/server/manifest.js.map,sha256=ExKboMSqfYY21wR81cERCpPtAi6sL-EA4zm312Wq2qw,2620 +gradio/templates/node/build/shims.js,sha256=a5PioTkIyBQKA-Ymh_cZEYZaoNlHzUaRTwvcnnt0mOs,726 +gradio/templates/register.mjs,sha256=KGuBPFzyHGapIVZqUYuOnuWrWO3YS9jhb66jwr-oChc,83 +gradio/test_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +gradio/test_data/__pycache__/__init__.cpython-313.pyc,, +gradio/test_data/__pycache__/blocks_configs.cpython-313.pyc,, +gradio/test_data/blocks_configs.py,sha256=ahwjrVEo3i0GtvmxISqcdyC0vcyuGcTqmYjQF758XGA,39078 +gradio/test_data/cheetah1-copy.jpg,sha256=NVUL-7qZblnCQq8A9qFKnA0FXfvFKtBpoaTowcOcoJU,20552 +gradio/test_data/cheetah2.jpg,sha256=aILnFKpD1gpCn3BKXd069LNwj4lwGzvMliYSE0mFN5U,72783 +gradio/test_data/flagged_no_log/a.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +gradio/test_data/flagged_no_log/b.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +gradio/test_data/flagged_no_log/c.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +gradio/test_data/flagged_with_log/log.csv,sha256=Spi96R_dEQk9_iapnIaQSnP4QMDLC-il8q-dro9U3I0,25 +gradio/test_data/rectangles.gif,sha256=-EvY6BHOiwIRxxIXjoFdyfnQibzytrWEEM8a4SzLwJA,1699 +gradio/test_data/test_audio.mp3,sha256=C3tKwGw8uXzCQgB_R54uCfK5xQAi0_FocrqvZRlduE8,11717 +gradio/test_data/test_audio.wav,sha256=LZmSH5nFApJR4jcqcKugsPCKbt1KLc5fbvwnwO7xixU,47148 +gradio/test_data/test_image.png,sha256=OWx7U1hp5EGP2dlldjXlE0xrpiaBkFnwsm6bj7yCp2E,1951 +gradio/themes/__init__.py,sha256=kq02Qf8vsYe3rUUDFpH1u_FO5nAHx9k4RVFEaWg4WKw,865 +gradio/themes/__pycache__/__init__.cpython-313.pyc,, +gradio/themes/__pycache__/app.cpython-313.pyc,, +gradio/themes/__pycache__/base.cpython-313.pyc,, +gradio/themes/__pycache__/builder_app.cpython-313.pyc,, +gradio/themes/__pycache__/citrus.cpython-313.pyc,, +gradio/themes/__pycache__/default.cpython-313.pyc,, +gradio/themes/__pycache__/glass.cpython-313.pyc,, +gradio/themes/__pycache__/monochrome.cpython-313.pyc,, +gradio/themes/__pycache__/ocean.cpython-313.pyc,, +gradio/themes/__pycache__/origin.cpython-313.pyc,, +gradio/themes/__pycache__/soft.cpython-313.pyc,, +gradio/themes/__pycache__/upload_theme.cpython-313.pyc,, +gradio/themes/app.py,sha256=GKsFTwhmXnRrXstnm_PD5AA0IyuoDYWdWG56ATIx7yg,4905 +gradio/themes/base.py,sha256=_22yJ7pSx7--mUbFVCdbwBR7gy-mjUzpk1ySh5yuhnQ,99673 +gradio/themes/builder_app.py,sha256=KZuUfS8orALmV4iFEBU6m7AZlGQnbuaLqi91Z2fkqrc,41332 +gradio/themes/citrus.py,sha256=zJQ5A-sben1nsb76Ld1b7UrTe8i1EJwXBaEqbbZscPo,6090 +gradio/themes/default.py,sha256=gUfofZ5c7yWt1twe4k_VFkYyR2ndNGOSgQtzrv-8p9A,3946 +gradio/themes/glass.py,sha256=bwXX00ftcbJQkhO-AHa1cy8jHq5Tv2sRurg50h24yBk,4790 +gradio/themes/monochrome.py,sha256=XF_U7_TF7FDaMP-IKD-Pvtzf8yyeXqzPPlZcZjiS1YI,4323 +gradio/themes/ocean.py,sha256=4GauHHWjctRj7CtGpAyJGLqV23_9GgPCf7wVXmetG3Q,3826 +gradio/themes/origin.py,sha256=JXfp3Jmsh2VubKKBFUlpxNZCoScfvG-1SXPDll4IGwc,6022 +gradio/themes/soft.py,sha256=R9_PH9WupPiMH7lXgTrUPZ85qL9sgOJxQUTqhmBWKeQ,4823 +gradio/themes/upload_theme.py,sha256=D61HgBLfmypPT3MSqPz9Um1B1ArH0zD-m9rQwZCXgjM,1599 +gradio/themes/utils/__init__.py,sha256=b20V66a-NpTzOSVFMcUTlbDlISL4ysZjOAJXEbyIx8k,179 +gradio/themes/utils/__pycache__/__init__.cpython-313.pyc,, +gradio/themes/utils/__pycache__/colors.cpython-313.pyc,, +gradio/themes/utils/__pycache__/fonts.cpython-313.pyc,, +gradio/themes/utils/__pycache__/readme_content.cpython-313.pyc,, +gradio/themes/utils/__pycache__/semver_match.cpython-313.pyc,, +gradio/themes/utils/__pycache__/sizes.cpython-313.pyc,, +gradio/themes/utils/__pycache__/theme_dropdown.cpython-313.pyc,, +gradio/themes/utils/colors.py,sha256=wADPDozHcSqw06FWvKoCEB1zeRTbB4SIyageeWzUcPs,6576 +gradio/themes/utils/fonts.py,sha256=8aEM4ez_x5lIaXxPfUIFwUy2bKuPH-h5iT3RxLm1gOs,3363 +gradio/themes/utils/readme_content.py,sha256=CZrKKzEkmm5tk9WwjmTqVvzCNEif_f8dA52Dk_s4UQs,344 +gradio/themes/utils/semver_match.py,sha256=v9LWYZL6G9YYcXnXJrtGp8kI_MTUlwV8SMR1ZbkelJM,1226 +gradio/themes/utils/sizes.py,sha256=9U1z9Hdoc_cE8_zonRsnQjhS03g6ar3RBngXjIoK-Y8,2109 +gradio/themes/utils/theme_dropdown.py,sha256=qtDcenXKzA6Rw3a09RkEkXnmjODeY-ACx6V9Ab5NLm4,1649 +gradio/tunneling.py,sha256=Yx7DIj7CMx8wbg7ZX7SZ7yfYgVskPrCWtl5Xbx6HqTM,7403 +gradio/utils.py,sha256=-DfKfuRQkoaqZnRJsTwlQZM4mi3pzot40iflMG0qTwc,57712 diff --git a/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/WHEEL b/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..12228d414b6cfed7c39d3781c85c63256a1d7fb5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.27.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/entry_points.txt b/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/entry_points.txt new file mode 100644 index 0000000000000000000000000000000000000000..de8d177383c9fac8bb90bf4c0feac388afbb59bd --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +gradio = gradio.cli:cli +upload_theme = gradio.themes.upload_theme:main diff --git a/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/licenses/LICENSE b/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/licenses/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio-5.50.0.dist-info/licenses/LICENSE @@ -0,0 +1,201 @@ + 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/python3.13/site-packages/gradio/templates.py b/.venv/lib/python3.13/site-packages/gradio/templates.py new file mode 100644 index 0000000000000000000000000000000000000000..ca065611629e4d43a49327d79a7fffcec19504a6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates.py @@ -0,0 +1,867 @@ +from __future__ import annotations + +from collections.abc import Callable, Iterable, Sequence +from pathlib import Path +from typing import TYPE_CHECKING, Any, Literal + +import numpy as np +import PIL.Image + +from gradio import components +from gradio.components.audio import WaveformOptions +from gradio.components.image_editor import Brush, Eraser, LayerOptions, WebcamOptions +from gradio.components.textbox import InputHTMLAttributes +from gradio.i18n import I18nData + +if TYPE_CHECKING: + from gradio.components import Timer + + +class TextArea(components.Textbox): + """ + Sets: lines=7 + """ + + is_template = True + + def __init__( + self, + value: str | Callable | None = None, + *, + lines: int = 7, + max_lines: int = 20, + placeholder: str | None = None, + label: str | I18nData | None = None, + info: str | I18nData | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + show_label: bool | None = None, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] | Literal["hidden"] = True, + elem_id: str | None = None, + autofocus: bool = False, + autoscroll: bool = True, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + type: Literal["text", "password", "email"] = "text", + text_align: Literal["left", "right"] | None = None, + rtl: bool = False, + show_copy_button: bool = False, + max_length: int | None = None, + submit_btn: str | bool | None = False, + stop_btn: str | bool | None = False, + html_attributes: InputHTMLAttributes | None = None, + ): + super().__init__( + value=value, + lines=lines, + max_lines=max_lines, + placeholder=placeholder, + label=label, + info=info, + every=every, + inputs=inputs, + show_label=show_label, + container=container, + scale=scale, + min_width=min_width, + interactive=interactive, + visible=visible, + elem_id=elem_id, + autofocus=autofocus, + autoscroll=autoscroll, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + type=type, + text_align=text_align, + rtl=rtl, + show_copy_button=show_copy_button, + max_length=max_length, + submit_btn=submit_btn, + stop_btn=stop_btn, + html_attributes=html_attributes, + ) + + +class Sketchpad(components.ImageEditor): + """ + Sets: sources=(), brush=Brush(colors=["#000000"], color_mode="fixed") + """ + + is_template = True + + def __init__( + self, + value: str | PIL.Image.Image | np.ndarray | None = None, + *, + height: int | str | None = None, + width: int | str | None = None, + image_mode: Literal[ + "1", "L", "P", "RGB", "RGBA", "CMYK", "YCbCr", "LAB", "HSV", "I", "F" + ] = "RGBA", + sources: Iterable[Literal["upload", "webcam", "clipboard"]] = (), + type: Literal["numpy", "pil", "filepath"] = "numpy", + label: str | I18nData | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + show_label: bool | None = None, + show_download_button: bool = True, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + placeholder: str | None = None, + mirror_webcam: bool | None = None, + webcam_options: WebcamOptions | None = None, + show_share_button: bool | None = None, + _selectable: bool = False, + crop_size: tuple[int | float, int | float] | str | None = None, + transforms: Iterable[Literal["crop"]] = ("crop",), + eraser: Eraser | None = None, + brush: Brush | None = None, + format: str = "webp", + canvas_size: tuple[int, int] = (800, 800), + fixed_canvas: bool = False, + show_fullscreen_button: bool = True, + layers: LayerOptions | bool = True, + ): + if not brush: + brush = Brush(colors=["#000000"], color_mode="fixed") + super().__init__( + value=value, + height=height, + width=width, + image_mode=image_mode, + sources=sources, + type=type, + label=label, + every=every, + inputs=inputs, + show_label=show_label, + show_download_button=show_download_button, + container=container, + scale=scale, + min_width=min_width, + interactive=interactive, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + placeholder=placeholder, + mirror_webcam=mirror_webcam, + webcam_options=webcam_options, + show_share_button=show_share_button, + _selectable=_selectable, + crop_size=crop_size, + transforms=transforms, + eraser=eraser, + brush=brush, + format=format, + layers=layers, + canvas_size=canvas_size, + show_fullscreen_button=show_fullscreen_button, + fixed_canvas=fixed_canvas, + ) + + +class Paint(components.ImageEditor): + """ + Sets: sources=() + """ + + is_template = True + + def __init__( + self, + value: str | PIL.Image.Image | np.ndarray | None = None, + *, + height: int | str | None = None, + width: int | str | None = None, + image_mode: Literal[ + "1", "L", "P", "RGB", "RGBA", "CMYK", "YCbCr", "LAB", "HSV", "I", "F" + ] = "RGBA", + sources: Iterable[Literal["upload", "webcam", "clipboard"]] = (), + type: Literal["numpy", "pil", "filepath"] = "numpy", + label: str | I18nData | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + show_label: bool | None = None, + show_download_button: bool = True, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + mirror_webcam: bool | None = None, + webcam_options: WebcamOptions | None = None, + show_share_button: bool | None = None, + _selectable: bool = False, + crop_size: tuple[int | float, int | float] | str | None = None, + transforms: Iterable[Literal["crop"]] = ("crop",), + eraser: Eraser | None = None, + brush: Brush | None = None, + format: str = "webp", + layers: LayerOptions | bool = True, + canvas_size: tuple[int, int] = (800, 800), + fixed_canvas: bool = False, + show_fullscreen_button: bool = True, + placeholder: str | None = None, + ): + super().__init__( + value=value, + height=height, + width=width, + image_mode=image_mode, + sources=sources, + type=type, + label=label, + every=every, + inputs=inputs, + show_label=show_label, + show_download_button=show_download_button, + container=container, + scale=scale, + min_width=min_width, + interactive=interactive, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + mirror_webcam=mirror_webcam, + webcam_options=webcam_options, + show_share_button=show_share_button, + _selectable=_selectable, + crop_size=crop_size, + transforms=transforms, + eraser=eraser, + brush=brush, + format=format, + layers=layers, + canvas_size=canvas_size, + show_fullscreen_button=show_fullscreen_button, + placeholder=placeholder, + fixed_canvas=fixed_canvas, + ) + + +class ImageMask(components.ImageEditor): + """ + Sets: brush=Brush(colors=["#000000"], color_mode="fixed") + """ + + is_template = True + + def __init__( + self, + value: str | PIL.Image.Image | np.ndarray | None = None, + *, + height: int | str | None = None, + width: int | str | None = None, + image_mode: Literal[ + "1", "L", "P", "RGB", "RGBA", "CMYK", "YCbCr", "LAB", "HSV", "I", "F" + ] = "RGBA", + sources: Iterable[Literal["upload", "webcam", "clipboard"]] = ( + "upload", + "webcam", + "clipboard", + ), + type: Literal["numpy", "pil", "filepath"] = "numpy", + label: str | I18nData | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + show_label: bool | None = None, + show_download_button: bool = True, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + placeholder: str | None = None, + mirror_webcam: bool | None = None, + show_share_button: bool | None = None, + _selectable: bool = False, + crop_size: tuple[int | float, int | float] | str | None = None, + transforms: Iterable[Literal["crop"]] = ("crop",), + eraser: Eraser | None = None, + brush: Brush | None = None, + format: str = "webp", + layers: LayerOptions | bool = False, + canvas_size: tuple[int, int] = (800, 800), + fixed_canvas: bool = False, + show_fullscreen_button: bool = True, + webcam_options: WebcamOptions | None = None, + ): + if not brush: + brush = Brush(colors=["#000000"], color_mode="fixed") + super().__init__( + value=value, + height=height, + width=width, + image_mode=image_mode, + sources=sources, + type=type, + label=label, + every=every, + inputs=inputs, + show_label=show_label, + show_download_button=show_download_button, + container=container, + scale=scale, + min_width=min_width, + interactive=interactive, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + placeholder=placeholder, + mirror_webcam=mirror_webcam, + webcam_options=webcam_options, + show_share_button=show_share_button, + _selectable=_selectable, + crop_size=crop_size, + transforms=transforms, + eraser=eraser, + brush=brush, + format=format, + layers=layers, + canvas_size=canvas_size, + show_fullscreen_button=show_fullscreen_button, + fixed_canvas=fixed_canvas, + ) + + +class PlayableVideo(components.Video): + """ + Sets: format="mp4" + """ + + is_template = True + + def __init__( + self, + value: ( + str | Path | tuple[str | Path, str | Path | None] | Callable | None + ) = None, + *, + format: Literal["mp4"] = "mp4", + sources: ( + list[Literal["upload", "webcam"]] | Literal["upload", "webcam"] | None + ) = None, + height: int | str | None = None, + width: int | str | None = None, + label: str | I18nData | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + show_label: bool | None = None, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + mirror_webcam: bool | None = None, + webcam_options: WebcamOptions | None = None, + include_audio: bool | None = None, + autoplay: bool = False, + show_share_button: bool | None = None, + show_download_button: bool | None = None, + min_length: int | None = None, + max_length: int | None = None, + loop: bool = False, + streaming: bool = False, + watermark: str | Path | None = None, + webcam_constraints: dict[str, dict[str, int | str]] | None = None, + ): + sources = ["upload"] + super().__init__( + value=value, + format=format, + sources=sources, # type: ignore + height=height, + width=width, + label=label, + every=every, + inputs=inputs, + show_label=show_label, + container=container, + scale=scale, + min_width=min_width, + interactive=interactive, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + mirror_webcam=mirror_webcam, + include_audio=include_audio, + autoplay=autoplay, + show_share_button=show_share_button, + show_download_button=show_download_button, + min_length=min_length, + max_length=max_length, + loop=loop, + streaming=streaming, + watermark=watermark, + webcam_constraints=webcam_constraints, + webcam_options=webcam_options, + ) + + +class Microphone(components.Audio): + """ + Sets: sources=["microphone"] + """ + + is_template = True + + def __init__( + self, + value: str | Path | tuple[int, np.ndarray] | Callable | None = None, + *, + sources: ( + list[Literal["upload", "microphone"]] + | Literal["upload", "microphone"] + | None + ) = None, + type: Literal["numpy", "filepath"] = "numpy", + label: str | I18nData | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + show_label: bool | None = None, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + streaming: bool = False, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + format: Literal["wav", "mp3"] = "wav", + autoplay: bool = False, + show_download_button: bool | None = None, + show_share_button: bool | None = None, + editable: bool = True, + min_length: int | None = None, + max_length: int | None = None, + waveform_options: WaveformOptions | dict | None = None, + loop: bool = False, + recording: bool = False, + subtitles: str | Path | None = None, + ): + sources = ["microphone"] + super().__init__( + value, + sources=sources, + type=type, + label=label, + every=every, + inputs=inputs, + show_label=show_label, + container=container, + scale=scale, + min_width=min_width, + interactive=interactive, + visible=visible, + streaming=streaming, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + format=format, + autoplay=autoplay, + show_download_button=show_download_button, + show_share_button=show_share_button, + editable=editable, + min_length=min_length, + max_length=max_length, + waveform_options=waveform_options, + loop=loop, + recording=recording, + subtitles=subtitles, + ) + + +class Files(components.File): + """ + Sets: file_count="multiple" + """ + + is_template = True + + def __init__( + self, + value: str | list[str] | Callable | None = None, + *, + file_count: Literal["multiple"] = "multiple", + file_types: list[str] | None = None, + type: Literal["filepath", "binary"] = "filepath", + label: str | I18nData | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + show_label: bool | None = None, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + height: int | float | None = None, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + allow_reordering: bool = False, + ): + super().__init__( + value, + file_count=file_count, + file_types=file_types, + type=type, + label=label, + every=every, + inputs=inputs, + show_label=show_label, + container=container, + scale=scale, + min_width=min_width, + height=height, + interactive=interactive, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + allow_reordering=allow_reordering, + ) + + +class Numpy(components.Dataframe): + """ + Sets: type="numpy" + """ + + is_template = True + + def __init__( + self, + value: list[list[Any]] | Callable | None = None, + *, + headers: list[str] | None = None, + row_count: int | tuple[int, str] = (1, "dynamic"), + col_count: int | tuple[int, str] | None = None, + datatype: ( + Literal["str", "number", "bool", "date", "markdown", "html"] + | Sequence[Literal["str", "number", "bool", "date", "markdown", "html"]] + ) = "str", + type: Literal["numpy"] = "numpy", + latex_delimiters: list[dict[str, str | bool]] | None = None, + label: str | I18nData | None = None, + show_label: bool | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + max_height: int = 500, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + wrap: bool = False, + line_breaks: bool = True, + column_widths: list[str | int] | None = None, + show_row_numbers: bool = False, + show_search: Literal["none", "search", "filter"] = "none", + static_columns: list[int] | None = None, + pinned_columns: int | None = None, + show_fullscreen_button: bool = False, + max_chars: int | None = None, + show_copy_button: bool = False, + ): + super().__init__( + value=value, + headers=headers, + row_count=row_count, + col_count=col_count, + datatype=datatype, + type=type, + label=label, + show_label=show_label, + interactive=interactive, + visible=visible, + elem_id=elem_id, + wrap=wrap, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + line_breaks=line_breaks, + column_widths=column_widths, + every=every, + inputs=inputs, + max_height=max_height, + scale=scale, + latex_delimiters=latex_delimiters, + min_width=min_width, + show_row_numbers=show_row_numbers, + show_search=show_search, + pinned_columns=pinned_columns, + show_fullscreen_button=show_fullscreen_button, + max_chars=max_chars, + show_copy_button=show_copy_button, + static_columns=static_columns, + ) + + +class Matrix(components.Dataframe): + """ + Sets: type="array" + """ + + is_template = True + + def __init__( + self, + value: list[list[Any]] | Callable | None = None, + *, + headers: list[str] | None = None, + row_count: int | tuple[int, str] = (1, "dynamic"), + col_count: int | tuple[int, str] | None = None, + datatype: ( + Literal["str", "number", "bool", "date", "markdown", "html"] + | Sequence[Literal["str", "number", "bool", "date", "markdown", "html"]] + ) = "str", + type: Literal["array"] = "array", + latex_delimiters: list[dict[str, str | bool]] | None = None, + label: str | I18nData | None = None, + show_label: bool | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + max_height: int = 500, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + wrap: bool = False, + line_breaks: bool = True, + column_widths: list[str | int] | None = None, + show_row_numbers: bool = False, + show_search: Literal["none", "search", "filter"] = "none", + pinned_columns: int | None = None, + show_fullscreen_button: bool = False, + max_chars: int | None = None, + show_copy_button: bool = False, + static_columns: list[int] | None = None, + ): + super().__init__( + value=value, + headers=headers, + row_count=row_count, + col_count=col_count, + datatype=datatype, + type=type, + label=label, + show_label=show_label, + interactive=interactive, + visible=visible, + elem_id=elem_id, + wrap=wrap, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + line_breaks=line_breaks, + column_widths=column_widths, + every=every, + inputs=inputs, + max_height=max_height, + scale=scale, + latex_delimiters=latex_delimiters, + min_width=min_width, + show_row_numbers=show_row_numbers, + show_search=show_search, + pinned_columns=pinned_columns, + show_fullscreen_button=show_fullscreen_button, + max_chars=max_chars, + show_copy_button=show_copy_button, + static_columns=static_columns, + ) + + +class List(components.Dataframe): + """ + Sets: type="array", col_count=1 + """ + + is_template = True + + def __init__( + self, + value: list[list[Any]] | Callable | None = None, + *, + headers: list[str] | None = None, + row_count: int | tuple[int, str] = (1, "dynamic"), + col_count: Literal[1] = 1, + datatype: ( + Literal["str", "number", "bool", "date", "markdown", "html"] + | Sequence[Literal["str", "number", "bool", "date", "markdown", "html"]] + ) = "str", + type: Literal["array"] = "array", + latex_delimiters: list[dict[str, str | bool]] | None = None, + label: str | I18nData | None = None, + show_label: bool | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + max_height: int = 500, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + wrap: bool = False, + line_breaks: bool = True, + column_widths: list[str | int] | None = None, + show_row_numbers: bool = False, + show_search: Literal["none", "search", "filter"] = "none", + pinned_columns: int | None = None, + show_fullscreen_button: bool = False, + max_chars: int | None = None, + show_copy_button: bool = False, + static_columns: list[int] | None = None, + ): + super().__init__( + value=value, + headers=headers, + row_count=row_count, + col_count=col_count, + datatype=datatype, + type=type, + label=label, + show_label=show_label, + interactive=interactive, + visible=visible, + elem_id=elem_id, + wrap=wrap, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + line_breaks=line_breaks, + column_widths=column_widths, + every=every, + inputs=inputs, + max_height=max_height, + scale=scale, + latex_delimiters=latex_delimiters, + min_width=min_width, + show_row_numbers=show_row_numbers, + show_search=show_search, + static_columns=static_columns, + pinned_columns=pinned_columns, + show_fullscreen_button=show_fullscreen_button, + max_chars=max_chars, + show_copy_button=show_copy_button, + ) + + +Mic = Microphone diff --git a/.venv/lib/python3.13/site-packages/gradio/templates.pyi b/.venv/lib/python3.13/site-packages/gradio/templates.pyi new file mode 100644 index 0000000000000000000000000000000000000000..b0848577d77aa263501561d71305cb01357e9355 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates.pyi @@ -0,0 +1,918 @@ +from __future__ import annotations + +from collections.abc import Callable, Iterable, Sequence +from pathlib import Path +from typing import TYPE_CHECKING, Any, Literal + +import numpy as np +import PIL.Image + +from gradio import components +from gradio.components.audio import WaveformOptions +from gradio.components.image_editor import Brush, Eraser, LayerOptions, WebcamOptions +from gradio.components.textbox import InputHTMLAttributes +from gradio.i18n import I18nData + +if TYPE_CHECKING: + from gradio.components import Timer + +from gradio.events import Dependency + +class TextArea(components.Textbox): + """ + Sets: lines=7 + """ + + is_template = True + + def __init__( + self, + value: str | Callable | None = None, + *, + lines: int = 7, + max_lines: int = 20, + placeholder: str | None = None, + label: str | I18nData | None = None, + info: str | I18nData | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + show_label: bool | None = None, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] | Literal["hidden"] = True, + elem_id: str | None = None, + autofocus: bool = False, + autoscroll: bool = True, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + type: Literal["text", "password", "email"] = "text", + text_align: Literal["left", "right"] | None = None, + rtl: bool = False, + show_copy_button: bool = False, + max_length: int | None = None, + submit_btn: str | bool | None = False, + stop_btn: str | bool | None = False, + html_attributes: InputHTMLAttributes | None = None, + ): + super().__init__( + value=value, + lines=lines, + max_lines=max_lines, + placeholder=placeholder, + label=label, + info=info, + every=every, + inputs=inputs, + show_label=show_label, + container=container, + scale=scale, + min_width=min_width, + interactive=interactive, + visible=visible, + elem_id=elem_id, + autofocus=autofocus, + autoscroll=autoscroll, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + type=type, + text_align=text_align, + rtl=rtl, + show_copy_button=show_copy_button, + max_length=max_length, + submit_btn=submit_btn, + stop_btn=stop_btn, + html_attributes=html_attributes, + ) + from typing import Callable, Literal, Sequence, Any, TYPE_CHECKING + from gradio.blocks import Block + if TYPE_CHECKING: + from gradio.components import Timer + from gradio.components.base import Component + + +class Sketchpad(components.ImageEditor): + """ + Sets: sources=(), brush=Brush(colors=["#000000"], color_mode="fixed") + """ + + is_template = True + + def __init__( + self, + value: str | PIL.Image.Image | np.ndarray | None = None, + *, + height: int | str | None = None, + width: int | str | None = None, + image_mode: Literal[ + "1", "L", "P", "RGB", "RGBA", "CMYK", "YCbCr", "LAB", "HSV", "I", "F" + ] = "RGBA", + sources: Iterable[Literal["upload", "webcam", "clipboard"]] = (), + type: Literal["numpy", "pil", "filepath"] = "numpy", + label: str | I18nData | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + show_label: bool | None = None, + show_download_button: bool = True, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + placeholder: str | None = None, + mirror_webcam: bool | None = None, + webcam_options: WebcamOptions | None = None, + show_share_button: bool | None = None, + _selectable: bool = False, + crop_size: tuple[int | float, int | float] | str | None = None, + transforms: Iterable[Literal["crop"]] = ("crop",), + eraser: Eraser | None = None, + brush: Brush | None = None, + format: str = "webp", + canvas_size: tuple[int, int] = (800, 800), + fixed_canvas: bool = False, + show_fullscreen_button: bool = True, + layers: LayerOptions | bool = True, + ): + if not brush: + brush = Brush(colors=["#000000"], color_mode="fixed") + super().__init__( + value=value, + height=height, + width=width, + image_mode=image_mode, + sources=sources, + type=type, + label=label, + every=every, + inputs=inputs, + show_label=show_label, + show_download_button=show_download_button, + container=container, + scale=scale, + min_width=min_width, + interactive=interactive, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + placeholder=placeholder, + mirror_webcam=mirror_webcam, + webcam_options=webcam_options, + show_share_button=show_share_button, + _selectable=_selectable, + crop_size=crop_size, + transforms=transforms, + eraser=eraser, + brush=brush, + format=format, + layers=layers, + canvas_size=canvas_size, + show_fullscreen_button=show_fullscreen_button, + fixed_canvas=fixed_canvas, + ) + from typing import Callable, Literal, Sequence, Any, TYPE_CHECKING + from gradio.blocks import Block + if TYPE_CHECKING: + from gradio.components import Timer + from gradio.components.base import Component + + +class Paint(components.ImageEditor): + """ + Sets: sources=() + """ + + is_template = True + + def __init__( + self, + value: str | PIL.Image.Image | np.ndarray | None = None, + *, + height: int | str | None = None, + width: int | str | None = None, + image_mode: Literal[ + "1", "L", "P", "RGB", "RGBA", "CMYK", "YCbCr", "LAB", "HSV", "I", "F" + ] = "RGBA", + sources: Iterable[Literal["upload", "webcam", "clipboard"]] = (), + type: Literal["numpy", "pil", "filepath"] = "numpy", + label: str | I18nData | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + show_label: bool | None = None, + show_download_button: bool = True, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + mirror_webcam: bool | None = None, + webcam_options: WebcamOptions | None = None, + show_share_button: bool | None = None, + _selectable: bool = False, + crop_size: tuple[int | float, int | float] | str | None = None, + transforms: Iterable[Literal["crop"]] = ("crop",), + eraser: Eraser | None = None, + brush: Brush | None = None, + format: str = "webp", + layers: LayerOptions | bool = True, + canvas_size: tuple[int, int] = (800, 800), + fixed_canvas: bool = False, + show_fullscreen_button: bool = True, + placeholder: str | None = None, + ): + super().__init__( + value=value, + height=height, + width=width, + image_mode=image_mode, + sources=sources, + type=type, + label=label, + every=every, + inputs=inputs, + show_label=show_label, + show_download_button=show_download_button, + container=container, + scale=scale, + min_width=min_width, + interactive=interactive, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + mirror_webcam=mirror_webcam, + webcam_options=webcam_options, + show_share_button=show_share_button, + _selectable=_selectable, + crop_size=crop_size, + transforms=transforms, + eraser=eraser, + brush=brush, + format=format, + layers=layers, + canvas_size=canvas_size, + show_fullscreen_button=show_fullscreen_button, + placeholder=placeholder, + fixed_canvas=fixed_canvas, + ) + from typing import Callable, Literal, Sequence, Any, TYPE_CHECKING + from gradio.blocks import Block + if TYPE_CHECKING: + from gradio.components import Timer + from gradio.components.base import Component + + +class ImageMask(components.ImageEditor): + """ + Sets: brush=Brush(colors=["#000000"], color_mode="fixed") + """ + + is_template = True + + def __init__( + self, + value: str | PIL.Image.Image | np.ndarray | None = None, + *, + height: int | str | None = None, + width: int | str | None = None, + image_mode: Literal[ + "1", "L", "P", "RGB", "RGBA", "CMYK", "YCbCr", "LAB", "HSV", "I", "F" + ] = "RGBA", + sources: Iterable[Literal["upload", "webcam", "clipboard"]] = ( + "upload", + "webcam", + "clipboard", + ), + type: Literal["numpy", "pil", "filepath"] = "numpy", + label: str | I18nData | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + show_label: bool | None = None, + show_download_button: bool = True, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + placeholder: str | None = None, + mirror_webcam: bool | None = None, + show_share_button: bool | None = None, + _selectable: bool = False, + crop_size: tuple[int | float, int | float] | str | None = None, + transforms: Iterable[Literal["crop"]] = ("crop",), + eraser: Eraser | None = None, + brush: Brush | None = None, + format: str = "webp", + layers: LayerOptions | bool = False, + canvas_size: tuple[int, int] = (800, 800), + fixed_canvas: bool = False, + show_fullscreen_button: bool = True, + webcam_options: WebcamOptions | None = None, + ): + if not brush: + brush = Brush(colors=["#000000"], color_mode="fixed") + super().__init__( + value=value, + height=height, + width=width, + image_mode=image_mode, + sources=sources, + type=type, + label=label, + every=every, + inputs=inputs, + show_label=show_label, + show_download_button=show_download_button, + container=container, + scale=scale, + min_width=min_width, + interactive=interactive, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + placeholder=placeholder, + mirror_webcam=mirror_webcam, + webcam_options=webcam_options, + show_share_button=show_share_button, + _selectable=_selectable, + crop_size=crop_size, + transforms=transforms, + eraser=eraser, + brush=brush, + format=format, + layers=layers, + canvas_size=canvas_size, + show_fullscreen_button=show_fullscreen_button, + fixed_canvas=fixed_canvas, + ) + from typing import Callable, Literal, Sequence, Any, TYPE_CHECKING + from gradio.blocks import Block + if TYPE_CHECKING: + from gradio.components import Timer + from gradio.components.base import Component + + +class PlayableVideo(components.Video): + """ + Sets: format="mp4" + """ + + is_template = True + + def __init__( + self, + value: ( + str | Path | tuple[str | Path, str | Path | None] | Callable | None + ) = None, + *, + format: Literal["mp4"] = "mp4", + sources: ( + list[Literal["upload", "webcam"]] | Literal["upload", "webcam"] | None + ) = None, + height: int | str | None = None, + width: int | str | None = None, + label: str | I18nData | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + show_label: bool | None = None, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + mirror_webcam: bool | None = None, + webcam_options: WebcamOptions | None = None, + include_audio: bool | None = None, + autoplay: bool = False, + show_share_button: bool | None = None, + show_download_button: bool | None = None, + min_length: int | None = None, + max_length: int | None = None, + loop: bool = False, + streaming: bool = False, + watermark: str | Path | None = None, + webcam_constraints: dict[str, dict[str, int | str]] | None = None, + ): + sources = ["upload"] + super().__init__( + value=value, + format=format, + sources=sources, # type: ignore + height=height, + width=width, + label=label, + every=every, + inputs=inputs, + show_label=show_label, + container=container, + scale=scale, + min_width=min_width, + interactive=interactive, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + mirror_webcam=mirror_webcam, + include_audio=include_audio, + autoplay=autoplay, + show_share_button=show_share_button, + show_download_button=show_download_button, + min_length=min_length, + max_length=max_length, + loop=loop, + streaming=streaming, + watermark=watermark, + webcam_constraints=webcam_constraints, + webcam_options=webcam_options, + ) + from typing import Callable, Literal, Sequence, Any, TYPE_CHECKING + from gradio.blocks import Block + if TYPE_CHECKING: + from gradio.components import Timer + from gradio.components.base import Component + + +class Microphone(components.Audio): + """ + Sets: sources=["microphone"] + """ + + is_template = True + + def __init__( + self, + value: str | Path | tuple[int, np.ndarray] | Callable | None = None, + *, + sources: ( + list[Literal["upload", "microphone"]] + | Literal["upload", "microphone"] + | None + ) = None, + type: Literal["numpy", "filepath"] = "numpy", + label: str | I18nData | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + show_label: bool | None = None, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + streaming: bool = False, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + format: Literal["wav", "mp3"] = "wav", + autoplay: bool = False, + show_download_button: bool | None = None, + show_share_button: bool | None = None, + editable: bool = True, + min_length: int | None = None, + max_length: int | None = None, + waveform_options: WaveformOptions | dict | None = None, + loop: bool = False, + recording: bool = False, + subtitles: str | Path | None = None, + ): + sources = ["microphone"] + super().__init__( + value, + sources=sources, + type=type, + label=label, + every=every, + inputs=inputs, + show_label=show_label, + container=container, + scale=scale, + min_width=min_width, + interactive=interactive, + visible=visible, + streaming=streaming, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + format=format, + autoplay=autoplay, + show_download_button=show_download_button, + show_share_button=show_share_button, + editable=editable, + min_length=min_length, + max_length=max_length, + waveform_options=waveform_options, + loop=loop, + recording=recording, + subtitles=subtitles, + ) + from typing import Callable, Literal, Sequence, Any, TYPE_CHECKING + from gradio.blocks import Block + if TYPE_CHECKING: + from gradio.components import Timer + from gradio.components.base import Component + + +class Files(components.File): + """ + Sets: file_count="multiple" + """ + + is_template = True + + def __init__( + self, + value: str | list[str] | Callable | None = None, + *, + file_count: Literal["multiple"] = "multiple", + file_types: list[str] | None = None, + type: Literal["filepath", "binary"] = "filepath", + label: str | I18nData | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + show_label: bool | None = None, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + height: int | float | None = None, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + allow_reordering: bool = False, + ): + super().__init__( + value, + file_count=file_count, + file_types=file_types, + type=type, + label=label, + every=every, + inputs=inputs, + show_label=show_label, + container=container, + scale=scale, + min_width=min_width, + height=height, + interactive=interactive, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + allow_reordering=allow_reordering, + ) + from typing import Callable, Literal, Sequence, Any, TYPE_CHECKING + from gradio.blocks import Block + if TYPE_CHECKING: + from gradio.components import Timer + from gradio.components.base import Component + + +class Numpy(components.Dataframe): + """ + Sets: type="numpy" + """ + + is_template = True + + def __init__( + self, + value: list[list[Any]] | Callable | None = None, + *, + headers: list[str] | None = None, + row_count: int | tuple[int, str] = (1, "dynamic"), + col_count: int | tuple[int, str] | None = None, + datatype: ( + Literal["str", "number", "bool", "date", "markdown", "html"] + | Sequence[Literal["str", "number", "bool", "date", "markdown", "html"]] + ) = "str", + type: Literal["numpy"] = "numpy", + latex_delimiters: list[dict[str, str | bool]] | None = None, + label: str | I18nData | None = None, + show_label: bool | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + max_height: int = 500, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + wrap: bool = False, + line_breaks: bool = True, + column_widths: list[str | int] | None = None, + show_row_numbers: bool = False, + show_search: Literal["none", "search", "filter"] = "none", + static_columns: list[int] | None = None, + pinned_columns: int | None = None, + show_fullscreen_button: bool = False, + max_chars: int | None = None, + show_copy_button: bool = False, + ): + super().__init__( + value=value, + headers=headers, + row_count=row_count, + col_count=col_count, + datatype=datatype, + type=type, + label=label, + show_label=show_label, + interactive=interactive, + visible=visible, + elem_id=elem_id, + wrap=wrap, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + line_breaks=line_breaks, + column_widths=column_widths, + every=every, + inputs=inputs, + max_height=max_height, + scale=scale, + latex_delimiters=latex_delimiters, + min_width=min_width, + show_row_numbers=show_row_numbers, + show_search=show_search, + pinned_columns=pinned_columns, + show_fullscreen_button=show_fullscreen_button, + max_chars=max_chars, + show_copy_button=show_copy_button, + static_columns=static_columns, + ) + from typing import Callable, Literal, Sequence, Any, TYPE_CHECKING + from gradio.blocks import Block + if TYPE_CHECKING: + from gradio.components import Timer + from gradio.components.base import Component + + +class Matrix(components.Dataframe): + """ + Sets: type="array" + """ + + is_template = True + + def __init__( + self, + value: list[list[Any]] | Callable | None = None, + *, + headers: list[str] | None = None, + row_count: int | tuple[int, str] = (1, "dynamic"), + col_count: int | tuple[int, str] | None = None, + datatype: ( + Literal["str", "number", "bool", "date", "markdown", "html"] + | Sequence[Literal["str", "number", "bool", "date", "markdown", "html"]] + ) = "str", + type: Literal["array"] = "array", + latex_delimiters: list[dict[str, str | bool]] | None = None, + label: str | I18nData | None = None, + show_label: bool | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + max_height: int = 500, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + wrap: bool = False, + line_breaks: bool = True, + column_widths: list[str | int] | None = None, + show_row_numbers: bool = False, + show_search: Literal["none", "search", "filter"] = "none", + pinned_columns: int | None = None, + show_fullscreen_button: bool = False, + max_chars: int | None = None, + show_copy_button: bool = False, + static_columns: list[int] | None = None, + ): + super().__init__( + value=value, + headers=headers, + row_count=row_count, + col_count=col_count, + datatype=datatype, + type=type, + label=label, + show_label=show_label, + interactive=interactive, + visible=visible, + elem_id=elem_id, + wrap=wrap, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + line_breaks=line_breaks, + column_widths=column_widths, + every=every, + inputs=inputs, + max_height=max_height, + scale=scale, + latex_delimiters=latex_delimiters, + min_width=min_width, + show_row_numbers=show_row_numbers, + show_search=show_search, + pinned_columns=pinned_columns, + show_fullscreen_button=show_fullscreen_button, + max_chars=max_chars, + show_copy_button=show_copy_button, + static_columns=static_columns, + ) + from typing import Callable, Literal, Sequence, Any, TYPE_CHECKING + from gradio.blocks import Block + if TYPE_CHECKING: + from gradio.components import Timer + from gradio.components.base import Component + + +class List(components.Dataframe): + """ + Sets: type="array", col_count=1 + """ + + is_template = True + + def __init__( + self, + value: list[list[Any]] | Callable | None = None, + *, + headers: list[str] | None = None, + row_count: int | tuple[int, str] = (1, "dynamic"), + col_count: Literal[1] = 1, + datatype: ( + Literal["str", "number", "bool", "date", "markdown", "html"] + | Sequence[Literal["str", "number", "bool", "date", "markdown", "html"]] + ) = "str", + type: Literal["array"] = "array", + latex_delimiters: list[dict[str, str | bool]] | None = None, + label: str | I18nData | None = None, + show_label: bool | None = None, + every: Timer | float | None = None, + inputs: ( + components.Component + | Sequence[components.Component] + | set[components.Component] + | None + ) = None, + max_height: int = 500, + scale: int | None = None, + min_width: int = 160, + interactive: bool | None = None, + visible: bool | Literal["hidden"] = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + key: int | str | tuple[int | str, ...] | None = None, + preserved_by_key: list[str] | str | None = "value", + wrap: bool = False, + line_breaks: bool = True, + column_widths: list[str | int] | None = None, + show_row_numbers: bool = False, + show_search: Literal["none", "search", "filter"] = "none", + pinned_columns: int | None = None, + show_fullscreen_button: bool = False, + max_chars: int | None = None, + show_copy_button: bool = False, + static_columns: list[int] | None = None, + ): + super().__init__( + value=value, + headers=headers, + row_count=row_count, + col_count=col_count, + datatype=datatype, + type=type, + label=label, + show_label=show_label, + interactive=interactive, + visible=visible, + elem_id=elem_id, + wrap=wrap, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key, + line_breaks=line_breaks, + column_widths=column_widths, + every=every, + inputs=inputs, + max_height=max_height, + scale=scale, + latex_delimiters=latex_delimiters, + min_width=min_width, + show_row_numbers=show_row_numbers, + show_search=show_search, + static_columns=static_columns, + pinned_columns=pinned_columns, + show_fullscreen_button=show_fullscreen_button, + max_chars=max_chars, + show_copy_button=show_copy_button, + ) + from typing import Callable, Literal, Sequence, Any, TYPE_CHECKING + from gradio.blocks import Block + if TYPE_CHECKING: + from gradio.components import Timer + from gradio.components.base import Component + + +Mic = Microphone \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/stores-D_Cz4lHU.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/stores-D_Cz4lHU.js.map new file mode 100644 index 0000000000000000000000000000000000000000..19a5543a9b2c803c539b1d696021dbeca8939bf3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/stores-D_Cz4lHU.js.map @@ -0,0 +1 @@ +{"version":3,"file":"stores-D_Cz4lHU.js","sources":["../../../../../../js/app/.svelte-kit/adapter-node/chunks/stores.js"],"sourcesContent":["import{getContext as r}from\"svelte\";import\"./exports.js\";import\"svelte/store\";function e(t,s=JSON.parse){try{return s(sessionStorage[t])}catch{}}const o=\"sveltekit:snapshot\",n=\"sveltekit:scroll\";e(n);e(o);const i=()=>{const t=r(\"__svelte__\");return{page:{subscribe:t.page.subscribe},navigating:{subscribe:t.navigating.subscribe},updated:t.updated}},b={subscribe(t){return i().page.subscribe(t)}};export{b as p};\n//# sourceMappingURL=stores.js.map\n"],"names":["r"],"mappings":";;;AAA8E,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAM,MAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAACA,UAAC,CAAC,YAAY,CAAC,CAAC,OAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;;;;"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/sv-CBaAzwhi.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/sv-CBaAzwhi.js new file mode 100644 index 0000000000000000000000000000000000000000..b231f2935d4251627357096ea9330adfabda1e83 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/sv-CBaAzwhi.js @@ -0,0 +1,4 @@ +const e="Svenska",t={annotated_image:"Annoterad bild"},r={allow_recording_access:"Tillåt mikrofonåtkomst för inspelning.",audio:"Ljud",record_from_microphone:"Spela in från mikrofon",stop_recording:"Stoppa inspelning",no_device_support:"Kan inte få åtkomst till medieenheter. Se till att du använder en säker källa (https) eller localhost (eller har gett ett giltigt SSL-certifikat till ssl_verify) och att du har gett webbläsaren åtkomst till din enhet.",stop:"Stopp",resume:"Fortsätt",record:"Spela in",no_microphone:"Ingen mikrofon hittades",pause:"Paus",play:"Spela upp",waiting:"Väntar",drop_to_upload:"Släpp en ljudfil här för att ladda upp"},a={connection_can_break:"På mobila enheter kan anslutningen brytas om fliken lämnas eller om enheten går i viloläge, och du förlorar din plats i kön.",long_requests_queue:"Det är en lång kö med väntande förfrågningar. Duplicera detta Space för att hoppa över kön.",lost_connection:"Anslutningen bröts eftersom sidan lämnades. Återgår till kön...",waiting_for_inputs:"Väntar på att fil(er) ska vara klara att ladda upp, vänligen försök igen."},o={checkbox:"Kryssruta",checkbox_group:"Kryssrutgrupp"},n={code:"Kod"},l={color_picker:"Färgväljare"},i={built_with:"Byggt med",built_with_gradio:"Byggt med Gradio",clear:"Rensa",download:"Ladda ner",edit:"Redigera",empty:"Tom",error:"Fel",hosted_on:"Värd på",loading:"Laddar",logo:"Logotyp",or:"eller",remove:"Ta bort",settings:"Inställningar",share:"Dela",submit:"Skicka",undo:"Ångra",no_devices:"Inga enheter hittades",language:"Språk",display_theme:"Visningstema",pwa:"Progressiv webbapplikation"},d={incorrect_format:"Fel format, endast CSV- och TSV-filer stöds",new_column:"Lägg till kolumn",new_row:"Ny rad",add_row_above:"Lägg till rad ovanför",add_row_below:"Lägg till rad nedanför",add_column_left:"Lägg till kolumn till vänster",add_column_right:"Lägg till kolumn till höger",delete_row:"Ta bort rad",delete_column:"Ta bort kolumn",sort_column:"Sortera kolumn",sort_ascending:"Sortera stigande",sort_descending:"Sortera fallande",drop_to_upload:"Släpp CSV- eller TSV-filer här för att importera data till dataramverk",clear_sort:"Rensa sortering"},s={dropdown:"Rullgardinsmeny"},p={build_error:"Det finns ett byggfel",config_error:"Det finns ett konfigurationsfel",contact_page_author:"Kontakta sidans författare för att informera dem.",no_app_file:"Det finns ingen app-fil",runtime_error:"Det finns ett körtidsfel",space_not_working:'"Space fungerar inte eftersom" {0}',space_paused:"Space är pausat",use_via_api:"Använd via API",use_via_api_or_mcp:"Använd via API eller MCP"},c={uploading:"Laddar upp..."},g={highlighted_text:"Markerad text"},_={allow_webcam_access:"Tillåt webbkameråtkomst för inspelning.",brush_color:"Penselfärg",brush_radius:"Penselstorlek",image:"Bild",remove_image:"Ta bort bild",select_brush_color:"Välj penselfärg",start_drawing:"Börja rita",use_brush:"Använd pensel",drop_to_upload:"Släpp en bildfil här för att ladda upp"},u={label:"Etikett"},m={enable_cookies:"Om du besöker ett HuggingFace Space i inkognitoläge måste du aktivera tredjepartscookies.",incorrect_credentials:"Felaktiga inloggningsuppgifter",username:"Användarnamn",password:"Lösenord",login:"Logga in"},f={number:"Nummer"},k={plot:"Diagram"},h={radio:"Radioknapp"},b={slider:"Skjutreglage"},S={click_to_upload:"Klicka för att ladda upp",drop_audio:"Släpp ljud här",drop_csv:"Släpp CSV här",drop_file:"Släpp fil här",drop_image:"Släpp bild här",drop_video:"Släpp video här",drop_gallery:"Släpp media här",paste_clipboard:"Klistra in från urklipp"},v={drop_to_upload:"Släpp en videofil här för att ladda upp"},w={edit:"Redigera",retry:"Försök igen",undo:"Ångra",submit:"Skicka",cancel:"Avbryt",like:"Gilla",dislike:"Ogilla",clear:"Rensa chatten"},y={_name:e,"3D_model":{"3d_model":"3D-modell",drop_to_upload:"Släpp en 3D-modellfil (.obj, .glb, .stl, .gltf, .splat eller .ply) här för att ladda upp"},annotated_image:t,audio:r,blocks:a,checkbox:o,code:n,color_picker:l,common:i,dataframe:d,dropdown:s,errors:p,file:c,highlighted_text:g,image:_,label:u,login:m,number:f,plot:k,radio:h,slider:b,upload_text:S,video:v,chatbot:w}; + +export { e as _name, t as annotated_image, r as audio, a as blocks, w as chatbot, o as checkbox, n as code, l as color_picker, i as common, d as dataframe, y as default, s as dropdown, p as errors, c as file, g as highlighted_text, _ as image, u as label, m as login, f as number, k as plot, h as radio, b as slider, S as upload_text, v as video }; +//# sourceMappingURL=sv-CBaAzwhi.js.map diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/sv-CBaAzwhi.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/sv-CBaAzwhi.js.map new file mode 100644 index 0000000000000000000000000000000000000000..b4a69d9a1ac281236f26b5ca5e25cfc6bcc2aa76 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/sv-CBaAzwhi.js.map @@ -0,0 +1 @@ +{"version":3,"file":"sv-CBaAzwhi.js","sources":["../../../../../../js/app/.svelte-kit/adapter-node/chunks/sv.js"],"sourcesContent":["const e=\"Svenska\",t={annotated_image:\"Annoterad bild\"},r={allow_recording_access:\"Tillåt mikrofonåtkomst för inspelning.\",audio:\"Ljud\",record_from_microphone:\"Spela in från mikrofon\",stop_recording:\"Stoppa inspelning\",no_device_support:\"Kan inte få åtkomst till medieenheter. Se till att du använder en säker källa (https) eller localhost (eller har gett ett giltigt SSL-certifikat till ssl_verify) och att du har gett webbläsaren åtkomst till din enhet.\",stop:\"Stopp\",resume:\"Fortsätt\",record:\"Spela in\",no_microphone:\"Ingen mikrofon hittades\",pause:\"Paus\",play:\"Spela upp\",waiting:\"Väntar\",drop_to_upload:\"Släpp en ljudfil här för att ladda upp\"},a={connection_can_break:\"På mobila enheter kan anslutningen brytas om fliken lämnas eller om enheten går i viloläge, och du förlorar din plats i kön.\",long_requests_queue:\"Det är en lång kö med väntande förfrågningar. Duplicera detta Space för att hoppa över kön.\",lost_connection:\"Anslutningen bröts eftersom sidan lämnades. Återgår till kön...\",waiting_for_inputs:\"Väntar på att fil(er) ska vara klara att ladda upp, vänligen försök igen.\"},o={checkbox:\"Kryssruta\",checkbox_group:\"Kryssrutgrupp\"},n={code:\"Kod\"},l={color_picker:\"Färgväljare\"},i={built_with:\"Byggt med\",built_with_gradio:\"Byggt med Gradio\",clear:\"Rensa\",download:\"Ladda ner\",edit:\"Redigera\",empty:\"Tom\",error:\"Fel\",hosted_on:\"Värd på\",loading:\"Laddar\",logo:\"Logotyp\",or:\"eller\",remove:\"Ta bort\",settings:\"Inställningar\",share:\"Dela\",submit:\"Skicka\",undo:\"Ångra\",no_devices:\"Inga enheter hittades\",language:\"Språk\",display_theme:\"Visningstema\",pwa:\"Progressiv webbapplikation\"},d={incorrect_format:\"Fel format, endast CSV- och TSV-filer stöds\",new_column:\"Lägg till kolumn\",new_row:\"Ny rad\",add_row_above:\"Lägg till rad ovanför\",add_row_below:\"Lägg till rad nedanför\",add_column_left:\"Lägg till kolumn till vänster\",add_column_right:\"Lägg till kolumn till höger\",delete_row:\"Ta bort rad\",delete_column:\"Ta bort kolumn\",sort_column:\"Sortera kolumn\",sort_ascending:\"Sortera stigande\",sort_descending:\"Sortera fallande\",drop_to_upload:\"Släpp CSV- eller TSV-filer här för att importera data till dataramverk\",clear_sort:\"Rensa sortering\"},s={dropdown:\"Rullgardinsmeny\"},p={build_error:\"Det finns ett byggfel\",config_error:\"Det finns ett konfigurationsfel\",contact_page_author:\"Kontakta sidans författare för att informera dem.\",no_app_file:\"Det finns ingen app-fil\",runtime_error:\"Det finns ett körtidsfel\",space_not_working:'\"Space fungerar inte eftersom\" {0}',space_paused:\"Space är pausat\",use_via_api:\"Använd via API\",use_via_api_or_mcp:\"Använd via API eller MCP\"},c={uploading:\"Laddar upp...\"},g={highlighted_text:\"Markerad text\"},_={allow_webcam_access:\"Tillåt webbkameråtkomst för inspelning.\",brush_color:\"Penselfärg\",brush_radius:\"Penselstorlek\",image:\"Bild\",remove_image:\"Ta bort bild\",select_brush_color:\"Välj penselfärg\",start_drawing:\"Börja rita\",use_brush:\"Använd pensel\",drop_to_upload:\"Släpp en bildfil här för att ladda upp\"},u={label:\"Etikett\"},m={enable_cookies:\"Om du besöker ett HuggingFace Space i inkognitoläge måste du aktivera tredjepartscookies.\",incorrect_credentials:\"Felaktiga inloggningsuppgifter\",username:\"Användarnamn\",password:\"Lösenord\",login:\"Logga in\"},f={number:\"Nummer\"},k={plot:\"Diagram\"},h={radio:\"Radioknapp\"},b={slider:\"Skjutreglage\"},S={click_to_upload:\"Klicka för att ladda upp\",drop_audio:\"Släpp ljud här\",drop_csv:\"Släpp CSV här\",drop_file:\"Släpp fil här\",drop_image:\"Släpp bild här\",drop_video:\"Släpp video här\",drop_gallery:\"Släpp media här\",paste_clipboard:\"Klistra in från urklipp\"},v={drop_to_upload:\"Släpp en videofil här för att ladda upp\"},w={edit:\"Redigera\",retry:\"Försök igen\",undo:\"Ångra\",submit:\"Skicka\",cancel:\"Avbryt\",like:\"Gilla\",dislike:\"Ogilla\",clear:\"Rensa chatten\"},y={_name:e,\"3D_model\":{\"3d_model\":\"3D-modell\",drop_to_upload:\"Släpp en 3D-modellfil (.obj, .glb, .stl, .gltf, .splat eller .ply) här för att ladda upp\"},annotated_image:t,audio:r,blocks:a,checkbox:o,code:n,color_picker:l,common:i,dataframe:d,dropdown:s,errors:p,file:c,highlighted_text:g,image:_,label:u,login:m,number:f,plot:k,radio:h,slider:b,upload_text:S,video:v,chatbot:w};export{e as _name,t as annotated_image,r as audio,a as blocks,w as chatbot,o as checkbox,n as code,l as color_picker,i as common,d as dataframe,y as default,s as dropdown,p as errors,c as file,g as highlighted_text,_ as image,u as label,m as login,f as number,k as plot,h as radio,b as slider,S as upload_text,v as video};\n//# sourceMappingURL=sv.js.map\n"],"names":[],"mappings":"AAAK,MAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,wCAAwC,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,wBAAwB,CAAC,cAAc,CAAC,mBAAmB,CAAC,iBAAiB,CAAC,2NAA2N,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,yBAAyB,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,wCAAwC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,8HAA8H,CAAC,mBAAmB,CAAC,6FAA6F,CAAC,eAAe,CAAC,iEAAiE,CAAC,kBAAkB,CAAC,2EAA2E,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,uBAAuB,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,cAAc,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,6CAA6C,CAAC,UAAU,CAAC,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,uBAAuB,CAAC,aAAa,CAAC,wBAAwB,CAAC,eAAe,CAAC,+BAA+B,CAAC,gBAAgB,CAAC,6BAA6B,CAAC,UAAU,CAAC,aAAa,CAAC,aAAa,CAAC,gBAAgB,CAAC,WAAW,CAAC,gBAAgB,CAAC,cAAc,CAAC,kBAAkB,CAAC,eAAe,CAAC,kBAAkB,CAAC,cAAc,CAAC,wEAAwE,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,uBAAuB,CAAC,YAAY,CAAC,iCAAiC,CAAC,mBAAmB,CAAC,mDAAmD,CAAC,WAAW,CAAC,yBAAyB,CAAC,aAAa,CAAC,0BAA0B,CAAC,iBAAiB,CAAC,oCAAoC,CAAC,YAAY,CAAC,iBAAiB,CAAC,WAAW,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,yCAAyC,CAAC,WAAW,CAAC,YAAY,CAAC,YAAY,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,cAAc,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,aAAa,CAAC,YAAY,CAAC,SAAS,CAAC,eAAe,CAAC,cAAc,CAAC,wCAAwC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,2FAA2F,CAAC,qBAAqB,CAAC,gCAAgC,CAAC,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,0BAA0B,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,eAAe,CAAC,UAAU,CAAC,gBAAgB,CAAC,UAAU,CAAC,iBAAiB,CAAC,YAAY,CAAC,iBAAiB,CAAC,eAAe,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,yCAAyC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,cAAc,CAAC,0FAA0F,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;;;;"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/ta-CIRcMeU1.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/ta-CIRcMeU1.js new file mode 100644 index 0000000000000000000000000000000000000000..c165d778e2633630ef43411e9e8daaadf060ebff --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/ta-CIRcMeU1.js @@ -0,0 +1,4 @@ +const o="தமிழ்",e={built_with_gradio:"கிரேடியோவுடன் உருவாக்கப்பட்டது",clear:"அழிக்கவும்",or:"அல்லது",submit:"சமர்ப்பிக்கவும்",built_with:"உருவாக்கப்பட்டது",download:"பதிவிறக்கம்",edit:"திருத்து",empty:"காலியாக உள்ளது",error:"பிழை",hosted_on:"இதில் ஹோஸ்ட் செய்யப்பட்டது",loading:"ஏற்றுகிறது",logo:"லோகோ",remove:"நீக்கு",settings:"அமைப்புகள்",share:"பகிர்",undo:"செயல்தவிர்",no_devices:"சாதனங்கள் எதுவும் கிடைக்கவில்லை",language:"மொழி",display_theme:"காட்சி தீம்",pwa:"முன்னேற்ற வலை பயன்பாடு"},t={click_to_upload:"பதிவேற்ற கிளிக் செய்யவும்",drop_audio:"ஆடியோவை இங்கே விடவும்",drop_csv:"CSV ஐ இங்கே விடவும்",drop_file:"கோப்பை இங்கே விடவும்",drop_image:"படத்தை இங்கே விடவும்",drop_video:"வீடியோவை இங்கே விடவும்",drop_gallery:"மீடியாவை இங்கே விடவும்",paste_clipboard:"கிளிப்போர்டிலிருந்து ஒட்டவும்"},r={annotated_image:"குறிப்பிடப்பட்ட படம்"},a={allow_recording_access:"தயவுசெய்து பதிவு செய்ய மைக்ரோஃபோன் அணுகலை அனுமதிக்கவும்.",audio:"ஒலி",drop_to_upload:"ஒலிக் கோப்பை பதிவேற்ற இங்கே விடவும்",record_from_microphone:"மைக்ரோஃபோனிலிருந்து பதிவு செய்யவும்",stop_recording:"பதிவை நிறுத்தவும்",no_device_support:"மீடியா சாதனங்களை அணுக முடியவில்லை. நீங்கள் பாதுகாப்பான மூலத்தில் (https) அல்லது localhost இல் இயங்குகிறீர்களா (அல்லது ssl_verify க்கு செல்லுபடியாகும் SSL சான்றிதழை அனுப்பியுள்ளீர்களா) என்பதையும், உங்கள் சாதனத்திற்கான உலாவி அணுகலை அனுமதித்துள்ளீர்களா என்பதையும் சரிபார்க்கவும்.",stop:"நிறுத்து",resume:"தொடரவும்",record:"பதிவு செய்",no_microphone:"மைக்ரோஃபோன் எதுவும் கிடைக்கவில்லை",pause:"இடைநிறுத்து",play:"இயக்கு",waiting:"காத்திருக்கிறது"},c={connection_can_break:"மொபைலில், இந்தத் தாவல் ஃபோகஸை இழந்தால் அல்லது சாதனம் உறங்கினால், இணைப்பு துண்டிக்கப்பட்டு, வரிசையில் உங்கள் இடத்தை இழக்கலாம்.",long_requests_queue:"காத்திருக்கும் கோரிக்கைகளின் நீண்ட வரிசை உள்ளது. வரிசையைத் தவிர்க்க இந்த Space ஐ நகலெடுக்கவும்.",lost_connection:"பக்கத்தை விட்டு வெளியேறியதால் இணைப்பு துண்டிக்கப்பட்டது. வரிசைக்கு மீண்டும் இணைகிறது...",waiting_for_inputs:"கோப்பு(கள்) பதிவேற்றம் முடிவடைய காத்திருக்கிறது, தயவுசெய்து மீண்டும் முயற்சிக்கவும்."},_={checkbox:"தேர்வுப்பெட்டி",checkbox_group:"தேர்வுப்பெட்டி குழு"},n={code:"குறியீடு"},d={color_picker:"வண்ணத் தேர்வி"},i={incorrect_format:"தவறான வடிவம், CSV மற்றும் TSV கோப்புகள் மட்டுமே ஆதரிக்கப்படுகின்றன",new_column:"நெடுவரிசை சேர்க்க",new_row:"புதிய வரிசை",add_row_above:"மேலே வரிசை சேர்க்க",add_row_below:"கீழே வரிசை சேர்க்க",delete_row:"வரிசையை நீக்கு",delete_column:"நெடுவரிசையை நீக்கு",add_column_left:"இடது பக்கத்தில் நெடுவரிசை சேர்க்க",add_column_right:"வலது பக்கத்தில் நெடுவரிசை சேர்க்க",sort_column:"நெடுவரிசையை வரிசைப்படுத்து",sort_ascending:"ஏறுவரிசையில் வரிசைப்படுத்து",sort_descending:"இறங்குவரிசையில் வரிசைப்படுத்து",drop_to_upload:"தரவுத்தளத்திற்கு தரவை இறக்குமதி செய்ய CSV அல்லது TSV கோப்புகளை இங்கே விடவும்",clear_sort:"வரிசைப்படுத்தலை அழி"},l={dropdown:"கீழ்தோன்றல் பட்டியல்"},s={build_error:"உருவாக்க பிழை உள்ளது",config_error:"கட்டமைப்பு பிழை உள்ளது",contact_page_author:"தயவுசெய்து பக்க ஆசிரியரைத் தொடர்பு கொண்டு தெரிவிக்கவும்.",no_app_file:"பயன்பாட்டுக் கோப்பு இல்லை",runtime_error:"இயக்க நேர பிழை உள்ளது",space_not_working:'"Space செயல்படவில்லை ஏனெனில்" {0}',space_paused:"Space இடைநிறுத்தப்பட்டுள்ளது",use_via_api:"API மூலம் பயன்படுத்தவும்",use_via_api_or_mcp:"API அல்லது MCP மூலம் பயன்படுத்தவும்"},p={uploading:"பதிவேற்றுகிறது..."},u={highlighted_text:"சிறப்பிக்கப்பட்ட உரை"},g={allow_webcam_access:"தயவுசெய்து பதிவு செய்ய வெப்கேம் அணுகலை அனுமதிக்கவும்.",brush_color:"தூரிகை நிறம்",brush_radius:"தூரிகை அளவு",image:"படம்",remove_image:"படத்தை நீக்கு",select_brush_color:"தூரிகை நிறத்தைத் தேர்ந்தெடுக்கவும்",start_drawing:"வரைய தொடங்கவும்",use_brush:"தூரிகையைப் பயன்படுத்தவும்",drop_to_upload:"பட கோப்பை பதிவேற்ற இங்கே விடவும்"},m={label:"லேபிள்"},b={enable_cookies:"நீங்கள் மறைநிலை பயன்முறையில் HuggingFace Space ஐப் பார்வையிட்டால், மூன்றாம் தரப்பு குக்கீகளை இயக்க வேண்டும்.",incorrect_credentials:"தவறான சான்றுகள்",username:"பயனர்பெயர்",password:"கடவுச்சொல்",login:"உள்நுழைய"},h={number:"எண்"},w={plot:"வரைபடம்"},k={radio:"ரேடியோ பொத்தான்"},f={slider:"சறுக்கி"},v={drop_to_upload:"வீடியோ கோப்பை பதிவேற்ற இங்கே விடவும்"},S={edit:"திருத்து",retry:"மீண்டும் முயற்சி",undo:"செயல்தவிர்",submit:"சமர்ப்பிக்கவும்",cancel:"ரத்து",like:"விரும்புகிறேன்",dislike:"விரும்பவில்லை",clear:"உரையாடலை அழி"},x={_name:o,common:e,upload_text:t,"3D_model":{"3d_model":"3D மாதிரி",drop_to_upload:"3D மாதிரி கோப்பை (.obj, .glb, .stl, .gltf, .splat, அல்லது .ply) பதிவேற்ற இங்கே விடவும்"},annotated_image:r,audio:a,blocks:c,checkbox:_,code:n,color_picker:d,dataframe:i,dropdown:l,errors:s,file:p,highlighted_text:u,image:g,label:m,login:b,number:h,plot:w,radio:k,slider:f,video:v,chatbot:S}; + +export { o as _name, r as annotated_image, a as audio, c as blocks, S as chatbot, _ as checkbox, n as code, d as color_picker, e as common, i as dataframe, x as default, l as dropdown, s as errors, p as file, u as highlighted_text, g as image, m as label, b as login, h as number, w as plot, k as radio, f as slider, t as upload_text, v as video }; +//# sourceMappingURL=ta-CIRcMeU1.js.map diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/ta-CIRcMeU1.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/ta-CIRcMeU1.js.map new file mode 100644 index 0000000000000000000000000000000000000000..6fa4a1088b08a31361c90b5df57808716a5f7ef0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/ta-CIRcMeU1.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ta-CIRcMeU1.js","sources":["../../../../../../js/app/.svelte-kit/adapter-node/chunks/ta.js"],"sourcesContent":["const o=\"தமிழ்\",e={built_with_gradio:\"கிரேடியோவுடன் உருவாக்கப்பட்டது\",clear:\"அழிக்கவும்\",or:\"அல்லது\",submit:\"சமர்ப்பிக்கவும்\",built_with:\"உருவாக்கப்பட்டது\",download:\"பதிவிறக்கம்\",edit:\"திருத்து\",empty:\"காலியாக உள்ளது\",error:\"பிழை\",hosted_on:\"இதில் ஹோஸ்ட் செய்யப்பட்டது\",loading:\"ஏற்றுகிறது\",logo:\"லோகோ\",remove:\"நீக்கு\",settings:\"அமைப்புகள்\",share:\"பகிர்\",undo:\"செயல்தவிர்\",no_devices:\"சாதனங்கள் எதுவும் கிடைக்கவில்லை\",language:\"மொழி\",display_theme:\"காட்சி தீம்\",pwa:\"முன்னேற்ற வலை பயன்பாடு\"},t={click_to_upload:\"பதிவேற்ற கிளிக் செய்யவும்\",drop_audio:\"ஆடியோவை இங்கே விடவும்\",drop_csv:\"CSV ஐ இங்கே விடவும்\",drop_file:\"கோப்பை இங்கே விடவும்\",drop_image:\"படத்தை இங்கே விடவும்\",drop_video:\"வீடியோவை இங்கே விடவும்\",drop_gallery:\"மீடியாவை இங்கே விடவும்\",paste_clipboard:\"கிளிப்போர்டிலிருந்து ஒட்டவும்\"},r={annotated_image:\"குறிப்பிடப்பட்ட படம்\"},a={allow_recording_access:\"தயவுசெய்து பதிவு செய்ய மைக்ரோஃபோன் அணுகலை அனுமதிக்கவும்.\",audio:\"ஒலி\",drop_to_upload:\"ஒலிக் கோப்பை பதிவேற்ற இங்கே விடவும்\",record_from_microphone:\"மைக்ரோஃபோனிலிருந்து பதிவு செய்யவும்\",stop_recording:\"பதிவை நிறுத்தவும்\",no_device_support:\"மீடியா சாதனங்களை அணுக முடியவில்லை. நீங்கள் பாதுகாப்பான மூலத்தில் (https) அல்லது localhost இல் இயங்குகிறீர்களா (அல்லது ssl_verify க்கு செல்லுபடியாகும் SSL சான்றிதழை அனுப்பியுள்ளீர்களா) என்பதையும், உங்கள் சாதனத்திற்கான உலாவி அணுகலை அனுமதித்துள்ளீர்களா என்பதையும் சரிபார்க்கவும்.\",stop:\"நிறுத்து\",resume:\"தொடரவும்\",record:\"பதிவு செய்\",no_microphone:\"மைக்ரோஃபோன் எதுவும் கிடைக்கவில்லை\",pause:\"இடைநிறுத்து\",play:\"இயக்கு\",waiting:\"காத்திருக்கிறது\"},c={connection_can_break:\"மொபைலில், இந்தத் தாவல் ஃபோகஸை இழந்தால் அல்லது சாதனம் உறங்கினால், இணைப்பு துண்டிக்கப்பட்டு, வரிசையில் உங்கள் இடத்தை இழக்கலாம்.\",long_requests_queue:\"காத்திருக்கும் கோரிக்கைகளின் நீண்ட வரிசை உள்ளது. வரிசையைத் தவிர்க்க இந்த Space ஐ நகலெடுக்கவும்.\",lost_connection:\"பக்கத்தை விட்டு வெளியேறியதால் இணைப்பு துண்டிக்கப்பட்டது. வரிசைக்கு மீண்டும் இணைகிறது...\",waiting_for_inputs:\"கோப்பு(கள்) பதிவேற்றம் முடிவடைய காத்திருக்கிறது, தயவுசெய்து மீண்டும் முயற்சிக்கவும்.\"},_={checkbox:\"தேர்வுப்பெட்டி\",checkbox_group:\"தேர்வுப்பெட்டி குழு\"},n={code:\"குறியீடு\"},d={color_picker:\"வண்ணத் தேர்வி\"},i={incorrect_format:\"தவறான வடிவம், CSV மற்றும் TSV கோப்புகள் மட்டுமே ஆதரிக்கப்படுகின்றன\",new_column:\"நெடுவரிசை சேர்க்க\",new_row:\"புதிய வரிசை\",add_row_above:\"மேலே வரிசை சேர்க்க\",add_row_below:\"கீழே வரிசை சேர்க்க\",delete_row:\"வரிசையை நீக்கு\",delete_column:\"நெடுவரிசையை நீக்கு\",add_column_left:\"இடது பக்கத்தில் நெடுவரிசை சேர்க்க\",add_column_right:\"வலது பக்கத்தில் நெடுவரிசை சேர்க்க\",sort_column:\"நெடுவரிசையை வரிசைப்படுத்து\",sort_ascending:\"ஏறுவரிசையில் வரிசைப்படுத்து\",sort_descending:\"இறங்குவரிசையில் வரிசைப்படுத்து\",drop_to_upload:\"தரவுத்தளத்திற்கு தரவை இறக்குமதி செய்ய CSV அல்லது TSV கோப்புகளை இங்கே விடவும்\",clear_sort:\"வரிசைப்படுத்தலை அழி\"},l={dropdown:\"கீழ்தோன்றல் பட்டியல்\"},s={build_error:\"உருவாக்க பிழை உள்ளது\",config_error:\"கட்டமைப்பு பிழை உள்ளது\",contact_page_author:\"தயவுசெய்து பக்க ஆசிரியரைத் தொடர்பு கொண்டு தெரிவிக்கவும்.\",no_app_file:\"பயன்பாட்டுக் கோப்பு இல்லை\",runtime_error:\"இயக்க நேர பிழை உள்ளது\",space_not_working:'\"Space செயல்படவில்லை ஏனெனில்\" {0}',space_paused:\"Space இடைநிறுத்தப்பட்டுள்ளது\",use_via_api:\"API மூலம் பயன்படுத்தவும்\",use_via_api_or_mcp:\"API அல்லது MCP மூலம் பயன்படுத்தவும்\"},p={uploading:\"பதிவேற்றுகிறது...\"},u={highlighted_text:\"சிறப்பிக்கப்பட்ட உரை\"},g={allow_webcam_access:\"தயவுசெய்து பதிவு செய்ய வெப்கேம் அணுகலை அனுமதிக்கவும்.\",brush_color:\"தூரிகை நிறம்\",brush_radius:\"தூரிகை அளவு\",image:\"படம்\",remove_image:\"படத்தை நீக்கு\",select_brush_color:\"தூரிகை நிறத்தைத் தேர்ந்தெடுக்கவும்\",start_drawing:\"வரைய தொடங்கவும்\",use_brush:\"தூரிகையைப் பயன்படுத்தவும்\",drop_to_upload:\"பட கோப்பை பதிவேற்ற இங்கே விடவும்\"},m={label:\"லேபிள்\"},b={enable_cookies:\"நீங்கள் மறைநிலை பயன்முறையில் HuggingFace Space ஐப் பார்வையிட்டால், மூன்றாம் தரப்பு குக்கீகளை இயக்க வேண்டும்.\",incorrect_credentials:\"தவறான சான்றுகள்\",username:\"பயனர்பெயர்\",password:\"கடவுச்சொல்\",login:\"உள்நுழைய\"},h={number:\"எண்\"},w={plot:\"வரைபடம்\"},k={radio:\"ரேடியோ பொத்தான்\"},f={slider:\"சறுக்கி\"},v={drop_to_upload:\"வீடியோ கோப்பை பதிவேற்ற இங்கே விடவும்\"},S={edit:\"திருத்து\",retry:\"மீண்டும் முயற்சி\",undo:\"செயல்தவிர்\",submit:\"சமர்ப்பிக்கவும்\",cancel:\"ரத்து\",like:\"விரும்புகிறேன்\",dislike:\"விரும்பவில்லை\",clear:\"உரையாடலை அழி\"},x={_name:o,common:e,upload_text:t,\"3D_model\":{\"3d_model\":\"3D மாதிரி\",drop_to_upload:\"3D மாதிரி கோப்பை (.obj, .glb, .stl, .gltf, .splat, அல்லது .ply) பதிவேற்ற இங்கே விடவும்\"},annotated_image:r,audio:a,blocks:c,checkbox:_,code:n,color_picker:d,dataframe:i,dropdown:l,errors:s,file:p,highlighted_text:u,image:g,label:m,login:b,number:h,plot:w,radio:k,slider:f,video:v,chatbot:S};export{o as _name,r as annotated_image,a as audio,c as blocks,S as chatbot,_ as checkbox,n as code,d as color_picker,e as common,i as dataframe,x as default,l as dropdown,s as errors,p as file,u as highlighted_text,g as image,m as label,b as login,h as number,w as plot,k as radio,f as slider,t as upload_text,v as video};\n//# sourceMappingURL=ta.js.map\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/th-CWKCe4yc.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/th-CWKCe4yc.js new file mode 100644 index 0000000000000000000000000000000000000000..820e1fa388638bc1c9a4cd3b2a0b9c00b19d26d4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/th-CWKCe4yc.js @@ -0,0 +1,4 @@ +const o="ภาษาไทย",e={annotated_image:"รูปภาพที่มีคำอธิบาย"},t={allow_recording_access:"กรุณาอนุญาตการเข้าถึงไมโครโฟนเพื่อบันทึกเสียง",audio:"เสียง",drop_to_upload:"ลากและวางไฟล์เสียงที่นี่เพื่ออัปโหลด",record_from_microphone:"บันทึกจากไมโครโฟน",stop_recording:"หยุดบันทึก",no_device_support:"ไม่สามารถเข้าถึงอุปกรณ์สื่อได้ โปรดตรวจสอบว่าคุณใช้งานบนโดเมนที่ปลอดภัย (https) หรือ localhost (หรือคุณได้กำหนดค่า SSL ที่ถูกต้อง) และอนุญาตให้เบราว์เซอร์เข้าถึงอุปกรณ์ของคุณ",stop:"หยุด",resume:"ทำงานต่อ",record:"บันทึก",no_microphone:"ไม่พบไมโครโฟน",pause:"หยุดชั่วคราว",play:"เล่น",waiting:"กำลังรอ"},r={connection_can_break:"บนมือถือ การเชื่อมต่ออาจหลุดหากแท็บนี้ไม่ได้อยู่ในโฟกัสหรืออุปกรณ์เข้าสู่โหมดพัก ส่งผลให้เสียตำแหน่งในคิว",long_requests_queue:"มีคิวคำขอรออยู่เป็นจำนวนมาก คัดลอก Space นี้เพื่อข้ามคิว",lost_connection:"การเชื่อมต่อขาดหายเนื่องจากออกจากหน้า กำลังเข้าคิวใหม่...",waiting_for_inputs:"กำลังรอไฟล์อัปโหลดเสร็จ กรุณาลองใหม่"},a={checkbox:"กล่องเลือก",checkbox_group:"กลุ่มกล่องเลือก"},c={code:"โค้ด"},_={color_picker:"ตัวเลือกสี"},n={built_with:"สร้างด้วย",built_with_gradio:"สร้างด้วย Gradio",clear:"ล้าง",download:"ดาวน์โหลด",edit:"แก้ไข",empty:"ว่างเปล่า",error:"ข้อผิดพลาด",hosted_on:"โฮสต์บน",loading:"กำลังโหลด",logo:"โลโก้",or:"หรือ",remove:"ลบ",settings:"การตั้งค่า",share:"แชร์",submit:"ส่ง",undo:"เลิกทำ",no_devices:"ไม่พบอุปกรณ์",language:"ภาษา",display_theme:"ธีมการแสดงผล",pwa:"โปรเกรสซีฟเว็บแอป"},d={incorrect_format:"รูปแบบไม่ถูกต้อง รองรับเฉพาะไฟล์ CSV และ TSV",new_column:"เพิ่มคอลัมน์",new_row:"แถวใหม่",add_row_above:"เพิ่มแถวด้านบน",add_row_below:"เพิ่มแถวด้านล่าง",delete_row:"ลบแถว",delete_column:"ลบคอลัมน์",add_column_left:"เพิ่มคอลัมน์ทางซ้าย",add_column_right:"เพิ่มคอลัมน์ทางขวา",sort_column:"เรียงลำดับคอลัมน์",sort_ascending:"เรียงจากน้อยไปมาก",sort_descending:"เรียงจากมากไปน้อย",drop_to_upload:"ลากและวางไฟล์ CSV หรือ TSV ที่นี่เพื่อนำเข้าข้อมูลลงในตาราง",clear_sort:"ล้างการเรียงลำดับ"},i={dropdown:"เมนูดรอปดาวน์"},l={build_error:"เกิดข้อผิดพลาดในการสร้าง",config_error:"เกิดข้อผิดพลาดในการกำหนดค่า",contact_page_author:"โปรดติดต่อผู้ดูแลเพจเพื่อแจ้งให้ทราบ",no_app_file:"ไม่พบไฟล์แอป",runtime_error:"เกิดข้อผิดพลาดขณะทำงาน",space_not_working:'"Space ใช้งานไม่ได้เนื่องจาก" {0}',space_paused:"Space ถูกหยุดชั่วคราว",use_via_api:"ใช้งานผ่าน API",use_via_api_or_mcp:"ใช้งานผ่าน API หรือ MCP"},s={uploading:"กำลังอัปโหลด..."},p={highlighted_text:"ข้อความที่ถูกเน้น"},u={allow_webcam_access:"กรุณาอนุญาตการเข้าถึงเว็บแคมเพื่อบันทึกภาพ",brush_color:"สีแปรง",brush_radius:"ขนาดแปรง",image:"รูปภาพ",remove_image:"ลบรูปภาพ",select_brush_color:"เลือกสีแปรง",start_drawing:"เริ่มวาด",use_brush:"ใช้แปรง",drop_to_upload:"ลากและวางไฟล์รูปภาพที่นี่เพื่ออัปโหลด"},g={label:"ป้ายกำกับ"},m={enable_cookies:"หากคุณเข้าใช้งาน HuggingFace Space ในโหมดไม่ระบุตัวตน คุณต้องเปิดใช้งานคุกกี้ของบุคคลที่สาม",incorrect_credentials:"ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง",username:"ชื่อผู้ใช้",password:"รหัสผ่าน",login:"เข้าสู่ระบบ"},b={number:"ตัวเลข"},h={plot:"กราฟ"},w={radio:"ปุ่มตัวเลือก"},k={slider:"แถบเลื่อน"},f={click_to_upload:"คลิกเพื่ออัปโหลด",drop_audio:"ลากและวางไฟล์เสียงที่นี่",drop_csv:"ลากและวางไฟล์ CSV ที่นี่",drop_file:"ลากและวางไฟล์ที่นี่",drop_image:"ลากและวางไฟล์รูปภาพที่นี่",drop_video:"ลากและวางไฟล์วิดีโอที่นี่",drop_gallery:"ลากและวางไฟล์สื่อที่นี่",paste_clipboard:"วางจากคลิปบอร์ด"},v={drop_to_upload:"ลากและวางไฟล์วิดีโอที่นี่เพื่ออัปโหลด"},S={edit:"แก้ไข",retry:"ลองใหม่",undo:"เลิกทำ",submit:"ส่ง",cancel:"ยกเลิก",like:"ถูกใจ",dislike:"ไม่ถูกใจ",clear:"ล้างการสนทนา"},x={_name:o,"3D_model":{"3d_model":"โมเดล 3 มิติ",drop_to_upload:"ลากและวางไฟล์โมเดล 3 มิติ (.obj, .glb, .stl, .gltf, .splat, หรือ .ply) ที่นี่เพื่ออัปโหลด"},annotated_image:e,audio:t,blocks:r,checkbox:a,code:c,color_picker:_,common:n,dataframe:d,dropdown:i,errors:l,file:s,highlighted_text:p,image:u,label:g,login:m,number:b,plot:h,radio:w,slider:k,upload_text:f,video:v,chatbot:S}; + +export { o as _name, e as annotated_image, t as audio, r as blocks, S as chatbot, a as checkbox, c as code, _ as color_picker, n as common, d as dataframe, x as default, i as dropdown, l as errors, s as file, p as highlighted_text, u as image, g as label, m as login, b as number, h as plot, w as radio, k as slider, f as upload_text, v as video }; +//# sourceMappingURL=th-CWKCe4yc.js.map diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/th-CWKCe4yc.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/th-CWKCe4yc.js.map new file mode 100644 index 0000000000000000000000000000000000000000..bf6dcb15d0abf199ccc7c5009f92e5c347f97aab --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/th-CWKCe4yc.js.map @@ -0,0 +1 @@ +{"version":3,"file":"th-CWKCe4yc.js","sources":["../../../../../../js/app/.svelte-kit/adapter-node/chunks/th.js"],"sourcesContent":["const o=\"ภาษาไทย\",e={annotated_image:\"รูปภาพที่มีคำอธิบาย\"},t={allow_recording_access:\"กรุณาอนุญาตการเข้าถึงไมโครโฟนเพื่อบันทึกเสียง\",audio:\"เสียง\",drop_to_upload:\"ลากและวางไฟล์เสียงที่นี่เพื่ออัปโหลด\",record_from_microphone:\"บันทึกจากไมโครโฟน\",stop_recording:\"หยุดบันทึก\",no_device_support:\"ไม่สามารถเข้าถึงอุปกรณ์สื่อได้ โปรดตรวจสอบว่าคุณใช้งานบนโดเมนที่ปลอดภัย (https) หรือ localhost (หรือคุณได้กำหนดค่า SSL ที่ถูกต้อง) และอนุญาตให้เบราว์เซอร์เข้าถึงอุปกรณ์ของคุณ\",stop:\"หยุด\",resume:\"ทำงานต่อ\",record:\"บันทึก\",no_microphone:\"ไม่พบไมโครโฟน\",pause:\"หยุดชั่วคราว\",play:\"เล่น\",waiting:\"กำลังรอ\"},r={connection_can_break:\"บนมือถือ การเชื่อมต่ออาจหลุดหากแท็บนี้ไม่ได้อยู่ในโฟกัสหรืออุปกรณ์เข้าสู่โหมดพัก ส่งผลให้เสียตำแหน่งในคิว\",long_requests_queue:\"มีคิวคำขอรออยู่เป็นจำนวนมาก คัดลอก Space นี้เพื่อข้ามคิว\",lost_connection:\"การเชื่อมต่อขาดหายเนื่องจากออกจากหน้า กำลังเข้าคิวใหม่...\",waiting_for_inputs:\"กำลังรอไฟล์อัปโหลดเสร็จ กรุณาลองใหม่\"},a={checkbox:\"กล่องเลือก\",checkbox_group:\"กลุ่มกล่องเลือก\"},c={code:\"โค้ด\"},_={color_picker:\"ตัวเลือกสี\"},n={built_with:\"สร้างด้วย\",built_with_gradio:\"สร้างด้วย Gradio\",clear:\"ล้าง\",download:\"ดาวน์โหลด\",edit:\"แก้ไข\",empty:\"ว่างเปล่า\",error:\"ข้อผิดพลาด\",hosted_on:\"โฮสต์บน\",loading:\"กำลังโหลด\",logo:\"โลโก้\",or:\"หรือ\",remove:\"ลบ\",settings:\"การตั้งค่า\",share:\"แชร์\",submit:\"ส่ง\",undo:\"เลิกทำ\",no_devices:\"ไม่พบอุปกรณ์\",language:\"ภาษา\",display_theme:\"ธีมการแสดงผล\",pwa:\"โปรเกรสซีฟเว็บแอป\"},d={incorrect_format:\"รูปแบบไม่ถูกต้อง รองรับเฉพาะไฟล์ CSV และ TSV\",new_column:\"เพิ่มคอลัมน์\",new_row:\"แถวใหม่\",add_row_above:\"เพิ่มแถวด้านบน\",add_row_below:\"เพิ่มแถวด้านล่าง\",delete_row:\"ลบแถว\",delete_column:\"ลบคอลัมน์\",add_column_left:\"เพิ่มคอลัมน์ทางซ้าย\",add_column_right:\"เพิ่มคอลัมน์ทางขวา\",sort_column:\"เรียงลำดับคอลัมน์\",sort_ascending:\"เรียงจากน้อยไปมาก\",sort_descending:\"เรียงจากมากไปน้อย\",drop_to_upload:\"ลากและวางไฟล์ CSV หรือ TSV ที่นี่เพื่อนำเข้าข้อมูลลงในตาราง\",clear_sort:\"ล้างการเรียงลำดับ\"},i={dropdown:\"เมนูดรอปดาวน์\"},l={build_error:\"เกิดข้อผิดพลาดในการสร้าง\",config_error:\"เกิดข้อผิดพลาดในการกำหนดค่า\",contact_page_author:\"โปรดติดต่อผู้ดูแลเพจเพื่อแจ้งให้ทราบ\",no_app_file:\"ไม่พบไฟล์แอป\",runtime_error:\"เกิดข้อผิดพลาดขณะทำงาน\",space_not_working:'\"Space ใช้งานไม่ได้เนื่องจาก\" {0}',space_paused:\"Space ถูกหยุดชั่วคราว\",use_via_api:\"ใช้งานผ่าน API\",use_via_api_or_mcp:\"ใช้งานผ่าน API หรือ MCP\"},s={uploading:\"กำลังอัปโหลด...\"},p={highlighted_text:\"ข้อความที่ถูกเน้น\"},u={allow_webcam_access:\"กรุณาอนุญาตการเข้าถึงเว็บแคมเพื่อบันทึกภาพ\",brush_color:\"สีแปรง\",brush_radius:\"ขนาดแปรง\",image:\"รูปภาพ\",remove_image:\"ลบรูปภาพ\",select_brush_color:\"เลือกสีแปรง\",start_drawing:\"เริ่มวาด\",use_brush:\"ใช้แปรง\",drop_to_upload:\"ลากและวางไฟล์รูปภาพที่นี่เพื่ออัปโหลด\"},g={label:\"ป้ายกำกับ\"},m={enable_cookies:\"หากคุณเข้าใช้งาน HuggingFace Space ในโหมดไม่ระบุตัวตน คุณต้องเปิดใช้งานคุกกี้ของบุคคลที่สาม\",incorrect_credentials:\"ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง\",username:\"ชื่อผู้ใช้\",password:\"รหัสผ่าน\",login:\"เข้าสู่ระบบ\"},b={number:\"ตัวเลข\"},h={plot:\"กราฟ\"},w={radio:\"ปุ่มตัวเลือก\"},k={slider:\"แถบเลื่อน\"},f={click_to_upload:\"คลิกเพื่ออัปโหลด\",drop_audio:\"ลากและวางไฟล์เสียงที่นี่\",drop_csv:\"ลากและวางไฟล์ CSV ที่นี่\",drop_file:\"ลากและวางไฟล์ที่นี่\",drop_image:\"ลากและวางไฟล์รูปภาพที่นี่\",drop_video:\"ลากและวางไฟล์วิดีโอที่นี่\",drop_gallery:\"ลากและวางไฟล์สื่อที่นี่\",paste_clipboard:\"วางจากคลิปบอร์ด\"},v={drop_to_upload:\"ลากและวางไฟล์วิดีโอที่นี่เพื่ออัปโหลด\"},S={edit:\"แก้ไข\",retry:\"ลองใหม่\",undo:\"เลิกทำ\",submit:\"ส่ง\",cancel:\"ยกเลิก\",like:\"ถูกใจ\",dislike:\"ไม่ถูกใจ\",clear:\"ล้างการสนทนา\"},x={_name:o,\"3D_model\":{\"3d_model\":\"โมเดล 3 มิติ\",drop_to_upload:\"ลากและวางไฟล์โมเดล 3 มิติ (.obj, .glb, .stl, .gltf, .splat, หรือ .ply) ที่นี่เพื่ออัปโหลด\"},annotated_image:e,audio:t,blocks:r,checkbox:a,code:c,color_picker:_,common:n,dataframe:d,dropdown:i,errors:l,file:s,highlighted_text:p,image:u,label:g,login:m,number:b,plot:h,radio:w,slider:k,upload_text:f,video:v,chatbot:S};export{o as _name,e as annotated_image,t as audio,r as blocks,S as chatbot,a as checkbox,c as code,_ as color_picker,n as common,d as dataframe,x as default,i as dropdown,l as errors,s as file,p as highlighted_text,u as image,g as label,m as login,b as number,h as plot,w as radio,k as slider,f as upload_text,v as video};\n//# sourceMappingURL=th.js.map\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/tinycolor-BAU9cgwS.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/tinycolor-BAU9cgwS.js new file mode 100644 index 0000000000000000000000000000000000000000..66daabc3fb0acffeec440fe69162c2f0d2eca74c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/tinycolor-BAU9cgwS.js @@ -0,0 +1,4 @@ +function m(t){"@babel/helpers - typeof";return m=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(r){return typeof r}:function(r){return r&&typeof Symbol=="function"&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},m(t)}var T=/^\s+/,C=/\s+$/;function s(t,r){if(t=t||"",r=r||{},t instanceof s)return t;if(!(this instanceof s))return new s(t,r);var e=I(t);this._originalInput=t,this._r=e.r,this._g=e.g,this._b=e.b,this._a=e.a,this._roundA=Math.round(100*this._a)/100,this._format=r.format||e.format,this._gradientType=r.gradientType,this._r<1&&(this._r=Math.round(this._r)),this._g<1&&(this._g=Math.round(this._g)),this._b<1&&(this._b=Math.round(this._b)),this._ok=e.ok;}s.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return !this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var r=this.toRgb();return (r.r*299+r.g*587+r.b*114)/1e3},getLuminance:function(){var r=this.toRgb(),e,a,i,n,h,f;return e=r.r/255,a=r.g/255,i=r.b/255,e<=.03928?n=e/12.92:n=Math.pow((e+.055)/1.055,2.4),a<=.03928?h=a/12.92:h=Math.pow((a+.055)/1.055,2.4),i<=.03928?f=i/12.92:f=Math.pow((i+.055)/1.055,2.4),.2126*n+.7152*h+.0722*f},setAlpha:function(r){return this._a=w(r),this._roundA=Math.round(100*this._a)/100,this},toHsv:function(){var r=A(this._r,this._g,this._b);return {h:r.h*360,s:r.s,v:r.v,a:this._a}},toHsvString:function(){var r=A(this._r,this._g,this._b),e=Math.round(r.h*360),a=Math.round(r.s*100),i=Math.round(r.v*100);return this._a==1?"hsv("+e+", "+a+"%, "+i+"%)":"hsva("+e+", "+a+"%, "+i+"%, "+this._roundA+")"},toHsl:function(){var r=x(this._r,this._g,this._b);return {h:r.h*360,s:r.s,l:r.l,a:this._a}},toHslString:function(){var r=x(this._r,this._g,this._b),e=Math.round(r.h*360),a=Math.round(r.s*100),i=Math.round(r.l*100);return this._a==1?"hsl("+e+", "+a+"%, "+i+"%)":"hsla("+e+", "+a+"%, "+i+"%, "+this._roundA+")"},toHex:function(r){return S(this._r,this._g,this._b,r)},toHexString:function(r){return "#"+this.toHex(r)},toHex8:function(r){return B(this._r,this._g,this._b,this._a,r)},toHex8String:function(r){return "#"+this.toHex8(r)},toRgb:function(){return {r:Math.round(this._r),g:Math.round(this._g),b:Math.round(this._b),a:this._a}},toRgbString:function(){return this._a==1?"rgb("+Math.round(this._r)+", "+Math.round(this._g)+", "+Math.round(this._b)+")":"rgba("+Math.round(this._r)+", "+Math.round(this._g)+", "+Math.round(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return {r:Math.round(u(this._r,255)*100)+"%",g:Math.round(u(this._g,255)*100)+"%",b:Math.round(u(this._b,255)*100)+"%",a:this._a}},toPercentageRgbString:function(){return this._a==1?"rgb("+Math.round(u(this._r,255)*100)+"%, "+Math.round(u(this._g,255)*100)+"%, "+Math.round(u(this._b,255)*100)+"%)":"rgba("+Math.round(u(this._r,255)*100)+"%, "+Math.round(u(this._g,255)*100)+"%, "+Math.round(u(this._b,255)*100)+"%, "+this._roundA+")"},toName:function(){return this._a===0?"transparent":this._a<1?!1:X[S(this._r,this._g,this._b,!0)]||!1},toFilter:function(r){var e="#"+k(this._r,this._g,this._b,this._a),a=e,i=this._gradientType?"GradientType = 1, ":"";if(r){var n=s(r);a="#"+k(n._r,n._g,n._b,n._a);}return "progid:DXImageTransform.Microsoft.gradient("+i+"startColorstr="+e+",endColorstr="+a+")"},toString:function(r){var e=!!r;r=r||this._format;var a=!1,i=this._a<1&&this._a>=0,n=!e&&i&&(r==="hex"||r==="hex6"||r==="hex3"||r==="hex4"||r==="hex8"||r==="name");return n?r==="name"&&this._a===0?this.toName():this.toRgbString():(r==="rgb"&&(a=this.toRgbString()),r==="prgb"&&(a=this.toPercentageRgbString()),(r==="hex"||r==="hex6")&&(a=this.toHexString()),r==="hex3"&&(a=this.toHexString(!0)),r==="hex4"&&(a=this.toHex8String(!0)),r==="hex8"&&(a=this.toHex8String()),r==="name"&&(a=this.toName()),r==="hsl"&&(a=this.toHslString()),r==="hsv"&&(a=this.toHsvString()),a||this.toHexString())},clone:function(){return s(this.toString())},_applyModification:function(r,e){var a=r.apply(null,[this].concat([].slice.call(e)));return this._r=a._r,this._g=a._g,this._b=a._b,this.setAlpha(a._a),this},lighten:function(){return this._applyModification(O,arguments)},brighten:function(){return this._applyModification(q,arguments)},darken:function(){return this._applyModification(D,arguments)},desaturate:function(){return this._applyModification(z,arguments)},saturate:function(){return this._applyModification(G,arguments)},greyscale:function(){return this._applyModification(L,arguments)},spin:function(){return this._applyModification(U,arguments)},_applyCombination:function(r,e){return r.apply(null,[this].concat([].slice.call(e)))},analogous:function(){return this._applyCombination(j,arguments)},complement:function(){return this._applyCombination(V,arguments)},monochromatic:function(){return this._applyCombination(W,arguments)},splitcomplement:function(){return this._applyCombination($,arguments)},triad:function(){return this._applyCombination(H,[3])},tetrad:function(){return this._applyCombination(H,[4])}};s.fromRatio=function(t,r){if(m(t)=="object"){var e={};for(var a in t)t.hasOwnProperty(a)&&(a==="a"?e[a]=t[a]:e[a]=_(t[a]));t=e;}return s(t,r)};function I(t){var r={r:0,g:0,b:0},e=1,a=null,i=null,n=null,h=!1,f=!1;return typeof t=="string"&&(t=Q(t)),m(t)=="object"&&(p(t.r)&&p(t.g)&&p(t.b)?(r=P(t.r,t.g,t.b),h=!0,f=String(t.r).substr(-1)==="%"?"prgb":"rgb"):p(t.h)&&p(t.s)&&p(t.v)?(a=_(t.s),i=_(t.v),r=N(t.h,a,i),h=!0,f="hsv"):p(t.h)&&p(t.s)&&p(t.l)&&(a=_(t.s),n=_(t.l),r=E(t.h,a,n),h=!0,f="hsl"),t.hasOwnProperty("a")&&(e=t.a)),e=w(e),{ok:h,format:t.format||f,r:Math.min(255,Math.max(r.r,0)),g:Math.min(255,Math.max(r.g,0)),b:Math.min(255,Math.max(r.b,0)),a:e}}function P(t,r,e){return {r:u(t,255)*255,g:u(r,255)*255,b:u(e,255)*255}}function x(t,r,e){t=u(t,255),r=u(r,255),e=u(e,255);var a=Math.max(t,r,e),i=Math.min(t,r,e),n,h,f=(a+i)/2;if(a==i)n=h=0;else {var o=a-i;switch(h=f>.5?o/(2-a-i):o/(a+i),a){case t:n=(r-e)/o+(r1&&(d-=1),d<1/6?g+(v-g)*6*d:d<1/2?v:d<2/3?g+(v-g)*(2/3-d)*6:g}if(r===0)a=i=n=e;else {var f=e<.5?e*(1+r):e+r-e*r,o=2*e-f;a=h(o,f,t+1/3),i=h(o,f,t),n=h(o,f,t-1/3);}return {r:a*255,g:i*255,b:n*255}}function A(t,r,e){t=u(t,255),r=u(r,255),e=u(e,255);var a=Math.max(t,r,e),i=Math.min(t,r,e),n,h,f=a,o=a-i;if(h=a===0?0:o/a,a==i)n=0;else {switch(a){case t:n=(r-e)/o+(r>1)+720)%360;--r;)a.h=(a.h+i)%360,n.push(s(a));return n}function W(t,r){r=r||6;for(var e=s(t).toHsv(),a=e.h,i=e.s,n=e.v,h=[],f=1/r;r--;)h.push(s({h:a,s:i,v:n})),n=(n+f)%1;return h}s.mix=function(t,r,e){e=e===0?0:e||50;var a=s(t).toRgb(),i=s(r).toRgb(),n=e/100,h={r:(i.r-a.r)*n+a.r,g:(i.g-a.g)*n+a.g,b:(i.b-a.b)*n+a.b,a:(i.a-a.a)*n+a.a};return s(h)};s.readability=function(t,r){var e=s(t),a=s(r);return (Math.max(e.getLuminance(),a.getLuminance())+.05)/(Math.min(e.getLuminance(),a.getLuminance())+.05)};s.isReadable=function(t,r,e){var a=s.readability(t,r),i,n;switch(n=!1,i=Y(e),i.level+i.size){case"AAsmall":case"AAAlarge":n=a>=4.5;break;case"AAlarge":n=a>=3;break;case"AAAsmall":n=a>=7;break}return n};s.mostReadable=function(t,r,e){var a=null,i=0,n,h,f,o;e=e||{},h=e.includeFallbackColors,f=e.level,o=e.size;for(var g=0;gi&&(i=n,a=s(r[g]));return s.isReadable(t,a,{level:f,size:o})||!h?a:(e.includeFallbackColors=!1,s.mostReadable(t,["#fff","#000"],e))};var M=s.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},X=s.hexNames=Z(M);function Z(t){var r={};for(var e in t)t.hasOwnProperty(e)&&(r[t[e]]=e);return r}function w(t){return t=parseFloat(t),(isNaN(t)||t<0||t>1)&&(t=1),t}function u(t,r){J(t)&&(t="100%");var e=K(t);return t=Math.min(r,Math.max(0,parseFloat(t))),e&&(t=parseInt(t*r,10)/100),Math.abs(t-r)<1e-6?1:t%r/parseFloat(r)}function y(t){return Math.min(1,Math.max(0,t))}function l(t){return parseInt(t,16)}function J(t){return typeof t=="string"&&t.indexOf(".")!=-1&&parseFloat(t)===1}function K(t){return typeof t=="string"&&t.indexOf("%")!=-1}function b(t){return t.length==1?"0"+t:""+t}function _(t){return t<=1&&(t=t*100+"%"),t}function F(t){return Math.round(parseFloat(t)*255).toString(16)}function R(t){return l(t)/255}var c=function(){var t="[-\\+]?\\d+%?",r="[-\\+]?\\d*\\.\\d+%?",e="(?:"+r+")|(?:"+t+")",a="[\\s|\\(]+("+e+")[,|\\s]+("+e+")[,|\\s]+("+e+")\\s*\\)?",i="[\\s|\\(]+("+e+")[,|\\s]+("+e+")[,|\\s]+("+e+")[,|\\s]+("+e+")\\s*\\)?";return {CSS_UNIT:new RegExp(e),rgb:new RegExp("rgb"+a),rgba:new RegExp("rgba"+i),hsl:new RegExp("hsl"+a),hsla:new RegExp("hsla"+i),hsv:new RegExp("hsv"+a),hsva:new RegExp("hsva"+i),hex3:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex4:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex8:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/}}();function p(t){return !!c.CSS_UNIT.exec(t)}function Q(t){t=t.replace(T,"").replace(C,"").toLowerCase();var r=!1;if(M[t])t=M[t],r=!0;else if(t=="transparent")return {r:0,g:0,b:0,a:0,format:"name"};var e;return (e=c.rgb.exec(t))?{r:e[1],g:e[2],b:e[3]}:(e=c.rgba.exec(t))?{r:e[1],g:e[2],b:e[3],a:e[4]}:(e=c.hsl.exec(t))?{h:e[1],s:e[2],l:e[3]}:(e=c.hsla.exec(t))?{h:e[1],s:e[2],l:e[3],a:e[4]}:(e=c.hsv.exec(t))?{h:e[1],s:e[2],v:e[3]}:(e=c.hsva.exec(t))?{h:e[1],s:e[2],v:e[3],a:e[4]}:(e=c.hex8.exec(t))?{r:l(e[1]),g:l(e[2]),b:l(e[3]),a:R(e[4]),format:r?"name":"hex8"}:(e=c.hex6.exec(t))?{r:l(e[1]),g:l(e[2]),b:l(e[3]),format:r?"name":"hex"}:(e=c.hex4.exec(t))?{r:l(e[1]+""+e[1]),g:l(e[2]+""+e[2]),b:l(e[3]+""+e[3]),a:R(e[4]+""+e[4]),format:r?"name":"hex8"}:(e=c.hex3.exec(t))?{r:l(e[1]+""+e[1]),g:l(e[2]+""+e[2]),b:l(e[3]+""+e[3]),format:r?"name":"hex"}:!1}function Y(t){var r,e;return t=t||{level:"AA",size:"small"},r=(t.level||"AA").toUpperCase(),e=(t.size||"small").toLowerCase(),r!=="AA"&&r!=="AAA"&&(r="AA"),e!=="small"&&e!=="large"&&(e="small"),{level:r,size:e}} + +export { s }; +//# sourceMappingURL=tinycolor-BAU9cgwS.js.map diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/tinycolor-BAU9cgwS.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/tinycolor-BAU9cgwS.js.map new file mode 100644 index 0000000000000000000000000000000000000000..3580ebf168402994d36fb5ba94cb88d4b363e880 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/tinycolor-BAU9cgwS.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tinycolor-BAU9cgwS.js","sources":["../../../../../../js/app/.svelte-kit/adapter-node/chunks/tinycolor.js"],"sourcesContent":["function m(t){\"@babel/helpers - typeof\";return m=typeof Symbol==\"function\"&&typeof Symbol.iterator==\"symbol\"?function(r){return typeof r}:function(r){return r&&typeof Symbol==\"function\"&&r.constructor===Symbol&&r!==Symbol.prototype?\"symbol\":typeof r},m(t)}var T=/^\\s+/,C=/\\s+$/;function s(t,r){if(t=t||\"\",r=r||{},t instanceof s)return t;if(!(this instanceof s))return new s(t,r);var e=I(t);this._originalInput=t,this._r=e.r,this._g=e.g,this._b=e.b,this._a=e.a,this._roundA=Math.round(100*this._a)/100,this._format=r.format||e.format,this._gradientType=r.gradientType,this._r<1&&(this._r=Math.round(this._r)),this._g<1&&(this._g=Math.round(this._g)),this._b<1&&(this._b=Math.round(this._b)),this._ok=e.ok}s.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var r=this.toRgb();return(r.r*299+r.g*587+r.b*114)/1e3},getLuminance:function(){var r=this.toRgb(),e,a,i,n,h,f;return e=r.r/255,a=r.g/255,i=r.b/255,e<=.03928?n=e/12.92:n=Math.pow((e+.055)/1.055,2.4),a<=.03928?h=a/12.92:h=Math.pow((a+.055)/1.055,2.4),i<=.03928?f=i/12.92:f=Math.pow((i+.055)/1.055,2.4),.2126*n+.7152*h+.0722*f},setAlpha:function(r){return this._a=w(r),this._roundA=Math.round(100*this._a)/100,this},toHsv:function(){var r=A(this._r,this._g,this._b);return{h:r.h*360,s:r.s,v:r.v,a:this._a}},toHsvString:function(){var r=A(this._r,this._g,this._b),e=Math.round(r.h*360),a=Math.round(r.s*100),i=Math.round(r.v*100);return this._a==1?\"hsv(\"+e+\", \"+a+\"%, \"+i+\"%)\":\"hsva(\"+e+\", \"+a+\"%, \"+i+\"%, \"+this._roundA+\")\"},toHsl:function(){var r=x(this._r,this._g,this._b);return{h:r.h*360,s:r.s,l:r.l,a:this._a}},toHslString:function(){var r=x(this._r,this._g,this._b),e=Math.round(r.h*360),a=Math.round(r.s*100),i=Math.round(r.l*100);return this._a==1?\"hsl(\"+e+\", \"+a+\"%, \"+i+\"%)\":\"hsla(\"+e+\", \"+a+\"%, \"+i+\"%, \"+this._roundA+\")\"},toHex:function(r){return S(this._r,this._g,this._b,r)},toHexString:function(r){return\"#\"+this.toHex(r)},toHex8:function(r){return B(this._r,this._g,this._b,this._a,r)},toHex8String:function(r){return\"#\"+this.toHex8(r)},toRgb:function(){return{r:Math.round(this._r),g:Math.round(this._g),b:Math.round(this._b),a:this._a}},toRgbString:function(){return this._a==1?\"rgb(\"+Math.round(this._r)+\", \"+Math.round(this._g)+\", \"+Math.round(this._b)+\")\":\"rgba(\"+Math.round(this._r)+\", \"+Math.round(this._g)+\", \"+Math.round(this._b)+\", \"+this._roundA+\")\"},toPercentageRgb:function(){return{r:Math.round(u(this._r,255)*100)+\"%\",g:Math.round(u(this._g,255)*100)+\"%\",b:Math.round(u(this._b,255)*100)+\"%\",a:this._a}},toPercentageRgbString:function(){return this._a==1?\"rgb(\"+Math.round(u(this._r,255)*100)+\"%, \"+Math.round(u(this._g,255)*100)+\"%, \"+Math.round(u(this._b,255)*100)+\"%)\":\"rgba(\"+Math.round(u(this._r,255)*100)+\"%, \"+Math.round(u(this._g,255)*100)+\"%, \"+Math.round(u(this._b,255)*100)+\"%, \"+this._roundA+\")\"},toName:function(){return this._a===0?\"transparent\":this._a<1?!1:X[S(this._r,this._g,this._b,!0)]||!1},toFilter:function(r){var e=\"#\"+k(this._r,this._g,this._b,this._a),a=e,i=this._gradientType?\"GradientType = 1, \":\"\";if(r){var n=s(r);a=\"#\"+k(n._r,n._g,n._b,n._a)}return\"progid:DXImageTransform.Microsoft.gradient(\"+i+\"startColorstr=\"+e+\",endColorstr=\"+a+\")\"},toString:function(r){var e=!!r;r=r||this._format;var a=!1,i=this._a<1&&this._a>=0,n=!e&&i&&(r===\"hex\"||r===\"hex6\"||r===\"hex3\"||r===\"hex4\"||r===\"hex8\"||r===\"name\");return n?r===\"name\"&&this._a===0?this.toName():this.toRgbString():(r===\"rgb\"&&(a=this.toRgbString()),r===\"prgb\"&&(a=this.toPercentageRgbString()),(r===\"hex\"||r===\"hex6\")&&(a=this.toHexString()),r===\"hex3\"&&(a=this.toHexString(!0)),r===\"hex4\"&&(a=this.toHex8String(!0)),r===\"hex8\"&&(a=this.toHex8String()),r===\"name\"&&(a=this.toName()),r===\"hsl\"&&(a=this.toHslString()),r===\"hsv\"&&(a=this.toHsvString()),a||this.toHexString())},clone:function(){return s(this.toString())},_applyModification:function(r,e){var a=r.apply(null,[this].concat([].slice.call(e)));return this._r=a._r,this._g=a._g,this._b=a._b,this.setAlpha(a._a),this},lighten:function(){return this._applyModification(O,arguments)},brighten:function(){return this._applyModification(q,arguments)},darken:function(){return this._applyModification(D,arguments)},desaturate:function(){return this._applyModification(z,arguments)},saturate:function(){return this._applyModification(G,arguments)},greyscale:function(){return this._applyModification(L,arguments)},spin:function(){return this._applyModification(U,arguments)},_applyCombination:function(r,e){return r.apply(null,[this].concat([].slice.call(e)))},analogous:function(){return this._applyCombination(j,arguments)},complement:function(){return this._applyCombination(V,arguments)},monochromatic:function(){return this._applyCombination(W,arguments)},splitcomplement:function(){return this._applyCombination($,arguments)},triad:function(){return this._applyCombination(H,[3])},tetrad:function(){return this._applyCombination(H,[4])}};s.fromRatio=function(t,r){if(m(t)==\"object\"){var e={};for(var a in t)t.hasOwnProperty(a)&&(a===\"a\"?e[a]=t[a]:e[a]=_(t[a]));t=e}return s(t,r)};function I(t){var r={r:0,g:0,b:0},e=1,a=null,i=null,n=null,h=!1,f=!1;return typeof t==\"string\"&&(t=Q(t)),m(t)==\"object\"&&(p(t.r)&&p(t.g)&&p(t.b)?(r=P(t.r,t.g,t.b),h=!0,f=String(t.r).substr(-1)===\"%\"?\"prgb\":\"rgb\"):p(t.h)&&p(t.s)&&p(t.v)?(a=_(t.s),i=_(t.v),r=N(t.h,a,i),h=!0,f=\"hsv\"):p(t.h)&&p(t.s)&&p(t.l)&&(a=_(t.s),n=_(t.l),r=E(t.h,a,n),h=!0,f=\"hsl\"),t.hasOwnProperty(\"a\")&&(e=t.a)),e=w(e),{ok:h,format:t.format||f,r:Math.min(255,Math.max(r.r,0)),g:Math.min(255,Math.max(r.g,0)),b:Math.min(255,Math.max(r.b,0)),a:e}}function P(t,r,e){return{r:u(t,255)*255,g:u(r,255)*255,b:u(e,255)*255}}function x(t,r,e){t=u(t,255),r=u(r,255),e=u(e,255);var a=Math.max(t,r,e),i=Math.min(t,r,e),n,h,f=(a+i)/2;if(a==i)n=h=0;else{var o=a-i;switch(h=f>.5?o/(2-a-i):o/(a+i),a){case t:n=(r-e)/o+(r1&&(d-=1),d<1/6?g+(v-g)*6*d:d<1/2?v:d<2/3?g+(v-g)*(2/3-d)*6:g}if(r===0)a=i=n=e;else{var f=e<.5?e*(1+r):e+r-e*r,o=2*e-f;a=h(o,f,t+1/3),i=h(o,f,t),n=h(o,f,t-1/3)}return{r:a*255,g:i*255,b:n*255}}function A(t,r,e){t=u(t,255),r=u(r,255),e=u(e,255);var a=Math.max(t,r,e),i=Math.min(t,r,e),n,h,f=a,o=a-i;if(h=a===0?0:o/a,a==i)n=0;else{switch(a){case t:n=(r-e)/o+(r>1)+720)%360;--r;)a.h=(a.h+i)%360,n.push(s(a));return n}function W(t,r){r=r||6;for(var e=s(t).toHsv(),a=e.h,i=e.s,n=e.v,h=[],f=1/r;r--;)h.push(s({h:a,s:i,v:n})),n=(n+f)%1;return h}s.mix=function(t,r,e){e=e===0?0:e||50;var a=s(t).toRgb(),i=s(r).toRgb(),n=e/100,h={r:(i.r-a.r)*n+a.r,g:(i.g-a.g)*n+a.g,b:(i.b-a.b)*n+a.b,a:(i.a-a.a)*n+a.a};return s(h)};s.readability=function(t,r){var e=s(t),a=s(r);return(Math.max(e.getLuminance(),a.getLuminance())+.05)/(Math.min(e.getLuminance(),a.getLuminance())+.05)};s.isReadable=function(t,r,e){var a=s.readability(t,r),i,n;switch(n=!1,i=Y(e),i.level+i.size){case\"AAsmall\":case\"AAAlarge\":n=a>=4.5;break;case\"AAlarge\":n=a>=3;break;case\"AAAsmall\":n=a>=7;break}return n};s.mostReadable=function(t,r,e){var a=null,i=0,n,h,f,o;e=e||{},h=e.includeFallbackColors,f=e.level,o=e.size;for(var g=0;gi&&(i=n,a=s(r[g]));return s.isReadable(t,a,{level:f,size:o})||!h?a:(e.includeFallbackColors=!1,s.mostReadable(t,[\"#fff\",\"#000\"],e))};var M=s.names={aliceblue:\"f0f8ff\",antiquewhite:\"faebd7\",aqua:\"0ff\",aquamarine:\"7fffd4\",azure:\"f0ffff\",beige:\"f5f5dc\",bisque:\"ffe4c4\",black:\"000\",blanchedalmond:\"ffebcd\",blue:\"00f\",blueviolet:\"8a2be2\",brown:\"a52a2a\",burlywood:\"deb887\",burntsienna:\"ea7e5d\",cadetblue:\"5f9ea0\",chartreuse:\"7fff00\",chocolate:\"d2691e\",coral:\"ff7f50\",cornflowerblue:\"6495ed\",cornsilk:\"fff8dc\",crimson:\"dc143c\",cyan:\"0ff\",darkblue:\"00008b\",darkcyan:\"008b8b\",darkgoldenrod:\"b8860b\",darkgray:\"a9a9a9\",darkgreen:\"006400\",darkgrey:\"a9a9a9\",darkkhaki:\"bdb76b\",darkmagenta:\"8b008b\",darkolivegreen:\"556b2f\",darkorange:\"ff8c00\",darkorchid:\"9932cc\",darkred:\"8b0000\",darksalmon:\"e9967a\",darkseagreen:\"8fbc8f\",darkslateblue:\"483d8b\",darkslategray:\"2f4f4f\",darkslategrey:\"2f4f4f\",darkturquoise:\"00ced1\",darkviolet:\"9400d3\",deeppink:\"ff1493\",deepskyblue:\"00bfff\",dimgray:\"696969\",dimgrey:\"696969\",dodgerblue:\"1e90ff\",firebrick:\"b22222\",floralwhite:\"fffaf0\",forestgreen:\"228b22\",fuchsia:\"f0f\",gainsboro:\"dcdcdc\",ghostwhite:\"f8f8ff\",gold:\"ffd700\",goldenrod:\"daa520\",gray:\"808080\",green:\"008000\",greenyellow:\"adff2f\",grey:\"808080\",honeydew:\"f0fff0\",hotpink:\"ff69b4\",indianred:\"cd5c5c\",indigo:\"4b0082\",ivory:\"fffff0\",khaki:\"f0e68c\",lavender:\"e6e6fa\",lavenderblush:\"fff0f5\",lawngreen:\"7cfc00\",lemonchiffon:\"fffacd\",lightblue:\"add8e6\",lightcoral:\"f08080\",lightcyan:\"e0ffff\",lightgoldenrodyellow:\"fafad2\",lightgray:\"d3d3d3\",lightgreen:\"90ee90\",lightgrey:\"d3d3d3\",lightpink:\"ffb6c1\",lightsalmon:\"ffa07a\",lightseagreen:\"20b2aa\",lightskyblue:\"87cefa\",lightslategray:\"789\",lightslategrey:\"789\",lightsteelblue:\"b0c4de\",lightyellow:\"ffffe0\",lime:\"0f0\",limegreen:\"32cd32\",linen:\"faf0e6\",magenta:\"f0f\",maroon:\"800000\",mediumaquamarine:\"66cdaa\",mediumblue:\"0000cd\",mediumorchid:\"ba55d3\",mediumpurple:\"9370db\",mediumseagreen:\"3cb371\",mediumslateblue:\"7b68ee\",mediumspringgreen:\"00fa9a\",mediumturquoise:\"48d1cc\",mediumvioletred:\"c71585\",midnightblue:\"191970\",mintcream:\"f5fffa\",mistyrose:\"ffe4e1\",moccasin:\"ffe4b5\",navajowhite:\"ffdead\",navy:\"000080\",oldlace:\"fdf5e6\",olive:\"808000\",olivedrab:\"6b8e23\",orange:\"ffa500\",orangered:\"ff4500\",orchid:\"da70d6\",palegoldenrod:\"eee8aa\",palegreen:\"98fb98\",paleturquoise:\"afeeee\",palevioletred:\"db7093\",papayawhip:\"ffefd5\",peachpuff:\"ffdab9\",peru:\"cd853f\",pink:\"ffc0cb\",plum:\"dda0dd\",powderblue:\"b0e0e6\",purple:\"800080\",rebeccapurple:\"663399\",red:\"f00\",rosybrown:\"bc8f8f\",royalblue:\"4169e1\",saddlebrown:\"8b4513\",salmon:\"fa8072\",sandybrown:\"f4a460\",seagreen:\"2e8b57\",seashell:\"fff5ee\",sienna:\"a0522d\",silver:\"c0c0c0\",skyblue:\"87ceeb\",slateblue:\"6a5acd\",slategray:\"708090\",slategrey:\"708090\",snow:\"fffafa\",springgreen:\"00ff7f\",steelblue:\"4682b4\",tan:\"d2b48c\",teal:\"008080\",thistle:\"d8bfd8\",tomato:\"ff6347\",turquoise:\"40e0d0\",violet:\"ee82ee\",wheat:\"f5deb3\",white:\"fff\",whitesmoke:\"f5f5f5\",yellow:\"ff0\",yellowgreen:\"9acd32\"},X=s.hexNames=Z(M);function Z(t){var r={};for(var e in t)t.hasOwnProperty(e)&&(r[t[e]]=e);return r}function w(t){return t=parseFloat(t),(isNaN(t)||t<0||t>1)&&(t=1),t}function u(t,r){J(t)&&(t=\"100%\");var e=K(t);return t=Math.min(r,Math.max(0,parseFloat(t))),e&&(t=parseInt(t*r,10)/100),Math.abs(t-r)<1e-6?1:t%r/parseFloat(r)}function y(t){return Math.min(1,Math.max(0,t))}function l(t){return parseInt(t,16)}function J(t){return typeof t==\"string\"&&t.indexOf(\".\")!=-1&&parseFloat(t)===1}function K(t){return typeof t==\"string\"&&t.indexOf(\"%\")!=-1}function b(t){return t.length==1?\"0\"+t:\"\"+t}function _(t){return t<=1&&(t=t*100+\"%\"),t}function F(t){return Math.round(parseFloat(t)*255).toString(16)}function R(t){return l(t)/255}var c=function(){var t=\"[-\\\\+]?\\\\d+%?\",r=\"[-\\\\+]?\\\\d*\\\\.\\\\d+%?\",e=\"(?:\"+r+\")|(?:\"+t+\")\",a=\"[\\\\s|\\\\(]+(\"+e+\")[,|\\\\s]+(\"+e+\")[,|\\\\s]+(\"+e+\")\\\\s*\\\\)?\",i=\"[\\\\s|\\\\(]+(\"+e+\")[,|\\\\s]+(\"+e+\")[,|\\\\s]+(\"+e+\")[,|\\\\s]+(\"+e+\")\\\\s*\\\\)?\";return{CSS_UNIT:new RegExp(e),rgb:new RegExp(\"rgb\"+a),rgba:new RegExp(\"rgba\"+i),hsl:new RegExp(\"hsl\"+a),hsla:new RegExp(\"hsla\"+i),hsv:new RegExp(\"hsv\"+a),hsva:new RegExp(\"hsva\"+i),hex3:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex4:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex8:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/}}();function p(t){return!!c.CSS_UNIT.exec(t)}function Q(t){t=t.replace(T,\"\").replace(C,\"\").toLowerCase();var r=!1;if(M[t])t=M[t],r=!0;else if(t==\"transparent\")return{r:0,g:0,b:0,a:0,format:\"name\"};var e;return(e=c.rgb.exec(t))?{r:e[1],g:e[2],b:e[3]}:(e=c.rgba.exec(t))?{r:e[1],g:e[2],b:e[3],a:e[4]}:(e=c.hsl.exec(t))?{h:e[1],s:e[2],l:e[3]}:(e=c.hsla.exec(t))?{h:e[1],s:e[2],l:e[3],a:e[4]}:(e=c.hsv.exec(t))?{h:e[1],s:e[2],v:e[3]}:(e=c.hsva.exec(t))?{h:e[1],s:e[2],v:e[3],a:e[4]}:(e=c.hex8.exec(t))?{r:l(e[1]),g:l(e[2]),b:l(e[3]),a:R(e[4]),format:r?\"name\":\"hex8\"}:(e=c.hex6.exec(t))?{r:l(e[1]),g:l(e[2]),b:l(e[3]),format:r?\"name\":\"hex\"}:(e=c.hex4.exec(t))?{r:l(e[1]+\"\"+e[1]),g:l(e[2]+\"\"+e[2]),b:l(e[3]+\"\"+e[3]),a:R(e[4]+\"\"+e[4]),format:r?\"name\":\"hex8\"}:(e=c.hex3.exec(t))?{r:l(e[1]+\"\"+e[1]),g:l(e[2]+\"\"+e[2]),b:l(e[3]+\"\"+e[3]),format:r?\"name\":\"hex\"}:!1}function Y(t){var r,e;return t=t||{level:\"AA\",size:\"small\"},r=(t.level||\"AA\").toUpperCase(),e=(t.size||\"small\").toLowerCase(),r!==\"AA\"&&r!==\"AAA\"&&(r=\"AA\"),e!==\"small\"&&e!==\"large\"&&(e=\"small\"),{level:r,size:e}}export{s as t};\n//# sourceMappingURL=tinycolor.js.map\n"],"names":[],"mappings":"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AAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,C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AAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC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,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;;;;"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/tr-BjNdPtGX.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/tr-BjNdPtGX.js new file mode 100644 index 0000000000000000000000000000000000000000..b197b72e627610059ff0f4ab3811289a14cda36a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/tr-BjNdPtGX.js @@ -0,0 +1,4 @@ +const a="Türkçe",e={built_with_gradio:"Gradio ile oluşturulmuştur",clear:"Temizle",or:"veya",submit:"Gönder",built_with:"İle oluşturuldu",download:"İndir",edit:"Düzenle",empty:"Boş",error:"Hata",hosted_on:"Şurada barındırılıyor:",loading:"Yükleniyor",logo:"Logo",remove:"Kaldır",settings:"Ayarlar",share:"Paylaş",undo:"Geri Al",no_devices:"Hiçbir cihaz bulunamadı",language:"Dil",display_theme:"Görünüm Teması",pwa:"Progressive Web Uygulaması"},r={click_to_upload:"Yüklemek için tıkla",drop_audio:"Ses dosyasını buraya sürükle",drop_csv:"CSV dosyasını buraya sürükle",drop_file:"Dosyayı buraya sürükle",drop_image:"Resmi buraya sürükle",drop_video:"Videoyu buraya sürükle",drop_gallery:"Medyayı buraya bırak",paste_clipboard:"Panodan yapıştır"},i={annotated_image:"Açıklamalı Görüntü"},o={allow_recording_access:"Lütfen kayıt yapmak için mikrofona erişim izni verin.",audio:"Ses",drop_to_upload:"Yüklemek için bir ses dosyasını buraya bırakın",record_from_microphone:"Mikrofondan kaydet",stop_recording:"Kaydı durdur",no_device_support:"Medya cihazlarına erişilemedi. Güvenli bir kökende (https) veya yerel makinede (localhost) çalıştığınızdan emin olun (veya geçerli bir SSL sertifikası ile ssl_verify'yi geçtiniz) ve tarayıcınızın cihazınıza erişim izni verdiğini kontrol edin.",stop:"Durdur",resume:"Devam Et",record:"Kaydet",no_microphone:"Hiçbir mikrofon bulunamadı",pause:"Duraklat",play:"Oynat",waiting:"Bekliyor"},n={connection_can_break:"Mobil cihazda, bu sekme odaklanmadığında veya cihaz uyku moduna geçtiğinde bağlantı kopabilir ve kuyrukta olduğunuz yer kaybedilebilir.",long_requests_queue:"Bekleyen isteklerin uzun bir kuyruğu var. Kuyruktan atlamak için bu Space'i kopyalayın.",lost_connection:"Sayfa terk edildiği için bağlantı kaybedildi. Kuyruğa yeniden katılıyor...",waiting_for_inputs:"Dosya(lar)ın yükleme işlemini tamamlaması bekleniyor, lütfen yeniden deneyin."},l={checkbox:"Onay Kutusu",checkbox_group:"Onay Kutusu Grubu"},t={code:"Kod"},d={color_picker:"Renk Seçici"},s={incorrect_format:"Yanlış format, sadece CSV ve TSV dosyaları destekleniyor",new_column:"Sütun ekle",new_row:"Yeni satır",add_row_above:"Yukarıya satır ekle",add_row_below:"Aşağıya satır ekle",delete_row:"Satırı sil",delete_column:"Sütunu sil",add_column_left:"Sola sütun ekle",add_column_right:"Sağa sütun ekle",sort_column:"Sütunu sırala",sort_ascending:"Artan sırala",sort_descending:"Azalan sırala",drop_to_upload:"Veriyi veri çerçevesine aktarmak için CSV veya TSV dosyalarını buraya bırakın",clear_sort:"Sıralamayı temizle"},u={dropdown:"Açılır Liste"},c={build_error:"Bir derleme hatası var",config_error:"Bir yapılandırma hatası var",contact_page_author:"Lütfen sayfanın yazarıyla iletişime geçin ve bildirin.",no_app_file:"Uygulama dosyası yok",runtime_error:"Bir çalışma zamanı hatası var",space_not_working:'"Space çalışmıyor çünkü" {0}',space_paused:"Space duraklatıldı",use_via_api:"API üzerinden kullan",use_via_api_or_mcp:"API veya MCP üzerinden kullan"},_={uploading:"Yükleniyor..."},y={highlighted_text:"Vurgulanan Metin"},k={allow_webcam_access:"Lütfen kayıt için web kamerasına erişim izni verin.",brush_color:"Fırça rengi",brush_radius:"Fırça boyutu",image:"Görüntü",remove_image:"Resmi kaldır",select_brush_color:"Fırça rengini seç",start_drawing:"Çizim yapmaya başla",use_brush:"Fırça kullan",drop_to_upload:"Yüklemek için bir görüntü dosyasını buraya bırakın"},m={label:"Etiket"},b={enable_cookies:"Eğer HuggingFace Space'i Gizli Mod'da ziyaret ediyorsanız, üçüncü taraf çerezleri etkinleştirmelisiniz.",incorrect_credentials:"Yanlış kimlik bilgileri",username:"Kullanıcı adı",password:"Parola",login:"Giriş yap"},p={number:"Sayı"},g={plot:"Grafik"},h={radio:"Radyo Düğmesi"},v={slider:"Kaydırıcı"},z={drop_to_upload:"Yüklemek için bir video dosyasını buraya bırakın"},f={edit:"Düzenle",retry:"Tekrar Dene",undo:"Geri Al",submit:"Gönder",cancel:"İptal",like:"Beğen",dislike:"Beğenme",clear:"Sohbeti Temizle"},S={_name:a,common:e,upload_text:r,"3D_model":{"3d_model":"3D Model",drop_to_upload:"Yüklemek için bir 3D model dosyasını (.obj, .glb, .stl, .gltf, .splat veya .ply) buraya bırakın"},annotated_image:i,audio:o,blocks:n,checkbox:l,code:t,color_picker:d,dataframe:s,dropdown:u,errors:c,file:_,highlighted_text:y,image:k,label:m,login:b,number:p,plot:g,radio:h,slider:v,video:z,chatbot:f}; + +export { a as _name, i as annotated_image, o as audio, n as blocks, f as chatbot, l as checkbox, t as code, d as color_picker, e as common, s as dataframe, S as default, u as dropdown, c as errors, _ as file, y as highlighted_text, k as image, m as label, b as login, p as number, g as plot, h as radio, v as slider, r as upload_text, z as video }; +//# sourceMappingURL=tr-BjNdPtGX.js.map diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/tr-BjNdPtGX.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/tr-BjNdPtGX.js.map new file mode 100644 index 0000000000000000000000000000000000000000..d62e6aa13b1e11e3e55e3d66dce86f37e9a043fa --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/tr-BjNdPtGX.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tr-BjNdPtGX.js","sources":["../../../../../../js/app/.svelte-kit/adapter-node/chunks/tr.js"],"sourcesContent":["const a=\"Türkçe\",e={built_with_gradio:\"Gradio ile oluşturulmuştur\",clear:\"Temizle\",or:\"veya\",submit:\"Gönder\",built_with:\"İle oluşturuldu\",download:\"İndir\",edit:\"Düzenle\",empty:\"Boş\",error:\"Hata\",hosted_on:\"Şurada barındırılıyor:\",loading:\"Yükleniyor\",logo:\"Logo\",remove:\"Kaldır\",settings:\"Ayarlar\",share:\"Paylaş\",undo:\"Geri Al\",no_devices:\"Hiçbir cihaz bulunamadı\",language:\"Dil\",display_theme:\"Görünüm Teması\",pwa:\"Progressive Web Uygulaması\"},r={click_to_upload:\"Yüklemek için tıkla\",drop_audio:\"Ses dosyasını buraya sürükle\",drop_csv:\"CSV dosyasını buraya sürükle\",drop_file:\"Dosyayı buraya sürükle\",drop_image:\"Resmi buraya sürükle\",drop_video:\"Videoyu buraya sürükle\",drop_gallery:\"Medyayı buraya bırak\",paste_clipboard:\"Panodan yapıştır\"},i={annotated_image:\"Açıklamalı Görüntü\"},o={allow_recording_access:\"Lütfen kayıt yapmak için mikrofona erişim izni verin.\",audio:\"Ses\",drop_to_upload:\"Yüklemek için bir ses dosyasını buraya bırakın\",record_from_microphone:\"Mikrofondan kaydet\",stop_recording:\"Kaydı durdur\",no_device_support:\"Medya cihazlarına erişilemedi. Güvenli bir kökende (https) veya yerel makinede (localhost) çalıştığınızdan emin olun (veya geçerli bir SSL sertifikası ile ssl_verify'yi geçtiniz) ve tarayıcınızın cihazınıza erişim izni verdiğini kontrol edin.\",stop:\"Durdur\",resume:\"Devam Et\",record:\"Kaydet\",no_microphone:\"Hiçbir mikrofon bulunamadı\",pause:\"Duraklat\",play:\"Oynat\",waiting:\"Bekliyor\"},n={connection_can_break:\"Mobil cihazda, bu sekme odaklanmadığında veya cihaz uyku moduna geçtiğinde bağlantı kopabilir ve kuyrukta olduğunuz yer kaybedilebilir.\",long_requests_queue:\"Bekleyen isteklerin uzun bir kuyruğu var. Kuyruktan atlamak için bu Space'i kopyalayın.\",lost_connection:\"Sayfa terk edildiği için bağlantı kaybedildi. Kuyruğa yeniden katılıyor...\",waiting_for_inputs:\"Dosya(lar)ın yükleme işlemini tamamlaması bekleniyor, lütfen yeniden deneyin.\"},l={checkbox:\"Onay Kutusu\",checkbox_group:\"Onay Kutusu Grubu\"},t={code:\"Kod\"},d={color_picker:\"Renk Seçici\"},s={incorrect_format:\"Yanlış format, sadece CSV ve TSV dosyaları destekleniyor\",new_column:\"Sütun ekle\",new_row:\"Yeni satır\",add_row_above:\"Yukarıya satır ekle\",add_row_below:\"Aşağıya satır ekle\",delete_row:\"Satırı sil\",delete_column:\"Sütunu sil\",add_column_left:\"Sola sütun ekle\",add_column_right:\"Sağa sütun ekle\",sort_column:\"Sütunu sırala\",sort_ascending:\"Artan sırala\",sort_descending:\"Azalan sırala\",drop_to_upload:\"Veriyi veri çerçevesine aktarmak için CSV veya TSV dosyalarını buraya bırakın\",clear_sort:\"Sıralamayı temizle\"},u={dropdown:\"Açılır Liste\"},c={build_error:\"Bir derleme hatası var\",config_error:\"Bir yapılandırma hatası var\",contact_page_author:\"Lütfen sayfanın yazarıyla iletişime geçin ve bildirin.\",no_app_file:\"Uygulama dosyası yok\",runtime_error:\"Bir çalışma zamanı hatası var\",space_not_working:'\"Space çalışmıyor çünkü\" {0}',space_paused:\"Space duraklatıldı\",use_via_api:\"API üzerinden kullan\",use_via_api_or_mcp:\"API veya MCP üzerinden kullan\"},_={uploading:\"Yükleniyor...\"},y={highlighted_text:\"Vurgulanan Metin\"},k={allow_webcam_access:\"Lütfen kayıt için web kamerasına erişim izni verin.\",brush_color:\"Fırça rengi\",brush_radius:\"Fırça boyutu\",image:\"Görüntü\",remove_image:\"Resmi kaldır\",select_brush_color:\"Fırça rengini seç\",start_drawing:\"Çizim yapmaya başla\",use_brush:\"Fırça kullan\",drop_to_upload:\"Yüklemek için bir görüntü dosyasını buraya bırakın\"},m={label:\"Etiket\"},b={enable_cookies:\"Eğer HuggingFace Space'i Gizli Mod'da ziyaret ediyorsanız, üçüncü taraf çerezleri etkinleştirmelisiniz.\",incorrect_credentials:\"Yanlış kimlik bilgileri\",username:\"Kullanıcı adı\",password:\"Parola\",login:\"Giriş yap\"},p={number:\"Sayı\"},g={plot:\"Grafik\"},h={radio:\"Radyo Düğmesi\"},v={slider:\"Kaydırıcı\"},z={drop_to_upload:\"Yüklemek için bir video dosyasını buraya bırakın\"},f={edit:\"Düzenle\",retry:\"Tekrar Dene\",undo:\"Geri Al\",submit:\"Gönder\",cancel:\"İptal\",like:\"Beğen\",dislike:\"Beğenme\",clear:\"Sohbeti Temizle\"},S={_name:a,common:e,upload_text:r,\"3D_model\":{\"3d_model\":\"3D Model\",drop_to_upload:\"Yüklemek için bir 3D model dosyasını (.obj, .glb, .stl, .gltf, .splat veya .ply) buraya bırakın\"},annotated_image:i,audio:o,blocks:n,checkbox:l,code:t,color_picker:d,dataframe:s,dropdown:u,errors:c,file:_,highlighted_text:y,image:k,label:m,login:b,number:p,plot:g,radio:h,slider:v,video:z,chatbot:f};export{a as _name,i as annotated_image,o as audio,n as blocks,f as chatbot,l as checkbox,t as code,d as color_picker,e as common,s as dataframe,S as default,u as dropdown,c as errors,_ as file,y as highlighted_text,k as image,m as label,b as login,p as number,g as plot,h as radio,v as slider,r as upload_text,z as video};\n//# sourceMappingURL=tr.js.map\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/uk-DxkC9TjY.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/uk-DxkC9TjY.js new file mode 100644 index 0000000000000000000000000000000000000000..920dd942657f739d319b2eeeb1d5196c8bbddeed --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/uk-DxkC9TjY.js @@ -0,0 +1,4 @@ +const o="Українська",e={built_with_gradio:"Зроблено на основі Gradio",clear:"Очистити",or:"або",submit:"Надіслати",settings:"Налаштування",built_with:"Зроблено з",download:"Завантажити",edit:"Редагувати",empty:"Порожній",error:"Помилка",hosted_on:"Розміщено на",loading:"Завантаження",logo:"Логотип",remove:"Видалити",share:"Поділитися",undo:"Скасувати",no_devices:"Пристроїв не знайдено",language:"Мова",display_theme:"Тема оформлення",pwa:"Прогресивний веб-додаток"},r={click_to_upload:"Натисніть, щоб завантажити",drop_audio:"Перетягніть аудіо сюди",drop_csv:"Перетягніть CSV-файл сюди",drop_file:"Перетягніть файл сюди",drop_image:"Перетягніть зображення сюди",drop_video:"Перетягніть відео сюди",drop_gallery:"Перетягніть медіа сюди",paste_clipboard:"Вставити з буфера обміну"},t={annotated_image:"Анотоване зображення"},a={allow_recording_access:"Будь ласка, дайте доступ до мікрофона для запису.",audio:"Аудіо",drop_to_upload:"Перетягніть аудіофайл сюди, щоб завантажити",record_from_microphone:"Записати з мікрофона",stop_recording:"Зупинити запис",no_device_support:"Медійні пристрої не можуть бути доступні. Переконайтеся, що ви запускаєте з захищеного джерела (https) або localhost (або ви передали дійсний SSL-сертифікат до ssl_verify), і ви дозволили браузеру доступ до вашого пристрою.",stop:"Зупинити",resume:"Відновити",record:"Записати",no_microphone:"Мікрофон не виявлено",pause:"Пауза",play:"Відтворити",waiting:"Очікування"},c={connection_can_break:"На мобільному пристрої з'єднання може перерватися, якщо ця вкладка втрачає фокус або пристрій увійде в режим сну, в результаті чого ви втратите своє місце в черзі.",long_requests_queue:"У черзі залишилось багато запитів. Скопіюйте цей Space, щоб пропустити чергу.",lost_connection:"З'єднання втрачено через вихід зі сторінки. Переміщення до кінця черги...",waiting_for_inputs:"Чекаємо завершення завантаження файлу(ів), будь ласка, спробуйте ще раз."},_={checkbox:"Прапорець",checkbox_group:"Група прапорців"},n={code:"Код"},d={color_picker:"Вибір кольору"},i={incorrect_format:"Неправильний формат, підтримуються лише файли CSV та TSV",new_column:"Додати стовпець",new_row:"Новий рядок",add_row_above:"Додати рядок вище",add_row_below:"Додати рядок нижче",delete_row:"Видалити рядок",delete_column:"Видалити стовпець",add_column_left:"Додати стовпець зліва",add_column_right:"Додати стовпець справа",sort_column:"Сортувати стовпець",sort_ascending:"Сортувати за зростанням",sort_descending:"Сортувати за спаданням",drop_to_upload:"Перетягніть CSV або TSV файли сюди, щоб імпортувати дані в таблицю даних",clear_sort:"Очистити сортування"},l={dropdown:"Випадне меню"},s={build_error:"Є помилка побудови",config_error:"Є помилка конфігурації",contact_page_author:"Будь ласка, зв'яжіться з автором сторінки, щоб повідомити.",no_app_file:"Немає файлу додатку",runtime_error:"Є помилка виконання",space_not_working:'"Space не працює, оскільки" {0}',space_paused:"Space призупинено",use_via_api:"Використовувати через API",use_via_api_or_mcp:"Використовувати через API або MCP"},p={uploading:"Завантаження..."},u={highlighted_text:"Виділений текст"},g={allow_webcam_access:"Будь ласка, дайте доступ до веб-камери для запису.",brush_color:"Колір пензля",brush_radius:"Розмір пензля",image:"Зображення",remove_image:"Видалити зображення",select_brush_color:"Виберіть колір пензля",start_drawing:"Почніть малювати",use_brush:"Використовуйте пензель",drop_to_upload:"Перетягніть файл зображення сюди, щоб завантажити"},m={label:"Мітка"},b={enable_cookies:"Якщо ви відвідуєте HuggingFace Space у режимі Інкогніто, вам потрібно увімкнути сторонні куки.",incorrect_credentials:"Неправильні облікові дані",username:"Ім'я користувача",password:"Пароль",login:"Увійти"},h={number:"Число"},w={plot:"Діаграма"},k={radio:"Перемикач"},f={slider:"Повзунок"},v={drop_to_upload:"Перетягніть відеофайл сюди, щоб завантажити"},S={edit:"Редагувати",retry:"Повторити",undo:"Скасувати",submit:"Надіслати",cancel:"Скасувати",like:"Подобається",dislike:"Не подобається",clear:"Очистити чат"},x={_name:o,common:e,upload_text:r,"3D_model":{"3d_model":"3D-модель",drop_to_upload:"Перетягніть файл 3D-моделі (.obj, .glb, .stl, .gltf, .splat або .ply) сюди, щоб завантажити"},annotated_image:t,audio:a,blocks:c,checkbox:_,code:n,color_picker:d,dataframe:i,dropdown:l,errors:s,file:p,highlighted_text:u,image:g,label:m,login:b,number:h,plot:w,radio:k,slider:f,video:v,chatbot:S}; + +export { o as _name, t as annotated_image, a as audio, c as blocks, S as chatbot, _ as checkbox, n as code, d as color_picker, e as common, i as dataframe, x as default, l as dropdown, s as errors, p as file, u as highlighted_text, g as image, m as label, b as login, h as number, w as plot, k as radio, f as slider, r as upload_text, v as video }; +//# sourceMappingURL=uk-DxkC9TjY.js.map diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/uk-DxkC9TjY.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/uk-DxkC9TjY.js.map new file mode 100644 index 0000000000000000000000000000000000000000..39d494b4a75257ecd3132721a941cc4f62469962 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/uk-DxkC9TjY.js.map @@ -0,0 +1 @@ +{"version":3,"file":"uk-DxkC9TjY.js","sources":["../../../../../../js/app/.svelte-kit/adapter-node/chunks/uk.js"],"sourcesContent":["const o=\"Українська\",e={built_with_gradio:\"Зроблено на основі Gradio\",clear:\"Очистити\",or:\"або\",submit:\"Надіслати\",settings:\"Налаштування\",built_with:\"Зроблено з\",download:\"Завантажити\",edit:\"Редагувати\",empty:\"Порожній\",error:\"Помилка\",hosted_on:\"Розміщено на\",loading:\"Завантаження\",logo:\"Логотип\",remove:\"Видалити\",share:\"Поділитися\",undo:\"Скасувати\",no_devices:\"Пристроїв не знайдено\",language:\"Мова\",display_theme:\"Тема оформлення\",pwa:\"Прогресивний веб-додаток\"},r={click_to_upload:\"Натисніть, щоб завантажити\",drop_audio:\"Перетягніть аудіо сюди\",drop_csv:\"Перетягніть CSV-файл сюди\",drop_file:\"Перетягніть файл сюди\",drop_image:\"Перетягніть зображення сюди\",drop_video:\"Перетягніть відео сюди\",drop_gallery:\"Перетягніть медіа сюди\",paste_clipboard:\"Вставити з буфера обміну\"},t={annotated_image:\"Анотоване зображення\"},a={allow_recording_access:\"Будь ласка, дайте доступ до мікрофона для запису.\",audio:\"Аудіо\",drop_to_upload:\"Перетягніть аудіофайл сюди, щоб завантажити\",record_from_microphone:\"Записати з мікрофона\",stop_recording:\"Зупинити запис\",no_device_support:\"Медійні пристрої не можуть бути доступні. Переконайтеся, що ви запускаєте з захищеного джерела (https) або localhost (або ви передали дійсний SSL-сертифікат до ssl_verify), і ви дозволили браузеру доступ до вашого пристрою.\",stop:\"Зупинити\",resume:\"Відновити\",record:\"Записати\",no_microphone:\"Мікрофон не виявлено\",pause:\"Пауза\",play:\"Відтворити\",waiting:\"Очікування\"},c={connection_can_break:\"На мобільному пристрої з'єднання може перерватися, якщо ця вкладка втрачає фокус або пристрій увійде в режим сну, в результаті чого ви втратите своє місце в черзі.\",long_requests_queue:\"У черзі залишилось багато запитів. Скопіюйте цей Space, щоб пропустити чергу.\",lost_connection:\"З'єднання втрачено через вихід зі сторінки. Переміщення до кінця черги...\",waiting_for_inputs:\"Чекаємо завершення завантаження файлу(ів), будь ласка, спробуйте ще раз.\"},_={checkbox:\"Прапорець\",checkbox_group:\"Група прапорців\"},n={code:\"Код\"},d={color_picker:\"Вибір кольору\"},i={incorrect_format:\"Неправильний формат, підтримуються лише файли CSV та TSV\",new_column:\"Додати стовпець\",new_row:\"Новий рядок\",add_row_above:\"Додати рядок вище\",add_row_below:\"Додати рядок нижче\",delete_row:\"Видалити рядок\",delete_column:\"Видалити стовпець\",add_column_left:\"Додати стовпець зліва\",add_column_right:\"Додати стовпець справа\",sort_column:\"Сортувати стовпець\",sort_ascending:\"Сортувати за зростанням\",sort_descending:\"Сортувати за спаданням\",drop_to_upload:\"Перетягніть CSV або TSV файли сюди, щоб імпортувати дані в таблицю даних\",clear_sort:\"Очистити сортування\"},l={dropdown:\"Випадне меню\"},s={build_error:\"Є помилка побудови\",config_error:\"Є помилка конфігурації\",contact_page_author:\"Будь ласка, зв'яжіться з автором сторінки, щоб повідомити.\",no_app_file:\"Немає файлу додатку\",runtime_error:\"Є помилка виконання\",space_not_working:'\"Space не працює, оскільки\" {0}',space_paused:\"Space призупинено\",use_via_api:\"Використовувати через API\",use_via_api_or_mcp:\"Використовувати через API або MCP\"},p={uploading:\"Завантаження...\"},u={highlighted_text:\"Виділений текст\"},g={allow_webcam_access:\"Будь ласка, дайте доступ до веб-камери для запису.\",brush_color:\"Колір пензля\",brush_radius:\"Розмір пензля\",image:\"Зображення\",remove_image:\"Видалити зображення\",select_brush_color:\"Виберіть колір пензля\",start_drawing:\"Почніть малювати\",use_brush:\"Використовуйте пензель\",drop_to_upload:\"Перетягніть файл зображення сюди, щоб завантажити\"},m={label:\"Мітка\"},b={enable_cookies:\"Якщо ви відвідуєте HuggingFace Space у режимі Інкогніто, вам потрібно увімкнути сторонні куки.\",incorrect_credentials:\"Неправильні облікові дані\",username:\"Ім'я користувача\",password:\"Пароль\",login:\"Увійти\"},h={number:\"Число\"},w={plot:\"Діаграма\"},k={radio:\"Перемикач\"},f={slider:\"Повзунок\"},v={drop_to_upload:\"Перетягніть відеофайл сюди, щоб завантажити\"},S={edit:\"Редагувати\",retry:\"Повторити\",undo:\"Скасувати\",submit:\"Надіслати\",cancel:\"Скасувати\",like:\"Подобається\",dislike:\"Не подобається\",clear:\"Очистити чат\"},x={_name:o,common:e,upload_text:r,\"3D_model\":{\"3d_model\":\"3D-модель\",drop_to_upload:\"Перетягніть файл 3D-моделі (.obj, .glb, .stl, .gltf, .splat або .ply) сюди, щоб завантажити\"},annotated_image:t,audio:a,blocks:c,checkbox:_,code:n,color_picker:d,dataframe:i,dropdown:l,errors:s,file:p,highlighted_text:u,image:g,label:m,login:b,number:h,plot:w,radio:k,slider:f,video:v,chatbot:S};export{o as _name,t as annotated_image,a as audio,c as blocks,S as chatbot,_ as checkbox,n as code,d as color_picker,e as common,i as dataframe,x as default,l as dropdown,s as errors,p as file,u as highlighted_text,g as image,m as label,b as login,h as number,w as plot,k as radio,f as slider,r as upload_text,v as video};\n//# sourceMappingURL=uk.js.map\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/ur-DPrEFG9j.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/ur-DPrEFG9j.js new file mode 100644 index 0000000000000000000000000000000000000000..5d0abf93c1c3ef798a9dddb2388006368aa96167 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/ur-DPrEFG9j.js @@ -0,0 +1,4 @@ +const o="اردو",e={built_with_gradio:"Gradio کے ساتھ بنایا گیا",clear:"صاف کریں",or:"یا",submit:"جمع کریں",settings:"ترتیبات",built_with:"کے ساتھ بنایا گیا",download:"ڈاؤن لوڈ کریں",edit:"ترمیم کریں",empty:"خالی",error:"خطا",hosted_on:"پر میزبانی کی جا رہی ہے",loading:"لوڈ ہو رہا ہے",logo:"لوگو",remove:"حذف کریں",share:"شیئر کریں",undo:"واپس لیں",no_devices:"کوئی ڈیوائس نہیں ملی",language:"زبان",display_theme:"تھیم کی نمائش",pwa:"پروگریسیو ویب ایپ"},r={click_to_upload:"اپ لوڈ کے لیے کلک کریں",drop_audio:"یہاں آڈیو ڈراپ کریں",drop_csv:"یہاں CSV ڈراپ کریں",drop_file:"یہاں فائل ڈراپ کریں",drop_image:"یہاں تصویر ڈراپ کریں",drop_video:"یہاں ویڈیو ڈراپ کریں",drop_gallery:"میڈیا یہاں ڈالیں",paste_clipboard:"کلپ بورڈ سے پیسٹ کریں"},t={annotated_image:"تشریحی تصویر"},a={allow_recording_access:"براہ مہربانی ریکارڈنگ کے لیے مائیکروفون تک رسائی کی اجازت دیں۔",audio:"آڈیو",drop_to_upload:"اپلوڈ کرنے کے لیے آڈیو فائل یہاں ڈراپ کریں",record_from_microphone:"مائیکروفون سے ریکارڈ کریں",stop_recording:"ریکارڈنگ بند کریں",no_device_support:"میڈیا ڈیوائسز تک رسائی حاصل نہیں کی جا سکی۔ یقینی بنائیں کہ آپ محفوظ ذریعہ (https) یا localhost پر چلا رہے ہیں (یا آپ نے ssl_verify میں درست SSL سرٹیفکیٹ منتقل کیا ہے)، اور آپ نے براؤزر کو اپنے ڈیوائس تک رسائی کی اجازت دی ہے۔",stop:"روکیں",resume:"دوبارہ شروع کریں",record:"ریکارڈ کریں",no_microphone:"کوئی مائیکروفون نہیں ملا",pause:"روکیں",play:"چلائیں",waiting:"انتظار کر رہا ہے"},c={connection_can_break:"موبائل پر، اگر اس ٹیب کا فوکس کھو جائے یا ڈیوائس سلیپ موڈ میں چلا جائے تو کنکشن ٹوٹ سکتا ہے، جس سے آپ قطار میں اپنی جگہ کھو سکتے ہیں۔",long_requests_queue:"درخواستوں کی ایک لمبی قطار زیر التواء ہے۔ قطار چھوڑنے کے لیے اس Space کو ڈپلیکیٹ کریں۔",lost_connection:"صفحہ چھوڑنے کی وجہ سے کنکشن کھو گیا۔ قطار میں دوبارہ شامل ہو رہا ہے...",waiting_for_inputs:"فائل(وں) کے اپ لوڈ ہونے کا انتظار ہے، براہ کرم دوبارہ کوشش کریں۔"},_={checkbox:"چیک باکس",checkbox_group:"چیک باکس گروپ"},n={code:"کوڈ"},d={color_picker:"رنگ منتخب کرنے والا"},i={incorrect_format:"غلط فارمیٹ، صرف CSV اور TSV فائلوں کی حمایت کی جاتی ہے",new_column:"کالم شامل کریں",new_row:"نئی قطار",add_row_above:"اوپر قطار شامل کریں",add_row_below:"نیچے قطار شامل کریں",delete_row:"قطار حذف کریں",delete_column:"کالم حذف کریں",add_column_left:"بائیں طرف کالم شامل کریں",add_column_right:"دائیں طرف کالم شامل کریں",sort_column:"کالم کو ترتیب دیں",sort_ascending:"صعودی ترتیب دیں",sort_descending:"نزولی ترتیب دیں",drop_to_upload:"ڈیٹا کو ڈیٹا فریم میں درآمد کرنے کے لیے CSV یا TSV فائلیں یہاں ڈراپ کریں",clear_sort:"ترتیب صاف کریں"},l={dropdown:"ڈراپ ڈاؤن"},s={build_error:"تعمیر میں خطا ہے",config_error:"ترتیب میں خطا ہے",contact_page_author:"براہ کرم صفحہ کے مصنف سے رابطہ کریں تاکہ انہیں مطلع کیا جا سکے۔",no_app_file:"کوئی ایپ فائل نہیں ہے",runtime_error:"رن ٹائم میں خطا ہے",space_not_working:'"Space کام نہیں کر رہا ہے کیونکہ" {0}',space_paused:"Space موقوف ہے",use_via_api:"API کے ذریعے استعمال کریں",use_via_api_or_mcp:"API یا MCP کے ذریعے استعمال کریں"},p={uploading:"اپلوڈ ہو رہا ہے..."},u={highlighted_text:"نمایاں کردہ متن"},g={allow_webcam_access:"براہ مہربانی ریکارڈنگ کے لیے ویب کیم تک رسائی کی اجازت دیں۔",brush_color:"برش کا رنگ",brush_radius:"برش کا سائز",image:"تصویر",remove_image:"تصویر حذف کریں",select_brush_color:"برش کا رنگ منتخب کریں",start_drawing:"ڈرائنگ شروع کریں",use_brush:"برش استعمال کریں",drop_to_upload:"اپلوڈ کرنے کے لیے تصویر فائل یہاں ڈراپ کریں"},m={label:"لیبل"},b={enable_cookies:"اگر آپ انکوگنیٹو موڈ میں HuggingFace Space ملاحظہ کر رہے ہیں تو، آپ کو تیسرے فریق کے کوکیز کو فعال کرنا ہوگا۔",incorrect_credentials:"غلط اسناد",username:"صارف نام",password:"پاس ورڈ",login:"لاگ ان کریں"},h={number:"نمبر"},w={plot:"گراف"},k={radio:"ریڈیو بٹن"},f={slider:"سلائیڈر"},v={drop_to_upload:"اپلوڈ کرنے کے لیے ویڈیو فائل یہاں ڈراپ کریں"},S={edit:"ترمیم",retry:"دوبارہ کوشش",undo:"واپس",submit:"جمع کریں",cancel:"منسوخ",like:"پسند",dislike:"ناپسند",clear:"گفتگو صاف کریں"},x={_name:o,common:e,upload_text:r,"3D_model":{"3d_model":"3D ماڈل",drop_to_upload:"اپلوڈ کرنے کے لیے 3D ماڈل (.obj, .glb, .stl, .gltf, .splat، یا .ply) فائل یہاں ڈراپ کریں"},annotated_image:t,audio:a,blocks:c,checkbox:_,code:n,color_picker:d,dataframe:i,dropdown:l,errors:s,file:p,highlighted_text:u,image:g,label:m,login:b,number:h,plot:w,radio:k,slider:f,video:v,chatbot:S}; + +export { o as _name, t as annotated_image, a as audio, c as blocks, S as chatbot, _ as checkbox, n as code, d as color_picker, e as common, i as dataframe, x as default, l as dropdown, s as errors, p as file, u as highlighted_text, g as image, m as label, b as login, h as number, w as plot, k as radio, f as slider, r as upload_text, v as video }; +//# sourceMappingURL=ur-DPrEFG9j.js.map diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/ur-DPrEFG9j.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/ur-DPrEFG9j.js.map new file mode 100644 index 0000000000000000000000000000000000000000..64a6f1679d8e9aaa89060eff21fa5a148973070b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/ur-DPrEFG9j.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ur-DPrEFG9j.js","sources":["../../../../../../js/app/.svelte-kit/adapter-node/chunks/ur.js"],"sourcesContent":["const o=\"اردو\",e={built_with_gradio:\"Gradio کے ساتھ بنایا گیا\",clear:\"صاف کریں\",or:\"یا\",submit:\"جمع کریں\",settings:\"ترتیبات\",built_with:\"کے ساتھ بنایا گیا\",download:\"ڈاؤن لوڈ کریں\",edit:\"ترمیم کریں\",empty:\"خالی\",error:\"خطا\",hosted_on:\"پر میزبانی کی جا رہی ہے\",loading:\"لوڈ ہو رہا ہے\",logo:\"لوگو\",remove:\"حذف کریں\",share:\"شیئر کریں\",undo:\"واپس لیں\",no_devices:\"کوئی ڈیوائس نہیں ملی\",language:\"زبان\",display_theme:\"تھیم کی نمائش\",pwa:\"پروگریسیو ویب ایپ\"},r={click_to_upload:\"اپ لوڈ کے لیے کلک کریں\",drop_audio:\"یہاں آڈیو ڈراپ کریں\",drop_csv:\"یہاں CSV ڈراپ کریں\",drop_file:\"یہاں فائل ڈراپ کریں\",drop_image:\"یہاں تصویر ڈراپ کریں\",drop_video:\"یہاں ویڈیو ڈراپ کریں\",drop_gallery:\"میڈیا یہاں ڈالیں\",paste_clipboard:\"کلپ بورڈ سے پیسٹ کریں\"},t={annotated_image:\"تشریحی تصویر\"},a={allow_recording_access:\"براہ مہربانی ریکارڈنگ کے لیے مائیکروفون تک رسائی کی اجازت دیں۔\",audio:\"آڈیو\",drop_to_upload:\"اپلوڈ کرنے کے لیے آڈیو فائل یہاں ڈراپ کریں\",record_from_microphone:\"مائیکروفون سے ریکارڈ کریں\",stop_recording:\"ریکارڈنگ بند کریں\",no_device_support:\"میڈیا ڈیوائسز تک رسائی حاصل نہیں کی جا سکی۔ یقینی بنائیں کہ آپ محفوظ ذریعہ (https) یا localhost پر چلا رہے ہیں (یا آپ نے ssl_verify میں درست SSL سرٹیفکیٹ منتقل کیا ہے)، اور آپ نے براؤزر کو اپنے ڈیوائس تک رسائی کی اجازت دی ہے۔\",stop:\"روکیں\",resume:\"دوبارہ شروع کریں\",record:\"ریکارڈ کریں\",no_microphone:\"کوئی مائیکروفون نہیں ملا\",pause:\"روکیں\",play:\"چلائیں\",waiting:\"انتظار کر رہا ہے\"},c={connection_can_break:\"موبائل پر، اگر اس ٹیب کا فوکس کھو جائے یا ڈیوائس سلیپ موڈ میں چلا جائے تو کنکشن ٹوٹ سکتا ہے، جس سے آپ قطار میں اپنی جگہ کھو سکتے ہیں۔\",long_requests_queue:\"درخواستوں کی ایک لمبی قطار زیر التواء ہے۔ قطار چھوڑنے کے لیے اس Space کو ڈپلیکیٹ کریں۔\",lost_connection:\"صفحہ چھوڑنے کی وجہ سے کنکشن کھو گیا۔ قطار میں دوبارہ شامل ہو رہا ہے...\",waiting_for_inputs:\"فائل(وں) کے اپ لوڈ ہونے کا انتظار ہے، براہ کرم دوبارہ کوشش کریں۔\"},_={checkbox:\"چیک باکس\",checkbox_group:\"چیک باکس گروپ\"},n={code:\"کوڈ\"},d={color_picker:\"رنگ منتخب کرنے والا\"},i={incorrect_format:\"غلط فارمیٹ، صرف CSV اور TSV فائلوں کی حمایت کی جاتی ہے\",new_column:\"کالم شامل کریں\",new_row:\"نئی قطار\",add_row_above:\"اوپر قطار شامل کریں\",add_row_below:\"نیچے قطار شامل کریں\",delete_row:\"قطار حذف کریں\",delete_column:\"کالم حذف کریں\",add_column_left:\"بائیں طرف کالم شامل کریں\",add_column_right:\"دائیں طرف کالم شامل کریں\",sort_column:\"کالم کو ترتیب دیں\",sort_ascending:\"صعودی ترتیب دیں\",sort_descending:\"نزولی ترتیب دیں\",drop_to_upload:\"ڈیٹا کو ڈیٹا فریم میں درآمد کرنے کے لیے CSV یا TSV فائلیں یہاں ڈراپ کریں\",clear_sort:\"ترتیب صاف کریں\"},l={dropdown:\"ڈراپ ڈاؤن\"},s={build_error:\"تعمیر میں خطا ہے\",config_error:\"ترتیب میں خطا ہے\",contact_page_author:\"براہ کرم صفحہ کے مصنف سے رابطہ کریں تاکہ انہیں مطلع کیا جا سکے۔\",no_app_file:\"کوئی ایپ فائل نہیں ہے\",runtime_error:\"رن ٹائم میں خطا ہے\",space_not_working:'\"Space کام نہیں کر رہا ہے کیونکہ\" {0}',space_paused:\"Space موقوف ہے\",use_via_api:\"API کے ذریعے استعمال کریں\",use_via_api_or_mcp:\"API یا MCP کے ذریعے استعمال کریں\"},p={uploading:\"اپلوڈ ہو رہا ہے...\"},u={highlighted_text:\"نمایاں کردہ متن\"},g={allow_webcam_access:\"براہ مہربانی ریکارڈنگ کے لیے ویب کیم تک رسائی کی اجازت دیں۔\",brush_color:\"برش کا رنگ\",brush_radius:\"برش کا سائز\",image:\"تصویر\",remove_image:\"تصویر حذف کریں\",select_brush_color:\"برش کا رنگ منتخب کریں\",start_drawing:\"ڈرائنگ شروع کریں\",use_brush:\"برش استعمال کریں\",drop_to_upload:\"اپلوڈ کرنے کے لیے تصویر فائل یہاں ڈراپ کریں\"},m={label:\"لیبل\"},b={enable_cookies:\"اگر آپ انکوگنیٹو موڈ میں HuggingFace Space ملاحظہ کر رہے ہیں تو، آپ کو تیسرے فریق کے کوکیز کو فعال کرنا ہوگا۔\",incorrect_credentials:\"غلط اسناد\",username:\"صارف نام\",password:\"پاس ورڈ\",login:\"لاگ ان کریں\"},h={number:\"نمبر\"},w={plot:\"گراف\"},k={radio:\"ریڈیو بٹن\"},f={slider:\"سلائیڈر\"},v={drop_to_upload:\"اپلوڈ کرنے کے لیے ویڈیو فائل یہاں ڈراپ کریں\"},S={edit:\"ترمیم\",retry:\"دوبارہ کوشش\",undo:\"واپس\",submit:\"جمع کریں\",cancel:\"منسوخ\",like:\"پسند\",dislike:\"ناپسند\",clear:\"گفتگو صاف کریں\"},x={_name:o,common:e,upload_text:r,\"3D_model\":{\"3d_model\":\"3D ماڈل\",drop_to_upload:\"اپلوڈ کرنے کے لیے 3D ماڈل (.obj, .glb, .stl, .gltf, .splat، یا .ply) فائل یہاں ڈراپ کریں\"},annotated_image:t,audio:a,blocks:c,checkbox:_,code:n,color_picker:d,dataframe:i,dropdown:l,errors:s,file:p,highlighted_text:u,image:g,label:m,login:b,number:h,plot:w,radio:k,slider:f,video:v,chatbot:S};export{o as _name,t as annotated_image,a as audio,c as blocks,S as chatbot,_ as checkbox,n as code,d as color_picker,e as common,i as dataframe,x as default,l as dropdown,s as errors,p as file,u as highlighted_text,g as image,m as label,b as login,h as number,w as plot,k as radio,f as slider,r as upload_text,v as video};\n//# sourceMappingURL=ur.js.map\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/uz-BUySSN8V.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/uz-BUySSN8V.js new file mode 100644 index 0000000000000000000000000000000000000000..73a5d4c675251f6ba8541e869d3c69289530b8d0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/uz-BUySSN8V.js @@ -0,0 +1,4 @@ +const a="O'zbek",i={built_with_gradio:"Gradio bilan yaratilgan",clear:"Tozalash",submit:"Yuborish",built_with:"Bilan yaratilgan",download:"Yuklab olish",edit:"Tahrirlash",empty:"Bo'sh",error:"Xato",hosted_on:"Joylashtirilgan",loading:"Yuklanmoqda",logo:"Logo",or:"yoki",remove:"O'chirish",settings:"Sozlamalar",share:"Ulashish",undo:"Bekor qilish",no_devices:"Hech qanday qurilma topilmadi",language:"Til",display_theme:"Ko'rinish mavzusi",pwa:"Progressive web-ilova"},o={click_to_upload:"Yuklash uchun bosing",drop_audio:"Audioni shu yerga tashlang",drop_csv:"CSV faylni shu yerga tashlang",drop_file:"Faylni shu yerga tashlang",drop_image:"Rasmni shu yerga tashlang",drop_video:"Videoni shu yerga tashlang",drop_gallery:"Mediafaylni shu yerga tashlang",paste_clipboard:"Klipboarddan qo'yish"},n={annotated_image:"Izohli rasm"},r={allow_recording_access:"Iltimos, yozib olish uchun mikrofonga ruxsat bering.",audio:"Audio",drop_to_upload:"Audio faylni yuklash uchun shu yerga tashlang",record_from_microphone:"Mikrofondan yozib olish",stop_recording:"Yozib olishni to'xtatish",no_device_support:"Media qurilmalariga kira olmadik. Xavfsiz manbada (https) yoki localhost-da ishlayotganingizni tekshiring (yoki to'g'ri SSL sertifikatini ssl_verify-ga berganingizni) va brauzer qurilmangizga kirishiga ruxsat berganingizni tekshiring.",stop:"To'xtatish",resume:"Davom ettirish",record:"Yozib olish",no_microphone:"Mikrofon topilmadi",pause:"Pauza",play:"Ijro etish",waiting:"Kutilmoqda"},l={connection_can_break:"Mobil qurilmada, agar bu yorliq fokusdan chiqsa yoki qurilma uyqu rejimiga o'tsa, aloqa uzilib, navbatdagi o'rningizni yo'qotishingiz mumkin.",long_requests_queue:"So'rovlar navbati juda uzun. Navbatni chetlab o'tish uchun bu Space-ni nusxalang.",lost_connection:"Sahifadan chiqib ketganligi sababli aloqa uzildi. Navbatga qayta qo'shilmoqda...",waiting_for_inputs:"Fayl(lar) yuklanib bo'lishini kutish, iltimos, qayta urinib ko'ring."},s={checkbox:"Belgilash katagi",checkbox_group:"Belgilash kataklari guruhi"},t={code:"Kod"},e={color_picker:"Rang tanlagich"},h={incorrect_format:"Noto'g'ri format, faqat CSV va TSV fayllari qo'llab-quvvatlanadi",new_column:"Ustun qo'shish",new_row:"Yangi qator",add_row_above:"Yuqoriga qator qo'shish",add_row_below:"Pastga qator qo'shish",delete_row:"Qatorni o'chirish",delete_column:"Ustunni o'chirish",add_column_left:"Chapga ustun qo'shish",add_column_right:"O'ngga ustun qo'shish",sort_column:"Ustunni saralash",sort_ascending:"O'sish tartibida saralash",sort_descending:"Kamayish tartibida saralash",drop_to_upload:"Ma'lumotlarni ma'lumotlar jadvaliga import qilish uchun CSV yoki TSV fayllarini shu yerga tashlang",clear_sort:"Saralashni tozalash"},u={dropdown:"Ochiluvchi ro'yxat"},d={build_error:"Tuzilish xatosi mavjud",config_error:"Konfiguratsiya xatosi mavjud",contact_page_author:"Iltimos, sahifa muallifiga bog'laning va ularga xabar bering.",no_app_file:"Ilova fayli yo'q",runtime_error:"Bajarilish vaqti xatosi mavjud",space_not_working:'"Space ishlamayapti, chunki" {0}',space_paused:"Space to'xtatilgan",use_via_api:"API orqali foydalaning",use_via_api_or_mcp:"API yoki MCP orqali foydalaning"},g={uploading:"Yuklanmoqda..."},c={highlighted_text:"Ajratilgan matn"},_={allow_webcam_access:"Iltimos, yozib olish uchun veb-kameraga ruxsat bering.",brush_color:"Cho'tka rangi",brush_radius:"Cho'tka o'lchami",image:"Rasm",remove_image:"Rasmni o'chirish",select_brush_color:"Cho'tka rangini tanlang",start_drawing:"Chizishni boshlang",use_brush:"Cho'tkadan foydalaning",drop_to_upload:"Rasm faylini yuklash uchun shu yerga tashlang"},m={label:"Yorliq"},b={enable_cookies:"Agar HuggingFace Space-ni Inkognito rejimida ko'rayotgan bo'lsangiz, uchinchi tomon kukilarini yoqishingiz kerak.",incorrect_credentials:"Noto'g'ri kirish ma'lumotlari",username:"Foydalanuvchi nomi",password:"Parol",login:"Kirish"},p={number:"Raqam"},y={plot:"Grafik"},k={radio:"Radio tugma"},q={slider:"Slayder"},f={drop_to_upload:"Video faylni yuklash uchun shu yerga tashlang"},v={edit:"Tahrirlash",retry:"Qayta urinish",undo:"Bekor qilish",submit:"Yuborish",cancel:"Bekor qilish",like:"Yoqdi",dislike:"Yoqmadi",clear:"Suhbatni tozalash"},z={_name:a,common:i,upload_text:o,"3D_model":{"3d_model":"3D model",drop_to_upload:"3D model (.obj, .glb, .stl, .gltf, .splat yoki .ply) faylni yuklash uchun shu yerga tashlang"},annotated_image:n,audio:r,blocks:l,checkbox:s,code:t,color_picker:e,dataframe:h,dropdown:u,errors:d,file:g,highlighted_text:c,image:_,label:m,login:b,number:p,plot:y,radio:k,slider:q,video:f,chatbot:v}; + +export { a as _name, n as annotated_image, r as audio, l as blocks, v as chatbot, s as checkbox, t as code, e as color_picker, i as common, h as dataframe, z as default, u as dropdown, d as errors, g as file, c as highlighted_text, _ as image, m as label, b as login, p as number, y as plot, k as radio, q as slider, o as upload_text, f as video }; +//# sourceMappingURL=uz-BUySSN8V.js.map diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/uz-BUySSN8V.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/uz-BUySSN8V.js.map new file mode 100644 index 0000000000000000000000000000000000000000..0bd7a44fc85f37835d102c16bfa6e50e068ca04c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/uz-BUySSN8V.js.map @@ -0,0 +1 @@ +{"version":3,"file":"uz-BUySSN8V.js","sources":["../../../../../../js/app/.svelte-kit/adapter-node/chunks/uz.js"],"sourcesContent":["const a=\"O'zbek\",i={built_with_gradio:\"Gradio bilan yaratilgan\",clear:\"Tozalash\",submit:\"Yuborish\",built_with:\"Bilan yaratilgan\",download:\"Yuklab olish\",edit:\"Tahrirlash\",empty:\"Bo'sh\",error:\"Xato\",hosted_on:\"Joylashtirilgan\",loading:\"Yuklanmoqda\",logo:\"Logo\",or:\"yoki\",remove:\"O'chirish\",settings:\"Sozlamalar\",share:\"Ulashish\",undo:\"Bekor qilish\",no_devices:\"Hech qanday qurilma topilmadi\",language:\"Til\",display_theme:\"Ko'rinish mavzusi\",pwa:\"Progressive web-ilova\"},o={click_to_upload:\"Yuklash uchun bosing\",drop_audio:\"Audioni shu yerga tashlang\",drop_csv:\"CSV faylni shu yerga tashlang\",drop_file:\"Faylni shu yerga tashlang\",drop_image:\"Rasmni shu yerga tashlang\",drop_video:\"Videoni shu yerga tashlang\",drop_gallery:\"Mediafaylni shu yerga tashlang\",paste_clipboard:\"Klipboarddan qo'yish\"},n={annotated_image:\"Izohli rasm\"},r={allow_recording_access:\"Iltimos, yozib olish uchun mikrofonga ruxsat bering.\",audio:\"Audio\",drop_to_upload:\"Audio faylni yuklash uchun shu yerga tashlang\",record_from_microphone:\"Mikrofondan yozib olish\",stop_recording:\"Yozib olishni to'xtatish\",no_device_support:\"Media qurilmalariga kira olmadik. Xavfsiz manbada (https) yoki localhost-da ishlayotganingizni tekshiring (yoki to'g'ri SSL sertifikatini ssl_verify-ga berganingizni) va brauzer qurilmangizga kirishiga ruxsat berganingizni tekshiring.\",stop:\"To'xtatish\",resume:\"Davom ettirish\",record:\"Yozib olish\",no_microphone:\"Mikrofon topilmadi\",pause:\"Pauza\",play:\"Ijro etish\",waiting:\"Kutilmoqda\"},l={connection_can_break:\"Mobil qurilmada, agar bu yorliq fokusdan chiqsa yoki qurilma uyqu rejimiga o'tsa, aloqa uzilib, navbatdagi o'rningizni yo'qotishingiz mumkin.\",long_requests_queue:\"So'rovlar navbati juda uzun. Navbatni chetlab o'tish uchun bu Space-ni nusxalang.\",lost_connection:\"Sahifadan chiqib ketganligi sababli aloqa uzildi. Navbatga qayta qo'shilmoqda...\",waiting_for_inputs:\"Fayl(lar) yuklanib bo'lishini kutish, iltimos, qayta urinib ko'ring.\"},s={checkbox:\"Belgilash katagi\",checkbox_group:\"Belgilash kataklari guruhi\"},t={code:\"Kod\"},e={color_picker:\"Rang tanlagich\"},h={incorrect_format:\"Noto'g'ri format, faqat CSV va TSV fayllari qo'llab-quvvatlanadi\",new_column:\"Ustun qo'shish\",new_row:\"Yangi qator\",add_row_above:\"Yuqoriga qator qo'shish\",add_row_below:\"Pastga qator qo'shish\",delete_row:\"Qatorni o'chirish\",delete_column:\"Ustunni o'chirish\",add_column_left:\"Chapga ustun qo'shish\",add_column_right:\"O'ngga ustun qo'shish\",sort_column:\"Ustunni saralash\",sort_ascending:\"O'sish tartibida saralash\",sort_descending:\"Kamayish tartibida saralash\",drop_to_upload:\"Ma'lumotlarni ma'lumotlar jadvaliga import qilish uchun CSV yoki TSV fayllarini shu yerga tashlang\",clear_sort:\"Saralashni tozalash\"},u={dropdown:\"Ochiluvchi ro'yxat\"},d={build_error:\"Tuzilish xatosi mavjud\",config_error:\"Konfiguratsiya xatosi mavjud\",contact_page_author:\"Iltimos, sahifa muallifiga bog'laning va ularga xabar bering.\",no_app_file:\"Ilova fayli yo'q\",runtime_error:\"Bajarilish vaqti xatosi mavjud\",space_not_working:'\"Space ishlamayapti, chunki\" {0}',space_paused:\"Space to'xtatilgan\",use_via_api:\"API orqali foydalaning\",use_via_api_or_mcp:\"API yoki MCP orqali foydalaning\"},g={uploading:\"Yuklanmoqda...\"},c={highlighted_text:\"Ajratilgan matn\"},_={allow_webcam_access:\"Iltimos, yozib olish uchun veb-kameraga ruxsat bering.\",brush_color:\"Cho'tka rangi\",brush_radius:\"Cho'tka o'lchami\",image:\"Rasm\",remove_image:\"Rasmni o'chirish\",select_brush_color:\"Cho'tka rangini tanlang\",start_drawing:\"Chizishni boshlang\",use_brush:\"Cho'tkadan foydalaning\",drop_to_upload:\"Rasm faylini yuklash uchun shu yerga tashlang\"},m={label:\"Yorliq\"},b={enable_cookies:\"Agar HuggingFace Space-ni Inkognito rejimida ko'rayotgan bo'lsangiz, uchinchi tomon kukilarini yoqishingiz kerak.\",incorrect_credentials:\"Noto'g'ri kirish ma'lumotlari\",username:\"Foydalanuvchi nomi\",password:\"Parol\",login:\"Kirish\"},p={number:\"Raqam\"},y={plot:\"Grafik\"},k={radio:\"Radio tugma\"},q={slider:\"Slayder\"},f={drop_to_upload:\"Video faylni yuklash uchun shu yerga tashlang\"},v={edit:\"Tahrirlash\",retry:\"Qayta urinish\",undo:\"Bekor qilish\",submit:\"Yuborish\",cancel:\"Bekor qilish\",like:\"Yoqdi\",dislike:\"Yoqmadi\",clear:\"Suhbatni tozalash\"},z={_name:a,common:i,upload_text:o,\"3D_model\":{\"3d_model\":\"3D model\",drop_to_upload:\"3D model (.obj, .glb, .stl, .gltf, .splat yoki .ply) faylni yuklash uchun shu yerga tashlang\"},annotated_image:n,audio:r,blocks:l,checkbox:s,code:t,color_picker:e,dataframe:h,dropdown:u,errors:d,file:g,highlighted_text:c,image:_,label:m,login:b,number:p,plot:y,radio:k,slider:q,video:f,chatbot:v};export{a as _name,n as annotated_image,r as audio,l as blocks,v as chatbot,s as checkbox,t as code,e as color_picker,i as common,h as dataframe,z as default,u as dropdown,d as errors,g as file,c as highlighted_text,_ as image,m as label,b as login,p as number,y as plot,k as radio,q as slider,o as upload_text,f as video};\n//# sourceMappingURL=uz.js.map\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/vega-embed.module-DsI9BZ1D.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/vega-embed.module-DsI9BZ1D.js new file mode 100644 index 0000000000000000000000000000000000000000..3f92cf600bacc713bdccff0012207db5e068c529 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/vega-embed.module-DsI9BZ1D.js @@ -0,0 +1,193 @@ +import { x as xt$1, v as v3, A as Ag$1, u as ug$1, P as PH, e as et$1, X as X$1, M as Mr$1, f as fg$1, c as cc$1, Y as Y$1, U, L as LH, a as x3, p as p3, H, t as t5, g as ge$1, b as pP, d as tt$1 } from './vega-interpreter.module-D8ONVnUK.js'; +import { H as Hr$1 } from './2-2QjpS3e7.js'; +import './dispatch-DGVRt-1i.js'; +import './ssr-C3HYbsxA.js'; +import './index-ClteBeTX.js'; +import './Component-NmRBwSfF.js'; +import 'path'; +import 'url'; +import 'fs'; + +var _p=/("(?:[^\\"]|\\.)*")|[:,]/g,Rp=function(t,n){var i,r,s;return n=n||{},i=JSON.stringify([1],void 0,n.indent===void 0?2:n.indent).slice(2,-3),r=i===""?1/0:n.maxLength===void 0?80:n.maxLength,s=n.replacer,function o(a,c,l){var u,f,d,g,p,h,m,y,b,C,k,N;if(a&&typeof a.toJSON=="function"&&(a=a.toJSON()),k=JSON.stringify(a,s),k===void 0)return k;if(m=r-c.length-l,k.length<=m&&(b=k.replace(_p,function(_,L){return L||_+" "}),b.length<=m))return b;if(s!=null&&(a=JSON.parse(k),s=void 0),typeof a=="object"&&a!==null){if(y=c+i,d=[],f=0,Array.isArray(a))for(C="[",u="]",m=a.length;f0)return [C,i+d.join(`, +`+y),u].join(` +`+c)}return k}(t,"",0)};const Ns=Hr$1(Rp),Ip="vega-lite",Lp='Dominik Moritz, Kanit "Ham" Wongsuphasawat, Arvind Satyanarayan, Jeffrey Heer',Pp="5.17.0",zp=["Kanit Wongsuphasawat (http://kanitw.yellowpigz.com)","Dominik Moritz (https://www.domoritz.de)","Arvind Satyanarayan (https://arvindsatya.com)","Jeffrey Heer (https://jheer.org)"],Dp="https://vega.github.io/vega-lite/",Mp="Vega-Lite is a concise high-level language for interactive visualization.",jp=["vega","chart","visualization"],Up="build/vega-lite.js",Bp="build/vega-lite.min.js",Wp="build/vega-lite.min.js",Gp="build/src/index",Hp="build/src/index.d.ts",qp={vl2pdf:"./bin/vl2pdf",vl2png:"./bin/vl2png",vl2svg:"./bin/vl2svg",vl2vg:"./bin/vl2vg"},Vp=["bin","build","src","vega-lite*","tsconfig.json"],Xp={changelog:"conventional-changelog -p angular -r 2",prebuild:"yarn clean:build",build:"yarn build:only","build:only":"tsc -p tsconfig.build.json && rollup -c","prebuild:examples":"yarn build:only","build:examples":"yarn data && TZ=America/Los_Angeles scripts/build-examples.sh","prebuild:examples-full":"yarn build:only","build:examples-full":"TZ=America/Los_Angeles scripts/build-examples.sh 1","build:example":"TZ=America/Los_Angeles scripts/build-example.sh","build:toc":"yarn build:jekyll && scripts/generate-toc","build:site":"rollup -c site/rollup.config.mjs","build:jekyll":"pushd site && bundle exec jekyll build -q && popd","build:versions":"scripts/update-version.sh",clean:"yarn clean:build && del-cli 'site/data/*' 'examples/compiled/*.png' && find site/examples ! -name 'index.md' ! -name 'data' -type f -delete","clean:build":"del-cli 'build/*' !build/vega-lite-schema.json",data:"rsync -r node_modules/vega-datasets/data/* site/data",schema:"mkdir -p build && ts-json-schema-generator -f tsconfig.json -p src/index.ts -t TopLevelSpec --no-type-check --no-ref-encode > build/vega-lite-schema.json && yarn renameschema && cp build/vega-lite-schema.json site/_data/",renameschema:"scripts/rename-schema.sh",presite:"yarn data && yarn schema && yarn build:site && yarn build:versions && scripts/create-example-pages.sh",site:"yarn site:only","site:only":"pushd site && bundle exec jekyll serve -I -l && popd",prettierbase:"prettier '**/*.{md,css,yml}'",format:"eslint . --fix && yarn prettierbase --write",lint:"eslint . && yarn prettierbase --check",test:"yarn jest test/ && yarn lint && yarn schema && yarn jest examples/ && yarn test:runtime","test:cover":"yarn jest --collectCoverage test/","test:inspect":"node --inspect-brk ./node_modules/.bin/jest --runInBand test","test:runtime":"TZ=America/Los_Angeles npx jest test-runtime/ --config test-runtime/jest-config.json","test:runtime:generate":"yarn build:only && del-cli test-runtime/resources && VL_GENERATE_TESTS=true yarn test:runtime",watch:"tsc -p tsconfig.build.json -w","watch:site":"yarn build:site -w","watch:test":"yarn jest --watch test/","watch:test:runtime":"TZ=America/Los_Angeles npx jest --watch test-runtime/ --config test-runtime/jest-config.json",release:"release-it"},Yp={type:"git",url:"https://github.com/vega/vega-lite.git"},Kp="BSD-3-Clause",Jp={url:"https://github.com/vega/vega-lite/issues"},Qp={"@babel/core":"^7.23.9","@babel/preset-env":"^7.23.9","@babel/preset-typescript":"^7.23.3","@release-it/conventional-changelog":"^8.0.1","@rollup/plugin-alias":"^5.1.0","@rollup/plugin-babel":"^6.0.4","@rollup/plugin-commonjs":"^25.0.7","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^15.2.3","@rollup/plugin-terser":"^0.4.4","@types/d3":"^7.4.3","@types/jest":"^29.5.11","@types/pako":"^2.0.3","@typescript-eslint/eslint-plugin":"^6.20.0","@typescript-eslint/parser":"^6.20.0",ajv:"^8.12.0","ajv-formats":"^2.1.1",cheerio:"^1.0.0-rc.12","conventional-changelog-cli":"^4.1.0",d3:"^7.8.5","del-cli":"^5.1.0",eslint:"^8.56.0","eslint-config-prettier":"^9.1.0","eslint-plugin-jest":"^27.6.3","eslint-plugin-prettier":"^5.1.3","fast-json-stable-stringify":"~2.1.0","highlight.js":"^11.9.0",jest:"^29.7.0","jest-dev-server":"^9.0.2",mkdirp:"^3.0.1",pako:"^2.1.0",prettier:"^3.2.4",puppeteer:"^15.0.0","release-it":"^17.0.3",rollup:"^4.9.6","rollup-plugin-bundle-size":"^1.0.3",serve:"^14.2.1",terser:"^5.27.0","ts-jest":"^29.1.2","ts-json-schema-generator":"^1.5.0",typescript:"~5.3.3","vega-cli":"^5.27.0","vega-datasets":"^2.8.0","vega-embed":"^6.24.0","vega-tooltip":"^0.34.0","yaml-front-matter":"^4.1.1"},Zp={"json-stringify-pretty-compact":"~3.0.0",tslib:"~2.6.2","vega-event-selector":"~3.0.1","vega-expression":"~5.1.0","vega-util":"~1.17.2",yargs:"~17.7.2"},eg={vega:"^5.24.0"},tg={node:">=18"},ng={name:Ip,author:Lp,version:Pp,collaborators:zp,homepage:Dp,description:Mp,keywords:jp,main:Up,unpkg:Bp,jsdelivr:Wp,module:Gp,types:Hp,bin:qp,files:Vp,scripts:Xp,repository:Yp,license:Kp,bugs:Jp,devDependencies:Qp,dependencies:Zp,peerDependencies:eg,engines:tg};function xo(e){return !!e.or}function So(e){return !!e.and}function vo(e){return !!e.not}function gr(e,t){if(vo(e))gr(e.not,t);else if(So(e))for(const n of e.and)gr(n,t);else if(xo(e))for(const n of e.or)gr(n,t);else t(e);}function Hn(e,t){return vo(e)?{not:Hn(e.not,t)}:So(e)?{and:e.and.map(n=>Hn(n,t))}:xo(e)?{or:e.or.map(n=>Hn(n,t))}:t(e)}const z=structuredClone;function Wl(e){throw new Error(e)}function Jn(e,t){const n={};for(const i of t)X$1(e,i)&&(n[i]=e[i]);return n}function ke(e,t){const n={...e};for(const i of t)delete n[i];return n}Set.prototype.toJSON=function(){return `Set(${[...this].map(e=>J(e)).join(",")})`};function W(e){if(Mr$1(e))return e;const t=xt$1(e)?e:J(e);if(t.length<250)return t;let n=0;for(let i=0;ia===0?o:`[${o}]`),s=r.map((o,a)=>r.slice(0,a+1).join(""));for(const o of s)t.add(o);}return t}function wo(e,t){return e===void 0||t===void 0?!0:$o(Xs(e),Xs(t))}function K(e){return x(e).length===0}const x=Object.keys,Se=Object.values,Wt=Object.entries;function Li(e){return e===!0||e===!1}function re(e){const t=e.replace(/\W/g,"_");return (e.match(/^\d+/)?"_":"")+t}function Oi(e,t){return vo(e)?`!(${Oi(e.not,t)})`:So(e)?`(${e.and.map(n=>Oi(n,t)).join(") && (")})`:xo(e)?`(${e.or.map(n=>Oi(n,t)).join(") || (")})`:t(e)}function hr(e,t){if(t.length===0)return !0;const n=t.shift();return n in e&&hr(e[n],t)&&delete e[n],K(e)}function Wi(e){return e.charAt(0).toUpperCase()+e.substr(1)}function Co(e,t="datum"){const n=cc$1(e),i=[];for(let r=1;r<=n.length;r++){const s=`[${n.slice(0,r).map(Y$1).join("][")}]`;i.push(`${t}${s}`);}return i.join(" && ")}function ql(e,t="datum"){return `${t}[${Y$1(cc$1(e).join("."))}]`}function sg(e){return e.replace(/(\[|\]|\.|'|")/g,"\\$1")}function Ue(e){return `${cc$1(e).map(sg).join("\\.")}`}function vn(e,t,n){return e.replace(new RegExp(t.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),"g"),n)}function No(e){return `${cc$1(e).join(".")}`}function Qn(e){return e?cc$1(e).length:0}function le(...e){for(const t of e)if(t!==void 0)return t}let Vl=42;function Xl(e){const t=++Vl;return e?String(e)+t:t}function og(){Vl=42;}function Yl(e){return Kl(e)?e:`__${e}`}function Kl(e){return e.startsWith("__")}function Pi(e){if(e!==void 0)return (e%360+360)%360}function Ir(e){return Mr$1(e)?!0:!isNaN(e)&&!isNaN(parseFloat(e))}const ec=Object.getPrototypeOf(structuredClone({}));function Pe(e,t){if(e===t)return !0;if(e&&t&&typeof e=="object"&&typeof t=="object"){if(e.constructor.name!==t.constructor.name)return !1;let n,i;if(Array.isArray(e)){if(n=e.length,n!=t.length)return !1;for(i=n;i--!==0;)if(!Pe(e[i],t[i]))return !1;return !0}if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return !1;for(i of e.entries())if(!t.has(i[0]))return !1;for(i of e.entries())if(!Pe(i[1],t.get(i[0])))return !1;return !0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return !1;for(i of e.entries())if(!t.has(i[0]))return !1;return !0}if(ArrayBuffer.isView(e)&&ArrayBuffer.isView(t)){if(n=e.length,n!=t.length)return !1;for(i=n;i--!==0;)if(e[i]!==t[i])return !1;return !0}if(e.constructor===RegExp)return e.source===t.source&&e.flags===t.flags;if(e.valueOf!==Object.prototype.valueOf&&e.valueOf!==ec.valueOf)return e.valueOf()===t.valueOf();if(e.toString!==Object.prototype.toString&&e.toString!==ec.toString)return e.toString()===t.toString();const r=Object.keys(e);if(n=r.length,n!==Object.keys(t).length)return !1;for(i=n;i--!==0;)if(!Object.prototype.hasOwnProperty.call(t,r[i]))return !1;for(i=n;i--!==0;){const s=r[i];if(!Pe(e[s],t[s]))return !1}return !0}return e!==e&&t!==t}function J(e){const t=[];return function n(i){if(i&&i.toJSON&&typeof i.toJSON=="function"&&(i=i.toJSON()),i===void 0)return;if(typeof i=="number")return isFinite(i)?""+i:"null";if(typeof i!="object")return JSON.stringify(i);let r,s;if(Array.isArray(i)){for(s="[",r=0;rBr(e[t])?re(`_${t}_${Wt(e[t])}`):re(`_${t}_${e[t]}`)).join("")}function ee(e){return e===!0||Rn(e)&&!e.binned}function xe(e){return e==="binned"||Rn(e)&&e.binned===!0}function Rn(e){return et$1(e)}function Br(e){return e?.param}function tc(e){switch(e){case Nt:case Ft:case It:case Ae:case yt:case bt:case Zt:case Lt:case Jt:case Qt:case Oe:return 6;case en:return 4;default:return 10}}function Vi(e){return !!e?.expr}function Fe(e){const t=x(e||{}),n={};for(const i of t)n[i]=Le(e[i]);return n}function fu(e){const{anchor:t,frame:n,offset:i,orient:r,angle:s,limit:o,color:a,subtitleColor:c,subtitleFont:l,subtitleFontSize:u,subtitleFontStyle:f,subtitleFontWeight:d,subtitleLineHeight:g,subtitlePadding:p,...h}=e,m={...h,...a?{fill:a}:{}},y={...t?{anchor:t}:{},...n?{frame:n}:{},...i?{offset:i}:{},...r?{orient:r}:{},...s!==void 0?{angle:s}:{},...o!==void 0?{limit:o}:{}},b={...c?{subtitleColor:c}:{},...l?{subtitleFont:l}:{},...u?{subtitleFontSize:u}:{},...f?{subtitleFontStyle:f}:{},...d?{subtitleFontWeight:d}:{},...g?{subtitleLineHeight:g}:{},...p?{subtitlePadding:p}:{}},C=Jn(e,["align","baseline","dx","dy","limit"]);return {titleMarkConfig:m,subtitleMarkConfig:C,nonMarkTitleProperties:y,subtitle:b}}function jt(e){return xt$1(e)||U(e)&&xt$1(e[0])}function T(e){return !!e?.signal}function nn(e){return !!e.step}function Ag(e){return U(e)?!1:"fields"in e&&!("data"in e)}function Og(e){return U(e)?!1:"fields"in e&&"data"in e}function Ct(e){return U(e)?!1:"field"in e&&"data"in e}const _g={aria:1,description:1,ariaRole:1,ariaRoleDescription:1,blend:1,opacity:1,fill:1,fillOpacity:1,stroke:1,strokeCap:1,strokeWidth:1,strokeOpacity:1,strokeDash:1,strokeDashOffset:1,strokeJoin:1,strokeOffset:1,strokeMiterLimit:1,startAngle:1,endAngle:1,padAngle:1,innerRadius:1,outerRadius:1,size:1,shape:1,interpolate:1,tension:1,orient:1,align:1,baseline:1,text:1,dir:1,dx:1,dy:1,ellipsis:1,limit:1,radius:1,theta:1,angle:1,font:1,fontSize:1,fontWeight:1,fontStyle:1,lineBreak:1,lineHeight:1,cursor:1,href:1,tooltip:1,cornerRadius:1,cornerRadiusTopLeft:1,cornerRadiusTopRight:1,cornerRadiusBottomLeft:1,cornerRadiusBottomRight:1,aspect:1,width:1,height:1,url:1,smooth:1},Rg=x(_g),Ig={arc:1,area:1,group:1,image:1,line:1,path:1,rect:1,rule:1,shape:1,symbol:1,text:1,trail:1},Ys=["cornerRadius","cornerRadiusTopLeft","cornerRadiusTopRight","cornerRadiusBottomLeft","cornerRadiusBottomRight"];function du(e){const t=U(e.condition)?e.condition.map(nc):nc(e.condition);return {...Le(e),condition:t}}function Le(e){if(Vi(e)){const{expr:t,...n}=e;return {signal:t,...n}}return e}function nc(e){if(Vi(e)){const{expr:t,...n}=e;return {signal:t,...n}}return e}function ne(e){if(Vi(e)){const{expr:t,...n}=e;return {signal:t,...n}}return T(e)?e:e!==void 0?{value:e}:void 0}function Lg(e){return T(e)?e.signal:Y$1(e)}function ic(e){return T(e)?e.signal:Y$1(e.value)}function Xe(e){return T(e)?e.signal:e==null?null:Y$1(e)}function Pg(e,t,n){for(const i of n){const r=Ot(i,t.markDef,t.config);r!==void 0&&(e[i]=ne(r));}return e}function pu(e){return [].concat(e.type,e.style??[])}function X(e,t,n,i={}){const{vgChannel:r,ignoreVgConfig:s}=i;return r&&t[r]!==void 0?t[r]:t[e]!==void 0?t[e]:s&&(!r||r===e)?void 0:Ot(e,t,n,i)}function Ot(e,t,n,{vgChannel:i}={}){return le(i?mr(e,t,n.style):void 0,mr(e,t,n.style),i?n[t.type][i]:void 0,n[t.type][e],i?n.mark[i]:n.mark[e])}function mr(e,t,n){return gu(e,pu(t),n)}function gu(e,t,n){t=H(t);let i;for(const r of t){const s=n[r];s&&s[e]!==void 0&&(i=s[e]);}return i}function hu(e,t){return H(e).reduce((n,i)=>(n.field.push(E(i,t)),n.order.push(i.sort??"ascending"),n),{field:[],order:[]})}function mu(e,t){const n=[...e];return t.forEach(i=>{for(const r of n)if(Pe(r,i))return;n.push(i);}),n}function yu(e,t){return Pe(e,t)||!t?e:e?[...H(e),...H(t)].join(", "):t}function bu(e,t){const n=e.value,i=t.value;if(n==null||i===null)return {explicit:e.explicit,value:null};if((jt(n)||T(n))&&(jt(i)||T(i)))return {explicit:e.explicit,value:yu(n,i)};if(jt(n)||T(n))return {explicit:e.explicit,value:n};if(jt(i)||T(i))return {explicit:e.explicit,value:i};if(!jt(n)&&!T(n)&&!jt(i)&&!T(i))return {explicit:e.explicit,value:mu(n,i)};throw new Error("It should never reach here")}function Lo(e){return `Invalid specification ${J(e)}. Make sure the specification includes at least one of the following properties: "mark", "layer", "facet", "hconcat", "vconcat", "concat", or "repeat".`}const zg='Autosize "fit" only works for single views and layered views.';function rc(e){return `${e=="width"?"Width":"Height"} "container" only works for single views and layered views.`}function sc(e){const t=e=="width"?"Width":"Height",n=e=="width"?"x":"y";return `${t} "container" only works well with autosize "fit" or "fit-${n}".`}function oc(e){return e?`Dropping "fit-${e}" because spec has discrete ${_e(e)}.`:'Dropping "fit" because spec has discrete size.'}function Po(e){return `Unknown field for ${e}. Cannot calculate view size.`}function ac(e){return `Cannot project a selection on encoding channel "${e}", which has no field.`}function Dg(e,t){return `Cannot project a selection on encoding channel "${e}" as it uses an aggregate function ("${t}").`}function Mg(e){return `The "nearest" transform is not supported for ${e} marks.`}function xu(e){return `Selection not supported for ${e} yet.`}function jg(e){return `Cannot find a selection named "${e}".`}const Ug="Scale bindings are currently only supported for scales with unbinned, continuous domains.",Bg="Sequntial scales are deprecated. The available quantitative scale type values are linear, log, pow, sqrt, symlog, time and utc",Wg="Legend bindings are only supported for selections over an individual field or encoding channel.";function Gg(e){return `Lookups can only be performed on selection parameters. "${e}" is a variable parameter.`}function Hg(e){return `Cannot define and lookup the "${e}" selection in the same view. Try moving the lookup into a second, layered view?`}const qg="The same selection must be used to override scale domains in a layered view.",Vg='Interval selections should be initialized using "x", "y", "longitude", or "latitude" keys.';function Xg(e){return `Unknown repeated value "${e}".`}function cc(e){return `The "columns" property cannot be used when "${e}" has nested row/column.`}const Yg="Axes cannot be shared in concatenated or repeated views yet (https://github.com/vega/vega-lite/issues/2415).";function Kg(e){return `Unrecognized parse "${e}".`}function lc(e,t,n){return `An ancestor parsed field "${e}" as ${n} but a child wants to parse the field as ${t}.`}const Jg="Attempt to add the same child twice.";function Qg(e){return `Ignoring an invalid transform: ${J(e)}.`}const Zg='If "from.fields" is not specified, "as" has to be a string that specifies the key to be used for the data from the secondary source.';function uc(e){return `Config.customFormatTypes is not true, thus custom format type and format for channel ${e} are dropped.`}function eh(e){const{parentProjection:t,projection:n}=e;return `Layer's shared projection ${J(t)} is overridden by a child projection ${J(n)}.`}const th="Arc marks uses theta channel rather than angle, replacing angle with theta.";function nh(e){return `${e}Offset dropped because ${e} is continuous`}function ih(e,t,n){return `Channel ${e} is a ${t}. Converted to {value: ${J(n)}}.`}function Su(e){return `Invalid field type "${e}".`}function rh(e,t){return `Invalid field type "${e}" for aggregate: "${t}", using "quantitative" instead.`}function sh(e){return `Invalid aggregation operator "${e}".`}function vu(e,t){const{fill:n,stroke:i}=t;return `Dropping color ${e} as the plot also has ${n&&i?"fill and stroke":n?"fill":"stroke"}.`}function oh(e){return `Position range does not support relative band size for ${e}.`}function Ks(e,t){return `Dropping ${J(e)} from channel "${t}" since it does not contain any data field, datum, value, or signal.`}const ah="Line marks cannot encode size with a non-groupby field. You may want to use trail marks instead.";function Wr(e,t,n){return `${e} dropped as it is incompatible with "${t}".`}function ch(e){return `${e}-encoding is dropped as ${e} is not a valid encoding channel.`}function lh(e){return `${e} encoding should be discrete (ordinal / nominal / binned).`}function uh(e){return `${e} encoding should be discrete (ordinal / nominal / binned) or use a discretizing scale (e.g. threshold).`}function fh(e){return `Facet encoding dropped as ${e.join(" and ")} ${e.length>1?"are":"is"} also specified.`}function ks(e,t){return `Using discrete channel "${e}" to encode "${t}" field can be misleading as it does not encode ${t==="ordinal"?"order":"magnitude"}.`}function dh(e){return `The ${e} for range marks cannot be an expression`}function ph(e,t){return `Line mark is for continuous lines and thus cannot be used with ${e&&t?"x2 and y2":e?"x2":"y2"}. We will use the rule mark (line segments) instead.`}function gh(e,t){return `Specified orient "${e}" overridden with "${t}".`}function hh(e){return `Cannot use the scale property "${e}" with non-color channel.`}function mh(e){return `Cannot use the relative band size with ${e} scale.`}function yh(e){return `Using unaggregated domain with raw field has no effect (${J(e)}).`}function bh(e){return `Unaggregated domain not applicable for "${e}" since it produces values outside the origin domain of the source data.`}function xh(e){return `Unaggregated domain is currently unsupported for log scale (${J(e)}).`}function Sh(e){return `Cannot apply size to non-oriented mark "${e}".`}function vh(e,t,n){return `Channel "${e}" does not work with "${t}" scale. We are using "${n}" scale instead.`}function Eh(e,t){return `FieldDef does not work with "${e}" scale. We are using "${t}" scale instead.`}function Eu(e,t,n){return `${n}-scale's "${t}" is dropped as it does not work with ${e} scale.`}function $u(e){return `The step for "${e}" is dropped because the ${e==="width"?"x":"y"} is continuous.`}function $h(e,t,n,i){return `Conflicting ${t.toString()} property "${e.toString()}" (${J(n)} and ${J(i)}). Using ${J(n)}.`}function wh(e,t,n,i){return `Conflicting ${t.toString()} property "${e.toString()}" (${J(n)} and ${J(i)}). Using the union of the two domains.`}function Ch(e){return `Setting the scale to be independent for "${e}" means we also have to set the guide (axis or legend) to be independent.`}function Nh(e){return `Dropping sort property ${J(e)} as unioned domains only support boolean or op "count", "min", and "max".`}const fc="Domains that should be unioned has conflicting sort properties. Sort will be set to true.",Fh="Detected faceted independent scales that union domain of multiple fields from different data sources. We will use the first field. The result view size may be incorrect.",kh="Detected faceted independent scales that union domain of the same fields from different source. We will assume that this is the same field from a different fork of the same data source. However, if this is not the case, the result view size may be incorrect.",Th="Detected faceted independent scales that union domain of multiple fields from the same data source. We will use the first field. The result view size may be incorrect.";function Ah(e){return `Cannot stack "${e}" if there is already "${e}2".`}function Oh(e){return `Cannot stack non-linear scale (${e}).`}function _h(e){return `Stacking is applied even though the aggregate function is non-summative ("${e}").`}function yr(e,t){return `Invalid ${e}: ${J(t)}.`}function Rh(e){return `Dropping day from datetime ${J(e)} as day cannot be combined with other units.`}function Ih(e,t){return `${t?"extent ":""}${t&&e?"and ":""}${e?"center ":""}${t&&e?"are ":"is "}not needed when data are aggregated.`}function Lh(e,t,n){return `${e} is not usually used with ${t} for ${n}.`}function Ph(e,t){return `Continuous axis should not have customized aggregation function ${e}; ${t} already agregates the axis.`}function dc(e){return `1D error band does not support ${e}.`}function wu(e){return `Channel ${e} is required for "binned" bin.`}function zh(e){return `Channel ${e} should not be used with "binned" bin.`}function Dh(e){return `Domain for ${e} is required for threshold scale.`}const Cu=x3(p3);let ei=Cu;function Mh(e){return ei=e,ei}function jh(){return ei=Cu,ei}function S(...e){ei.warn(...e);}function Uh(...e){ei.debug(...e);}function In(e){if(e&&et$1(e)){for(const t of Do)if(t in e)return !0}return !1}const Nu=["january","february","march","april","may","june","july","august","september","october","november","december"],Bh=Nu.map(e=>e.substr(0,3)),Fu=["sunday","monday","tuesday","wednesday","thursday","friday","saturday"],Wh=Fu.map(e=>e.substr(0,3));function Gh(e){if(Ir(e)&&(e=+e),Mr$1(e))return e>4&&S(yr("quarter",e)),e-1;throw new Error(yr("quarter",e))}function Hh(e){if(Ir(e)&&(e=+e),Mr$1(e))return e-1;{const t=e.toLowerCase(),n=Nu.indexOf(t);if(n!==-1)return n;const i=t.substr(0,3),r=Bh.indexOf(i);if(r!==-1)return r;throw new Error(yr("month",e))}}function qh(e){if(Ir(e)&&(e=+e),Mr$1(e))return e%7;{const t=e.toLowerCase(),n=Fu.indexOf(t);if(n!==-1)return n;const i=t.substr(0,3),r=Wh.indexOf(i);if(r!==-1)return r;throw new Error(yr("day",e))}}function zo(e,t){const n=[];if(t&&e.day!==void 0&&x(e).length>1&&(S(Rh(e)),e=z(e),delete e.day),e.year!==void 0?n.push(e.year):n.push(2012),e.month!==void 0){const i=t?Hh(e.month):e.month;n.push(i);}else if(e.quarter!==void 0){const i=t?Gh(e.quarter):e.quarter;n.push(Mr$1(i)?i*3:`${i}*3`);}else n.push(0);if(e.date!==void 0)n.push(e.date);else if(e.day!==void 0){const i=t?qh(e.day):e.day;n.push(Mr$1(i)?i+1:`${i}+1`);}else n.push(1);for(const i of ["hours","minutes","seconds","milliseconds"]){const r=e[i];n.push(typeof r>"u"?0:r);}return n}function $n(e){const n=zo(e,!0).join(", ");return e.utc?`utc(${n})`:`datetime(${n})`}function Vh(e){const n=zo(e,!1).join(", ");return e.utc?`utc(${n})`:`datetime(${n})`}function Xh(e){const t=zo(e,!0);return e.utc?+new Date(Date.UTC(...t)):+new Date(...t)}const ku={year:1,quarter:1,month:1,week:1,day:1,dayofyear:1,date:1,hours:1,minutes:1,seconds:1,milliseconds:1},Do=x(ku);function Yh(e){return !!ku[e]}function Ln(e){return et$1(e)?e.binned:Tu(e)}function Tu(e){return e&&e.startsWith("binned")}function Mo(e){return e.startsWith("utc")}function Kh(e){return e.substring(3)}const Jh={"year-month":"%b %Y ","year-month-date":"%b %d, %Y "};function Gr(e){return Do.filter(t=>Ou(e,t))}function Au(e){const t=Gr(e);return t[t.length-1]}function Ou(e,t){const n=e.indexOf(t);return !(n<0||n>0&&t==="seconds"&&e.charAt(n-1)==="i"||e.length>n+3&&t==="day"&&e.charAt(n+3)==="o"||n>0&&t==="year"&&e.charAt(n-1)==="f")}function Qh(e,t,{end:n}={end:!1}){const i=Co(t),r=Mo(e)?"utc":"";function s(c){return c==="quarter"?`(${r}quarter(${i})-1)`:`${r}${c}(${i})`}let o;const a={};for(const c of Do)Ou(e,c)&&(a[c]=s(c),o=c);return n&&(a[o]+="+1"),Vh(a)}function _u(e){if(!e)return;const t=Gr(e);return `timeUnitSpecifier(${J(t)}, ${J(Jh)})`}function Zh(e,t,n){if(!e)return;const i=_u(e);return `${n||Mo(e)?"utc":"time"}Format(${t}, ${i})`}function me(e){if(!e)return;let t;return xt$1(e)?Tu(e)?t={unit:e.substring(6),binned:!0}:t={unit:e}:et$1(e)&&(t={...e,...e.unit?{unit:e.unit}:{}}),Mo(t.unit)&&(t.utc=!0,t.unit=Kh(t.unit)),t}function em(e){const{utc:t,...n}=me(e);return n.unit?(t?"utc":"")+x(n).map(i=>re(`${i==="unit"?"":`_${i}_`}${n[i]}`)).join(""):(t?"utc":"")+"timeunit"+x(n).map(i=>re(`_${i}_${n[i]}`)).join("")}function Ru(e,t=n=>n){const n=me(e),i=Au(n.unit);if(i&&i!=="day"){const r={year:2001,month:1,date:1,hours:0,minutes:0,seconds:0,milliseconds:0},{step:s,part:o}=Iu(i,n.step),a={...r,[o]:+r[o]+s};return `${t($n(a))} - ${t($n(r))}`}}const tm={year:1,month:1,date:1,hours:1,minutes:1,seconds:1,milliseconds:1};function nm(e){return !!tm[e]}function Iu(e,t=1){if(nm(e))return {part:e,step:t};switch(e){case"day":case"dayofyear":return {part:"date",step:t};case"quarter":return {part:"month",step:t*3};case"week":return {part:"date",step:t*7}}}function im(e){return e?.param}function jo(e){return !!e?.field&&e.equal!==void 0}function Uo(e){return !!e?.field&&e.lt!==void 0}function Bo(e){return !!e?.field&&e.lte!==void 0}function Wo(e){return !!e?.field&&e.gt!==void 0}function Go(e){return !!e?.field&&e.gte!==void 0}function Ho(e){if(e?.field){if(U(e.range)&&e.range.length===2)return !0;if(T(e.range))return !0}return !1}function qo(e){return !!e?.field&&(U(e.oneOf)||U(e.in))}function rm(e){return !!e?.field&&e.valid!==void 0}function Lu(e){return qo(e)||jo(e)||Ho(e)||Uo(e)||Wo(e)||Bo(e)||Go(e)}function st(e,t){return es(e,{timeUnit:t,wrapTime:!0})}function sm(e,t){return e.map(n=>st(n,t))}function Pu(e,t=!0){const{field:n}=e,i=me(e.timeUnit),{unit:r,binned:s}=i||{},o=E(e,{expr:"datum"}),a=r?`time(${s?o:Qh(r,n)})`:o;if(jo(e))return `${a}===${st(e.equal,r)}`;if(Uo(e)){const c=e.lt;return `${a}<${st(c,r)}`}else if(Wo(e)){const c=e.gt;return `${a}>${st(c,r)}`}else if(Bo(e)){const c=e.lte;return `${a}<=${st(c,r)}`}else if(Go(e)){const c=e.gte;return `${a}>=${st(c,r)}`}else {if(qo(e))return `indexof([${sm(e.oneOf,r).join(",")}], ${a}) !== -1`;if(rm(e))return Vo(a,e.valid);if(Ho(e)){const{range:c}=e,l=T(c)?{signal:`${c.signal}[0]`}:c[0],u=T(c)?{signal:`${c.signal}[1]`}:c[1];if(l!==null&&u!==null&&t)return "inrange("+a+", ["+st(l,r)+", "+st(u,r)+"])";const f=[];return l!==null&&f.push(`${a} >= ${st(l,r)}`),u!==null&&f.push(`${a} <= ${st(u,r)}`),f.length>0?f.join(" && "):"true"}}throw new Error(`Invalid field predicate: ${J(e)}`)}function Vo(e,t=!0){return t?`isValid(${e}) && isFinite(+${e})`:`!isValid(${e}) || !isFinite(+${e})`}function om(e){return Lu(e)&&e.timeUnit?{...e,timeUnit:me(e.timeUnit)}:e}const Xi={quantitative:"quantitative",ordinal:"ordinal",temporal:"temporal",nominal:"nominal",geojson:"geojson"};function am(e){return e==="quantitative"||e==="temporal"}function zu(e){return e==="ordinal"||e==="nominal"}const wn=Xi.quantitative,Xo=Xi.ordinal,ti=Xi.temporal,Yo=Xi.nominal,hi=Xi.geojson;function cm(e){if(e)switch(e=e.toLowerCase(),e){case"q":case wn:return "quantitative";case"t":case ti:return "temporal";case"o":case Xo:return "ordinal";case"n":case Yo:return "nominal";case hi:return "geojson"}}const Te={LINEAR:"linear",LOG:"log",POW:"pow",SQRT:"sqrt",SYMLOG:"symlog",IDENTITY:"identity",SEQUENTIAL:"sequential",TIME:"time",UTC:"utc",QUANTILE:"quantile",QUANTIZE:"quantize",THRESHOLD:"threshold",BIN_ORDINAL:"bin-ordinal",ORDINAL:"ordinal",POINT:"point",BAND:"band"},Js={linear:"numeric",log:"numeric",pow:"numeric",sqrt:"numeric",symlog:"numeric",identity:"numeric",sequential:"numeric",time:"time",utc:"time",ordinal:"ordinal","bin-ordinal":"bin-ordinal",point:"ordinal-position",band:"ordinal-position",quantile:"discretizing",quantize:"discretizing",threshold:"discretizing"};function lm(e,t){const n=Js[e],i=Js[t];return n===i||n==="ordinal-position"&&i==="time"||i==="ordinal-position"&&n==="time"}const um={linear:0,log:1,pow:1,sqrt:1,symlog:1,identity:1,sequential:1,time:0,utc:0,point:10,band:11,ordinal:0,"bin-ordinal":0,quantile:0,quantize:0,threshold:0};function pc(e){return um[e]}const Du=new Set(["linear","log","pow","sqrt","symlog"]),Mu=new Set([...Du,"time","utc"]);function ju(e){return Du.has(e)}const Uu=new Set(["quantile","quantize","threshold"]),fm=new Set([...Mu,...Uu,"sequential","identity"]),dm=new Set(["ordinal","bin-ordinal","point","band"]);function ye(e){return dm.has(e)}function De(e){return fm.has(e)}function Ye(e){return Mu.has(e)}function ni(e){return Uu.has(e)}const pm={pointPadding:.5,barBandPaddingInner:.1,rectBandPaddingInner:0,bandWithNestedOffsetPaddingInner:.2,bandWithNestedOffsetPaddingOuter:.2,minBandSize:2,minFontSize:8,maxFontSize:40,minOpacity:.3,maxOpacity:.8,minSize:9,minStrokeWidth:1,maxStrokeWidth:4,quantileCount:4,quantizeCount:4,zero:!0};function gm(e){return !xt$1(e)&&!!e.name}function Bu(e){return e?.param}function hm(e){return e?.unionWith}function mm(e){return et$1(e)&&"field"in e}const ym={type:1,domain:1,domainMax:1,domainMin:1,domainMid:1,domainRaw:1,align:1,range:1,rangeMax:1,rangeMin:1,scheme:1,bins:1,reverse:1,round:1,clamp:1,nice:1,base:1,exponent:1,constant:1,interpolate:1,zero:1,padding:1,paddingInner:1,paddingOuter:1},{type:kw,domain:Tw,range:Aw,rangeMax:Ow,rangeMin:_w,scheme:Rw,...bm}=ym,xm=x(bm);function Qs(e,t){switch(t){case"type":case"domain":case"reverse":case"range":return !0;case"scheme":case"interpolate":return !["point","band","identity"].includes(e);case"bins":return !["point","band","identity","ordinal"].includes(e);case"round":return Ye(e)||e==="band"||e==="point";case"padding":case"rangeMin":case"rangeMax":return Ye(e)||["point","band"].includes(e);case"paddingOuter":case"align":return ["point","band"].includes(e);case"paddingInner":return e==="band";case"domainMax":case"domainMid":case"domainMin":case"domainRaw":case"clamp":return Ye(e);case"nice":return Ye(e)||e==="quantize"||e==="threshold";case"exponent":return e==="pow";case"base":return e==="log";case"constant":return e==="symlog";case"zero":return De(e)&&!G(["log","time","utc","threshold","quantile"],e)}}function Wu(e,t){switch(t){case"interpolate":case"scheme":case"domainMid":return qn(e)?void 0:hh(t);case"align":case"type":case"bins":case"domain":case"domainMax":case"domainMin":case"domainRaw":case"range":case"base":case"exponent":case"constant":case"nice":case"padding":case"paddingInner":case"paddingOuter":case"rangeMax":case"rangeMin":case"reverse":case"round":case"clamp":case"zero":return}}function Sm(e,t){return G([Xo,Yo],t)?e===void 0||ye(e):t===ti?G([Te.TIME,Te.UTC,void 0],e):t===wn?ju(e)||ni(e)||e===void 0:!0}function vm(e,t,n=!1){if(!Pt(e))return !1;switch(e){case se:case be:case Kt:case gi:case We:case tt:return Ye(t)||t==="band"?!0:t==="point"?!n:!1;case It:case Zt:case Lt:case Jt:case Qt:case On:return Ye(t)||ni(t)||G(["band","point","ordinal"],t);case Ae:case yt:case bt:return t!=="band";case en:case Oe:return t==="ordinal"||ni(t)}}const Ne={arc:"arc",area:"area",bar:"bar",image:"image",line:"line",point:"point",rect:"rect",rule:"rule",text:"text",tick:"tick",trail:"trail",circle:"circle",square:"square",geoshape:"geoshape"},Gu=Ne.arc,Hr=Ne.area,qr=Ne.bar,Em=Ne.image,Vr=Ne.line,Xr=Ne.point,$m=Ne.rect,br=Ne.rule,Hu=Ne.text,Ko=Ne.tick,wm=Ne.trail,Jo=Ne.circle,Qo=Ne.square,qu=Ne.geoshape;function rn(e){return ["line","area","trail"].includes(e)}function zi(e){return ["rect","bar","image","arc"].includes(e)}const Cm=new Set(x(Ne));function pt(e){return e.type}const Nm=["stroke","strokeWidth","strokeDash","strokeDashOffset","strokeOpacity","strokeJoin","strokeMiterLimit"],Fm=["fill","fillOpacity"],km=[...Nm,...Fm],Tm={color:1,filled:1,invalid:1,order:1,radius2:1,theta2:1,timeUnitBandSize:1,timeUnitBandPosition:1},gc=x(Tm),Am={area:["line","point"],bar:["binSpacing","continuousBandSize","discreteBandSize","minBandSize"],rect:["binSpacing","continuousBandSize","discreteBandSize","minBandSize"],line:["point"],tick:["bandSize","thickness"]},Om={color:"#4c78a8",invalid:"filter",timeUnitBandSize:1},_m={mark:1,arc:1,area:1,bar:1,circle:1,image:1,line:1,point:1,rect:1,rule:1,square:1,text:1,tick:1,trail:1,geoshape:1},Vu=x(_m);function Cn(e){return e&&e.band!=null}const Rm={horizontal:["cornerRadiusTopRight","cornerRadiusBottomRight"],vertical:["cornerRadiusTopLeft","cornerRadiusTopRight"]},Xu=5,Im={binSpacing:1,continuousBandSize:Xu,minBandSize:.25,timeUnitBandPosition:.5},Lm={binSpacing:0,continuousBandSize:Xu,minBandSize:.25,timeUnitBandPosition:.5},Pm={thickness:1};function zm(e){return pt(e)?e.type:e}function Zo(e){const{channel:t,channelDef:n,markDef:i,scale:r,config:s}=e,o=ta(e);return v(n)&&!lu(n.aggregate)&&r&&Ye(r.get("type"))?Dm({fieldDef:n,channel:t,markDef:i,ref:o,config:s}):o}function Dm({fieldDef:e,channel:t,markDef:n,ref:i,config:r}){return rn(n.type)?i:X("invalid",n,r)===null?[Mm(e,t),i]:i}function Mm(e,t){const n=ea(e,!0),r=_n(t)==="y"?{field:{group:"height"}}:{value:0};return {test:n,...r}}function ea(e,t=!0){return Vo(xt$1(e)?e:E(e,{expr:"datum"}),!t)}function jm(e){const{datum:t}=e;return In(t)?$n(t):`${J(t)}`}function mn(e,t,n,i){const r={};if(t&&(r.scale=t),vt(e)){const{datum:s}=e;In(s)?r.signal=$n(s):T(s)?r.signal=s.signal:Vi(s)?r.signal=s.expr:r.value=s;}else r.field=E(e,n);if(i){const{offset:s,band:o}=i;s&&(r.offset=s),o&&(r.band=o);}return r}function xr({scaleName:e,fieldOrDatumDef:t,fieldOrDatumDef2:n,offset:i,startSuffix:r,endSuffix:s="end",bandPosition:o=.5}){const a=!T(o)&&0{switch(t.fieldTitle){case"plain":return e.field;case"functional":return ey(e);default:return Zm(e,t)}};let lf=cf;function uf(e){lf=e;}function ty(){uf(cf);}function Vn(e,t,{allowDisabling:n,includeDefault:i=!0}){const r=sa(e)?.title;if(!v(e))return r??e.title;const s=e,o=i?oa(s,t):void 0;return n?le(r,s.title,o):r??s.title??o}function sa(e){if(ri(e)&&e.axis)return e.axis;if(of(e)&&e.legend)return e.legend;if(ia(e)&&e.header)return e.header}function oa(e,t){return lf(e,t)}function Er(e){if(af(e)){const{format:t,formatType:n}=e;return {format:t,formatType:n}}else {const t=sa(e)??{},{format:n,formatType:i}=t;return {format:n,formatType:i}}}function ny(e,t){switch(t){case"latitude":case"longitude":return "quantitative";case"row":case"column":case"facet":case"shape":case"strokeDash":return "nominal";case"order":return "ordinal"}if(ra(e)&&U(e.sort))return "ordinal";const{aggregate:n,bin:i,timeUnit:r}=e;if(r)return "temporal";if(i||n&&!tn(n)&&!At(n))return "quantitative";if(Pn(e)&&e.scale?.type)switch(Js[e.scale.type]){case"numeric":case"discretizing":return "quantitative";case"time":return "temporal"}return "nominal"}function gt(e){if(v(e))return e;if(Qr(e))return e.condition}function fe(e){if(D(e))return e;if(Ji(e))return e.condition}function ff(e,t,n,i={}){if(xt$1(e)||Mr$1(e)||Ag$1(e)){const r=xt$1(e)?"string":Mr$1(e)?"number":"boolean";return S(ih(t,r,e)),{value:e}}return D(e)?$r(e,t,n,i):Ji(e)?{...e,condition:$r(e.condition,t,n,i)}:e}function $r(e,t,n,i){if(af(e)){const{format:r,formatType:s,...o}=e;if(Nn(s)&&!n.customFormatTypes)return S(uc(t)),$r(o,t,n,i)}else {const r=ri(e)?"axis":of(e)?"legend":ia(e)?"header":null;if(r&&e[r]){const{format:s,formatType:o,...a}=e[r];if(Nn(o)&&!n.customFormatTypes)return S(uc(t)),$r({...e,[r]:a},t,n,i)}}return v(e)?aa(e,t,i):iy(e)}function iy(e){let t=e.type;if(t)return e;const{datum:n}=e;return t=Mr$1(n)?"quantitative":xt$1(n)?"nominal":In(n)?"temporal":void 0,{...e,type:t}}function aa(e,t,{compositeMark:n=!1}={}){const{aggregate:i,timeUnit:r,bin:s,field:o}=e,a={...e};if(!n&&i&&!Io(i)&&!tn(i)&&!At(i)&&(S(sh(i)),delete a.aggregate),r&&(a.timeUnit=me(r)),o&&(a.field=`${o}`),ee(s)&&(a.bin=Zr(s,t)),xe(s)&&!ue(t)&&S(zh(t)),Ce(a)){const{type:c}=a,l=cm(c);c!==l&&(a.type=l),c!=="quantitative"&&lu(i)&&(S(rh(c,i)),a.type="quantitative");}else if(!iu(t)){const c=ny(a,t);a.type=c;}if(Ce(a)){const{compatible:c,warning:l}=ry(a,t)||{};c===!1&&S(l);}if(ra(a)&&xt$1(a.sort)){const{sort:c}=a;if(mc(c))return {...a,sort:{encoding:c}};const l=c.substr(1);if(c.charAt(0)==="-"&&mc(l))return {...a,sort:{encoding:l,order:"descending"}}}if(ia(a)){const{header:c}=a;if(c){const{orient:l,...u}=c;if(l)return {...a,header:{...u,labelOrient:c.labelOrient||l,titleOrient:c.titleOrient||l}}}}return a}function Zr(e,t){return Ag$1(e)?{maxbins:tc(t)}:e==="binned"?{binned:!0}:!e.maxbins&&!e.step?{...e,maxbins:tc(t)}:e}const Mn={compatible:!0};function ry(e,t){const n=e.type;if(n==="geojson"&&t!=="shape")return {compatible:!1,warning:`Channel ${t} should not be used with a geojson data.`};switch(t){case Nt:case Ft:case Lr:return vr(e)?Mn:{compatible:!1,warning:lh(t)};case se:case be:case Kt:case gi:case Ae:case yt:case bt:case Gi:case Hi:case Pr:case En:case zr:case Dr:case On:case We:case tt:case Mr:return Mn;case it:case Be:case nt:case rt:return n!==wn?{compatible:!1,warning:`Channel ${t} should be used with a quantitative field only, not ${e.type} field.`}:Mn;case Lt:case Jt:case Qt:case Zt:case It:case Rt:case _t:case et:case mt:return n==="nominal"&&!e.sort?{compatible:!1,warning:`Channel ${t} should not be used with an unsorted discrete field.`}:Mn;case Oe:case en:return !vr(e)&&!Jm(e)?{compatible:!1,warning:uh(t)}:Mn;case Zn:return e.type==="nominal"&&!("sort"in e)?{compatible:!1,warning:"Channel order is inappropriate for nominal field, which has no inherent order."}:Mn}}function si(e){const{formatType:t}=Er(e);return t==="time"||!t&&sy(e)}function sy(e){return e&&(e.type==="temporal"||v(e)&&!!e.timeUnit)}function es(e,{timeUnit:t,type:n,wrapTime:i,undefinedIfExprNotRequired:r}){const s=t&&me(t)?.unit;let o=s||n==="temporal",a;return Vi(e)?a=e.expr:T(e)?a=e.signal:In(e)?(o=!0,a=$n(e)):(xt$1(e)||Mr$1(e))&&o&&(a=`datetime(${J(e)})`,Yh(s)&&(Mr$1(e)&&e<1e4||xt$1(e)&&isNaN(Date.parse(e)))&&(a=$n({[s]:e}))),a?i&&o?`time(${a})`:a:r?void 0:J(e)}function df(e,t){const{type:n}=e;return t.map(i=>{const r=v(e)&&!Ln(e.timeUnit)?e.timeUnit:void 0,s=es(i,{timeUnit:r,type:n,undefinedIfExprNotRequired:!0});return s!==void 0?{signal:s}:i})}function Qi(e,t){return ee(e.bin)?Pt(t)&&["ordinal","nominal"].includes(e.type):(console.warn("Only call this method for binned field defs."),!1)}const xc={labelAlign:{part:"labels",vgProp:"align"},labelBaseline:{part:"labels",vgProp:"baseline"},labelColor:{part:"labels",vgProp:"fill"},labelFont:{part:"labels",vgProp:"font"},labelFontSize:{part:"labels",vgProp:"fontSize"},labelFontStyle:{part:"labels",vgProp:"fontStyle"},labelFontWeight:{part:"labels",vgProp:"fontWeight"},labelOpacity:{part:"labels",vgProp:"opacity"},labelOffset:null,labelPadding:null,gridColor:{part:"grid",vgProp:"stroke"},gridDash:{part:"grid",vgProp:"strokeDash"},gridDashOffset:{part:"grid",vgProp:"strokeDashOffset"},gridOpacity:{part:"grid",vgProp:"opacity"},gridWidth:{part:"grid",vgProp:"strokeWidth"},tickColor:{part:"ticks",vgProp:"stroke"},tickDash:{part:"ticks",vgProp:"strokeDash"},tickDashOffset:{part:"ticks",vgProp:"strokeDashOffset"},tickOpacity:{part:"ticks",vgProp:"opacity"},tickSize:null,tickWidth:{part:"ticks",vgProp:"strokeWidth"}};function Zi(e){return e?.condition}const pf=["domain","grid","labels","ticks","title"],oy={grid:"grid",gridCap:"grid",gridColor:"grid",gridDash:"grid",gridDashOffset:"grid",gridOpacity:"grid",gridScale:"grid",gridWidth:"grid",orient:"main",bandPosition:"both",aria:"main",description:"main",domain:"main",domainCap:"main",domainColor:"main",domainDash:"main",domainDashOffset:"main",domainOpacity:"main",domainWidth:"main",format:"main",formatType:"main",labelAlign:"main",labelAngle:"main",labelBaseline:"main",labelBound:"main",labelColor:"main",labelFlush:"main",labelFlushOffset:"main",labelFont:"main",labelFontSize:"main",labelFontStyle:"main",labelFontWeight:"main",labelLimit:"main",labelLineHeight:"main",labelOffset:"main",labelOpacity:"main",labelOverlap:"main",labelPadding:"main",labels:"main",labelSeparation:"main",maxExtent:"main",minExtent:"main",offset:"both",position:"main",tickCap:"main",tickColor:"main",tickDash:"main",tickDashOffset:"main",tickMinStep:"both",tickOffset:"both",tickOpacity:"main",tickRound:"both",ticks:"main",tickSize:"main",tickWidth:"both",title:"main",titleAlign:"main",titleAnchor:"main",titleAngle:"main",titleBaseline:"main",titleColor:"main",titleFont:"main",titleFontSize:"main",titleFontStyle:"main",titleFontWeight:"main",titleLimit:"main",titleLineHeight:"main",titleOpacity:"main",titlePadding:"main",titleX:"main",titleY:"main",encode:"both",scale:"both",tickBand:"both",tickCount:"both",tickExtra:"both",translate:"both",values:"both",zindex:"both"},gf={orient:1,aria:1,bandPosition:1,description:1,domain:1,domainCap:1,domainColor:1,domainDash:1,domainDashOffset:1,domainOpacity:1,domainWidth:1,format:1,formatType:1,grid:1,gridCap:1,gridColor:1,gridDash:1,gridDashOffset:1,gridOpacity:1,gridWidth:1,labelAlign:1,labelAngle:1,labelBaseline:1,labelBound:1,labelColor:1,labelFlush:1,labelFlushOffset:1,labelFont:1,labelFontSize:1,labelFontStyle:1,labelFontWeight:1,labelLimit:1,labelLineHeight:1,labelOffset:1,labelOpacity:1,labelOverlap:1,labelPadding:1,labels:1,labelSeparation:1,maxExtent:1,minExtent:1,offset:1,position:1,tickBand:1,tickCap:1,tickColor:1,tickCount:1,tickDash:1,tickDashOffset:1,tickExtra:1,tickMinStep:1,tickOffset:1,tickOpacity:1,tickRound:1,ticks:1,tickSize:1,tickWidth:1,title:1,titleAlign:1,titleAnchor:1,titleAngle:1,titleBaseline:1,titleColor:1,titleFont:1,titleFontSize:1,titleFontStyle:1,titleFontWeight:1,titleLimit:1,titleLineHeight:1,titleOpacity:1,titlePadding:1,titleX:1,titleY:1,translate:1,values:1,zindex:1},ay={...gf,style:1,labelExpr:1,encoding:1};function Sc(e){return !!ay[e]}const cy={axis:1,axisBand:1,axisBottom:1,axisDiscrete:1,axisLeft:1,axisPoint:1,axisQuantitative:1,axisRight:1,axisTemporal:1,axisTop:1,axisX:1,axisXBand:1,axisXDiscrete:1,axisXPoint:1,axisXQuantitative:1,axisXTemporal:1,axisY:1,axisYBand:1,axisYDiscrete:1,axisYPoint:1,axisYQuantitative:1,axisYTemporal:1},hf=x(cy);function zt(e){return "mark"in e}class ts{constructor(t,n){this.name=t,this.run=n;}hasMatchingType(t){return zt(t)?zm(t.mark)===this.name:!1}}function yn(e,t){const n=e&&e[t];return n?U(n)?Sn(n,i=>!!i.field):v(n)||Qr(n):!1}function mf(e,t){const n=e&&e[t];return n?U(n)?Sn(n,i=>!!i.field):v(n)||vt(n)||Ji(n):!1}function yf(e,t){if(ue(t)){const n=e[t];if((v(n)||vt(n))&&(zu(n.type)||v(n)&&n.timeUnit)){const i=Ao(t);return mf(e,i)}}return !1}function ca(e){return Sn(lg,t=>{if(yn(e,t)){const n=e[t];if(U(n))return Sn(n,i=>!!i.aggregate);{const i=gt(n);return i&&!!i.aggregate}}return !1})}function bf(e,t){const n=[],i=[],r=[],s=[],o={};return la(e,(a,c)=>{if(v(a)){const{field:l,aggregate:u,bin:f,timeUnit:d,...g}=a;if(u||d||f){const h=sa(a)?.title;let m=E(a,{forAs:!0});const y={...h?[]:{title:Vn(a,t,{allowDisabling:!0})},...g,field:m};if(u){let b;if(tn(u)?(b="argmax",m=E({op:"argmax",field:u.argmax},{forAs:!0}),y.field=`${m}.${l}`):At(u)?(b="argmin",m=E({op:"argmin",field:u.argmin},{forAs:!0}),y.field=`${m}.${l}`):u!=="boxplot"&&u!=="errorbar"&&u!=="errorband"&&(b=u),b){const C={op:b,as:m};l&&(C.field=l),s.push(C);}}else if(n.push(m),Ce(a)&&ee(f)){if(i.push({bin:f,field:l,as:m}),n.push(E(a,{binSuffix:"end"})),Qi(a,c)&&n.push(E(a,{binSuffix:"range"})),ue(c)){const b={field:`${m}_end`};o[`${c}2`]=b;}y.bin="binned",iu(c)||(y.type=wn);}else if(d&&!Ln(d)){r.push({timeUnit:d,field:l,as:m});const b=Ce(a)&&a.type!==ti&&"time";b&&(c===Gi||c===En?y.formatType=b:xg(c)?y.legend={formatType:b,...y.legend}:ue(c)&&(y.axis={formatType:b,...y.axis}));}o[c]=y;}else n.push(l),o[c]=e[c];}else o[c]=e[c];}),{bins:i,timeUnits:r,aggregate:s,groupby:n,encoding:o}}function ly(e,t,n){const i=vg(t,n);if(i){if(i==="binned"){const r=e[t===et?se:be];return !!(v(r)&&v(e[t])&&xe(r.bin))}}else return !1;return !0}function uy(e,t,n,i){const r={};for(const s of x(e))nu(s)||S(ch(s));for(let s of hg){if(!e[s])continue;const o=e[s];if(qi(s)){const a=gg(s),c=r[a];if(v(c)&&am(c.type)&&v(o)&&!c.timeUnit){S(nh(a));continue}}if(s==="angle"&&t==="arc"&&!e.theta&&(S(th),s=We),!ly(e,s,t)){S(Wr(s,t));continue}if(s===It&&t==="line"&>(e[s])?.aggregate){S(ah);continue}if(s===Ae&&(n?"fill"in e:"stroke"in e)){S(vu("encoding",{fill:"fill"in e,stroke:"stroke"in e}));continue}if(s===Hi||s===Zn&&!U(o)&&!Qe(o)||s===En&&U(o)){if(o){if(s===Zn){const a=e[s];if(sf(a)){r[s]=a;continue}}r[s]=H(o).reduce((a,c)=>(v(c)?a.push(aa(c,s)):S(Ks(c,s)),a),[]);}}else {if(s===En&&o===null)r[s]=null;else if(!v(o)&&!vt(o)&&!Qe(o)&&!Jr(o)&&!T(o)){S(Ks(o,s));continue}r[s]=ff(o,s,i);}}return r}function ns(e,t){const n={};for(const i of x(e)){const r=ff(e[i],i,t,{compositeMark:!0});n[i]=r;}return n}function fy(e){const t=[];for(const n of x(e))if(yn(e,n)){const i=e[n],r=H(i);for(const s of r)v(s)?t.push(s):Qr(s)&&t.push(s.condition);}return t}function la(e,t,n){if(e)for(const i of x(e)){const r=e[i];if(U(r))for(const s of r)t.call(n,s,i);else t.call(n,r,i);}}function dy(e,t,n,i){return e?x(e).reduce((r,s)=>{const o=e[s];return U(o)?o.reduce((a,c)=>t.call(i,a,c,s),r):t.call(i,r,o,s)},n):n}function xf(e,t){return x(t).reduce((n,i)=>{switch(i){case se:case be:case zr:case Mr:case Dr:case et:case mt:case Kt:case gi:case We:case Rt:case tt:case _t:case nt:case it:case rt:case Be:case Gi:case Oe:case On:case En:return n;case Zn:if(e==="line"||e==="trail")return n;case Hi:case Pr:{const r=t[i];if(U(r)||v(r))for(const s of H(r))s.aggregate||n.push(E(s,{}));return n}case It:if(e==="trail")return n;case Ae:case yt:case bt:case Lt:case Jt:case Qt:case en:case Zt:{const r=gt(t[i]);return r&&!r.aggregate&&n.push(E(r,{})),n}}},[])}function py(e){const{tooltip:t,...n}=e;if(!t)return {filteredEncoding:n};let i,r;if(U(t)){for(const s of t)s.aggregate?(i||(i=[]),i.push(s)):(r||(r=[]),r.push(s));i&&(n.tooltip=i);}else t.aggregate?n.tooltip=t:r=t;return U(r)&&r.length===1&&(r=r[0]),{customTooltipWithoutAggregatedField:r,filteredEncoding:n}}function eo(e,t,n,i=!0){if("tooltip"in n)return {tooltip:n.tooltip};const r=e.map(({fieldPrefix:o,titlePrefix:a})=>{const c=i?` of ${ua(t)}`:"";return {field:o+t.field,type:t.type,title:T(a)?{signal:`${a}"${escape(c)}"`}:a+c}}),s=fy(n).map(Ym);return {tooltip:[...r,...lt(s,W)]}}function ua(e){const{title:t,field:n}=e;return le(t,n)}function fa(e,t,n,i,r){const{scale:s,axis:o}=n;return ({partName:a,mark:c,positionPrefix:l,endPositionPrefix:u=void 0,extraEncoding:f={}})=>{const d=ua(n);return Sf(e,a,r,{mark:c,encoding:{[t]:{field:`${l}_${n.field}`,type:n.type,...d!==void 0?{title:d}:{},...s!==void 0?{scale:s}:{},...o!==void 0?{axis:o}:{}},...xt$1(u)?{[`${t}2`]:{field:`${u}_${n.field}`}}:{},...i,...f}})}}function Sf(e,t,n,i){const{clip:r,color:s,opacity:o}=e,a=e.type;return e[t]||e[t]===void 0&&n[t]?[{...i,mark:{...n[t],...r?{clip:r}:{},...s?{color:s}:{},...o?{opacity:o}:{},...pt(i.mark)?i.mark:{type:i.mark},style:`${a}-${String(t)}`,...Ag$1(e[t])?{}:e[t]}}]:[]}function vf(e,t,n){const{encoding:i}=e,r=t==="vertical"?"y":"x",s=i[r],o=i[`${r}2`],a=i[`${r}Error`],c=i[`${r}Error2`];return {continuousAxisChannelDef:rr(s,n),continuousAxisChannelDef2:rr(o,n),continuousAxisChannelDefError:rr(a,n),continuousAxisChannelDefError2:rr(c,n),continuousAxis:r}}function rr(e,t){if(e?.aggregate){const{aggregate:n,...i}=e;return n!==t&&S(Ph(n,t)),i}else return e}function Ef(e,t){const{mark:n,encoding:i}=e,{x:r,y:s}=i;if(pt(n)&&n.orient)return n.orient;if(Ut(r)){if(Ut(s)){const o=v(r)&&r.aggregate,a=v(s)&&s.aggregate;if(!o&&a===t)return "vertical";if(!a&&o===t)return "horizontal";if(o===t&&a===t)throw new Error("Both x and y cannot have aggregate");return si(s)&&!si(r)?"horizontal":"vertical"}return "horizontal"}else {if(Ut(s))return "vertical";throw new Error(`Need a valid continuous axis for ${t}s`)}}const wr="boxplot",gy=["box","median","outliers","rule","ticks"],hy=new ts(wr,wf);function $f(e){return Mr$1(e)?"tukey":e}function wf(e,{config:t}){e={...e,encoding:ns(e.encoding,t)};const{mark:n,encoding:i,params:r,projection:s,...o}=e,a=pt(n)?n:{type:n};r&&S(xu("boxplot"));const c=a.extent??t.boxplot.extent,l=X("size",a,t),u=a.invalid,f=$f(c),{bins:d,timeUnits:g,transform:p,continuousAxisChannelDef:h,continuousAxis:m,groupby:y,aggregate:b,encodingWithoutContinuousAxis:C,ticksOrient:k,boxOrient:N,customTooltipWithoutAggregatedField:_}=my(e,c,t),{color:L,size:U,...oe}=C,de=Ep=>fa(a,m,h,Ep,t.boxplot),Re=de(oe),sn=de(C),w=de({...oe,...U?{size:U}:{}}),$=eo([{fieldPrefix:f==="min-max"?"upper_whisker_":"max_",titlePrefix:"Max"},{fieldPrefix:"upper_box_",titlePrefix:"Q3"},{fieldPrefix:"mid_box_",titlePrefix:"Median"},{fieldPrefix:"lower_box_",titlePrefix:"Q1"},{fieldPrefix:f==="min-max"?"lower_whisker_":"min_",titlePrefix:"Min"}],h,C),I={type:"tick",color:"black",opacity:1,orient:k,invalid:u,aria:!1},O=f==="min-max"?$:eo([{fieldPrefix:"upper_whisker_",titlePrefix:"Upper Whisker"},{fieldPrefix:"lower_whisker_",titlePrefix:"Lower Whisker"}],h,C),P=[...Re({partName:"rule",mark:{type:"rule",invalid:u,aria:!1},positionPrefix:"lower_whisker",endPositionPrefix:"lower_box",extraEncoding:O}),...Re({partName:"rule",mark:{type:"rule",invalid:u,aria:!1},positionPrefix:"upper_box",endPositionPrefix:"upper_whisker",extraEncoding:O}),...Re({partName:"ticks",mark:I,positionPrefix:"lower_whisker",extraEncoding:O}),...Re({partName:"ticks",mark:I,positionPrefix:"upper_whisker",extraEncoding:O})],A=[...f!=="tukey"?P:[],...sn({partName:"box",mark:{type:"bar",...l?{size:l}:{},orient:N,invalid:u,ariaRoleDescription:"box"},positionPrefix:"lower_box",endPositionPrefix:"upper_box",extraEncoding:$}),...w({partName:"median",mark:{type:"tick",invalid:u,...et$1(t.boxplot.median)&&t.boxplot.median.color?{color:t.boxplot.median.color}:{},...l?{size:l}:{},orient:k,aria:!1},positionPrefix:"mid_box",extraEncoding:$})];if(f==="min-max")return {...o,transform:(o.transform??[]).concat(p),layer:A};const M=`datum["lower_box_${h.field}"]`,V=`datum["upper_box_${h.field}"]`,j=`(${V} - ${M})`,Q=`${M} - ${c} * ${j}`,ve=`${V} + ${c} * ${j}`,te=`datum["${h.field}"]`,on={joinaggregate:Cf(h.field),groupby:y},Cs={transform:[{filter:`(${Q} <= ${te}) && (${te} <= ${ve})`},{aggregate:[{op:"min",field:h.field,as:`lower_whisker_${h.field}`},{op:"max",field:h.field,as:`upper_whisker_${h.field}`},{op:"min",field:`lower_box_${h.field}`,as:`lower_box_${h.field}`},{op:"max",field:`upper_box_${h.field}`,as:`upper_box_${h.field}`},...b],groupby:y}],layer:P},{tooltip:K1,...Sp}=oe,{scale:Ya,axis:vp}=h,Ka=ua(h),Ja=ke(vp,["title"]),Qa=Sf(a,"outliers",t.boxplot,{transform:[{filter:`(${te} < ${Q}) || (${te} > ${ve})`}],mark:"point",encoding:{[m]:{field:h.field,type:h.type,...Ka!==void 0?{title:Ka}:{},...Ya!==void 0?{scale:Ya}:{},...K(Ja)?{}:{axis:Ja}},...Sp,...L?{color:L}:{},..._?{tooltip:_}:{}}})[0];let ir;const Za=[...d,...g,on];return Qa?ir={transform:Za,layer:[Qa,Cs]}:(ir=Cs,ir.transform.unshift(...Za)),{...o,layer:[ir,{transform:p,layer:A}]}}function Cf(e){return [{op:"q1",field:e,as:`lower_box_${e}`},{op:"q3",field:e,as:`upper_box_${e}`}]}function my(e,t,n){const i=Ef(e,wr),{continuousAxisChannelDef:r,continuousAxis:s}=vf(e,i,wr),o=r.field,a=$f(t),c=[...Cf(o),{op:"median",field:o,as:`mid_box_${o}`},{op:"min",field:o,as:(a==="min-max"?"lower_whisker_":"min_")+o},{op:"max",field:o,as:(a==="min-max"?"upper_whisker_":"max_")+o}],l=a==="min-max"||a==="tukey"?[]:[{calculate:`datum["upper_box_${o}"] - datum["lower_box_${o}"]`,as:`iqr_${o}`},{calculate:`min(datum["upper_box_${o}"] + datum["iqr_${o}"] * ${t}, datum["max_${o}"])`,as:`upper_whisker_${o}`},{calculate:`max(datum["lower_box_${o}"] - datum["iqr_${o}"] * ${t}, datum["min_${o}"])`,as:`lower_whisker_${o}`}],{[s]:u,...f}=e.encoding,{customTooltipWithoutAggregatedField:d,filteredEncoding:g}=py(f),{bins:p,timeUnits:h,aggregate:m,groupby:y,encoding:b}=bf(g,n),C=i==="vertical"?"horizontal":"vertical",k=i,N=[...p,...h,{aggregate:[...m,...c],groupby:y},...l];return {bins:p,timeUnits:h,transform:N,groupby:y,aggregate:m,continuousAxisChannelDef:r,continuousAxis:s,encodingWithoutContinuousAxis:b,ticksOrient:C,boxOrient:k,customTooltipWithoutAggregatedField:d}}const da="errorbar",yy=["ticks","rule"],by=new ts(da,Nf);function Nf(e,{config:t}){e={...e,encoding:ns(e.encoding,t)};const{transform:n,continuousAxisChannelDef:i,continuousAxis:r,encodingWithoutContinuousAxis:s,ticksOrient:o,markDef:a,outerSpec:c,tooltipEncoding:l}=Ff(e,da,t);delete s.size;const u=fa(a,r,i,s,t.errorbar),f=a.thickness,d=a.size,g={type:"tick",orient:o,aria:!1,...f!==void 0?{thickness:f}:{},...d!==void 0?{size:d}:{}},p=[...u({partName:"ticks",mark:g,positionPrefix:"lower",extraEncoding:l}),...u({partName:"ticks",mark:g,positionPrefix:"upper",extraEncoding:l}),...u({partName:"rule",mark:{type:"rule",ariaRoleDescription:"errorbar",...f!==void 0?{size:f}:{}},positionPrefix:"lower",endPositionPrefix:"upper",extraEncoding:l})];return {...c,transform:n,...p.length>1?{layer:p}:{...p[0]}}}function xy(e,t){const{encoding:n}=e;if(Sy(n))return {orient:Ef(e,t),inputType:"raw"};const i=vy(n),r=Ey(n),s=n.x,o=n.y;if(i){if(r)throw new Error(`${t} cannot be both type aggregated-upper-lower and aggregated-error`);const a=n.x2,c=n.y2;if(D(a)&&D(c))throw new Error(`${t} cannot have both x2 and y2`);if(D(a)){if(Ut(s))return {orient:"horizontal",inputType:"aggregated-upper-lower"};throw new Error(`Both x and x2 have to be quantitative in ${t}`)}else if(D(c)){if(Ut(o))return {orient:"vertical",inputType:"aggregated-upper-lower"};throw new Error(`Both y and y2 have to be quantitative in ${t}`)}throw new Error("No ranged axis")}else {const a=n.xError,c=n.xError2,l=n.yError,u=n.yError2;if(D(c)&&!D(a))throw new Error(`${t} cannot have xError2 without xError`);if(D(u)&&!D(l))throw new Error(`${t} cannot have yError2 without yError`);if(D(a)&&D(l))throw new Error(`${t} cannot have both xError and yError with both are quantiative`);if(D(a)){if(Ut(s))return {orient:"horizontal",inputType:"aggregated-error"};throw new Error("All x, xError, and xError2 (if exist) have to be quantitative")}else if(D(l)){if(Ut(o))return {orient:"vertical",inputType:"aggregated-error"};throw new Error("All y, yError, and yError2 (if exist) have to be quantitative")}throw new Error("No ranged axis")}}function Sy(e){return (D(e.x)||D(e.y))&&!D(e.x2)&&!D(e.y2)&&!D(e.xError)&&!D(e.xError2)&&!D(e.yError)&&!D(e.yError2)}function vy(e){return D(e.x2)||D(e.y2)}function Ey(e){return D(e.xError)||D(e.xError2)||D(e.yError)||D(e.yError2)}function Ff(e,t,n){const{mark:i,encoding:r,params:s,projection:o,...a}=e,c=pt(i)?i:{type:i};s&&S(xu(t));const{orient:l,inputType:u}=xy(e,t),{continuousAxisChannelDef:f,continuousAxisChannelDef2:d,continuousAxisChannelDefError:g,continuousAxisChannelDefError2:p,continuousAxis:h}=vf(e,l,t),{errorBarSpecificAggregate:m,postAggregateCalculates:y,tooltipSummary:b,tooltipTitleWithFieldName:C}=$y(c,f,d,g,p,u,t,n),{[h]:k,[h==="x"?"x2":"y2"]:N,[h==="x"?"xError":"yError"]:_,[h==="x"?"xError2":"yError2"]:L,...U}=r,{bins:oe,timeUnits:de,aggregate:Re,groupby:sn,encoding:w}=bf(U,n),$=[...Re,...m],I=u!=="raw"?[]:sn,O=eo(b,f,w,C);return {transform:[...a.transform??[],...oe,...de,...$.length===0?[]:[{aggregate:$,groupby:I}],...y],groupby:I,continuousAxisChannelDef:f,continuousAxis:h,encodingWithoutContinuousAxis:w,ticksOrient:l==="vertical"?"horizontal":"vertical",markDef:c,outerSpec:a,tooltipEncoding:O}}function $y(e,t,n,i,r,s,o,a){let c=[],l=[];const u=t.field;let f,d=!1;if(s==="raw"){const g=e.center?e.center:e.extent?e.extent==="iqr"?"median":"mean":a.errorbar.center,p=e.extent?e.extent:g==="mean"?"stderr":"iqr";if(g==="median"!=(p==="iqr")&&S(Lh(g,p,o)),p==="stderr"||p==="stdev")c=[{op:p,field:u,as:`extent_${u}`},{op:g,field:u,as:`center_${u}`}],l=[{calculate:`datum["center_${u}"] + datum["extent_${u}"]`,as:`upper_${u}`},{calculate:`datum["center_${u}"] - datum["extent_${u}"]`,as:`lower_${u}`}],f=[{fieldPrefix:"center_",titlePrefix:Wi(g)},{fieldPrefix:"upper_",titlePrefix:vc(g,p,"+")},{fieldPrefix:"lower_",titlePrefix:vc(g,p,"-")}],d=!0;else {let h,m,y;p==="ci"?(h="mean",m="ci0",y="ci1"):(h="median",m="q1",y="q3"),c=[{op:m,field:u,as:`lower_${u}`},{op:y,field:u,as:`upper_${u}`},{op:h,field:u,as:`center_${u}`}],f=[{fieldPrefix:"upper_",titlePrefix:Vn({field:u,aggregate:y,type:"quantitative"},a,{allowDisabling:!1})},{fieldPrefix:"lower_",titlePrefix:Vn({field:u,aggregate:m,type:"quantitative"},a,{allowDisabling:!1})},{fieldPrefix:"center_",titlePrefix:Vn({field:u,aggregate:h,type:"quantitative"},a,{allowDisabling:!1})}];}}else {(e.center||e.extent)&&S(Ih(e.center,e.extent)),s==="aggregated-upper-lower"?(f=[],l=[{calculate:`datum["${n.field}"]`,as:`upper_${u}`},{calculate:`datum["${u}"]`,as:`lower_${u}`}]):s==="aggregated-error"&&(f=[{fieldPrefix:"",titlePrefix:u}],l=[{calculate:`datum["${u}"] + datum["${i.field}"]`,as:`upper_${u}`}],r?l.push({calculate:`datum["${u}"] + datum["${r.field}"]`,as:`lower_${u}`}):l.push({calculate:`datum["${u}"] - datum["${i.field}"]`,as:`lower_${u}`}));for(const g of l)f.push({fieldPrefix:g.as.substring(0,6),titlePrefix:vn(vn(g.calculate,'datum["',""),'"]',"")});}return {postAggregateCalculates:l,errorBarSpecificAggregate:c,tooltipSummary:f,tooltipTitleWithFieldName:d}}function vc(e,t,n){return `${Wi(e)} ${n} ${t}`}const pa="errorband",wy=["band","borders"],Cy=new ts(pa,kf);function kf(e,{config:t}){e={...e,encoding:ns(e.encoding,t)};const{transform:n,continuousAxisChannelDef:i,continuousAxis:r,encodingWithoutContinuousAxis:s,markDef:o,outerSpec:a,tooltipEncoding:c}=Ff(e,pa,t),l=o,u=fa(l,r,i,s,t.errorband),f=e.encoding.x!==void 0&&e.encoding.y!==void 0;let d={type:f?"area":"rect"},g={type:f?"line":"rule"};const p={...l.interpolate?{interpolate:l.interpolate}:{},...l.tension&&l.interpolate?{tension:l.tension}:{}};return f?(d={...d,...p,ariaRoleDescription:"errorband"},g={...g,...p,aria:!1}):l.interpolate?S(dc("interpolate")):l.tension&&S(dc("tension")),{...a,transform:n,layer:[...u({partName:"band",mark:d,positionPrefix:"lower",endPositionPrefix:"upper",extraEncoding:c}),...u({partName:"borders",mark:g,positionPrefix:"lower",extraEncoding:c}),...u({partName:"borders",mark:g,positionPrefix:"upper",extraEncoding:c})]}}const Tf={};function ga(e,t,n){const i=new ts(e,t);Tf[e]={normalizer:i,parts:n};}function Ny(){return x(Tf)}ga(wr,wf,gy);ga(da,Nf,yy);ga(pa,kf,wy);const Fy=["gradientHorizontalMaxLength","gradientHorizontalMinLength","gradientVerticalMaxLength","gradientVerticalMinLength","unselectedOpacity"],Af={titleAlign:"align",titleAnchor:"anchor",titleAngle:"angle",titleBaseline:"baseline",titleColor:"color",titleFont:"font",titleFontSize:"fontSize",titleFontStyle:"fontStyle",titleFontWeight:"fontWeight",titleLimit:"limit",titleLineHeight:"lineHeight",titleOrient:"orient",titlePadding:"offset"},Of={labelAlign:"align",labelAnchor:"anchor",labelAngle:"angle",labelBaseline:"baseline",labelColor:"color",labelFont:"font",labelFontSize:"fontSize",labelFontStyle:"fontStyle",labelFontWeight:"fontWeight",labelLimit:"limit",labelLineHeight:"lineHeight",labelOrient:"orient",labelPadding:"offset"},ky=x(Af),Ty=x(Of),Ay={header:1,headerRow:1,headerColumn:1,headerFacet:1},_f=x(Ay),Rf=["size","shape","fill","stroke","strokeDash","strokeWidth","opacity"],Oy={gradientHorizontalMaxLength:200,gradientHorizontalMinLength:100,gradientVerticalMaxLength:200,gradientVerticalMinLength:64,unselectedOpacity:.35},_y={aria:1,clipHeight:1,columnPadding:1,columns:1,cornerRadius:1,description:1,direction:1,fillColor:1,format:1,formatType:1,gradientLength:1,gradientOpacity:1,gradientStrokeColor:1,gradientStrokeWidth:1,gradientThickness:1,gridAlign:1,labelAlign:1,labelBaseline:1,labelColor:1,labelFont:1,labelFontSize:1,labelFontStyle:1,labelFontWeight:1,labelLimit:1,labelOffset:1,labelOpacity:1,labelOverlap:1,labelPadding:1,labelSeparation:1,legendX:1,legendY:1,offset:1,orient:1,padding:1,rowPadding:1,strokeColor:1,symbolDash:1,symbolDashOffset:1,symbolFillColor:1,symbolLimit:1,symbolOffset:1,symbolOpacity:1,symbolSize:1,symbolStrokeColor:1,symbolStrokeWidth:1,symbolType:1,tickCount:1,tickMinStep:1,title:1,titleAlign:1,titleAnchor:1,titleBaseline:1,titleColor:1,titleFont:1,titleFontSize:1,titleFontStyle:1,titleFontWeight:1,titleLimit:1,titleLineHeight:1,titleOpacity:1,titleOrient:1,titlePadding:1,type:1,values:1,zindex:1},Ze="_vgsid_",Ry={point:{on:"click",fields:[Ze],toggle:"event.shiftKey",resolve:"global",clear:"dblclick"},interval:{on:"[pointerdown, window:pointerup] > window:pointermove!",encodings:["x","y"],translate:"[pointerdown, window:pointerup] > window:pointermove!",zoom:"wheel!",mark:{fill:"#333",fillOpacity:.125,stroke:"white"},resolve:"global",clear:"dblclick"}};function ha(e){return e==="legend"||!!e?.legend}function Ts(e){return ha(e)&&et$1(e)}function ma(e){return !!e?.select}function If(e){const t=[];for(const n of e||[]){if(ma(n))continue;const{expr:i,bind:r,...s}=n;if(r&&i){const o={...s,bind:r,init:i};t.push(o);}else {const o={...s,...i?{update:i}:{},...r?{bind:r}:{}};t.push(o);}}return t}function Iy(e){return is(e)||ba(e)||ya(e)}function ya(e){return "concat"in e}function is(e){return "vconcat"in e}function ba(e){return "hconcat"in e}function Lf({step:e,offsetIsDiscrete:t}){return t?e.for??"offset":"position"}function ht(e){return et$1(e)&&e.step!==void 0}function Ec(e){return e.view||e.width||e.height}const $c=20,Ly={align:1,bounds:1,center:1,columns:1,spacing:1},Py=x(Ly);function zy(e,t,n){const i=n[t],r={},{spacing:s,columns:o}=i;s!==void 0&&(r.spacing=s),o!==void 0&&(Kr(e)&&!Ki(e.facet)||ya(e))&&(r.columns=o),is(e)&&(r.columns=1);for(const a of Py)if(e[a]!==void 0)if(a==="spacing"){const c=e[a];r[a]=Mr$1(c)?c:{row:c.row??s,column:c.column??s};}else r[a]=e[a];return r}function to(e,t){return e[t]??e[t==="width"?"continuousWidth":"continuousHeight"]}function Cr(e,t){const n=Nr(e,t);return ht(n)?n.step:Pf}function Nr(e,t){const n=e[t]??e[t==="width"?"discreteWidth":"discreteHeight"];return le(n,{step:e.step})}const Pf=20,Dy={continuousWidth:200,continuousHeight:200,step:Pf},My={background:"white",padding:5,timeFormat:"%b %d, %Y",countTitle:"Count of Records",view:Dy,mark:Om,arc:{},area:{},bar:Im,circle:{},geoshape:{},image:{},line:{},point:{},rect:Lm,rule:{color:"black"},square:{},text:{color:"black"},tick:Pm,trail:{},boxplot:{size:14,extent:1.5,box:{},median:{color:"white"},outliers:{},rule:{},ticks:null},errorbar:{center:"mean",rule:!0,ticks:!1},errorband:{band:{opacity:.3},borders:!1},scale:pm,projection:{},legend:Oy,header:{titlePadding:10,labelPadding:10},headerColumn:{},headerRow:{},headerFacet:{},selection:Ry,style:{},title:{},facet:{spacing:$c},concat:{spacing:$c},normalizedNumberFormat:".0%"},Et=["#4c78a8","#f58518","#e45756","#72b7b2","#54a24b","#eeca3b","#b279a2","#ff9da6","#9d755d","#bab0ac"],wc={text:11,guideLabel:10,guideTitle:11,groupTitle:13,groupSubtitle:12},Cc={blue:Et[0],orange:Et[1],red:Et[2],teal:Et[3],green:Et[4],yellow:Et[5],purple:Et[6],pink:Et[7],brown:Et[8],gray0:"#000",gray1:"#111",gray2:"#222",gray3:"#333",gray4:"#444",gray5:"#555",gray6:"#666",gray7:"#777",gray8:"#888",gray9:"#999",gray10:"#aaa",gray11:"#bbb",gray12:"#ccc",gray13:"#ddd",gray14:"#eee",gray15:"#fff"};function jy(e={}){return {signals:[{name:"color",value:et$1(e)?{...Cc,...e}:Cc}],mark:{color:{signal:"color.blue"}},rule:{color:{signal:"color.gray0"}},text:{color:{signal:"color.gray0"}},style:{"guide-label":{fill:{signal:"color.gray0"}},"guide-title":{fill:{signal:"color.gray0"}},"group-title":{fill:{signal:"color.gray0"}},"group-subtitle":{fill:{signal:"color.gray0"}},cell:{stroke:{signal:"color.gray8"}}},axis:{domainColor:{signal:"color.gray13"},gridColor:{signal:"color.gray8"},tickColor:{signal:"color.gray13"}},range:{category:[{signal:"color.blue"},{signal:"color.orange"},{signal:"color.red"},{signal:"color.teal"},{signal:"color.green"},{signal:"color.yellow"},{signal:"color.purple"},{signal:"color.pink"},{signal:"color.brown"},{signal:"color.grey8"}]}}}function Uy(e){return {signals:[{name:"fontSize",value:et$1(e)?{...wc,...e}:wc}],text:{fontSize:{signal:"fontSize.text"}},style:{"guide-label":{fontSize:{signal:"fontSize.guideLabel"}},"guide-title":{fontSize:{signal:"fontSize.guideTitle"}},"group-title":{fontSize:{signal:"fontSize.groupTitle"}},"group-subtitle":{fontSize:{signal:"fontSize.groupSubtitle"}}}}}function By(e){return {text:{font:e},style:{"guide-label":{font:e},"guide-title":{font:e},"group-title":{font:e},"group-subtitle":{font:e}}}}function zf(e){const t=x(e||{}),n={};for(const i of t){const r=e[i];n[i]=Zi(r)?du(r):Le(r);}return n}function Wy(e){const t=x(e),n={};for(const i of t)n[i]=zf(e[i]);return n}const Gy=[...Vu,...hf,..._f,"background","padding","legend","lineBreak","scale","style","title","view"];function Df(e={}){const{color:t,font:n,fontSize:i,selection:r,...s}=e,o=v3({},z(My),n?By(n):{},t?jy(t):{},i?Uy(i):{},s||{});r&&fg$1(o,"selection",r,!0);const a=ke(o,Gy);for(const c of ["background","lineBreak","padding"])o[c]&&(a[c]=Le(o[c]));for(const c of Vu)o[c]&&(a[c]=Fe(o[c]));for(const c of hf)o[c]&&(a[c]=zf(o[c]));for(const c of _f)o[c]&&(a[c]=Fe(o[c]));return o.legend&&(a.legend=Fe(o.legend)),o.scale&&(a.scale=Fe(o.scale)),o.style&&(a.style=Wy(o.style)),o.title&&(a.title=Fe(o.title)),o.view&&(a.view=Fe(o.view)),a}const Hy=new Set(["view",...Cm]),qy=["color","fontSize","background","padding","facet","concat","numberFormat","numberFormatType","normalizedNumberFormat","normalizedNumberFormatType","timeFormat","countTitle","header","axisQuantitative","axisTemporal","axisDiscrete","axisPoint","axisXBand","axisXPoint","axisXDiscrete","axisXQuantitative","axisXTemporal","axisYBand","axisYPoint","axisYDiscrete","axisYQuantitative","axisYTemporal","scale","selection","overlay"],Vy={view:["continuousWidth","continuousHeight","discreteWidth","discreteHeight","step"],...Am};function Xy(e){e=z(e);for(const t of qy)delete e[t];if(e.axis)for(const t in e.axis)Zi(e.axis[t])&&delete e.axis[t];if(e.legend)for(const t of Fy)delete e.legend[t];if(e.mark){for(const t of gc)delete e.mark[t];e.mark.tooltip&&et$1(e.mark.tooltip)&&delete e.mark.tooltip;}e.params&&(e.signals=(e.signals||[]).concat(If(e.params)),delete e.params);for(const t of Hy){for(const i of gc)delete e[t][i];const n=Vy[t];if(n)for(const i of n)delete e[t][i];Ky(e,t);}for(const t of Ny())delete e[t];Yy(e);for(const t in e)et$1(e[t])&&K(e[t])&&delete e[t];return K(e)?void 0:e}function Yy(e){const{titleMarkConfig:t,subtitleMarkConfig:n,subtitle:i}=fu(e.title);K(t)||(e.style["group-title"]={...e.style["group-title"],...t}),K(n)||(e.style["group-subtitle"]={...e.style["group-subtitle"],...n}),K(i)?delete e.title:e.title=i;}function Ky(e,t,n,i){const r=e[t];t==="view"&&(n="cell");const s={...r,...e.style[n??t]};K(s)||(e.style[n??t]=s),delete e[t];}function rs(e){return "layer"in e}function Jy(e){return "repeat"in e}function Qy(e){return !U(e.repeat)&&e.repeat.layer}class xa{map(t,n){return Kr(t)?this.mapFacet(t,n):Jy(t)?this.mapRepeat(t,n):ba(t)?this.mapHConcat(t,n):is(t)?this.mapVConcat(t,n):ya(t)?this.mapConcat(t,n):this.mapLayerOrUnit(t,n)}mapLayerOrUnit(t,n){if(rs(t))return this.mapLayer(t,n);if(zt(t))return this.mapUnit(t,n);throw new Error(Lo(t))}mapLayer(t,n){return {...t,layer:t.layer.map(i=>this.mapLayerOrUnit(i,n))}}mapHConcat(t,n){return {...t,hconcat:t.hconcat.map(i=>this.map(i,n))}}mapVConcat(t,n){return {...t,vconcat:t.vconcat.map(i=>this.map(i,n))}}mapConcat(t,n){const{concat:i,...r}=t;return {...r,concat:i.map(s=>this.map(s,n))}}mapFacet(t,n){return {...t,spec:this.map(t.spec,n)}}mapRepeat(t,n){return {...t,spec:this.map(t.spec,n)}}}const Zy={zero:1,center:1,normalize:1};function eb(e){return e in Zy}const tb=new Set([Gu,qr,Hr,br,Xr,Jo,Qo,Vr,Hu,Ko]),nb=new Set([qr,Hr,Gu]);function jn(e){return v(e)&&ii(e)==="quantitative"&&!e.bin}function Nc(e,t,{orient:n,type:i}){const r=t==="x"?"y":"radius",s=t==="x"&&["bar","area"].includes(i),o=e[t],a=e[r];if(v(o)&&v(a))if(jn(o)&&jn(a)){if(o.stack)return t;if(a.stack)return r;const c=v(o)&&!!o.aggregate,l=v(a)&&!!a.aggregate;if(c!==l)return c?t:r;if(s){if(n==="vertical")return r;if(n==="horizontal")return t}}else {if(jn(o))return t;if(jn(a))return r}else {if(jn(o))return s&&n==="vertical"?void 0:t;if(jn(a))return s&&n==="horizontal"?void 0:r}}function ib(e){switch(e){case"x":return "y";case"y":return "x";case"theta":return "radius";case"radius":return "theta"}}function Mf(e,t){const n=pt(e)?e:{type:e},i=n.type;if(!tb.has(i))return null;const r=Nc(t,"x",n)||Nc(t,"theta",n);if(!r)return null;const s=t[r],o=v(s)?E(s,{}):void 0,a=ib(r),c=[],l=new Set;if(t[a]){const h=t[a],m=v(h)?E(h,{}):void 0;m&&m!==o&&(c.push(a),l.add(m));}const u=a==="x"?"xOffset":"yOffset",f=t[u],d=v(f)?E(f,{}):void 0;d&&d!==o&&(c.push(u),l.add(d));const g=mg.reduce((h,m)=>{if(m!=="tooltip"&&yn(t,m)){const y=t[m];for(const b of H(y)){const C=gt(b);if(C.aggregate)continue;const k=E(C,{});(!k||!l.has(k))&&h.push({channel:m,fieldDef:C});}}return h},[]);let p;return s.stack!==void 0?Ag$1(s.stack)?p=s.stack?"zero":null:p=s.stack:nb.has(i)&&(p="zero"),!p||!eb(p)||ca(t)&&g.length===0?null:s?.scale?.type&&s?.scale?.type!==Te.LINEAR?(s?.stack&&S(Oh(s.scale.type)),null):D(t[xt(r)])?(s.stack!==void 0&&S(Ah(r)),null):(v(s)&&s.aggregate&&!kg.has(s.aggregate)&&S(_h(s.aggregate)),{groupbyChannels:c,groupbyFields:l,fieldChannel:r,impute:s.impute===null?!1:rn(i),stackBy:g,offset:p})}function jf(e,t,n){const i=Fe(e),r=X("orient",i,n);if(i.orient=ab(i.type,t,r),r!==void 0&&r!==i.orient&&S(gh(i.orient,r)),i.type==="bar"&&i.orient){const c=X("cornerRadiusEnd",i,n);if(c!==void 0){const l=i.orient==="horizontal"&&t.x2||i.orient==="vertical"&&t.y2?["cornerRadius"]:Rm[i.orient];for(const u of l)i[u]=c;i.cornerRadiusEnd!==void 0&&delete i.cornerRadiusEnd;}}const s=X("opacity",i,n),o=X("fillOpacity",i,n);return s===void 0&&o===void 0&&(i.opacity=sb(i.type,t)),X("cursor",i,n)===void 0&&(i.cursor=rb(i,t,n)),i}function rb(e,t,n){return t.href||e.href||X("href",e,n)?"pointer":e.cursor}function sb(e,t){if(G([Xr,Ko,Jo,Qo],e)&&!ca(t))return .7}function ob(e,t,{graticule:n}){if(n)return !1;const i=Ot("filled",e,t),r=e.type;return le(i,r!==Xr&&r!==Vr&&r!==br)}function ab(e,t,n){switch(e){case Xr:case Jo:case Qo:case Hu:case $m:case Em:return}const{x:i,y:r,x2:s,y2:o}=t;switch(e){case qr:if(v(i)&&(xe(i.bin)||v(r)&&r.aggregate&&!i.aggregate))return "vertical";if(v(r)&&(xe(r.bin)||v(i)&&i.aggregate&&!r.aggregate))return "horizontal";if(o||s){if(n)return n;if(!s)return (v(i)&&i.type===wn&&!ee(i.bin)||Sr(i))&&v(r)&&xe(r.bin)?"horizontal":"vertical";if(!o)return (v(r)&&r.type===wn&&!ee(r.bin)||Sr(r))&&v(i)&&xe(i.bin)?"vertical":"horizontal"}case br:if(s&&!(v(i)&&xe(i.bin))&&o&&!(v(r)&&xe(r.bin)))return;case Hr:if(o)return v(r)&&xe(r.bin)?"horizontal":"vertical";if(s)return v(i)&&xe(i.bin)?"vertical":"horizontal";if(e===br){if(i&&!r)return "vertical";if(r&&!i)return "horizontal"}case Vr:case Ko:{const a=bc(i),c=bc(r);if(n)return n;if(a&&!c)return e!=="tick"?"horizontal":"vertical";if(!a&&c)return e!=="tick"?"vertical":"horizontal";if(a&&c)return "vertical";{const l=Ce(i)&&i.type===ti,u=Ce(r)&&r.type===ti;if(l&&!u)return "vertical";if(!l&&u)return "horizontal"}return}}return "vertical"}function cb(e){const{point:t,line:n,...i}=e;return x(i).length>1?i:i.type}function lb(e){for(const t of ["line","area","rule","trail"])e[t]&&(e={...e,[t]:ke(e[t],["point","line"])});return e}function As(e,t={},n){return e.point==="transparent"?{opacity:0}:e.point?et$1(e.point)?e.point:{}:e.point!==void 0?null:t.point||n.shape?et$1(t.point)?t.point:{}:void 0}function Fc(e,t={}){return e.line?e.line===!0?{}:e.line:e.line!==void 0?null:t.line?t.line===!0?{}:t.line:void 0}class ub{constructor(){this.name="path-overlay";}hasMatchingType(t,n){if(zt(t)){const{mark:i,encoding:r}=t,s=pt(i)?i:{type:i};switch(s.type){case"line":case"rule":case"trail":return !!As(s,n[s.type],r);case"area":return !!As(s,n[s.type],r)||!!Fc(s,n[s.type])}}return !1}run(t,n,i){const{config:r}=n,{params:s,projection:o,mark:a,name:c,encoding:l,...u}=t,f=ns(l,r),d=pt(a)?a:{type:a},g=As(d,r[d.type],f),p=d.type==="area"&&Fc(d,r[d.type]),h=[{name:c,...s?{params:s}:{},mark:cb({...d.type==="area"&&d.opacity===void 0&&d.fillOpacity===void 0?{opacity:.7}:{},...d}),encoding:ke(f,["shape"])}],m=Mf(jf(d,f,r),f);let y=f;if(m){const{fieldChannel:b,offset:C}=m;y={...f,[b]:{...f[b],...C?{stack:C}:{}}};}return y=ke(y,["y2","x2"]),p&&h.push({...o?{projection:o}:{},mark:{type:"line",...Jn(d,["clip","interpolate","tension","tooltip"]),...p},encoding:y}),g&&h.push({...o?{projection:o}:{},mark:{type:"point",opacity:1,filled:!0,...Jn(d,["clip","tooltip"]),...g},encoding:y}),i({...u,layer:h},{...n,config:lb(r)})}}function fb(e,t){return t?Ki(e)?Bf(e,t):Uf(e,t):e}function Os(e,t){return t?Bf(e,t):e}function no(e,t,n){const i=t[e];if(Vm(i)){if(i.repeat in n)return {...t,[e]:n[i.repeat]};S(Xg(i.repeat));return}return t}function Uf(e,t){if(e=no("field",e,t),e!==void 0){if(e===null)return null;if(ra(e)&&ut(e.sort)){const n=no("field",e.sort,t);e={...e,...n?{sort:n}:{}};}return e}}function kc(e,t){if(v(e))return Uf(e,t);{const n=no("datum",e,t);return n!==e&&!n.type&&(n.type="nominal"),n}}function Tc(e,t){if(D(e)){const n=kc(e,t);if(n)return n;if(Jr(e))return {condition:e.condition}}else {if(Ji(e)){const n=kc(e.condition,t);if(n)return {...e,condition:n};{const{condition:i,...r}=e;return r}}return e}}function Bf(e,t){const n={};for(const i in e)if(X$1(e,i)){const r=e[i];if(U(r))n[i]=r.map(s=>Tc(s,t)).filter(s=>s);else {const s=Tc(r,t);s!==void 0&&(n[i]=s);}}return n}class db{constructor(){this.name="RuleForRangedLine";}hasMatchingType(t){if(zt(t)){const{encoding:n,mark:i}=t;if(i==="line"||pt(i)&&i.type==="line")for(const r of pg){const s=_n(r),o=n[s];if(n[r]&&(v(o)&&!xe(o.bin)||vt(o)))return !0}}return !1}run(t,n,i){const{encoding:r,mark:s}=t;return S(ph(!!r.x2,!!r.y2)),i({...t,mark:et$1(s)?{...s,type:"rule"}:"rule"},n)}}class pb extends xa{constructor(){super(...arguments),this.nonFacetUnitNormalizers=[hy,by,Cy,new ub,new db];}map(t,n){if(zt(t)){const i=yn(t.encoding,Nt),r=yn(t.encoding,Ft),s=yn(t.encoding,Lr);if(i||r||s)return this.mapFacetedUnit(t,n)}return super.map(t,n)}mapUnit(t,n){const{parentEncoding:i,parentProjection:r}=n,s=Os(t.encoding,n.repeater),o={...t,...t.name?{name:[n.repeaterPrefix,t.name].filter(c=>c).join("_")}:{},...s?{encoding:s}:{}};if(i||r)return this.mapUnitWithParentEncodingOrProjection(o,n);const a=this.mapLayerOrUnit.bind(this);for(const c of this.nonFacetUnitNormalizers)if(c.hasMatchingType(o,n.config))return c.run(o,n,a);return o}mapRepeat(t,n){return Qy(t)?this.mapLayerRepeat(t,n):this.mapNonLayerRepeat(t,n)}mapLayerRepeat(t,n){const{repeat:i,spec:r,...s}=t,{row:o,column:a,layer:c}=i,{repeater:l={},repeaterPrefix:u=""}=n;return o||a?this.mapRepeat({...t,repeat:{...o?{row:o}:{},...a?{column:a}:{}},spec:{repeat:{layer:c},spec:r}},n):{...s,layer:c.map(f=>{const d={...l,layer:f},g=`${(r.name?`${r.name}_`:"")+u}child__layer_${re(f)}`,p=this.mapLayerOrUnit(r,{...n,repeater:d,repeaterPrefix:g});return p.name=g,p})}}mapNonLayerRepeat(t,n){const{repeat:i,spec:r,data:s,...o}=t;!U(i)&&t.columns&&(t=ke(t,["columns"]),S(cc("repeat")));const a=[],{repeater:c={},repeaterPrefix:l=""}=n,u=!U(i)&&i.row||[c?c.row:null],f=!U(i)&&i.column||[c?c.column:null],d=U(i)&&i||[c?c.repeat:null];for(const p of d)for(const h of u)for(const m of f){const y={repeat:p,row:h,column:m,layer:c.layer},b=(r.name?`${r.name}_`:"")+l+"child__"+(U(i)?`${re(p)}`:(i.row?`row_${re(h)}`:"")+(i.column?`column_${re(m)}`:"")),C=this.map(r,{...n,repeater:y,repeaterPrefix:b});C.name=b,a.push(ke(C,["data"]));}const g=U(i)?t.columns:i.column?i.column.length:1;return {data:r.data??s,align:"all",...o,columns:g,concat:a}}mapFacet(t,n){const{facet:i}=t;return Ki(i)&&t.columns&&(t=ke(t,["columns"]),S(cc("facet"))),super.mapFacet(t,n)}mapUnitWithParentEncodingOrProjection(t,n){const{encoding:i,projection:r}=t,{parentEncoding:s,parentProjection:o,config:a}=n,c=Oc({parentProjection:o,projection:r}),l=Ac({parentEncoding:s,encoding:Os(i,n.repeater)});return this.mapUnit({...t,...c?{projection:c}:{},...l?{encoding:l}:{}},{config:a})}mapFacetedUnit(t,n){const{row:i,column:r,facet:s,...o}=t.encoding,{mark:a,width:c,projection:l,height:u,view:f,params:d,encoding:g,...p}=t,{facetMapping:h,layout:m}=this.getFacetMappingAndLayout({row:i,column:r,facet:s},n),y=Os(o,n.repeater);return this.mapFacet({...p,...m,facet:h,spec:{...c?{width:c}:{},...u?{height:u}:{},...f?{view:f}:{},...l?{projection:l}:{},mark:a,encoding:y,...d?{params:d}:{}}},n)}getFacetMappingAndLayout(t,n){const{row:i,column:r,facet:s}=t;if(i||r){s&&S(fh([...i?[Nt]:[],...r?[Ft]:[]]));const o={},a={};for(const c of [Nt,Ft]){const l=t[c];if(l){const{align:u,center:f,spacing:d,columns:g,...p}=l;o[c]=p;for(const h of ["align","center","spacing"])l[h]!==void 0&&(a[h]??(a[h]={}),a[h][c]=l[h]);}}return {facetMapping:o,layout:a}}else {const{align:o,center:a,spacing:c,columns:l,...u}=s;return {facetMapping:fb(u,n.repeater),layout:{...o?{align:o}:{},...a?{center:a}:{},...c?{spacing:c}:{},...l?{columns:l}:{}}}}}mapLayer(t,{parentEncoding:n,parentProjection:i,...r}){const{encoding:s,projection:o,...a}=t,c={...r,parentEncoding:Ac({parentEncoding:n,encoding:s,layer:!0}),parentProjection:Oc({parentProjection:i,projection:o})};return super.mapLayer({...a,...t.name?{name:[c.repeaterPrefix,t.name].filter(l=>l).join("_")}:{}},c)}}function Ac({parentEncoding:e,encoding:t={},layer:n}){let i={};if(e){const r=new Set([...x(e),...x(t)]);for(const s of r){const o=t[s],a=e[s];if(D(o)){const c={...a,...o};i[s]=c;}else Ji(o)?i[s]={...o,condition:{...a,...o.condition}}:o||o===null?i[s]=o:(n||Qe(a)||T(a)||D(a)||U(a))&&(i[s]=a);}}else i=t;return !i||K(i)?void 0:i}function Oc(e){const{parentProjection:t,projection:n}=e;return t&&n&&S(eh({parentProjection:t,projection:n})),n??t}function Sa(e){return "filter"in e}function gb(e){return e?.stop!==void 0}function Wf(e){return "lookup"in e}function hb(e){return "data"in e}function mb(e){return "param"in e}function yb(e){return "pivot"in e}function bb(e){return "density"in e}function xb(e){return "quantile"in e}function Sb(e){return "regression"in e}function vb(e){return "loess"in e}function Eb(e){return "sample"in e}function $b(e){return "window"in e}function wb(e){return "joinaggregate"in e}function Cb(e){return "flatten"in e}function Nb(e){return "calculate"in e}function Gf(e){return "bin"in e}function Fb(e){return "impute"in e}function kb(e){return "timeUnit"in e}function Tb(e){return "aggregate"in e}function Ab(e){return "stack"in e}function Ob(e){return "fold"in e}function _b(e){return "extent"in e&&!("density"in e)}function Rb(e){return e.map(t=>Sa(t)?{filter:Hn(t.filter,om)}:t)}class Ib extends xa{map(t,n){return n.emptySelections??(n.emptySelections={}),n.selectionPredicates??(n.selectionPredicates={}),t=_c(t,n),super.map(t,n)}mapLayerOrUnit(t,n){if(t=_c(t,n),t.encoding){const i={};for(const[r,s]of Wt(t.encoding))i[r]=Hf(s,n);t={...t,encoding:i};}return super.mapLayerOrUnit(t,n)}mapUnit(t,n){const{selection:i,...r}=t;return i?{...r,params:Wt(i).map(([s,o])=>{const{init:a,bind:c,empty:l,...u}=o;u.type==="single"?(u.type="point",u.toggle=!1):u.type==="multi"&&(u.type="point"),n.emptySelections[s]=l!=="none";for(const f of Se(n.selectionPredicates[s]??{}))f.empty=l!=="none";return {name:s,value:a,select:u,bind:c}})}:t}}function _c(e,t){const{transform:n,...i}=e;if(n){const r=n.map(s=>{if(Sa(s))return {filter:io(s,t)};if(Gf(s)&&Rn(s.bin))return {...s,bin:qf(s.bin)};if(Wf(s)){const{selection:o,...a}=s.from;return o?{...s,from:{param:o,...a}}:s}return s});return {...i,transform:r}}return e}function Hf(e,t){const n=z(e);if(v(n)&&Rn(n.bin)&&(n.bin=qf(n.bin)),Pn(n)&&n.scale?.domain?.selection){const{selection:i,...r}=n.scale.domain;n.scale.domain={...r,...i?{param:i}:{}};}if(Jr(n))if(U(n.condition))n.condition=n.condition.map(i=>{const{selection:r,param:s,test:o,...a}=i;return s?i:{...a,test:io(i,t)}});else {const{selection:i,param:r,test:s,...o}=Hf(n.condition,t);n.condition=r?n.condition:{...o,test:io(n.condition,t)};}return n}function qf(e){const t=e.extent;if(t?.selection){const{selection:n,...i}=t;return {...e,extent:{...i,param:n}}}return e}function io(e,t){const n=i=>Hn(i,r=>{var s;const o=t.emptySelections[r]??!0,a={param:r,empty:o};return (s=t.selectionPredicates)[r]??(s[r]=[]),t.selectionPredicates[r].push(a),a});return e.selection?n(e.selection):Hn(e.test||e.filter,i=>i.selection?n(i.selection):i)}class ro extends xa{map(t,n){const i=n.selections??[];if(t.params&&!zt(t)){const r=[];for(const s of t.params)ma(s)?i.push(s):r.push(s);t.params=r;}return n.selections=i,super.map(t,n)}mapUnit(t,n){const i=n.selections;if(!i||!i.length)return t;const r=(n.path??[]).concat(t.name),s=[];for(const o of i)if(!o.views||!o.views.length)s.push(o);else for(const a of o.views)(xt$1(a)&&(a===t.name||r.includes(a))||U(a)&&a.map(c=>r.indexOf(c)).every((c,l,u)=>c!==-1&&(l===0||c>u[l-1])))&&s.push(o);return s.length&&(t.params=s),t}}for(const e of ["mapFacet","mapRepeat","mapHConcat","mapVConcat","mapLayer"]){const t=ro.prototype[e];ro.prototype[e]=function(n,i){return t.call(this,n,Lb(n,i))};}function Lb(e,t){return e.name?{...t,path:(t.path??[]).concat(e.name)}:t}function Vf(e,t){t===void 0&&(t=Df(e.config));const n=Mb(e,t),{width:i,height:r}=e,s=jb(n,{width:i,height:r,autosize:e.autosize},t);return {...n,...s?{autosize:s}:{}}}const Pb=new pb,zb=new Ib,Db=new ro;function Mb(e,t={}){const n={config:t};return Db.map(Pb.map(zb.map(e,n),n),n)}function Rc(e){return xt$1(e)?{type:e}:e??{}}function jb(e,t,n){let{width:i,height:r}=t;const s=zt(e)||rs(e),o={};s?i=="container"&&r=="container"?(o.type="fit",o.contains="padding"):i=="container"?(o.type="fit-x",o.contains="padding"):r=="container"&&(o.type="fit-y",o.contains="padding"):(i=="container"&&(S(rc("width")),i=void 0),r=="container"&&(S(rc("height")),r=void 0));const a={type:"pad",...o,...n?Rc(n.autosize):{},...Rc(e.autosize)};if(a.type==="fit"&&!s&&(S(zg),a.type="pad"),i=="container"&&!(a.type=="fit"||a.type=="fit-x")&&S(sc("width")),r=="container"&&!(a.type=="fit"||a.type=="fit-y")&&S(sc("height")),!Pe(a,{type:"pad"}))return a}function Ub(e){return e==="fit"||e==="fit-x"||e==="fit-y"}function Bb(e){return e?`fit-${jr(e)}`:"fit"}const Wb=["background","padding"];function Ic(e,t){const n={};for(const i of Wb)e&&e[i]!==void 0&&(n[i]=Le(e[i]));return t&&(n.params=e.params),n}class Dt{constructor(t={},n={}){this.explicit=t,this.implicit=n;}clone(){return new Dt(z(this.explicit),z(this.implicit))}combine(){return {...this.explicit,...this.implicit}}get(t){return le(this.explicit[t],this.implicit[t])}getWithExplicit(t){return this.explicit[t]!==void 0?{explicit:!0,value:this.explicit[t]}:this.implicit[t]!==void 0?{explicit:!1,value:this.implicit[t]}:{explicit:!1,value:void 0}}setWithExplicit(t,{value:n,explicit:i}){n!==void 0&&this.set(t,n,i);}set(t,n,i){return delete this[i?"implicit":"explicit"][t],this[i?"explicit":"implicit"][t]=n,this}copyKeyFromSplit(t,{explicit:n,implicit:i}){n[t]!==void 0?this.set(t,n[t],!0):i[t]!==void 0&&this.set(t,i[t],!1);}copyKeyFromObject(t,n){n[t]!==void 0&&this.set(t,n[t],!0);}copyAll(t){for(const n of x(t.combine())){const i=t.getWithExplicit(n);this.setWithExplicit(n,i);}}}function ct(e){return {explicit:!0,value:e}}function Ie(e){return {explicit:!1,value:e}}function Xf(e){return (t,n,i,r)=>{const s=e(t.value,n.value);return s>0?t:s<0?n:ss(t,n,i,r)}}function ss(e,t,n,i){return e.explicit&&t.explicit&&S($h(n,i,e.value,t.value)),e}function qt(e,t,n,i,r=ss){return e===void 0||e.value===void 0?t:e.explicit&&!t.explicit?e:t.explicit&&!e.explicit?t:Pe(e.value,t.value)?e:r(e,t,n,i)}class Gb extends Dt{constructor(t={},n={},i=!1){super(t,n),this.explicit=t,this.implicit=n,this.parseNothing=i;}clone(){const t=super.clone();return t.parseNothing=this.parseNothing,t}}function oi(e){return "url"in e}function Di(e){return "values"in e}function Yf(e){return "name"in e&&!oi(e)&&!Di(e)&&!Bt(e)}function Bt(e){return e&&(Kf(e)||Jf(e)||va(e))}function Kf(e){return "sequence"in e}function Jf(e){return "sphere"in e}function va(e){return "graticule"in e}var Z;(function(e){e[e.Raw=0]="Raw",e[e.Main=1]="Main",e[e.Row=2]="Row",e[e.Column=3]="Column",e[e.Lookup=4]="Lookup";})(Z||(Z={}));function Qf(e){const{signals:t,hasLegend:n,index:i,...r}=e;return r.field=Ue(r.field),r}function Fn(e,t=!0,n=ge$1){if(U(e)){const i=e.map(r=>Fn(r,t,n));return t?`[${i.join(", ")}]`:i}else if(In(e))return n(t?$n(e):Xh(e));return t?n(J(e)):e}function Hb(e,t){for(const n of Se(e.component.selection??{})){const i=n.name;let r=`${i}${Xt}, ${n.resolve==="global"?"true":`{unit: ${bn(e)}}`}`;for(const s of ls)s.defined(n)&&(s.signals&&(t=s.signals(e,n,t)),s.modifyExpr&&(r=s.modifyExpr(e,n,r)));t.push({name:i+$x,on:[{events:{signal:n.name+Xt},update:`modify(${Y$1(n.name+kn)}, ${r})`}]});}return Ea(t)}function qb(e,t){if(e.component.selection&&x(e.component.selection).length){const n=Y$1(e.getName("cell"));t.unshift({name:"facet",value:{},on:[{events:t5("pointermove","scope"),update:`isTuple(facet) ? facet : group(${n}).datum`}]});}return Ea(t)}function Vb(e,t){let n=!1;for(const i of Se(e.component.selection??{})){const r=i.name,s=Y$1(r+kn);if(t.filter(a=>a.name===r).length===0){const a=i.resolve==="global"?"union":i.resolve,c=i.type==="point"?", true, true)":")";t.push({name:i.name,update:`${md}(${s}, ${Y$1(a)}${c}`});}n=!0;for(const a of ls)a.defined(i)&&a.topLevelSignals&&(t=a.topLevelSignals(e,i,t));}return n&&t.filter(r=>r.name==="unit").length===0&&t.unshift({name:"unit",value:{},on:[{events:"pointermove",update:"isTuple(group()) ? group() : unit"}]}),Ea(t)}function Xb(e,t){const n=[...t],i=bn(e,{escape:!1});for(const r of Se(e.component.selection??{})){const s={name:r.name+kn};if(r.project.hasSelectionId&&(s.transform=[{type:"collect",sort:{field:Ze}}]),r.init){const a=r.project.items.map(Qf);s.values=r.project.hasSelectionId?r.init.map(c=>({unit:i,[Ze]:Fn(c,!1)[0]})):r.init.map(c=>({unit:i,fields:a,values:Fn(c,!1)}));}n.filter(a=>a.name===r.name+kn).length||n.push(s);}return n}function Zf(e,t){for(const n of Se(e.component.selection??{}))for(const i of ls)i.defined(n)&&i.marks&&(t=i.marks(e,n,t));return t}function Yb(e,t){for(const n of e.children)ae(n)&&(t=Zf(n,t));return t}function Kb(e,t,n,i){const r=vd(e,t.param,t);return {signal:De(n.get("type"))&&U(i)&&i[0]>i[1]?`isValid(${r}) && reverse(${r})`:r}}function Ea(e){return e.map(t=>(t.on&&!t.on.length&&delete t.on,t))}class Y{constructor(t,n){this.debugName=n,this._children=[],this._parent=null,t&&(this.parent=t);}clone(){throw new Error("Cannot clone node")}get parent(){return this._parent}set parent(t){this._parent=t,t&&t.addChild(this);}get children(){return this._children}numChildren(){return this._children.length}addChild(t,n){if(this._children.includes(t)){S(Jg);return}n!==void 0?this._children.splice(n,0,t):this._children.push(t);}removeChild(t){const n=this._children.indexOf(t);return this._children.splice(n,1),n}remove(){let t=this._parent.removeChild(this);for(const n of this._children)n._parent=this._parent,this._parent.addChild(n,t++);}insertAsParentOf(t){const n=t.parent;n.removeChild(this),this.parent=n,t.parent=this;}swapWithParent(){const t=this._parent,n=t.parent;for(const r of this._children)r.parent=t;this._children=[],t.removeChild(this);const i=t.parent.removeChild(t);this._parent=n,n.addChild(this,i),t.parent=this;}}class we extends Y{clone(){const t=new this.constructor;return t.debugName=`clone_${this.debugName}`,t._source=this._source,t._name=`clone_${this._name}`,t.type=this.type,t.refCounts=this.refCounts,t.refCounts[t._name]=0,t}constructor(t,n,i,r){super(t,n),this.type=i,this.refCounts=r,this._source=this._name=n,this.refCounts&&!(this._name in this.refCounts)&&(this.refCounts[this._name]=0);}dependentFields(){return new Set}producedFields(){return new Set}hash(){return this._hash===void 0&&(this._hash=`Output ${Xl()}`),this._hash}getSource(){return this.refCounts[this._name]++,this._source}isRequired(){return !!this.refCounts[this._name]}setSource(t){this._source=t;}}function _s(e){return e.as!==void 0}function Lc(e){return `${e}_end`}class ft extends Y{clone(){return new ft(null,z(this.timeUnits))}constructor(t,n){super(t),this.timeUnits=n;}static makeFromEncoding(t,n){const i=n.reduceFieldDef((r,s,o)=>{const{field:a,timeUnit:c}=s;if(c){let l;if(Ln(c)){if(ae(n)){const{mark:u,markDef:f,config:d}=n,g=Ht({fieldDef:s,markDef:f,config:d});(zi(u)||g)&&(l={timeUnit:me(c),field:a});}}else l={as:E(s,{forAs:!0}),field:a,timeUnit:c};if(ae(n)){const{mark:u,markDef:f,config:d}=n,g=Ht({fieldDef:s,markDef:f,config:d});zi(u)&&ue(o)&&g!==.5&&(l.rectBandPosition=g);}l&&(r[W(l)]=l);}return r},{});return K(i)?null:new ft(t,i)}static makeFromTransform(t,n){const{timeUnit:i,...r}={...n},s=me(i),o={...r,timeUnit:s};return new ft(t,{[W(o)]:o})}merge(t){this.timeUnits={...this.timeUnits};for(const n in t.timeUnits)this.timeUnits[n]||(this.timeUnits[n]=t.timeUnits[n]);for(const n of t.children)t.removeChild(n),n.parent=this;t.remove();}removeFormulas(t){const n={};for(const[i,r]of Wt(this.timeUnits)){const s=_s(r)?r.as:`${r.field}_end`;t.has(s)||(n[i]=r);}this.timeUnits=n;}producedFields(){return new Set(Se(this.timeUnits).map(t=>_s(t)?t.as:Lc(t.field)))}dependentFields(){return new Set(Se(this.timeUnits).map(t=>t.field))}hash(){return `TimeUnit ${W(this.timeUnits)}`}assemble(){const t=[];for(const n of Se(this.timeUnits)){const{rectBandPosition:i}=n,r=me(n.timeUnit);if(_s(n)){const{field:s,as:o}=n,{unit:a,utc:c,...l}=r,u=[o,`${o}_end`];t.push({field:Ue(s),type:"timeunit",...a?{units:Gr(a)}:{},...c?{timezone:"utc"}:{},...l,as:u}),t.push(...Pc(u,i,r));}else if(n){const{field:s}=n,o=s.replaceAll("\\.","."),a=ed({timeUnit:r,field:o}),c=Lc(o);t.push({type:"formula",expr:a,as:c}),t.push(...Pc([o,c],i,r));}}return t}}const os="offsetted_rect_start",as="offsetted_rect_end";function ed({timeUnit:e,field:t,reverse:n}){const{unit:i,utc:r}=e,s=Au(i),{part:o,step:a}=Iu(s,e.step);return `${r?"utcOffset":"timeOffset"}('${o}', datum['${t}'], ${n?-a:a})`}function Pc([e,t],n,i){if(n!==void 0&&n!==.5){const r=`datum['${e}']`,s=`datum['${t}']`;return [{type:"formula",expr:zc([ed({timeUnit:i,field:e,reverse:!0}),r],n+.5),as:`${e}_${os}`},{type:"formula",expr:zc([r,s],n+.5),as:`${e}_${as}`}]}return []}function zc([e,t],n){return `${1-n} * ${e} + ${n} * ${t}`}const er="_tuple_fields";class Jb{constructor(...t){this.items=t,this.hasChannel={},this.hasField={},this.hasSelectionId=!1;}}const Qb={defined:()=>!0,parse:(e,t,n)=>{const i=t.name,r=t.project??(t.project=new Jb),s={},o={},a=new Set,c=(p,h)=>{const m=h==="visual"?p.channel:p.field;let y=re(`${i}_${m}`);for(let b=1;a.has(y);b++)y=re(`${i}_${m}_${b}`);return a.add(y),{[h]:y}},l=t.type,u=e.config.selection[l],f=n.value!==void 0?H(n.value):null;let{fields:d,encodings:g}=et$1(n.select)?n.select:{};if(!d&&!g&&f){for(const p of f)if(et$1(p))for(const h of x(p))dg(h)?(g||(g=[])).push(h):l==="interval"?(S(Vg),g=u.encodings):(d??(d=[])).push(h);}!d&&!g&&(g=u.encodings,"fields"in u&&(d=u.fields));for(const p of g??[]){const h=e.fieldDef(p);if(h){let m=h.field;if(h.aggregate){S(Dg(p,h.aggregate));continue}else if(!m){S(ac(p));continue}if(h.timeUnit&&!Ln(h.timeUnit)){m=e.vgField(p);const y={timeUnit:h.timeUnit,as:m,field:h.field};o[W(y)]=y;}if(!s[m]){const y=l==="interval"&&Pt(p)&&De(e.getScaleComponent(p).get("type"))?"R":h.bin?"R-RE":"E",b={field:m,channel:p,type:y,index:r.items.length};b.signals={...c(b,"data"),...c(b,"visual")},r.items.push(s[m]=b),r.hasField[m]=s[m],r.hasSelectionId=r.hasSelectionId||m===Ze,eu(p)?(b.geoChannel=p,b.channel=Zl(p),r.hasChannel[b.channel]=s[m]):r.hasChannel[p]=s[m];}}else S(ac(p));}for(const p of d??[]){if(r.hasField[p])continue;const h={type:"E",field:p,index:r.items.length};h.signals={...c(h,"data")},r.items.push(h),r.hasField[p]=h,r.hasSelectionId=r.hasSelectionId||p===Ze;}f&&(t.init=f.map(p=>r.items.map(h=>et$1(p)?p[h.geoChannel||h.channel]!==void 0?p[h.geoChannel||h.channel]:p[h.field]:p))),K(o)||(r.timeUnit=new ft(null,o));},signals:(e,t,n)=>{const i=t.name+er;return n.filter(s=>s.name===i).length>0||t.project.hasSelectionId?n:n.concat({name:i,value:t.project.items.map(Qf)})}},kt={defined:e=>e.type==="interval"&&e.resolve==="global"&&e.bind&&e.bind==="scales",parse:(e,t)=>{const n=t.scales=[];for(const i of t.project.items){const r=i.channel;if(!Pt(r))continue;const s=e.getScaleComponent(r),o=s?s.get("type"):void 0;if(o=="sequential"&&S(Bg),!s||!De(o)){S(Ug);continue}s.set("selectionExtent",{param:t.name,field:i.field},!0),n.push(i);}},topLevelSignals:(e,t,n)=>{const i=t.scales.filter(o=>n.filter(a=>a.name===o.signals.data).length===0);if(!e.parent||Dc(e)||i.length===0)return n;const r=n.filter(o=>o.name===t.name)[0];let s=r.update;if(s.indexOf(md)>=0)r.update=`{${i.map(o=>`${Y$1(Ue(o.field))}: ${o.signals.data}`).join(", ")}}`;else {for(const o of i){const a=`${Y$1(Ue(o.field))}: ${o.signals.data}`;s.includes(a)||(s=`${s.substring(0,s.length-1)}, ${a}}`);}r.update=s;}return n.concat(i.map(o=>({name:o.signals.data})))},signals:(e,t,n)=>{if(e.parent&&!Dc(e))for(const i of t.scales){const r=n.find(s=>s.name===i.signals.data);r.push="outer",delete r.value,delete r.update;}return n}};function so(e,t){return `domain(${Y$1(e.scaleName(t))})`}function Dc(e){return e.parent&&Si(e.parent)&&!e.parent.parent}const Xn="_brush",td="_scale_trigger",Ei="geo_interval_init_tick",nd="_init",Zb="_center",ex={defined:e=>e.type==="interval",parse:(e,t,n)=>{var i;if(e.hasProjection){const r={...et$1(n.select)?n.select:{}};r.fields=[Ze],r.encodings||(r.encodings=n.value?x(n.value):[it,nt]),n.select={type:"interval",...r};}if(t.translate&&!kt.defined(t)){const r=`!event.item || event.item.mark.name !== ${Y$1(t.name+Xn)}`;for(const s of t.events){if(!s.between){S(`${s} is not an ordered event stream for interval selections.`);continue}const o=H((i=s.between[0]).filter??(i.filter=[]));o.indexOf(r)<0&&o.push(r);}}},signals:(e,t,n)=>{const i=t.name,r=i+Xt,s=Se(t.project.hasChannel).filter(a=>a.channel===se||a.channel===be),o=t.init?t.init[0]:null;if(n.push(...s.reduce((a,c)=>a.concat(tx(e,t,c,o&&o[c.index])),[])),e.hasProjection){const a=Y$1(e.projectionName()),c=e.projectionName()+Zb,{x:l,y:u}=t.project.hasChannel,f=l&&l.signals.visual,d=u&&u.signals.visual,g=l?o&&o[l.index]:`${c}[0]`,p=u?o&&o[u.index]:`${c}[1]`,h=N=>e.getSizeSignalRef(N).signal,m=`[[${f?f+"[0]":"0"}, ${d?d+"[0]":"0"}],[${f?f+"[1]":h("width")}, ${d?d+"[1]":h("height")}]]`;o&&(n.unshift({name:i+nd,init:`[scale(${a}, [${l?g[0]:g}, ${u?p[0]:p}]), scale(${a}, [${l?g[1]:g}, ${u?p[1]:p}])]`}),(!l||!u)&&(n.find(_=>_.name===c)||n.unshift({name:c,update:`invert(${a}, [${h("width")}/2, ${h("height")}/2])`})));const y=`intersect(${m}, {markname: ${Y$1(e.getName("marks"))}}, unit.mark)`,b=`{unit: ${bn(e)}}`,C=`vlSelectionTuples(${y}, ${b})`,k=s.map(N=>N.signals.visual);return n.concat({name:r,on:[{events:[...k.length?[{signal:k.join(" || ")}]:[],...o?[{signal:Ei}]:[]],update:C}]})}else {if(!kt.defined(t)){const l=i+td,u=s.map(f=>{const d=f.channel,{data:g,visual:p}=f.signals,h=Y$1(e.scaleName(d)),m=e.getScaleComponent(d).get("type"),y=De(m)?"+":"";return `(!isArray(${g}) || (${y}invert(${h}, ${p})[0] === ${y}${g}[0] && ${y}invert(${h}, ${p})[1] === ${y}${g}[1]))`});u.length&&n.push({name:l,value:{},on:[{events:s.map(f=>({scale:e.scaleName(f.channel)})),update:u.join(" && ")+` ? ${l} : {}`}]});}const a=s.map(l=>l.signals.data),c=`unit: ${bn(e)}, fields: ${i+er}, values`;return n.concat({name:r,...o?{init:`{${c}: ${Fn(o)}}`}:{},...a.length?{on:[{events:[{signal:a.join(" || ")}],update:`${a.join(" && ")} ? {${c}: [${a}]} : null`}]}:{}})}},topLevelSignals:(e,t,n)=>(ae(e)&&e.hasProjection&&t.init&&(n.filter(r=>r.name===Ei).length||n.unshift({name:Ei,value:null,on:[{events:"timer{1}",update:`${Ei} === null ? {} : ${Ei}`}]})),n),marks:(e,t,n)=>{const i=t.name,{x:r,y:s}=t.project.hasChannel,o=r?.signals.visual,a=s?.signals.visual,c=`data(${Y$1(t.name+kn)})`;if(kt.defined(t)||!r&&!s)return n;const l={x:r!==void 0?{signal:`${o}[0]`}:{value:0},y:s!==void 0?{signal:`${a}[0]`}:{value:0},x2:r!==void 0?{signal:`${o}[1]`}:{field:{group:"width"}},y2:s!==void 0?{signal:`${a}[1]`}:{field:{group:"height"}}};if(t.resolve==="global")for(const m of x(l))l[m]=[{test:`${c}.length && ${c}[0].unit === ${bn(e)}`,...l[m]},{value:0}];const{fill:u,fillOpacity:f,cursor:d,...g}=t.mark,p=x(g).reduce((m,y)=>(m[y]=[{test:[r!==void 0&&`${o}[0] !== ${o}[1]`,s!==void 0&&`${a}[0] !== ${a}[1]`].filter(b=>b).join(" && "),value:g[y]},{value:null}],m),{}),h=d??(t.translate?"move":null);return [{name:`${i+Xn}_bg`,type:"rect",clip:!0,encode:{enter:{fill:{value:u},fillOpacity:{value:f}},update:l}},...n,{name:i+Xn,type:"rect",clip:!0,encode:{enter:{...h?{cursor:{value:h}}:{},fill:{value:"transparent"}},update:{...l,...p}}}]}};function tx(e,t,n,i){const r=!e.hasProjection,s=n.channel,o=n.signals.visual,a=Y$1(r?e.scaleName(s):e.projectionName()),c=d=>`scale(${a}, ${d})`,l=e.getSizeSignalRef(s===se?"width":"height").signal,u=`${s}(unit)`,f=t.events.reduce((d,g)=>[...d,{events:g.between[0],update:`[${u}, ${u}]`},{events:g,update:`[${o}[0], clamp(${u}, 0, ${l})]`}],[]);if(r){const d=n.signals.data,g=kt.defined(t),p=e.getScaleComponent(s),h=p?p.get("type"):void 0,m=i?{init:Fn(i,!0,c)}:{value:[]};return f.push({events:{signal:t.name+td},update:De(h)?`[${c(`${d}[0]`)}, ${c(`${d}[1]`)}]`:"[0, 0]"}),g?[{name:d,on:[]}]:[{name:o,...m,on:f},{name:d,...i?{init:Fn(i)}:{},on:[{events:{signal:o},update:`${o}[0] === ${o}[1] ? null : invert(${a}, ${o})`}]}]}else {const d=s===se?0:1,g=t.name+nd,p=i?{init:`[${g}[0][${d}], ${g}[1][${d}]]`}:{value:[]};return [{name:o,...p,on:f}]}}const nx={defined:e=>e.type==="point",signals:(e,t,n)=>{const i=t.name,r=i+er,s=t.project,o="(item().isVoronoi ? datum.datum : datum)",a=Se(e.component.selection??{}).reduce((f,d)=>d.type==="interval"?f.concat(d.name+Xn):f,[]).map(f=>`indexof(item().mark.name, '${f}') < 0`).join(" && "),c=`datum && item().mark.marktype !== 'group' && indexof(item().mark.role, 'legend') < 0${a?` && ${a}`:""}`;let l=`unit: ${bn(e)}, `;if(t.project.hasSelectionId)l+=`${Ze}: ${o}[${Y$1(Ze)}]`;else {const f=s.items.map(d=>e.fieldDef(d.channel)?.bin?`[${o}[${Y$1(e.vgField(d.channel,{}))}], ${o}[${Y$1(e.vgField(d.channel,{binSuffix:"end"}))}]]`:`${o}[${Y$1(d.field)}]`).join(", ");l+=`fields: ${r}, values: [${f}]`;}const u=t.events;return n.concat([{name:i+Xt,on:u?[{events:u,update:`${c} ? {${l}} : null`,force:!0}]:[]}])}};function mi(e,t,n,i){const r=Jr(t)&&t.condition,s=i(t);if(r){const a=H(r).map(c=>{const l=i(c);if(qm(c)){const{param:u,empty:f}=c;return {test:Sd(e,{param:u,empty:f}),...l}}else return {test:Tr(e,c.test),...l}});return {[n]:[...a,...s!==void 0?[s]:[]]}}else return s!==void 0?{[n]:s}:{}}function $a(e,t="text"){const n=e.encoding[t];return mi(e,n,t,i=>cs(i,e.config))}function cs(e,t,n="datum"){if(e){if(Qe(e))return ne(e.value);if(D(e)){const{format:i,formatType:r}=Er(e);return na({fieldOrDatumDef:e,format:i,formatType:r,expr:n,config:t})}}}function id(e,t={}){const{encoding:n,markDef:i,config:r,stack:s}=e,o=n.tooltip;if(U(o))return {tooltip:Mc({tooltip:o},s,r,t)};{const a=t.reactiveGeom?"datum.datum":"datum";return mi(e,o,"tooltip",c=>{const l=cs(c,r,a);if(l)return l;if(c===null)return;let u=X("tooltip",i,r);if(u===!0&&(u={content:"encoding"}),xt$1(u))return {value:u};if(et$1(u))return T(u)?u:u.content==="encoding"?Mc(n,s,r,t):{signal:a}})}}function rd(e,t,n,{reactiveGeom:i}={}){const r={...n,...n.tooltipFormat},s={},o=i?"datum.datum":"datum",a=[];function c(u,f){const d=_n(f),g=Ce(u)?u:{...u,type:e[d].type},p=g.title||oa(g,r),h=H(p).join(", ").replaceAll(/"/g,'\\"');let m;if(ue(f)){const y=f==="x"?"x2":"y2",b=gt(e[y]);if(xe(g.bin)&&b){const C=E(g,{expr:o}),k=E(b,{expr:o}),{format:N,formatType:_}=Er(g);m=Yi(C,k,N,_,r),s[y]=!0;}}if((ue(f)||f===We||f===tt)&&t&&t.fieldChannel===f&&t.offset==="normalize"){const{format:y,formatType:b}=Er(g);m=na({fieldOrDatumDef:g,format:y,formatType:b,expr:o,config:r,normalizeStack:!0}).signal;}m??(m=cs(g,r,o).signal),a.push({channel:f,key:h,value:m});}la(e,(u,f)=>{v(u)?c(u,f):Qr(u)&&c(u.condition,f);});const l={};for(const{channel:u,key:f,value:d}of a)!s[u]&&!l[f]&&(l[f]=d);return l}function Mc(e,t,n,{reactiveGeom:i}={}){const r=rd(e,t,n,{reactiveGeom:i}),s=Wt(r).map(([o,a])=>`"${o}": ${a}`);return s.length>0?{signal:`{${s.join(", ")}}`}:void 0}function ix(e){const{markDef:t,config:n}=e,i=X("aria",t,n);return i===!1?{}:{...i?{aria:i}:{},...rx(e),...sx(e)}}function rx(e){const{mark:t,markDef:n,config:i}=e;if(i.aria===!1)return {};const r=X("ariaRoleDescription",n,i);return r!=null?{ariaRoleDescription:{value:r}}:t in Ig?{}:{ariaRoleDescription:{value:t}}}function sx(e){const{encoding:t,markDef:n,config:i,stack:r}=e,s=t.description;if(s)return mi(e,s,"description",c=>cs(c,e.config));const o=X("description",n,i);if(o!=null)return {description:ne(o)};if(i.aria===!1)return {};const a=rd(t,r,i);if(!K(a))return {description:{signal:Wt(a).map(([c,l],u)=>`"${u>0?"; ":""}${c}: " + (${l})`).join(" + ")}}}function he(e,t,n={}){const{markDef:i,encoding:r,config:s}=t,{vgChannel:o}=n;let{defaultRef:a,defaultValue:c}=n;a===void 0&&(c??(c=X(e,i,s,{vgChannel:o,ignoreVgConfig:!0})),c!==void 0&&(a=ne(c)));const l=r[e];return mi(t,l,o??e,u=>ta({channel:e,channelDef:u,markDef:i,config:s,scaleName:t.scaleName(e),scale:t.getScaleComponent(e),stack:null,defaultRef:a}))}function sd(e,t={filled:void 0}){const{markDef:n,encoding:i,config:r}=e,{type:s}=n,o=t.filled??X("filled",n,r),a=G(["bar","point","circle","square","geoshape"],s)?"transparent":void 0,c=X(o===!0?"color":void 0,n,r,{vgChannel:"fill"})??r.mark[o===!0&&"color"]??a,l=X(o===!1?"color":void 0,n,r,{vgChannel:"stroke"})??r.mark[o===!1&&"color"],u=o?"fill":"stroke",f={...c?{fill:ne(c)}:{},...l?{stroke:ne(l)}:{}};return n.color&&(o?n.fill:n.stroke)&&S(vu("property",{fill:"fill"in n,stroke:"stroke"in n})),{...f,...he("color",e,{vgChannel:u,defaultValue:o?c:l}),...he("fill",e,{defaultValue:i.fill?c:void 0}),...he("stroke",e,{defaultValue:i.stroke?l:void 0})}}function ox(e){const{encoding:t,mark:n}=e,i=t.order;return !rn(n)&&Qe(i)?mi(e,i,"zindex",r=>ne(r.value)):{}}function ai({channel:e,markDef:t,encoding:n={},model:i,bandPosition:r}){const s=`${e}Offset`,o=t[s],a=n[s];if((s==="xOffset"||s==="yOffset")&&a)return {offsetType:"encoding",offset:ta({channel:s,channelDef:a,markDef:t,config:i?.config,scaleName:i.scaleName(s),scale:i.getScaleComponent(s),stack:null,defaultRef:ne(o),bandPosition:r})};const c=t[s];return c?{offsetType:"visual",offset:c}:{}}function Ee(e,t,{defaultPos:n,vgChannel:i}){const{encoding:r,markDef:s,config:o,stack:a}=t,c=r[e],l=r[xt(e)],u=t.scaleName(e),f=t.getScaleComponent(e),{offset:d,offsetType:g}=ai({channel:e,markDef:s,encoding:r,model:t,bandPosition:.5}),p=wa({model:t,defaultPos:n,channel:e,scaleName:u,scale:f}),h=!c&&ue(e)&&(r.latitude||r.longitude)?{field:t.getName(e)}:ax({channel:e,channelDef:c,channel2Def:l,markDef:s,config:o,scaleName:u,scale:f,stack:a,offset:d,defaultRef:p,bandPosition:g==="encoding"?0:void 0});return h?{[i||e]:h}:void 0}function ax(e){const{channel:t,channelDef:n,scaleName:i,stack:r,offset:s,markDef:o}=e;if(D(n)&&r&&t===r.fieldChannel){if(v(n)){let a=n.bandPosition;if(a===void 0&&o.type==="text"&&(t==="radius"||t==="theta")&&(a=.5),a!==void 0)return xr({scaleName:i,fieldOrDatumDef:n,startSuffix:"start",bandPosition:a,offset:s})}return mn(n,i,{suffix:"end"},{offset:s})}return Zo(e)}function wa({model:e,defaultPos:t,channel:n,scaleName:i,scale:r}){const{markDef:s,config:o}=e;return ()=>{const a=_n(n),c=Gt(n),l=X(n,s,o,{vgChannel:c});if(l!==void 0)return _i(n,l);switch(t){case"zeroOrMin":case"zeroOrMax":if(i){const u=r.get("type");if(!G([Te.LOG,Te.TIME,Te.UTC],u)){if(r.domainDefinitelyIncludesZero())return {scale:i,value:0}}}if(t==="zeroOrMin")return a==="y"?{field:{group:"height"}}:{value:0};switch(a){case"radius":return {signal:`min(${e.width.signal},${e.height.signal})/2`};case"theta":return {signal:"2*PI"};case"x":return {field:{group:"width"}};case"y":return {value:0}}break;case"mid":return {...e[_e(n)],mult:.5}}}}const cx={left:"x",center:"xc",right:"x2"},lx={top:"y",middle:"yc",bottom:"y2"};function od(e,t,n,i="middle"){if(e==="radius"||e==="theta")return Gt(e);const r=e==="x"?"align":"baseline",s=X(r,t,n);let o;return T(s)?(S(dh(r)),o=void 0):o=s,e==="x"?cx[o||(i==="top"?"left":"center")]:lx[o||i]}function Fr(e,t,{defaultPos:n,defaultPos2:i,range:r}){return r?ad(e,t,{defaultPos:n,defaultPos2:i}):Ee(e,t,{defaultPos:n})}function ad(e,t,{defaultPos:n,defaultPos2:i}){const{markDef:r,config:s}=t,o=xt(e),a=_e(e),c=ux(t,i,o),l=c[a]?od(e,r,s):Gt(e);return {...Ee(e,t,{defaultPos:n,vgChannel:l}),...c}}function ux(e,t,n){const{encoding:i,mark:r,markDef:s,stack:o,config:a}=e,c=_n(n),l=_e(n),u=Gt(n),f=i[c],d=e.scaleName(c),g=e.getScaleComponent(c),{offset:p}=n in i||n in s?ai({channel:n,markDef:s,encoding:i,model:e}):ai({channel:c,markDef:s,encoding:i,model:e});if(!f&&(n==="x2"||n==="y2")&&(i.latitude||i.longitude)){const m=_e(n),y=e.markDef[m];return y!=null?{[m]:{value:y}}:{[u]:{field:e.getName(n)}}}const h=fx({channel:n,channelDef:f,channel2Def:i[n],markDef:s,config:a,scaleName:d,scale:g,stack:o,offset:p,defaultRef:void 0});return h!==void 0?{[u]:h}:sr(n,s)||sr(n,{[n]:mr(n,s,a.style),[l]:mr(l,s,a.style)})||sr(n,a[r])||sr(n,a.mark)||{[u]:wa({model:e,defaultPos:t,channel:n,scaleName:d,scale:g})()}}function fx({channel:e,channelDef:t,channel2Def:n,markDef:i,config:r,scaleName:s,scale:o,stack:a,offset:c,defaultRef:l}){return D(t)&&a&&e.charAt(0)===a.fieldChannel.charAt(0)?mn(t,s,{suffix:"start"},{offset:c}):Zo({channel:e,channelDef:n,scaleName:s,scale:o,stack:a,markDef:i,config:r,offset:c,defaultRef:l})}function sr(e,t){const n=_e(e),i=Gt(e);if(t[i]!==void 0)return {[i]:_i(e,t[i])};if(t[e]!==void 0)return {[i]:_i(e,t[e])};if(t[n]){const r=t[n];if(Cn(r))S(oh(n));else return {[n]:_i(e,r)}}}function Vt(e,t){const{config:n,encoding:i,markDef:r}=e,s=r.type,o=xt(t),a=_e(t),c=i[t],l=i[o],u=e.getScaleComponent(t),f=u?u.get("type"):void 0,d=r.orient,g=i[a]??i.size??X("size",r,n,{vgChannel:a}),p=ru(t),h=s==="bar"&&(t==="x"?d==="vertical":d==="horizontal");return v(c)&&(ee(c.bin)||xe(c.bin)||c.timeUnit&&!l)&&!(g&&!Cn(g))&&!i[p]&&!ye(f)?gx({fieldDef:c,fieldDef2:l,channel:t,model:e}):(D(c)&&ye(f)||h)&&!l?px(c,t,e):ad(t,e,{defaultPos:"zeroOrMax",defaultPos2:"zeroOrMin"})}function dx(e,t,n,i,r,s,o){if(Cn(r))if(n){const c=n.get("type");if(c==="band"){let l=`bandwidth('${t}')`;r.band!==1&&(l=`${r.band} * ${l}`);const u=Ot("minBandSize",{type:o},i);return {signal:u?`max(${Xe(u)}, ${l})`:l}}else r.band!==1&&(S(mh(c)),r=void 0);}else return {mult:r.band,field:{group:e}};else {if(T(r))return r;if(r)return {value:r}}if(n){const c=n.get("range");if(nn(c)&&Mr$1(c.step))return {value:c.step-2}}if(!s){const{bandPaddingInner:c,barBandPaddingInner:l,rectBandPaddingInner:u}=i.scale,f=le(c,o==="bar"?l:u);if(T(f))return {signal:`(1 - (${f.signal})) * ${e}`};if(Mr$1(f))return {signal:`${1-f} * ${e}`}}return {value:Cr(i.view,e)-2}}function px(e,t,n){const{markDef:i,encoding:r,config:s,stack:o}=n,a=i.orient,c=n.scaleName(t),l=n.getScaleComponent(t),u=_e(t),f=xt(t),d=ru(t),g=n.scaleName(d),p=n.getScaleComponent(Ao(t)),h=a==="horizontal"&&t==="y"||a==="vertical"&&t==="x";let m;(r.size||i.size)&&(h?m=he("size",n,{vgChannel:u,defaultRef:ne(i.size)}):S(Sh(i.type)));const y=!!m,b=nf({channel:t,fieldDef:e,markDef:i,config:s,scaleType:(l||p)?.get("type"),useVlSizeChannel:h});m=m||{[u]:dx(u,g||c,p||l,s,b,!!e,i.type)};const C=(l||p)?.get("type")==="band"&&Cn(b)&&!y?"top":"middle",k=od(t,i,s,C),N=k==="xc"||k==="yc",{offset:_,offsetType:L}=ai({channel:t,markDef:i,encoding:r,model:n,bandPosition:N?.5:0}),U$1=Zo({channel:t,channelDef:e,markDef:i,config:s,scaleName:c,scale:l,stack:o,offset:_,defaultRef:wa({model:n,defaultPos:"mid",channel:t,scaleName:c,scale:l}),bandPosition:N?L==="encoding"?0:.5:T(b)?{signal:`(1-${b})/2`}:Cn(b)?(1-b.band)/2:0});if(u)return {[k]:U$1,...m};{const oe=Gt(f),de=m[u],Re=_?{...de,offset:_}:de;return {[k]:U$1,[oe]:U(U$1)?[U$1[0],{...U$1[1],offset:Re}]:{...U$1,offset:Re}}}}function jc(e,t,n,i,r,s,o){if(Ql(e))return 0;const a=e==="x"||e==="y2",c=a?-t/2:t/2;if(T(n)||T(r)||T(i)||s){const l=Xe(n),u=Xe(r),f=Xe(i),d=Xe(s),p=s?`(${o} < ${d} ? ${a?"":"-"}0.5 * (${d} - (${o})) : ${c})`:c,h=f?`${f} + `:"",m=l?`(${l} ? -1 : 1) * `:"",y=u?`(${u} + ${p})`:p;return {signal:h+m+y}}else return r=r||0,i+(n?-r-c:+r+c)}function gx({fieldDef:e,fieldDef2:t,channel:n,model:i}){const{config:r,markDef:s,encoding:o}=i,a=i.getScaleComponent(n),c=i.scaleName(n),l=a?a.get("type"):void 0,u=a.get("reverse"),f=nf({channel:n,fieldDef:e,markDef:s,config:r,scaleType:l}),g=i.component.axes[n]?.[0]?.get("translate")??.5,p=ue(n)?X("binSpacing",s,r)??0:0,h=xt(n),m=Gt(n),y=Gt(h),b=Ot("minBandSize",s,r),{offset:C}=ai({channel:n,markDef:s,encoding:o,model:i,bandPosition:0}),{offset:k}=ai({channel:h,markDef:s,encoding:o,model:i,bandPosition:0}),N=Um({fieldDef:e,scaleName:c}),_=jc(n,p,u,g,C,b,N),L=jc(h,p,u,g,k??C,b,N),U=T(f)?{signal:`(1-${f.signal})/2`}:Cn(f)?(1-f.band)/2:.5,oe=Ht({fieldDef:e,fieldDef2:t,markDef:s,config:r});if(ee(e.bin)||e.timeUnit){const de=e.timeUnit&&oe!==.5;return {[y]:Uc({fieldDef:e,scaleName:c,bandPosition:U,offset:L,useRectOffsetField:de}),[m]:Uc({fieldDef:e,scaleName:c,bandPosition:T(U)?{signal:`1-${U.signal}`}:1-U,offset:_,useRectOffsetField:de})}}else if(xe(e.bin)){const de=mn(e,c,{},{offset:L});if(v(t))return {[y]:de,[m]:mn(t,c,{},{offset:_})};if(Rn(e.bin)&&e.bin.step)return {[y]:de,[m]:{signal:`scale("${c}", ${E(e,{expr:"datum"})} + ${e.bin.step})`,offset:_}}}S(wu(h));}function Uc({fieldDef:e,scaleName:t,bandPosition:n,offset:i,useRectOffsetField:r}){return xr({scaleName:t,fieldOrDatumDef:e,bandPosition:n,offset:i,...r?{startSuffix:os,endSuffix:as}:{}})}const hx=new Set(["aria","width","height"]);function Ge(e,t){const{fill:n=void 0,stroke:i=void 0}=t.color==="include"?sd(e):{};return {...mx(e.markDef,t),...Bc(e,"fill",n),...Bc(e,"stroke",i),...he("opacity",e),...he("fillOpacity",e),...he("strokeOpacity",e),...he("strokeWidth",e),...he("strokeDash",e),...ox(e),...id(e),...$a(e,"href"),...ix(e)}}function Bc(e,t,n){const{config:i,mark:r,markDef:s}=e;if(X("invalid",s,i)==="hide"&&n&&!rn(r)){const a=yx(e,{invalid:!0,channels:Ur});if(a)return {[t]:[{test:a,value:null},...H(n)]}}return n?{[t]:n}:{}}function mx(e,t){return Rg.reduce((n,i)=>(!hx.has(i)&&e[i]!==void 0&&t[i]!=="ignore"&&(n[i]=ne(e[i])),n),{})}function yx(e,{invalid:t=!1,channels:n}){const i=n.reduce((s,o)=>{const a=e.getScaleComponent(o);if(a){const c=a.get("type"),l=e.vgField(o,{expr:"datum"});l&&De(c)&&(s[l]=!0);}return s},{}),r=x(i);if(r.length>0){const s=t?"||":"&&";return r.map(o=>ea(o,t)).join(` ${s} `)}}function Ca(e){const{config:t,markDef:n}=e;if(X("invalid",n,t)){const r=bx(e,{channels:St});if(r)return {defined:{signal:r}}}return {}}function bx(e,{invalid:t=!1,channels:n}){const i=n.reduce((s,o)=>{const a=e.getScaleComponent(o);if(a){const c=a.get("type"),l=e.vgField(o,{expr:"datum",binSuffix:e.stack?.impute?"mid":void 0});l&&De(c)&&(s[l]=!0);}return s},{}),r=x(i);if(r.length>0){const s=t?"||":"&&";return r.map(o=>ea(o,t)).join(` ${s} `)}}function Wc(e,t){if(t!==void 0)return {[e]:ne(t)}}const Rs="voronoi",cd={defined:e=>e.type==="point"&&e.nearest,parse:(e,t)=>{if(t.events)for(const n of t.events)n.markname=e.getName(Rs);},marks:(e,t,n)=>{const{x:i,y:r}=t.project.hasChannel,s=e.mark;if(rn(s))return S(Mg(s)),n;const o={name:e.getName(Rs),type:"path",interactive:!0,from:{data:e.getName("marks")},encode:{update:{fill:{value:"transparent"},strokeWidth:{value:.35},stroke:{value:"transparent"},isVoronoi:{value:!0},...id(e,{reactiveGeom:!0})}},transform:[{type:"voronoi",x:{expr:i||!r?"datum.datum.x || 0":"0"},y:{expr:r||!i?"datum.datum.y || 0":"0"},size:[e.getSizeSignalRef("width"),e.getSizeSignalRef("height")]}]};let a=0,c=!1;return n.forEach((l,u)=>{const f=l.name??"";f===e.component.mark[0].name?a=u:f.indexOf(Rs)>=0&&(c=!0);}),c||n.splice(a+1,0,o),n}},ld={defined:e=>e.type==="point"&&e.resolve==="global"&&e.bind&&e.bind!=="scales"&&!ha(e.bind),parse:(e,t,n)=>yd(t,n),topLevelSignals:(e,t,n)=>{const i=t.name,r=t.project,s=t.bind,o=t.init&&t.init[0],a=cd.defined(t)?"(item().isVoronoi ? datum.datum : datum)":"datum";return r.items.forEach((c,l)=>{const u=re(`${i}_${c.field}`);n.filter(d=>d.name===u).length||n.unshift({name:u,...o?{init:Fn(o[l])}:{value:null},on:t.events?[{events:t.events,update:`datum && item().mark.marktype !== 'group' ? ${a}[${Y$1(c.field)}] : null`}]:[],bind:s[c.field]??s[c.channel]??s});}),n},signals:(e,t,n)=>{const i=t.name,r=t.project,s=n.filter(l=>l.name===i+Xt)[0],o=i+er,a=r.items.map(l=>re(`${i}_${l.field}`)),c=a.map(l=>`${l} !== null`).join(" && ");return a.length&&(s.update=`${c} ? {fields: ${o}, values: [${a.join(", ")}]} : null`),delete s.value,delete s.on,n}},kr="_toggle",ud={defined:e=>e.type==="point"&&!!e.toggle,signals:(e,t,n)=>n.concat({name:t.name+kr,value:!1,on:[{events:t.events,update:t.toggle}]}),modifyExpr:(e,t)=>{const n=t.name+Xt,i=t.name+kr;return `${i} ? null : ${n}, `+(t.resolve==="global"?`${i} ? null : true, `:`${i} ? null : {unit: ${bn(e)}}, `)+`${i} ? ${n} : null`}},xx={defined:e=>e.clear!==void 0&&e.clear!==!1,parse:(e,t)=>{t.clear&&(t.clear=xt$1(t.clear)?t5(t.clear,"view"):t.clear);},topLevelSignals:(e,t,n)=>{if(ld.defined(t))for(const i of t.project.items){const r=n.findIndex(s=>s.name===re(`${t.name}_${i.field}`));r!==-1&&n[r].on.push({events:t.clear,update:"null"});}return n},signals:(e,t,n)=>{function i(r,s){r!==-1&&n[r].on&&n[r].on.push({events:t.clear,update:s});}if(t.type==="interval")for(const r of t.project.items){const s=n.findIndex(o=>o.name===r.signals.visual);if(i(s,"[0, 0]"),s===-1){const o=n.findIndex(a=>a.name===r.signals.data);i(o,"null");}}else {let r=n.findIndex(s=>s.name===t.name+Xt);i(r,"null"),ud.defined(t)&&(r=n.findIndex(s=>s.name===t.name+kr),i(r,"false"));}return n}},fd={defined:e=>{const t=e.resolve==="global"&&e.bind&&ha(e.bind),n=e.project.items.length===1&&e.project.items[0].field!==Ze;return t&&!n&&S(Wg),t&&n},parse:(e,t,n)=>{const i=z(n);if(i.select=xt$1(i.select)?{type:i.select,toggle:t.toggle}:{...i.select,toggle:t.toggle},yd(t,i),et$1(n.select)&&(n.select.on||n.select.clear)){const o='event.item && indexof(event.item.mark.role, "legend") < 0';for(const a of t.events)a.filter=H(a.filter??[]),a.filter.includes(o)||a.filter.push(o);}const r=Ts(t.bind)?t.bind.legend:"click",s=xt$1(r)?t5(r,"view"):H(r);t.bind={legend:{merge:s}};},topLevelSignals:(e,t,n)=>{const i=t.name,r=Ts(t.bind)&&t.bind.legend,s=o=>a=>{const c=z(a);return c.markname=o,c};for(const o of t.project.items){if(!o.hasLegend)continue;const a=`${re(o.field)}_legend`,c=`${i}_${a}`;if(n.filter(u=>u.name===c).length===0){const u=r.merge.map(s(`${a}_symbols`)).concat(r.merge.map(s(`${a}_labels`))).concat(r.merge.map(s(`${a}_entries`)));n.unshift({name:c,...t.init?{}:{value:null},on:[{events:u,update:"isDefined(datum.value) ? datum.value : item().items[0].items[0].datum.value",force:!0},{events:r.merge,update:`!event.item || !datum ? null : ${c}`,force:!0}]});}}return n},signals:(e,t,n)=>{const i=t.name,r=t.project,s=n.find(d=>d.name===i+Xt),o=i+er,a=r.items.filter(d=>d.hasLegend).map(d=>re(`${i}_${re(d.field)}_legend`)),l=`${a.map(d=>`${d} !== null`).join(" && ")} ? {fields: ${o}, values: [${a.join(", ")}]} : null`;t.events&&a.length>0?s.on.push({events:a.map(d=>({signal:d})),update:l}):a.length>0&&(s.update=l,delete s.value,delete s.on);const u=n.find(d=>d.name===i+kr),f=Ts(t.bind)&&t.bind.legend;return u&&(t.events?u.on.push({...u.on[0],events:f}):u.on[0].events=f),n}};function Sx(e,t,n){const i=e.fieldDef(t)?.field;for(const r of Se(e.component.selection??{})){const s=r.project.hasField[i]??r.project.hasChannel[t];if(s&&fd.defined(r)){const o=n.get("selections")??[];o.push(r.name),n.set("selections",o,!1),s.hasLegend=!0;}}}const dd="_translate_anchor",pd="_translate_delta",vx={defined:e=>e.type==="interval"&&e.translate,signals:(e,t,n)=>{const i=t.name,r=kt.defined(t),s=i+dd,{x:o,y:a}=t.project.hasChannel;let c=t5(t.translate,"scope");return r||(c=c.map(l=>(l.between[0].markname=i+Xn,l))),n.push({name:s,value:{},on:[{events:c.map(l=>l.between[0]),update:"{x: x(unit), y: y(unit)"+(o!==void 0?`, extent_x: ${r?so(e,se):`slice(${o.signals.visual})`}`:"")+(a!==void 0?`, extent_y: ${r?so(e,be):`slice(${a.signals.visual})`}`:"")+"}"}]},{name:i+pd,value:{},on:[{events:c,update:`{x: ${s}.x - x(unit), y: ${s}.y - y(unit)}`}]}),o!==void 0&&Gc(e,t,o,"width",n),a!==void 0&&Gc(e,t,a,"height",n),n}};function Gc(e,t,n,i,r){const s=t.name,o=s+dd,a=s+pd,c=n.channel,l=kt.defined(t),u=r.filter(N=>N.name===n.signals[l?"data":"visual"])[0],f=e.getSizeSignalRef(i).signal,d=e.getScaleComponent(c),g=d&&d.get("type"),p=d&&d.get("reverse"),h=l?c===se?p?"":"-":p?"-":"":"",m=`${o}.extent_${c}`,y=`${h}${a}.${c} / ${l?`${f}`:`span(${m})`}`,b=!l||!d?"panLinear":g==="log"?"panLog":g==="symlog"?"panSymlog":g==="pow"?"panPow":"panLinear",C=l?g==="pow"?`, ${d.get("exponent")??1}`:g==="symlog"?`, ${d.get("constant")??1}`:"":"",k=`${b}(${m}, ${y}${C})`;u.on.push({events:{signal:a},update:l?k:`clampRange(${k}, 0, ${f})`});}const gd="_zoom_anchor",hd="_zoom_delta",Ex={defined:e=>e.type==="interval"&&e.zoom,signals:(e,t,n)=>{const i=t.name,r=kt.defined(t),s=i+hd,{x:o,y:a}=t.project.hasChannel,c=Y$1(e.scaleName(se)),l=Y$1(e.scaleName(be));let u=t5(t.zoom,"scope");return r||(u=u.map(f=>(f.markname=i+Xn,f))),n.push({name:i+gd,on:[{events:u,update:r?"{"+[c?`x: invert(${c}, x(unit))`:"",l?`y: invert(${l}, y(unit))`:""].filter(f=>f).join(", ")+"}":"{x: x(unit), y: y(unit)}"}]},{name:s,on:[{events:u,force:!0,update:"pow(1.001, event.deltaY * pow(16, event.deltaMode))"}]}),o!==void 0&&Hc(e,t,o,"width",n),a!==void 0&&Hc(e,t,a,"height",n),n}};function Hc(e,t,n,i,r){const s=t.name,o=n.channel,a=kt.defined(t),c=r.filter(b=>b.name===n.signals[a?"data":"visual"])[0],l=e.getSizeSignalRef(i).signal,u=e.getScaleComponent(o),f=u&&u.get("type"),d=a?so(e,o):c.name,g=s+hd,p=`${s}${gd}.${o}`,h=!a||!u?"zoomLinear":f==="log"?"zoomLog":f==="symlog"?"zoomSymlog":f==="pow"?"zoomPow":"zoomLinear",m=a?f==="pow"?`, ${u.get("exponent")??1}`:f==="symlog"?`, ${u.get("constant")??1}`:"":"",y=`${h}(${d}, ${p}, ${g}${m})`;c.on.push({events:{signal:g},update:a?y:`clampRange(${y}, 0, ${l})`});}const kn="_store",Xt="_tuple",$x="_modify",md="vlSelectionResolve",ls=[nx,ex,Qb,ud,ld,kt,fd,xx,vx,Ex,cd];function wx(e){let t=e.parent;for(;t&&!ze(t);)t=t.parent;return t}function bn(e,{escape:t}={escape:!0}){let n=t?Y$1(e.name):e.name;const i=wx(e);if(i){const{facet:r}=i;for(const s of je)r[s]&&(n+=` + '__facet_${s}_' + (facet[${Y$1(i.vgField(s))}])`);}return n}function Na(e){return Se(e.component.selection??{}).reduce((t,n)=>t||n.project.hasSelectionId,!1)}function yd(e,t){(xt$1(t.select)||!t.select.on)&&delete e.events,(xt$1(t.select)||!t.select.clear)&&delete e.clear,(xt$1(t.select)||!t.select.toggle)&&delete e.toggle;}function oo(e){const t=[];return e.type==="Identifier"?[e.name]:e.type==="Literal"?[e.value]:(e.type==="MemberExpression"&&(t.push(...oo(e.object)),t.push(...oo(e.property))),t)}function bd(e){return e.object.type==="MemberExpression"?bd(e.object):e.object.name==="datum"}function xd(e){const t=pP(e),n=new Set;return t.visit(i=>{i.type==="MemberExpression"&&bd(i)&&n.add(oo(i).slice(1).join("."));}),n}class yi extends Y{clone(){return new yi(null,this.model,z(this.filter))}constructor(t,n,i){super(t),this.model=n,this.filter=i,this.expr=Tr(this.model,this.filter,this),this._dependentFields=xd(this.expr);}dependentFields(){return this._dependentFields}producedFields(){return new Set}assemble(){return {type:"filter",expr:this.expr}}hash(){return `Filter ${this.expr}`}}function Cx(e,t){const n={},i=e.config.selection;if(!t||!t.length)return n;for(const r of t){const s=re(r.name),o=r.select,a=xt$1(o)?o:o.type,c=et$1(o)?z(o):{type:a},l=i[a];for(const d in l)d==="fields"||d==="encodings"||(d==="mark"&&(c[d]={...l[d],...c[d]}),(c[d]===void 0||c[d]===!0)&&(c[d]=z(l[d]??c[d])));const u=n[s]={...c,name:s,type:a,init:r.value,bind:r.bind,events:xt$1(c.on)?t5(c.on,"scope"):H(z(c.on))},f=z(r);for(const d of ls)d.defined(u)&&d.parse&&d.parse(e,u,f);}return n}function Sd(e,t,n,i="datum"){const r=xt$1(t)?t:t.param,s=re(r),o=Y$1(s+kn);let a;try{a=e.getSelectionComponent(s,r);}catch{return `!!${s}`}if(a.project.timeUnit){const d=n??e.component.data.raw,g=a.project.timeUnit.clone();d.parent?g.insertAsParentOf(d):d.parent=g;}const c=a.project.hasSelectionId?"vlSelectionIdTest(":"vlSelectionTest(",l=a.resolve==="global"?")":`, ${Y$1(a.resolve)})`,u=`${c}${o}, ${i}${l}`,f=`length(data(${o}))`;return t.empty===!1?`${f} && ${u}`:`!${f} || ${u}`}function vd(e,t,n){const i=re(t),r=n.encoding;let s=n.field,o;try{o=e.getSelectionComponent(i,t);}catch{return i}if(!r&&!s)s=o.project.items[0].field,o.project.items.length>1&&S(`A "field" or "encoding" must be specified when using a selection as a scale domain. Using "field": ${Y$1(s)}.`);else if(r&&!s){const a=o.project.items.filter(c=>c.channel===r);!a.length||a.length>1?(s=o.project.items[0].field,S((a.length?"Multiple ":"No ")+`matching ${Y$1(r)} encoding found for selection ${Y$1(n.param)}. Using "field": ${Y$1(s)}.`)):s=a[0].field;}return `${o.name}[${Y$1(Ue(s))}]`}function Nx(e,t){for(const[n,i]of Wt(e.component.selection??{})){const r=e.getName(`lookup_${n}`);e.component.data.outputNodes[r]=i.materialized=new we(new yi(t,e,{param:n}),r,Z.Lookup,e.component.data.outputNodeRefCounts);}}function Tr(e,t,n){return Oi(t,i=>xt$1(i)?i:im(i)?Sd(e,i,n):Pu(i))}function Fx(e,t){if(e)return U(e)&&!jt(e)?e.map(n=>oa(n,t)).join(", "):e}function Is(e,t,n,i){var r,s;e.encode??(e.encode={}),(r=e.encode)[t]??(r[t]={}),(s=e.encode[t]).update??(s.update={}),e.encode[t].update[n]=i;}function ki(e,t,n,i={header:!1}){const{disable:r,orient:s,scale:o,labelExpr:a,title:c,zindex:l,...u}=e.combine();if(!r){for(const f in u){const d=oy[f],g=u[f];if(d&&d!==t&&d!=="both")delete u[f];else if(Zi(g)){const{condition:p,...h}=g,m=H(p),y=xc[f];if(y){const{vgProp:b,part:C}=y,k=[...m.map(N=>{const{test:_,...L}=N;return {test:Tr(null,_),...L}}),h];Is(u,C,b,k),delete u[f];}else if(y===null){const b={signal:m.map(C=>{const{test:k,...N}=C;return `${Tr(null,k)} ? ${ic(N)} : `}).join("")+ic(h)};u[f]=b;}}else if(T(g)){const p=xc[f];if(p){const{vgProp:h,part:m}=p;Is(u,m,h,g),delete u[f];}}G(["labelAlign","labelBaseline"],f)&&u[f]===null&&delete u[f];}if(t==="grid"){if(!u.grid)return;if(u.encode){const{grid:f}=u.encode;u.encode={...f?{grid:f}:{}},K(u.encode)&&delete u.encode;}return {scale:o,orient:s,...u,domain:!1,labels:!1,aria:!1,maxExtent:0,minExtent:0,ticks:!1,zindex:le(l,0)}}else {if(!i.header&&e.mainExtracted)return;if(a!==void 0){let d=a;u.encode?.labels?.update&&T(u.encode.labels.update.text)&&(d=vn(a,"datum.label",u.encode.labels.update.text.signal)),Is(u,"labels","text",{signal:d});}if(u.labelAlign===null&&delete u.labelAlign,u.encode){for(const d of pf)e.hasAxisPart(d)||delete u.encode[d];K(u.encode)&&delete u.encode;}const f=Fx(c,n);return {scale:o,orient:s,grid:!1,...f?{title:f}:{},...u,...n.aria===!1?{aria:!1}:{},zindex:le(l,0)}}}}function Ed(e){const{axes:t}=e.component,n=[];for(const i of St)if(t[i]){for(const r of t[i])if(!r.get("disable")&&!r.get("gridScale")){const s=i==="x"?"height":"width",o=e.getSizeSignalRef(s).signal;s!==o&&n.push({name:s,update:o});}}return n}function kx(e,t){const{x:n=[],y:i=[]}=e;return [...n.map(r=>ki(r,"grid",t)),...i.map(r=>ki(r,"grid",t)),...n.map(r=>ki(r,"main",t)),...i.map(r=>ki(r,"main",t))].filter(r=>r)}function qc(e,t,n,i){return Object.assign.apply(null,[{},...e.map(r=>{if(r==="axisOrient"){const s=n==="x"?"bottom":"left",o=t[n==="x"?"axisBottom":"axisLeft"]||{},a=t[n==="x"?"axisTop":"axisRight"]||{},c=new Set([...x(o),...x(a)]),l={};for(const u of c.values())l[u]={signal:`${i.signal} === "${s}" ? ${Xe(o[u])} : ${Xe(a[u])}`};return l}return t[r]})])}function Tx(e,t,n,i){const r=t==="band"?["axisDiscrete","axisBand"]:t==="point"?["axisDiscrete","axisPoint"]:ju(t)?["axisQuantitative"]:t==="time"||t==="utc"?["axisTemporal"]:[],s=e==="x"?"axisX":"axisY",o=T(n)?"axisOrient":`axis${Wi(n)}`,a=[...r,...r.map(l=>s+l.substr(4))],c=["axis",o,s];return {vlOnlyAxisConfig:qc(a,i,e,n),vgAxisConfig:qc(c,i,e,n),axisConfigStyle:Ax([...c,...a],i)}}function Ax(e,t){const n=[{}];for(const i of e){let r=t[i]?.style;if(r){r=H(r);for(const s of r)n.push(t.style[s]);}}return Object.assign.apply(null,n)}function ao(e,t,n,i={}){const r=gu(e,n,t);if(r!==void 0)return {configFrom:"style",configValue:r};for(const s of ["vlOnlyAxisConfig","vgAxisConfig","axisConfigStyle"])if(i[s]?.[e]!==void 0)return {configFrom:s,configValue:i[s][e]};return {}}const Vc={scale:({model:e,channel:t})=>e.scaleName(t),format:({format:e})=>e,formatType:({formatType:e})=>e,grid:({fieldOrDatumDef:e,axis:t,scaleType:n})=>t.grid??Ox(n,e),gridScale:({model:e,channel:t})=>_x(e,t),labelAlign:({axis:e,labelAngle:t,orient:n,channel:i})=>e.labelAlign||wd(t,n,i),labelAngle:({labelAngle:e})=>e,labelBaseline:({axis:e,labelAngle:t,orient:n,channel:i})=>e.labelBaseline||$d(t,n,i),labelFlush:({axis:e,fieldOrDatumDef:t,channel:n})=>e.labelFlush??Ix(t.type,n),labelOverlap:({axis:e,fieldOrDatumDef:t,scaleType:n})=>e.labelOverlap??Lx(t.type,n,v(t)&&!!t.timeUnit,v(t)?t.sort:void 0),orient:({orient:e})=>e,tickCount:({channel:e,model:t,axis:n,fieldOrDatumDef:i,scaleType:r})=>{const s=e==="x"?"width":e==="y"?"height":void 0,o=s?t.getSizeSignalRef(s):void 0;return n.tickCount??zx({fieldOrDatumDef:i,scaleType:r,size:o,values:n.values})},tickMinStep:Dx,title:({axis:e,model:t,channel:n})=>{if(e.title!==void 0)return e.title;const i=Cd(t,n);if(i!==void 0)return i;const r=t.typedFieldDef(n),s=n==="x"?"x2":"y2",o=t.fieldDef(s);return mu(r?[yc(r)]:[],v(o)?[yc(o)]:[])},values:({axis:e,fieldOrDatumDef:t})=>Mx(e,t),zindex:({axis:e,fieldOrDatumDef:t,mark:n})=>e.zindex??jx(n,t)};function Ox(e,t){return !ye(e)&&v(t)&&!ee(t?.bin)&&!xe(t?.bin)}function _x(e,t){const n=t==="x"?"y":"x";if(e.getScaleComponent(n))return e.scaleName(n)}function Rx(e,t,n,i,r){const s=t?.labelAngle;if(s!==void 0)return T(s)?s:Pi(s);{const{configValue:o}=ao("labelAngle",i,t?.style,r);return o!==void 0?Pi(o):n===se&&G([Yo,Xo],e.type)&&!(v(e)&&e.timeUnit)?270:void 0}}function co(e){return `(((${e.signal} % 360) + 360) % 360)`}function $d(e,t,n,i){if(e!==void 0)if(n==="x"){if(T(e)){const r=co(e),s=T(t)?`(${t.signal} === "top")`:t==="top";return {signal:`(45 < ${r} && ${r} < 135) || (225 < ${r} && ${r} < 315) ? "middle" :(${r} <= 45 || 315 <= ${r}) === ${s} ? "bottom" : "top"`}}if(45{if(Pn(i)&&tf(i.sort)){const{field:s,timeUnit:o}=i,a=i.sort,c=a.map((l,u)=>`${Pu({field:s,timeUnit:o,equal:l})} ? ${u} : `).join("")+a.length;t=new ci(t,{calculate:c,as:li(i,r,{forAs:!0})});}}),t}producedFields(){return new Set([this.transform.as])}dependentFields(){return this._dependentFields}assemble(){return {type:"formula",expr:this.transform.calculate,as:this.transform.as}}hash(){return `Calculate ${W(this.transform)}`}}function li(e,t,n){return E(e,{prefix:t,suffix:"sort_index",...n})}function us(e,t){return G(["top","bottom"],t)?"column":G(["left","right"],t)||e==="row"?"row":"column"}function ui(e,t,n,i){const r=i==="row"?n.headerRow:i==="column"?n.headerColumn:n.headerFacet;return le((t||{})[e],r[e],n.header[e])}function fs(e,t,n,i){const r={};for(const s of e){const o=ui(s,t||{},n,i);o!==void 0&&(r[s]=o);}return r}const Fa=["row","column"],ka=["header","footer"];function Ux(e,t){const n=e.component.layoutHeaders[t].title,i=e.config?e.config:void 0,r=e.component.layoutHeaders[t].facetFieldDef?e.component.layoutHeaders[t].facetFieldDef:void 0,{titleAnchor:s,titleAngle:o,titleOrient:a}=fs(["titleAnchor","titleAngle","titleOrient"],r.header,i,t),c=us(t,a),l=Pi(o);return {name:`${t}-title`,type:"group",role:`${c}-title`,title:{text:n,...t==="row"?{orient:"left"}:{},style:"guide-title",...Fd(l,c),...Nd(c,l,s),...kd(i,r,t,ky,Af)}}}function Nd(e,t,n="middle"){switch(n){case"start":return {align:"left"};case"end":return {align:"right"}}const i=wd(t,e==="row"?"left":"top",e==="row"?"y":"x");return i?{align:i}:{}}function Fd(e,t){const n=$d(e,t==="row"?"left":"top",t==="row"?"y":"x",!0);return n?{baseline:n}:{}}function Bx(e,t){const n=e.component.layoutHeaders[t],i=[];for(const r of ka)if(n[r])for(const s of n[r]){const o=Gx(e,t,r,n,s);o!=null&&i.push(o);}return i}function Wx(e,t){const{sort:n}=e;return ut(n)?{field:E(n,{expr:"datum"}),order:n.order??"ascending"}:U(n)?{field:li(e,t,{expr:"datum"}),order:"ascending"}:{field:E(e,{expr:"datum"}),order:n??"ascending"}}function lo(e,t,n){const{format:i,formatType:r,labelAngle:s,labelAnchor:o,labelOrient:a,labelExpr:c}=fs(["format","formatType","labelAngle","labelAnchor","labelOrient","labelExpr"],e.header,n,t),l=na({fieldOrDatumDef:e,format:i,formatType:r,expr:"parent",config:n}).signal,u=us(t,a);return {text:{signal:c?vn(vn(c,"datum.label",l),"datum.value",E(e,{expr:"parent"})):l},...t==="row"?{orient:"left"}:{},style:"guide-label",frame:"group",...Fd(s,u),...Nd(u,s,o),...kd(n,e,t,Ty,Of)}}function Gx(e,t,n,i,r){if(r){let s=null;const{facetFieldDef:o}=i,a=e.config?e.config:void 0;if(o&&r.labels){const{labelOrient:f}=fs(["labelOrient"],o.header,a,t);(t==="row"&&!G(["top","bottom"],f)||t==="column"&&!G(["left","right"],f))&&(s=lo(o,t,a));}const c=ze(e)&&!Ki(e.facet),l=r.axes,u=l?.length>0;if(s||u){const f=t==="row"?"height":"width";return {name:e.getName(`${t}_${n}`),type:"group",role:`${t}-${n}`,...i.facetFieldDef?{from:{data:e.getName(`${t}_domain`)},sort:Wx(o,t)}:{},...u&&c?{from:{data:e.getName(`facet_domain_${t}`)}}:{},...s?{title:s}:{},...r.sizeSignal?{encode:{update:{[f]:r.sizeSignal}}}:{},...u?{axes:l}:{}}}}return null}const Hx={column:{start:0,end:1},row:{start:1,end:0}};function qx(e,t){return Hx[t][e]}function Vx(e,t){const n={};for(const i of je){const r=e[i];if(r?.facetFieldDef){const{titleAnchor:s,titleOrient:o}=fs(["titleAnchor","titleOrient"],r.facetFieldDef.header,t,i),a=us(i,o),c=qx(s,a);c!==void 0&&(n[a]=c);}}return K(n)?void 0:n}function kd(e,t,n,i,r){const s={};for(const o of i){if(!r[o])continue;const a=ui(o,t?.header,e,n);a!==void 0&&(s[r[o]]=a);}return s}function Ta(e){return [...or(e,"width"),...or(e,"height"),...or(e,"childWidth"),...or(e,"childHeight")]}function or(e,t){const n=t==="width"?"x":"y",i=e.component.layoutSize.get(t);if(!i||i==="merged")return [];const r=e.getSizeSignalRef(t).signal;if(i==="step"){const s=e.getScaleComponent(n);if(s){const o=s.get("type"),a=s.get("range");if(ye(o)&&nn(a)){const c=e.scaleName(n);return ze(e.parent)&&e.parent.component.resolve.scale[n]==="independent"?[Xc(c,a)]:[Xc(c,a),{name:r,update:Td(c,s,`domain('${c}').length`)}]}}throw new Error("layout size is step although width/height is not step.")}else if(i=="container"){const s=r.endsWith("width"),o=s?"containerSize()[0]":"containerSize()[1]",a=to(e.config.view,s?"width":"height"),c=`isFinite(${o}) ? ${o} : ${a}`;return [{name:r,init:c,on:[{update:c,events:"window:resize"}]}]}else return [{name:r,value:i}]}function Xc(e,t){const n=`${e}_step`;return T(t.step)?{name:n,update:t.step.signal}:{name:n,value:t.step}}function Td(e,t,n){const i=t.get("type"),r=t.get("padding"),s=le(t.get("paddingOuter"),r);let o=t.get("paddingInner");return o=i==="band"?o!==void 0?o:r:1,`bandspace(${n}, ${Xe(o)}, ${Xe(s)}) * ${e}_step`}function Ad(e){return e==="childWidth"?"width":e==="childHeight"?"height":e}function Od(e,t){return x(e).reduce((n,i)=>{const r=e[i];return {...n,...mi(t,r,i,s=>ne(s.value))}},{})}function _d(e,t){if(ze(t))return e==="theta"?"independent":"shared";if(Si(t))return "shared";if(Pa(t))return ue(e)||e==="theta"||e==="radius"?"independent":"shared";throw new Error("invalid model type for resolve")}function Aa(e,t){const n=e.scale[t],i=ue(t)?"axis":"legend";return n==="independent"?(e[i][t]==="shared"&&S(Ch(t)),"independent"):e[i][t]||"shared"}const Xx={..._y,disable:1,labelExpr:1,selections:1,opacity:1,shape:1,stroke:1,fill:1,size:1,strokeWidth:1,strokeDash:1,encode:1},Rd=x(Xx);class Yx extends Dt{}const Yc={symbols:Kx,gradient:Jx,labels:Qx,entries:Zx};function Kx(e,{fieldOrDatumDef:t,model:n,channel:i,legendCmpt:r,legendType:s}){if(s!=="symbol")return;const{markDef:o,encoding:a,config:c,mark:l}=n,u=o.filled&&l!=="trail";let f={...Pg({},n,km),...sd(n,{filled:u})};const d=r.get("symbolOpacity")??c.legend.symbolOpacity,g=r.get("symbolFillColor")??c.legend.symbolFillColor,p=r.get("symbolStrokeColor")??c.legend.symbolStrokeColor,h=d===void 0?Id(a.opacity)??o.opacity:void 0;if(f.fill){if(i==="fill"||u&&i===Ae)delete f.fill;else if(f.fill.field)g?delete f.fill:(f.fill=ne(c.legend.symbolBaseFillColor??"black"),f.fillOpacity=ne(h??1));else if(U(f.fill)){const m=uo(a.fill??a.color)??o.fill??(u&&o.color);m&&(f.fill=ne(m));}}if(f.stroke){if(i==="stroke"||!u&&i===Ae)delete f.stroke;else if(f.stroke.field||p)delete f.stroke;else if(U(f.stroke)){const m=le(uo(a.stroke||a.color),o.stroke,u?o.color:void 0);m&&(f.stroke={value:m});}}if(i!==Lt){const m=v(t)&&Pd(n,r,t);m?f.opacity=[{test:m,...ne(h??1)},ne(c.legend.unselectedOpacity)]:h&&(f.opacity=ne(h));}return f={...f,...e},K(f)?void 0:f}function Jx(e,{model:t,legendType:n,legendCmpt:i}){if(n!=="gradient")return;const{config:r,markDef:s,encoding:o}=t;let a={};const l=(i.get("gradientOpacity")??r.legend.gradientOpacity)===void 0?Id(o.opacity)||s.opacity:void 0;return l&&(a.opacity=ne(l)),a={...a,...e},K(a)?void 0:a}function Qx(e,{fieldOrDatumDef:t,model:n,channel:i,legendCmpt:r}){const s=n.legend(i)||{},o=n.config,a=v(t)?Pd(n,r,t):void 0,c=a?[{test:a,value:1},{value:o.legend.unselectedOpacity}]:void 0,{format:l,formatType:u}=s;let f;Nn(u)?f=Ke({fieldOrDatumDef:t,field:"datum.value",format:l,formatType:u,config:o}):l===void 0&&u===void 0&&o.customFormatTypes&&(t.type==="quantitative"&&o.numberFormatType?f=Ke({fieldOrDatumDef:t,field:"datum.value",format:o.numberFormat,formatType:o.numberFormatType,config:o}):t.type==="temporal"&&o.timeFormatType&&v(t)&&t.timeUnit===void 0&&(f=Ke({fieldOrDatumDef:t,field:"datum.value",format:o.timeFormat,formatType:o.timeFormatType,config:o})));const d={...c?{opacity:c}:{},...f?{text:f}:{},...e};return K(d)?void 0:d}function Zx(e,{legendCmpt:t}){return t.get("selections")?.length?{...e,fill:{value:"transparent"}}:e}function Id(e){return Ld(e,(t,n)=>Math.max(t,n.value))}function uo(e){return Ld(e,(t,n)=>le(t,n.value))}function Ld(e,t){if(Xm(e))return H(e.condition).reduce(t,e.value);if(Qe(e))return e.value}function Pd(e,t,n){const i=t.get("selections");if(!i?.length)return;const r=Y$1(n.field);return i.map(s=>`(!length(data(${Y$1(re(s)+kn)})) || (${s}[${r}] && indexof(${s}[${r}], datum.value) >= 0))`).join(" || ")}const Kc={direction:({direction:e})=>e,format:({fieldOrDatumDef:e,legend:t,config:n})=>{const{format:i,formatType:r}=t;return Ju(e,e.type,i,r,n,!1)},formatType:({legend:e,fieldOrDatumDef:t,scaleType:n})=>{const{formatType:i}=e;return Qu(i,t,n)},gradientLength:e=>{const{legend:t,legendConfig:n}=e;return t.gradientLength??n.gradientLength??oS(e)},labelOverlap:({legend:e,legendConfig:t,scaleType:n})=>e.labelOverlap??t.labelOverlap??aS(n),symbolType:({legend:e,markDef:t,channel:n,encoding:i})=>e.symbolType??tS(t.type,n,i.shape,t.shape),title:({fieldOrDatumDef:e,config:t})=>Vn(e,t,{allowDisabling:!0}),type:({legendType:e,scaleType:t,channel:n})=>{if(qn(n)&&Ye(t)){if(e==="gradient")return}else if(e==="symbol")return;return e},values:({fieldOrDatumDef:e,legend:t})=>eS(t,e)};function eS(e,t){const n=e.values;if(U(n))return df(t,n);if(T(n))return n}function tS(e,t,n,i){if(t!=="shape"){const r=uo(n)??i;if(r)return r}switch(e){case"bar":case"rect":case"image":case"square":return "square";case"line":case"trail":case"rule":return "stroke";case"arc":case"point":case"circle":case"tick":case"geoshape":case"area":case"text":return "circle"}}function nS(e){const{legend:t}=e;return le(t.type,iS(e))}function iS({channel:e,timeUnit:t,scaleType:n}){if(qn(e)){if(G(["quarter","month","day"],t))return "symbol";if(Ye(n))return "gradient"}return "symbol"}function rS({legendConfig:e,legendType:t,orient:n,legend:i}){return i.direction??e[t?"gradientDirection":"symbolDirection"]??sS(n,t)}function sS(e,t){switch(e){case"top":case"bottom":return "horizontal";case"left":case"right":case"none":case void 0:return;default:return t==="gradient"?"horizontal":void 0}}function oS({legendConfig:e,model:t,direction:n,orient:i,scaleType:r}){const{gradientHorizontalMaxLength:s,gradientHorizontalMinLength:o,gradientVerticalMaxLength:a,gradientVerticalMinLength:c}=e;if(Ye(r))return n==="horizontal"?i==="top"||i==="bottom"?Jc(t,"width",o,s):o:Jc(t,"height",c,a)}function Jc(e,t,n,i){return {signal:`clamp(${e.getSizeSignalRef(t).signal}, ${n}, ${i})`}}function aS(e){if(G(["quantile","threshold","log","symlog"],e))return "greedy"}function zd(e){const t=ae(e)?cS(e):dS(e);return e.component.legends=t,t}function cS(e){const{encoding:t}=e,n={};for(const i of [Ae,...Rf]){const r=fe(t[i]);!r||!e.getScaleComponent(i)||i===Oe&&v(r)&&r.type===hi||(n[i]=fS(e,i));}return n}function lS(e,t){const n=e.scaleName(t);if(e.mark==="trail"){if(t==="color")return {stroke:n};if(t==="size")return {strokeWidth:n}}return t==="color"?e.markDef.filled?{fill:n}:{stroke:n}:{[t]:n}}function uS(e,t,n,i){switch(t){case"disable":return n!==void 0;case"values":return !!n?.values;case"title":if(t==="title"&&e===i?.title)return !0}return e===(n||{})[t]}function fS(e,t){let n=e.legend(t);const{markDef:i,encoding:r,config:s}=e,o=s.legend,a=new Yx({},lS(e,t));Sx(e,t,a);const c=n!==void 0?!n:o.disable;if(a.set("disable",c,n!==void 0),c)return a;n=n||{};const l=e.getScaleComponent(t).get("type"),u=fe(r[t]),f=v(u)?me(u.timeUnit)?.unit:void 0,d=n.orient||s.legend.orient||"right",g=nS({legend:n,channel:t,timeUnit:f,scaleType:l}),p=rS({legend:n,legendType:g,orient:d,legendConfig:o}),h={legend:n,channel:t,model:e,markDef:i,encoding:r,fieldOrDatumDef:u,legendConfig:o,config:s,scaleType:l,orient:d,legendType:g,direction:p};for(const k of Rd){if(g==="gradient"&&k.startsWith("symbol")||g==="symbol"&&k.startsWith("gradient"))continue;const N=k in Kc?Kc[k](h):n[k];if(N!==void 0){const _=uS(N,k,n,e.fieldDef(t));(_||s.legend[k]===void 0)&&a.set(k,N,_);}}const m=n?.encoding??{},y=a.get("selections"),b={},C={fieldOrDatumDef:u,model:e,channel:t,legendCmpt:a,legendType:g};for(const k of ["labels","legend","title","symbols","gradient","entries"]){const N=Od(m[k]??{},e),_=k in Yc?Yc[k](N,C):N;_!==void 0&&!K(_)&&(b[k]={...y?.length&&v(u)?{name:`${re(u.field)}_legend_${k}`}:{},...y?.length?{interactive:!!y}:{},update:_});}return K(b)||a.set("encode",b,!!n?.encoding),a}function dS(e){const{legends:t,resolve:n}=e.component;for(const i of e.children){zd(i);for(const r of x(i.component.legends))n.legend[r]=Aa(e.component.resolve,r),n.legend[r]==="shared"&&(t[r]=Dd(t[r],i.component.legends[r]),t[r]||(n.legend[r]="independent",delete t[r]));}for(const i of x(t))for(const r of e.children)r.component.legends[i]&&n.legend[i]==="shared"&&delete r.component.legends[i];return t}function Dd(e,t){if(!e)return t.clone();const n=e.getWithExplicit("orient"),i=t.getWithExplicit("orient");if(n.explicit&&i.explicit&&n.value!==i.value)return;let r=!1;for(const s of Rd){const o=qt(e.getWithExplicit(s),t.getWithExplicit(s),s,"legend",(a,c)=>{switch(s){case"symbolType":return pS(a,c);case"title":return bu(a,c);case"type":return r=!0,Ie("symbol")}return ss(a,c,s,"legend")});e.setWithExplicit(s,o);}return r&&(e.implicit?.encode?.gradient&&hr(e.implicit,["encode","gradient"]),e.explicit?.encode?.gradient&&hr(e.explicit,["encode","gradient"])),e}function pS(e,t){return t.value==="circle"?t:e}function gS(e,t,n,i){var r,s;e.encode??(e.encode={}),(r=e.encode)[t]??(r[t]={}),(s=e.encode[t]).update??(s.update={}),e.encode[t].update[n]=i;}function Md(e){const t=e.component.legends,n={};for(const r of x(t)){const s=e.getScaleComponent(r),o=J(s.get("domains"));if(n[o])for(const a of n[o])Dd(a,t[r])||n[o].push(t[r]);else n[o]=[t[r].clone()];}return Se(n).flat().map(r=>hS(r,e.config)).filter(r=>r!==void 0)}function hS(e,t){const{disable:n,labelExpr:i,selections:r,...s}=e.combine();if(!n){if(t.aria===!1&&s.aria==null&&(s.aria=!1),s.encode?.symbols){const o=s.encode.symbols.update;o.fill&&o.fill.value!=="transparent"&&!o.stroke&&!s.stroke&&(o.stroke={value:"transparent"});for(const a of Rf)s[a]&&delete o[a];}if(s.title||delete s.title,i!==void 0){let o=i;s.encode?.labels?.update&&T(s.encode.labels.update.text)&&(o=vn(i,"datum.label",s.encode.labels.update.text.signal)),gS(s,"labels","text",{signal:o});}return s}}function mS(e){return Si(e)||Pa(e)?yS(e):jd(e)}function yS(e){return e.children.reduce((t,n)=>t.concat(n.assembleProjections()),jd(e))}function jd(e){const t=e.component.projection;if(!t||t.merged)return [];const n=t.combine(),{name:i}=n;if(t.data){const r={signal:`[${t.size.map(o=>o.signal).join(", ")}]`},s=t.data.reduce((o,a)=>{const c=T(a)?a.signal:`data('${e.lookupDataSource(a)}')`;return G(o,c)||o.push(c),o},[]);if(s.length<=0)throw new Error("Projection's fit didn't find any data sources");return [{name:i,size:r,fit:{signal:s.length>1?`[${s.join(", ")}]`:s[0]},...n}]}else return [{name:i,translate:{signal:"[width / 2, height / 2]"},...n}]}const bS=["type","clipAngle","clipExtent","center","rotate","precision","reflectX","reflectY","coefficient","distance","fraction","lobes","parallel","radius","ratio","spacing","tilt"];class Ud extends Dt{constructor(t,n,i,r){super({...n},{name:t}),this.specifiedProjection=n,this.size=i,this.data=r,this.merged=!1;}get isFit(){return !!this.data}}function Bd(e){e.component.projection=ae(e)?xS(e):ES(e);}function xS(e){if(e.hasProjection){const t=Fe(e.specifiedProjection),n=!(t&&(t.scale!=null||t.translate!=null)),i=n?[e.getSizeSignalRef("width"),e.getSizeSignalRef("height")]:void 0,r=n?SS(e):void 0,s=new Ud(e.projectionName(!0),{...Fe(e.config.projection),...t},i,r);return s.get("type")||s.set("type","equalEarth",!1),s}}function SS(e){const t=[],{encoding:n}=e;for(const i of [[it,nt],[Be,rt]])(fe(n[i[0]])||fe(n[i[1]]))&&t.push({signal:e.getName(`geojson_${t.length}`)});return e.channelHasField(Oe)&&e.typedFieldDef(Oe).type===hi&&t.push({signal:e.getName(`geojson_${t.length}`)}),t.length===0&&t.push(e.requestDataName(Z.Main)),t}function vS(e,t){const n=Eo(bS,r=>!!(!X$1(e.explicit,r)&&!X$1(t.explicit,r)||X$1(e.explicit,r)&&X$1(t.explicit,r)&&Pe(e.get(r),t.get(r))));if(Pe(e.size,t.size)){if(n)return e;if(Pe(e.explicit,{}))return t;if(Pe(t.explicit,{}))return e}return null}function ES(e){if(e.children.length===0)return;let t;for(const i of e.children)Bd(i);const n=Eo(e.children,i=>{const r=i.component.projection;if(r)if(t){const s=vS(t,r);return s&&(t=s),!!s}else return t=r,!0;else return !0});if(t&&n){const i=e.projectionName(!0),r=new Ud(i,t.specifiedProjection,t.size,z(t.data));for(const s of e.children){const o=s.component.projection;o&&(o.isFit&&r.data.push(...s.component.projection.data),s.renameProjection(o.get("name"),i),o.merged=!0);}return r}}function $S(e,t,n,i){if(Qi(t,n)){const r=ae(e)?e.axis(n)??e.legend(n)??{}:{},s=E(t,{expr:"datum"}),o=E(t,{expr:"datum",binSuffix:"end"});return {formulaAs:E(t,{binSuffix:"range",forAs:!0}),formula:Yi(s,o,r.format,r.formatType,i)}}return {}}function Wd(e,t){return `${uu(e)}_${t}`}function wS(e,t){return {signal:e.getName(`${t}_bins`),extentSignal:e.getName(`${t}_extent`)}}function Oa(e,t,n){const i=Zr(n,void 0)??{},r=Wd(i,t);return e.getName(`${r}_bins`)}function CS(e){return "as"in e}function Qc(e,t,n){let i,r;CS(e)?i=xt$1(e.as)?[e.as,`${e.as}_end`]:[e.as[0],e.as[1]]:i=[E(e,{forAs:!0}),E(e,{binSuffix:"end",forAs:!0})];const s={...Zr(t,void 0)},o=Wd(s,e.field),{signal:a,extentSignal:c}=wS(n,o);if(Br(s.extent)){const u=s.extent;r=vd(n,u.param,u),delete s.extent;}const l={bin:s,field:e.field,as:[i],...a?{signal:a}:{},...c?{extentSignal:c}:{},...r?{span:r}:{}};return {key:o,binComponent:l}}class dt extends Y{clone(){return new dt(null,z(this.bins))}constructor(t,n){super(t),this.bins=n;}static makeFromEncoding(t,n){const i=n.reduceFieldDef((r,s,o)=>{if(Ce(s)&&ee(s.bin)){const{key:a,binComponent:c}=Qc(s,s.bin,n);r[a]={...c,...r[a],...$S(n,s,o,n.config)};}return r},{});return K(i)?null:new dt(t,i)}static makeFromTransform(t,n,i){const{key:r,binComponent:s}=Qc(n,n.bin,i);return new dt(t,{[r]:s})}merge(t,n){for(const i of x(t.bins))i in this.bins?(n(t.bins[i].signal,this.bins[i].signal),this.bins[i].as=lt([...this.bins[i].as,...t.bins[i].as],W)):this.bins[i]=t.bins[i];for(const i of t.children)t.removeChild(i),i.parent=this;t.remove();}producedFields(){return new Set(Se(this.bins).map(t=>t.as).flat(2))}dependentFields(){return new Set(Se(this.bins).map(t=>t.field))}hash(){return `Bin ${W(this.bins)}`}assemble(){return Se(this.bins).flatMap(t=>{const n=[],[i,...r]=t.as,{extent:s,...o}=t.bin,a={type:"bin",field:Ue(t.field),as:i,signal:t.signal,...Br(s)?{extent:null}:{extent:s},...t.span?{span:{signal:`span(${t.span})`}}:{},...o};!s&&t.extentSignal&&(n.push({type:"extent",field:Ue(t.field),signal:t.extentSignal}),a.extent={signal:t.extentSignal}),n.push(a);for(const c of r)for(let l=0;l<2;l++)n.push({type:"formula",expr:E({field:i[l]},{expr:"datum"}),as:c[l]});return t.formula&&n.push({type:"formula",expr:t.formula,as:t.formulaAs}),n})}}function NS(e,t,n,i){const r=ae(i)?i.encoding[xt(t)]:void 0;if(Ce(n)&&ae(i)&&rf(n,r,i.markDef,i.config)){e.add(E(n,{})),e.add(E(n,{suffix:"end"}));const{mark:s,markDef:o,config:a}=i,c=Ht({fieldDef:n,markDef:o,config:a});zi(s)&&c!==.5&&ue(t)&&(e.add(E(n,{suffix:os})),e.add(E(n,{suffix:as}))),n.bin&&Qi(n,t)&&e.add(E(n,{binSuffix:"range"}));}else if(eu(t)){const s=Zl(t);e.add(i.getName(s));}else e.add(E(n));return Pn(n)&&mm(n.scale?.range)&&e.add(n.scale.range.field),e}function FS(e,t){for(const n of x(t)){const i=t[n];for(const r of x(i))n in e?e[n][r]=new Set([...e[n][r]??[],...i[r]]):e[n]={[r]:i[r]};}}class Je extends Y{clone(){return new Je(null,new Set(this.dimensions),z(this.measures))}constructor(t,n,i){super(t),this.dimensions=n,this.measures=i;}get groupBy(){return this.dimensions}static makeFromEncoding(t,n){let i=!1;n.forEachFieldDef(o=>{o.aggregate&&(i=!0);});const r={},s=new Set;return !i||(n.forEachFieldDef((o,a)=>{const{aggregate:c,field:l}=o;if(c)if(c==="count")r["*"]??(r["*"]={}),r["*"].count=new Set([E(o,{forAs:!0})]);else {if(At(c)||tn(c)){const u=At(c)?"argmin":"argmax",f=c[u];r[f]??(r[f]={}),r[f][u]=new Set([E({op:u,field:f},{forAs:!0})]);}else r[l]??(r[l]={}),r[l][c]=new Set([E(o,{forAs:!0})]);Pt(a)&&n.scaleDomain(a)==="unaggregated"&&(r[l]??(r[l]={}),r[l].min=new Set([E({field:l,aggregate:"min"},{forAs:!0})]),r[l].max=new Set([E({field:l,aggregate:"max"},{forAs:!0})]));}else NS(s,a,o,n);}),s.size+x(r).length===0)?null:new Je(t,s,r)}static makeFromTransform(t,n){const i=new Set,r={};for(const s of n.aggregate){const{op:o,field:a,as:c}=s;o&&(o==="count"?(r["*"]??(r["*"]={}),r["*"].count=new Set([c||E(s,{forAs:!0})])):(r[a]??(r[a]={}),r[a][o]=new Set([c||E(s,{forAs:!0})])));}for(const s of n.groupby??[])i.add(s);return i.size+x(r).length===0?null:new Je(t,i,r)}merge(t){return Hl(this.dimensions,t.dimensions)?(FS(this.measures,t.measures),!0):(Uh("different dimensions, cannot merge"),!1)}addDimensions(t){t.forEach(this.dimensions.add,this.dimensions);}dependentFields(){return new Set([...this.dimensions,...x(this.measures)])}producedFields(){const t=new Set;for(const n of x(this.measures))for(const i of x(this.measures[n])){const r=this.measures[n][i];r.size===0?t.add(`${i}_${n}`):r.forEach(t.add,t);}return t}hash(){return `Aggregate ${W({dimensions:this.dimensions,measures:this.measures})}`}assemble(){const t=[],n=[],i=[];for(const s of x(this.measures))for(const o of x(this.measures[s]))for(const a of this.measures[s][o])i.push(a),t.push(o),n.push(s==="*"?null:Ue(s));return {type:"aggregate",groupby:[...this.dimensions].map(Ue),ops:t,fields:n,as:i}}}class bi extends Y{constructor(t,n,i,r){super(t),this.model=n,this.name=i,this.data=r;for(const s of je){const o=n.facet[s];if(o){const{bin:a,sort:c}=o;this[s]={name:n.getName(`${s}_domain`),fields:[E(o),...ee(a)?[E(o,{binSuffix:"end"})]:[]],...ut(c)?{sortField:c}:U(c)?{sortIndexField:li(o,s)}:{}};}}this.childModel=n.child;}hash(){let t="Facet";for(const n of je)this[n]&&(t+=` ${n.charAt(0)}:${W(this[n])}`);return t}get fields(){const t=[];for(const n of je)this[n]?.fields&&t.push(...this[n].fields);return t}dependentFields(){const t=new Set(this.fields);for(const n of je)this[n]&&(this[n].sortField&&t.add(this[n].sortField.field),this[n].sortIndexField&&t.add(this[n].sortIndexField));return t}producedFields(){return new Set}getSource(){return this.name}getChildIndependentFieldsWithStep(){const t={};for(const n of St){const i=this.childModel.component.scales[n];if(i&&!i.merged){const r=i.get("type"),s=i.get("range");if(ye(r)&&nn(s)){const o=ds(this.childModel,n),a=La(o);a?t[n]=a:S(Po(n));}}}return t}assembleRowColumnHeaderData(t,n,i){const r={row:"y",column:"x",facet:void 0}[t],s=[],o=[],a=[];r&&i&&i[r]&&(n?(s.push(`distinct_${i[r]}`),o.push("max")):(s.push(i[r]),o.push("distinct")),a.push(`distinct_${i[r]}`));const{sortField:c,sortIndexField:l}=this[t];if(c){const{op:u=Yr,field:f}=c;s.push(f),o.push(u),a.push(E(c,{forAs:!0}));}else l&&(s.push(l),o.push("max"),a.push(l));return {name:this[t].name,source:n??this.data,transform:[{type:"aggregate",groupby:this[t].fields,...s.length?{fields:s,ops:o,as:a}:{}}]}}assembleFacetHeaderData(t){const{columns:n}=this.model.layout,{layoutHeaders:i}=this.model.component,r=[],s={};for(const c of Fa){for(const l of ka){const u=(i[c]&&i[c][l])??[];for(const f of u)if(f.axes?.length>0){s[c]=!0;break}}if(s[c]){const l=`length(data("${this.facet.name}"))`,u=c==="row"?n?{signal:`ceil(${l} / ${n})`}:1:n?{signal:`min(${l}, ${n})`}:{signal:l};r.push({name:`${this.facet.name}_${c}`,transform:[{type:"sequence",start:0,stop:u}]});}}const{row:o,column:a}=s;return (o||a)&&r.unshift(this.assembleRowColumnHeaderData("facet",null,t)),r}assemble(){const t=[];let n=null;const i=this.getChildIndependentFieldsWithStep(),{column:r,row:s,facet:o}=this;if(r&&s&&(i.x||i.y)){n=`cross_${this.column.name}_${this.row.name}`;const a=[].concat(i.x??[],i.y??[]),c=a.map(()=>"distinct");t.push({name:n,source:this.data,transform:[{type:"aggregate",groupby:this.fields,fields:a,ops:c}]});}for(const a of [Ft,Nt])this[a]&&t.push(this.assembleRowColumnHeaderData(a,n,i));if(o){const a=this.assembleFacetHeaderData(i);a&&t.push(...a);}return t}}function Zc(e){return e.startsWith("'")&&e.endsWith("'")||e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1):e}function kS(e,t){const n=Co(e);if(t==="number")return `toNumber(${n})`;if(t==="boolean")return `toBoolean(${n})`;if(t==="string")return `toString(${n})`;if(t==="date")return `toDate(${n})`;if(t==="flatten")return n;if(t.startsWith("date:")){const i=Zc(t.slice(5,t.length));return `timeParse(${n},'${i}')`}else if(t.startsWith("utc:")){const i=Zc(t.slice(4,t.length));return `utcParse(${n},'${i}')`}else return S(Kg(t)),null}function TS(e){const t={};return gr(e.filter,n=>{if(Lu(n)){let i=null;jo(n)?i=Le(n.equal):Bo(n)?i=Le(n.lte):Uo(n)?i=Le(n.lt):Wo(n)?i=Le(n.gt):Go(n)?i=Le(n.gte):Ho(n)?i=n.range[0]:qo(n)&&(i=(n.oneOf??n.in)[0]),i&&(In(i)?t[n.field]="date":Mr$1(i)?t[n.field]="number":xt$1(i)&&(t[n.field]="string")),n.timeUnit&&(t[n.field]="date");}}),t}function AS(e){const t={};function n(i){si(i)?t[i.field]="date":i.type==="quantitative"&&Fg(i.aggregate)?t[i.field]="number":Qn(i.field)>1?i.field in t||(t[i.field]="flatten"):Pn(i)&&ut(i.sort)&&Qn(i.sort.field)>1&&(i.sort.field in t||(t[i.sort.field]="flatten"));}if((ae(e)||ze(e))&&e.forEachFieldDef((i,r)=>{if(Ce(i))n(i);else {const s=_n(r),o=e.fieldDef(s);n({...i,type:o.type});}}),ae(e)){const{mark:i,markDef:r,encoding:s}=e;if(rn(i)&&!e.encoding.order){const o=r.orient==="horizontal"?"y":"x",a=s[o];v(a)&&a.type==="quantitative"&&!(a.field in t)&&(t[a.field]="number");}}return t}function OS(e){const t={};if(ae(e)&&e.component.selection)for(const n of x(e.component.selection)){const i=e.component.selection[n];for(const r of i.project.items)!r.channel&&Qn(r.field)>1&&(t[r.field]="flatten");}return t}class $e extends Y{clone(){return new $e(null,z(this._parse))}constructor(t,n){super(t),this._parse=n;}hash(){return `Parse ${W(this._parse)}`}static makeExplicit(t,n,i){let r={};const s=n.data;return !Bt(s)&&s?.format?.parse&&(r=s.format.parse),this.makeWithAncestors(t,r,{},i)}static makeWithAncestors(t,n,i,r){for(const a of x(i)){const c=r.getWithExplicit(a);c.value!==void 0&&(c.explicit||c.value===i[a]||c.value==="derived"||i[a]==="flatten"?delete i[a]:S(lc(a,i[a],c.value)));}for(const a of x(n)){const c=r.get(a);c!==void 0&&(c===n[a]?delete n[a]:S(lc(a,n[a],c)));}const s=new Dt(n,i);r.copyAll(s);const o={};for(const a of x(s.combine())){const c=s.get(a);c!==null&&(o[a]=c);}return x(o).length===0||r.parseNothing?null:new $e(t,o)}get parse(){return this._parse}merge(t){this._parse={...this._parse,...t.parse},t.remove();}assembleFormatParse(){const t={};for(const n of x(this._parse)){const i=this._parse[n];Qn(n)===1&&(t[n]=i);}return t}producedFields(){return new Set(x(this._parse))}dependentFields(){return new Set(x(this._parse))}assembleTransforms(t=!1){return x(this._parse).filter(n=>t?Qn(n)>1:!0).map(n=>{const i=kS(n,this._parse[n]);return i?{type:"formula",expr:i,as:No(n)}:null}).filter(n=>n!==null)}}class Yt extends Y{clone(){return new Yt(null)}constructor(t){super(t);}dependentFields(){return new Set}producedFields(){return new Set([Ze])}hash(){return "Identifier"}assemble(){return {type:"identifier",as:Ze}}}class tr extends Y{clone(){return new tr(null,this.params)}constructor(t,n){super(t),this.params=n;}dependentFields(){return new Set}producedFields(){}hash(){return `Graticule ${W(this.params)}`}assemble(){return {type:"graticule",...this.params===!0?{}:this.params}}}class nr extends Y{clone(){return new nr(null,this.params)}constructor(t,n){super(t),this.params=n;}dependentFields(){return new Set}producedFields(){return new Set([this.params.as??"data"])}hash(){return `Hash ${W(this.params)}`}assemble(){return {type:"sequence",...this.params}}}class Tn extends Y{constructor(t){super(null),t??(t={name:"source"});let n;if(Bt(t)||(n=t.format?{...ke(t.format,["parse"])}:{}),Di(t))this._data={values:t.values};else if(oi(t)){if(this._data={url:t.url},!n.type){let i=/(?:\.([^.]+))?$/.exec(t.url)[1];G(["json","csv","tsv","dsv","topojson"],i)||(i="json"),n.type=i;}}else Jf(t)?this._data={values:[{type:"Sphere"}]}:(Yf(t)||Bt(t))&&(this._data={});this._generator=Bt(t),t.name&&(this._name=t.name),n&&!K(n)&&(this._data.format=n);}dependentFields(){return new Set}producedFields(){}get data(){return this._data}hasName(){return !!this._name}get isGenerator(){return this._generator}get dataName(){return this._name}set dataName(t){this._name=t;}set parent(t){throw new Error("Source nodes have to be roots.")}remove(){throw new Error("Source nodes are roots and cannot be removed.")}hash(){throw new Error("Cannot hash sources")}assemble(){return {name:this._name,...this._data,transform:[]}}}var el=function(e,t,n,i,r){if(typeof t=="function"?e!==t||!r:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return t.set(e,n),n},_S=function(e,t,n,i){if(n==="a"&&!i)throw new TypeError("Private accessor was defined without a getter");if(typeof t=="function"?e!==t||!i:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return n==="m"?i:n==="a"?i.call(e):i?i.value:t.get(e)},Ti;function _a(e){return e instanceof Tn||e instanceof tr||e instanceof nr}class Ra{constructor(){Ti.set(this,void 0),el(this,Ti,!1);}setModified(){el(this,Ti,!0);}get modifiedFlag(){return _S(this,Ti,"f")}}Ti=new WeakMap;class zn extends Ra{getNodeDepths(t,n,i){i.set(t,n);for(const r of t.children)this.getNodeDepths(r,n+1,i);return i}optimize(t){const i=[...this.getNodeDepths(t,0,new Map).entries()].sort((r,s)=>s[1]-r[1]);for(const r of i)this.run(r[0]);return this.modifiedFlag}}class Ia extends Ra{optimize(t){this.run(t);for(const n of t.children)this.optimize(n);return this.modifiedFlag}}class RS extends Ia{mergeNodes(t,n){const i=n.shift();for(const r of n)t.removeChild(r),r.parent=i,r.remove();}run(t){const n=t.children.map(r=>r.hash()),i={};for(let r=0;r1&&(this.setModified(),this.mergeNodes(t,i[r]));}}class IS extends Ia{constructor(t){super(),this.requiresSelectionId=t&&Na(t);}run(t){t instanceof Yt&&(this.requiresSelectionId&&(_a(t.parent)||t.parent instanceof Je||t.parent instanceof $e)||(this.setModified(),t.remove()));}}class LS extends Ra{optimize(t){return this.run(t,new Set),this.modifiedFlag}run(t,n){let i=new Set;t instanceof ft&&(i=t.producedFields(),$o(i,n)&&(this.setModified(),t.removeFormulas(n),t.producedFields.length===0&&t.remove()));for(const r of t.children)this.run(r,new Set([...n,...i]));}}class PS extends Ia{constructor(){super();}run(t){t instanceof we&&!t.isRequired()&&(this.setModified(),t.remove());}}class zS extends zn{run(t){if(!_a(t)&&!(t.numChildren()>1)){for(const n of t.children)if(n instanceof $e)if(t instanceof $e)this.setModified(),t.merge(n);else {if(wo(t.producedFields(),n.dependentFields()))continue;this.setModified(),n.swapWithParent();}}}}class DS extends zn{run(t){const n=[...t.children],i=t.children.filter(r=>r instanceof $e);if(t.numChildren()>1&&i.length>=1){const r={},s=new Set;for(const o of i){const a=o.parse;for(const c of x(a))c in r?r[c]!==a[c]&&s.add(c):r[c]=a[c];}for(const o of s)delete r[o];if(!K(r)){this.setModified();const o=new $e(t,r);for(const a of n){if(a instanceof $e)for(const c of x(r))delete a.parse[c];t.removeChild(a),a.parent=o,a instanceof $e&&x(a.parse).length===0&&a.remove();}}}}}class MS extends zn{run(t){t instanceof we||t.numChildren()>0||t instanceof bi||t instanceof Tn||(this.setModified(),t.remove());}}class jS extends zn{run(t){const n=t.children.filter(r=>r instanceof ft),i=n.pop();for(const r of n)this.setModified(),i.merge(r);}}class US extends zn{run(t){const n=t.children.filter(r=>r instanceof Je),i={};for(const r of n){const s=W(r.groupBy);s in i||(i[s]=[]),i[s].push(r);}for(const r of x(i)){const s=i[r];if(s.length>1){const o=s.pop();for(const a of s)o.merge(a)&&(t.removeChild(a),a.parent=o,a.remove(),this.setModified());}}}}class BS extends zn{constructor(t){super(),this.model=t;}run(t){const n=!(_a(t)||t instanceof yi||t instanceof $e||t instanceof Yt),i=[],r=[];for(const s of t.children)s instanceof dt&&(n&&!wo(t.producedFields(),s.dependentFields())?i.push(s):r.push(s));if(i.length>0){const s=i.pop();for(const o of i)s.merge(o,this.model.renameSignal.bind(this.model));this.setModified(),t instanceof dt?t.merge(s,this.model.renameSignal.bind(this.model)):s.swapWithParent();}if(r.length>1){const s=r.pop();for(const o of r)s.merge(o,this.model.renameSignal.bind(this.model));this.setModified();}}}class WS extends zn{run(t){const n=[...t.children];if(!Sn(n,o=>o instanceof we)||t.numChildren()<=1)return;const r=[];let s;for(const o of n)if(o instanceof we){let a=o;for(;a.numChildren()===1;){const[c]=a.children;if(c instanceof we)a=c;else break}r.push(...a.children),s?(t.removeChild(o),o.parent=s.parent,s.parent.removeChild(s),s.parent=a,this.setModified()):s=a;}else r.push(o);if(r.length){this.setModified();for(const o of r)o.parent.removeChild(o),o.parent=s;}}}class Dn extends Y{clone(){return new Dn(null,z(this.transform))}constructor(t,n){super(t),this.transform=n;}addDimensions(t){this.transform.groupby=lt(this.transform.groupby.concat(t),n=>n);}dependentFields(){const t=new Set;return this.transform.groupby&&this.transform.groupby.forEach(t.add,t),this.transform.joinaggregate.map(n=>n.field).filter(n=>n!==void 0).forEach(t.add,t),t}producedFields(){return new Set(this.transform.joinaggregate.map(this.getDefaultName))}getDefaultName(t){return t.as??E(t)}hash(){return `JoinAggregateTransform ${W(this.transform)}`}assemble(){const t=[],n=[],i=[];for(const s of this.transform.joinaggregate)n.push(s.op),i.push(this.getDefaultName(s)),t.push(s.field===void 0?null:s.field);const r=this.transform.groupby;return {type:"joinaggregate",as:i,ops:n,fields:t,...r!==void 0?{groupby:r}:{}}}}function GS(e){return e.stack.stackBy.reduce((t,n)=>{const i=n.fieldDef,r=E(i);return r&&t.push(r),t},[])}function HS(e){return U(e)&&e.every(t=>xt$1(t))&&e.length>1}class Tt extends Y{clone(){return new Tt(null,z(this._stack))}constructor(t,n){super(t),this._stack=n;}static makeFromTransform(t,n){const{stack:i,groupby:r,as:s,offset:o="zero"}=n,a=[],c=[];if(n.sort!==void 0)for(const f of n.sort)a.push(f.field),c.push(le(f.order,"ascending"));const l={field:a,order:c};let u;return HS(s)?u=s:xt$1(s)?u=[s,`${s}_end`]:u=[`${n.stack}_start`,`${n.stack}_end`],new Tt(t,{dimensionFieldDefs:[],stackField:i,groupby:r,offset:o,sort:l,facetby:[],as:u})}static makeFromEncoding(t,n){const i=n.stack,{encoding:r}=n;if(!i)return null;const{groupbyChannels:s,fieldChannel:o,offset:a,impute:c}=i,l=s.map(g=>{const p=r[g];return gt(p)}).filter(g=>!!g),u=GS(n),f=n.encoding.order;let d;if(U(f)||v(f))d=hu(f);else {const g=sf(f)?f.sort:o==="y"?"descending":"ascending";d=u.reduce((p,h)=>(p.field.includes(h)||(p.field.push(h),p.order.push(g)),p),{field:[],order:[]});}return new Tt(t,{dimensionFieldDefs:l,stackField:n.vgField(o),facetby:[],stackby:u,sort:d,offset:a,impute:c,as:[n.vgField(o,{suffix:"start",forAs:!0}),n.vgField(o,{suffix:"end",forAs:!0})]})}get stack(){return this._stack}addDimensions(t){this._stack.facetby.push(...t);}dependentFields(){const t=new Set;return t.add(this._stack.stackField),this.getGroupbyFields().forEach(t.add,t),this._stack.facetby.forEach(t.add,t),this._stack.sort.field.forEach(t.add,t),t}producedFields(){return new Set(this._stack.as)}hash(){return `Stack ${W(this._stack)}`}getGroupbyFields(){const{dimensionFieldDefs:t,impute:n,groupby:i}=this._stack;return t.length>0?t.map(r=>r.bin?n?[E(r,{binSuffix:"mid"})]:[E(r,{}),E(r,{binSuffix:"end"})]:[E(r)]).flat():i??[]}assemble(){const t=[],{facetby:n,dimensionFieldDefs:i,stackField:r,stackby:s,sort:o,offset:a,impute:c,as:l}=this._stack;if(c)for(const u of i){const{bandPosition:f=.5,bin:d}=u;if(d){const g=E(u,{expr:"datum"}),p=E(u,{expr:"datum",binSuffix:"end"});t.push({type:"formula",expr:`${f}*${g}+${1-f}*${p}`,as:E(u,{binSuffix:"mid",forAs:!0})});}t.push({type:"impute",field:r,groupby:[...s,...n],key:E(u,{binSuffix:"mid"}),method:"value",value:0});}return t.push({type:"stack",groupby:[...this.getGroupbyFields(),...n],field:r,sort:o,as:l,offset:a}),t}}class xi extends Y{clone(){return new xi(null,z(this.transform))}constructor(t,n){super(t),this.transform=n;}addDimensions(t){this.transform.groupby=lt(this.transform.groupby.concat(t),n=>n);}dependentFields(){const t=new Set;return (this.transform.groupby??[]).forEach(t.add,t),(this.transform.sort??[]).forEach(n=>t.add(n.field)),this.transform.window.map(n=>n.field).filter(n=>n!==void 0).forEach(t.add,t),t}producedFields(){return new Set(this.transform.window.map(this.getDefaultName))}getDefaultName(t){return t.as??E(t)}hash(){return `WindowTransform ${W(this.transform)}`}assemble(){const t=[],n=[],i=[],r=[];for(const f of this.transform.window)n.push(f.op),i.push(this.getDefaultName(f)),r.push(f.param===void 0?null:f.param),t.push(f.field===void 0?null:f.field);const s=this.transform.frame,o=this.transform.groupby;if(s&&s[0]===null&&s[1]===null&&n.every(f=>Io(f)))return {type:"joinaggregate",as:i,ops:n,fields:t,...o!==void 0?{groupby:o}:{}};const a=[],c=[];if(this.transform.sort!==void 0)for(const f of this.transform.sort)a.push(f.field),c.push(f.order??"ascending");const l={field:a,order:c},u=this.transform.ignorePeers;return {type:"window",params:r,as:i,ops:n,fields:t,sort:l,...u!==void 0?{ignorePeers:u}:{},...o!==void 0?{groupby:o}:{},...s!==void 0?{frame:s}:{}}}}function qS(e){function t(n){if(!(n instanceof bi)){const i=n.clone();if(i instanceof we){const r=po+i.getSource();i.setSource(r),e.model.component.data.outputNodes[r]=i;}else (i instanceof Je||i instanceof Tt||i instanceof xi||i instanceof Dn)&&i.addDimensions(e.fields);for(const r of n.children.flatMap(t))r.parent=i;return [i]}return n.children.flatMap(t)}return t}function fo(e){if(e instanceof bi)if(e.numChildren()===1&&!(e.children[0]instanceof we)){const t=e.children[0];(t instanceof Je||t instanceof Tt||t instanceof xi||t instanceof Dn)&&t.addDimensions(e.fields),t.swapWithParent(),fo(e);}else {const t=e.model.component.data.main;Gd(t);const n=qS(e),i=e.children.map(n).flat();for(const r of i)r.parent=t;}else e.children.map(fo);}function Gd(e){if(e instanceof we&&e.type===Z.Main&&e.numChildren()===1){const t=e.children[0];t instanceof bi||(t.swapWithParent(),Gd(e));}}const po="scale_",ar=5;function go(e){for(const t of e){for(const n of t.children)if(n.parent!==t)return !1;if(!go(t.children))return !1}return !0}function He(e,t){let n=!1;for(const i of t)n=e.optimize(i)||n;return n}function tl(e,t,n){let i=e.sources,r=!1;return r=He(new PS,i)||r,r=He(new IS(t),i)||r,i=i.filter(s=>s.numChildren()>0),r=He(new MS,i)||r,i=i.filter(s=>s.numChildren()>0),n||(r=He(new zS,i)||r,r=He(new BS(t),i)||r,r=He(new LS,i)||r,r=He(new DS,i)||r,r=He(new US,i)||r,r=He(new jS,i)||r,r=He(new RS,i)||r,r=He(new WS,i)||r),e.sources=i,r}function VS(e,t){go(e.sources);let n=0,i=0;for(let r=0;rt(n))}}function Hd(e){ae(e)?XS(e):YS(e);}function XS(e){const t=e.component.scales;for(const n of x(t)){const i=JS(e,n);if(t[n].setWithExplicit("domains",i),ZS(e,n),e.component.data.isFaceted){let s=e;for(;!ze(s)&&s.parent;)s=s.parent;if(s.component.resolve.scale[n]==="shared")for(const a of i.value)Ct(a)&&(a.data=po+a.data.replace(po,""));}}}function YS(e){for(const n of e.children)Hd(n);const t=e.component.scales;for(const n of x(t)){let i,r=null;for(const s of e.children){const o=s.component.scales[n];if(o){i===void 0?i=o.getWithExplicit("domains"):i=qt(i,o.getWithExplicit("domains"),"domains","scale",ho);const a=o.get("selectionExtent");r&&a&&r.param!==a.param&&S(qg),r=a;}}t[n].setWithExplicit("domains",i),r&&t[n].set("selectionExtent",r,!0);}}function KS(e,t,n,i){if(e==="unaggregated"){const{valid:r,reason:s}=nl(t,n);if(!r){S(s);return}}else if(e===void 0&&i.useUnaggregatedDomain){const{valid:r}=nl(t,n);if(r)return "unaggregated"}return e}function JS(e,t){const n=e.getScaleComponent(t).get("type"),{encoding:i}=e,r=KS(e.scaleDomain(t),e.typedFieldDef(t),n,e.config.scale);return r!==e.scaleDomain(t)&&(e.specifiedScales[t]={...e.specifiedScales[t],domain:r}),t==="x"&&fe(i.x2)?fe(i.x)?qt(Mt(n,r,e,"x"),Mt(n,r,e,"x2"),"domain","scale",ho):Mt(n,r,e,"x2"):t==="y"&&fe(i.y2)?fe(i.y)?qt(Mt(n,r,e,"y"),Mt(n,r,e,"y2"),"domain","scale",ho):Mt(n,r,e,"y2"):Mt(n,r,e,t)}function QS(e,t,n){return e.map(i=>({signal:`{data: ${es(i,{timeUnit:n,type:t})}}`}))}function Ls(e,t,n){const i=me(n)?.unit;return t==="temporal"||i?QS(e,t,i):[e]}function Mt(e,t,n,i){const{encoding:r,markDef:s,mark:o,config:a,stack:c}=n,l=fe(r[i]),{type:u}=l,f=l.timeUnit;if(hm(t)){const p=Mt(e,void 0,n,i),h=Ls(t.unionWith,u,f);return ct([...h,...p.value])}else {if(T(t))return ct([t]);if(t&&t!=="unaggregated"&&!Bu(t))return ct(Ls(t,u,f))}if(c&&i===c.fieldChannel){if(c.offset==="normalize")return Ie([[0,1]]);const p=n.requestDataName(Z.Main);return Ie([{data:p,field:n.vgField(i,{suffix:"start"})},{data:p,field:n.vgField(i,{suffix:"end"})}])}const d=Pt(i)&&v(l)?ev(n,i,e):void 0;if(vt(l)){const p=Ls([l.datum],u,f);return Ie(p)}const g=l;if(t==="unaggregated"){const p=n.requestDataName(Z.Main),{field:h}=l;return Ie([{data:p,field:E({field:h,aggregate:"min"})},{data:p,field:E({field:h,aggregate:"max"})}])}else if(ee(g.bin)){if(ye(e))return Ie(e==="bin-ordinal"?[]:[{data:Li(d)?n.requestDataName(Z.Main):n.requestDataName(Z.Raw),field:n.vgField(i,Qi(g,i)?{binSuffix:"range"}:{}),sort:d===!0||!et$1(d)?{field:n.vgField(i,{}),op:"min"}:d}]);{const{bin:p}=g;if(ee(p)){const h=Oa(n,g.field,p);return Ie([new ge(()=>{const m=n.getSignalName(h);return `[${m}.start, ${m}.stop]`})])}else return Ie([{data:n.requestDataName(Z.Main),field:n.vgField(i,{})}])}}else if(g.timeUnit&&G(["time","utc"],e)){const p=r[xt(i)];if(rf(g,p,s,a)){const h=n.requestDataName(Z.Main),m=Ht({fieldDef:g,fieldDef2:p,markDef:s,config:a}),y=zi(o)&&m!==.5&&ue(i);return Ie([{data:h,field:n.vgField(i,y?{suffix:os}:{})},{data:h,field:n.vgField(i,{suffix:y?as:"end"})}])}}return Ie(d?[{data:Li(d)?n.requestDataName(Z.Main):n.requestDataName(Z.Raw),field:n.vgField(i),sort:d}]:[{data:n.requestDataName(Z.Main),field:n.vgField(i)}])}function Ps(e,t){const{op:n,field:i,order:r}=e;return {op:n??(t?"sum":Yr),...i?{field:Ue(i)}:{},...r?{order:r}:{}}}function ZS(e,t){const n=e.component.scales[t],i=e.specifiedScales[t].domain,r=e.fieldDef(t)?.bin,s=Bu(i)&&i,o=Rn(r)&&Br(r.extent)&&r.extent;(s||o)&&n.set("selectionExtent",s??o,!0);}function ev(e,t,n){if(!ye(n))return;const i=e.fieldDef(t),r=i.sort;if(tf(r))return {op:"min",field:li(i,t),order:"ascending"};const{stack:s}=e,o=s?new Set([...s.groupbyFields,...s.stackBy.map(a=>a.fieldDef.field)]):void 0;if(ut(r)){const a=s&&!o.has(r.field);return Ps(r,a)}else if(ef(r)){const{encoding:a,order:c}=r,l=e.fieldDef(a),{aggregate:u,field:f}=l,d=s&&!o.has(f);if(At(u)||tn(u))return Ps({field:E(l),order:c},d);if(Io(u)||!u)return Ps({op:u,field:f,order:c},d)}else {if(r==="descending")return {op:"min",field:e.vgField(t),order:"descending"};if(G(["ascending",void 0],r))return !0}}function nl(e,t){const{aggregate:n,type:i}=e;return n?xt$1(n)&&!Tg.has(n)?{valid:!1,reason:bh(n)}:i==="quantitative"&&t==="log"?{valid:!1,reason:xh(e)}:{valid:!0}:{valid:!1,reason:yh(e)}}function ho(e,t,n,i){return e.explicit&&t.explicit&&S(wh(n,i,e.value,t.value)),{explicit:e.explicit,value:[...e.value,...t.value]}}function tv(e){const t=lt(e.map(o=>{if(Ct(o)){const{sort:a,...c}=o;return c}return o}),W),n=lt(e.map(o=>{if(Ct(o)){const a=o.sort;return a!==void 0&&!Li(a)&&("op"in a&&a.op==="count"&&delete a.field,a.order==="ascending"&&delete a.order),a}}).filter(o=>o!==void 0),W);if(t.length===0)return;if(t.length===1){const o=e[0];if(Ct(o)&&n.length>0){let a=n[0];if(n.length>1){S(fc);const c=n.filter(l=>et$1(l)&&"op"in l&&l.op!=="min");n.every(l=>et$1(l)&&"op"in l)&&c.length===1?a=c[0]:a=!0;}else if(et$1(a)&&"field"in a){const c=a.field;o.field===c&&(a=a.order?{order:a.order}:!0);}return {...o,sort:a}}return o}const i=lt(n.map(o=>Li(o)||!("op"in o)||xt$1(o.op)&&o.op in Cg?o:(S(Nh(o)),!0)),W);let r;i.length===1?r=i[0]:i.length>1&&(S(fc),r=!0);const s=lt(e.map(o=>Ct(o)?o.data:null),o=>o);return s.length===1&&s[0]!==null?{data:s[0],fields:t.map(a=>a.field),...r?{sort:r}:{}}:{fields:t,...r?{sort:r}:{}}}function La(e){if(Ct(e)&&xt$1(e.field))return e.field;if(Ag(e)){let t;for(const n of e.fields)if(Ct(n)&&xt$1(n.field)){if(!t)t=n.field;else if(t!==n.field)return S(Fh),t}return S(kh),t}else if(Og(e)){S(Th);const t=e.fields[0];return xt$1(t)?t:void 0}}function ds(e,t){const i=e.component.scales[t].get("domains").map(r=>(Ct(r)&&(r.data=e.lookupDataSource(r.data)),r));return tv(i)}function qd(e){return Si(e)||Pa(e)?e.children.reduce((t,n)=>t.concat(qd(n)),il(e)):il(e)}function il(e){return x(e.component.scales).reduce((t,n)=>{const i=e.component.scales[n];if(i.merged)return t;const r=i.combine(),{name:s,type:o,selectionExtent:a,domains:c,range:l,reverse:u,...f}=r,d=nv(r.range,s,n,e),g=ds(e,n),p=a?Kb(e,a,i,g):null;return t.push({name:s,type:o,...g?{domain:g}:{},...p?{domainRaw:p}:{},range:d,...u!==void 0?{reverse:u}:{},...f}),t},[])}function nv(e,t,n,i){if(ue(n)){if(nn(e))return {step:{signal:`${t}_step`}}}else if(et$1(e)&&Ct(e))return {...e,data:i.lookupDataSource(e.data)};return e}class Vd extends Dt{constructor(t,n){super({},{name:t}),this.merged=!1,this.setWithExplicit("type",n);}domainDefinitelyIncludesZero(){return this.get("zero")!==!1?!0:Sn(this.get("domains"),t=>U(t)&&t.length===2&&Mr$1(t[0])&&t[0]<=0&&Mr$1(t[1])&&t[1]>=0)}}const iv=["range","scheme"];function rv(e){const t=e.component.scales;for(const n of Ur){const i=t[n];if(!i)continue;const r=sv(n,e);i.setWithExplicit("range",r);}}function rl(e,t){const n=e.fieldDef(t);if(n?.bin){const{bin:i,field:r}=n,s=_e(t),o=e.getName(s);if(et$1(i)&&i.binned&&i.step!==void 0)return new ge(()=>{const a=e.scaleName(t),c=`(domain("${a}")[1] - domain("${a}")[0]) / ${i.step}`;return `${e.getSignalName(o)} / (${c})`});if(ee(i)){const a=Oa(e,r,i);return new ge(()=>{const c=e.getSignalName(a),l=`(${c}.stop - ${c}.start) / ${c}.step`;return `${e.getSignalName(o)} / (${l})`})}}}function sv(e,t){const n=t.specifiedScales[e],{size:i}=t,s=t.getScaleComponent(e).get("type");for(const f of iv)if(n[f]!==void 0){const d=Qs(s,f),g=Wu(e,f);if(!d)S(Eu(s,f,e));else if(g)S(g);else switch(f){case"range":{const p=n.range;if(U(p)){if(ue(e))return ct(p.map(h=>{if(h==="width"||h==="height"){const m=t.getName(h),y=t.getSignalName.bind(t);return ge.fromName(y,m)}return h}))}else if(et$1(p))return ct({data:t.requestDataName(Z.Main),field:p.field,sort:{op:"min",field:t.vgField(e)}});return ct(p)}case"scheme":return ct(ov(n[f]))}}const o=e===se||e==="xOffset"?"width":"height",a=i[o];if(ht(a)){if(ue(e))if(ye(s)){const f=Yd(a,t,e);if(f)return ct({step:f})}else S($u(o));else if(qi(e)){const f=e===Kt?"x":"y";if(t.getScaleComponent(f).get("type")==="band"){const p=Kd(a,s);if(p)return ct(p)}}}const{rangeMin:c,rangeMax:l}=n,u=av(e,t);return (c!==void 0||l!==void 0)&&Qs(s,"rangeMin")&&U(u)&&u.length===2?ct([c??u[0],l??u[1]]):Ie(u)}function ov(e){return gm(e)?{scheme:e.name,...ke(e,["name"])}:{scheme:e}}function Xd(e,t,n,{center:i}={}){const r=_e(e),s=t.getName(r),o=t.getSignalName.bind(t);return e===be&&De(n)?i?[ge.fromName(a=>`${o(a)}/2`,s),ge.fromName(a=>`-${o(a)}/2`,s)]:[ge.fromName(o,s),0]:i?[ge.fromName(a=>`-${o(a)}/2`,s),ge.fromName(a=>`${o(a)}/2`,s)]:[0,ge.fromName(o,s)]}function av(e,t){const{size:n,config:i,mark:r,encoding:s}=t,{type:o}=fe(s[e]),c=t.getScaleComponent(e).get("type"),{domain:l,domainMid:u}=t.specifiedScales[e];switch(e){case se:case be:{if(G(["point","band"],c)){const f=Jd(e,n,i.view);if(ht(f))return {step:Yd(f,t,e)}}return Xd(e,t,c)}case Kt:case gi:return cv(e,t,c);case It:{const f=t.component.scales[e].get("zero"),d=Qd(r,f,i),g=fv(r,n,t,i);return ni(c)?uv(d,g,lv(c,i,l,e)):[d,g]}case We:return [0,Math.PI*2];case On:return [0,360];case tt:return [0,new ge(()=>{const f=t.getSignalName(ze(t.parent)?"child_width":"width"),d=t.getSignalName(ze(t.parent)?"child_height":"height");return `min(${f},${d})/2`})];case Zt:return [i.scale.minStrokeWidth,i.scale.maxStrokeWidth];case en:return [[1,0],[4,2],[2,1],[1,1],[1,2,4,2]];case Oe:return "symbol";case Ae:case yt:case bt:return c==="ordinal"?o==="nominal"?"category":"ordinal":u!==void 0?"diverging":r==="rect"||r==="geoshape"?"heatmap":"ramp";case Lt:case Jt:case Qt:return [i.scale.minOpacity,i.scale.maxOpacity]}}function Yd(e,t,n){const{encoding:i}=t,r=t.getScaleComponent(n),s=Ao(n),o=i[s];if(Lf({step:e,offsetIsDiscrete:D(o)&&zu(o.type)})==="offset"&&mf(i,s)){const c=t.getScaleComponent(s);let u=`domain('${t.scaleName(s)}').length`;if(c.get("type")==="band"){const d=c.get("paddingInner")??c.get("padding")??0,g=c.get("paddingOuter")??c.get("padding")??0;u=`bandspace(${u}, ${d}, ${g})`;}const f=r.get("paddingInner")??r.get("padding");return {signal:`${e.step} * ${u} / (1-${Lg(f)})`}}else return e.step}function Kd(e,t){if(Lf({step:e,offsetIsDiscrete:ye(t)})==="offset")return {step:e.step}}function cv(e,t,n){const i=e===Kt?"x":"y",r=t.getScaleComponent(i);if(!r)return Xd(i,t,n,{center:!0});const s=r.get("type"),o=t.scaleName(i),{markDef:a,config:c}=t;if(s==="band"){const l=Jd(i,t.size,t.config.view);if(ht(l)){const u=Kd(l,n);if(u)return u}return [0,{signal:`bandwidth('${o}')`}]}else {const l=t.encoding[i];if(v(l)&&l.timeUnit){const u=Ru(l.timeUnit,p=>`scale('${o}', ${p})`),f=t.config.scale.bandWithNestedOffsetPaddingInner,d=Ht({fieldDef:l,markDef:a,config:c})-.5,g=d!==0?` + ${d}`:"";if(f){const p=T(f)?`${f.signal}/2`+g:`${f/2+d}`,h=T(f)?`(1 - ${f.signal}/2)`+g:`${1-f/2+d}`;return [{signal:`${p} * (${u})`},{signal:`${h} * (${u})`}]}return [0,{signal:u}]}return Wl(`Cannot use ${e} scale if ${i} scale is not discrete.`)}}function Jd(e,t,n){const i=e===se?"width":"height",r=t[i];return r||Nr(n,i)}function lv(e,t,n,i){switch(e){case"quantile":return t.scale.quantileCount;case"quantize":return t.scale.quantizeCount;case"threshold":return n!==void 0&&U(n)?n.length+1:(S(Dh(i)),3)}}function uv(e,t,n){const i=()=>{const r=Xe(t),s=Xe(e),o=`(${r} - ${s}) / (${n} - 1)`;return `sequence(${s}, ${r} + ${o}, ${o})`};return T(t)?new ge(i):{signal:i()}}function Qd(e,t,n){if(t)return T(t)?{signal:`${t.signal} ? 0 : ${Qd(e,!1,n)}`}:0;switch(e){case"bar":case"tick":return n.scale.minBandSize;case"line":case"trail":case"rule":return n.scale.minStrokeWidth;case"text":return n.scale.minFontSize;case"point":case"square":case"circle":return n.scale.minSize}throw new Error(Wr("size",e))}const sl=.95;function fv(e,t,n,i){const r={x:rl(n,"x"),y:rl(n,"y")};switch(e){case"bar":case"tick":{if(i.scale.maxBandSize!==void 0)return i.scale.maxBandSize;const s=ol(t,r,i.view);return Mr$1(s)?s-1:new ge(()=>`${s.signal} - 1`)}case"line":case"trail":case"rule":return i.scale.maxStrokeWidth;case"text":return i.scale.maxFontSize;case"point":case"square":case"circle":{if(i.scale.maxSize)return i.scale.maxSize;const s=ol(t,r,i.view);return Mr$1(s)?Math.pow(sl*s,2):new ge(()=>`pow(${sl} * ${s.signal}, 2)`)}}throw new Error(Wr("size",e))}function ol(e,t,n){const i=ht(e.width)?e.width.step:Cr(n,"width"),r=ht(e.height)?e.height.step:Cr(n,"height");return t.x||t.y?new ge(()=>`min(${[t.x?t.x.signal:i,t.y?t.y.signal:r].join(", ")})`):Math.min(i,r)}function Zd(e,t){ae(e)?dv(e,t):tp(e,t);}function dv(e,t){const n=e.component.scales,{config:i,encoding:r,markDef:s,specifiedScales:o}=e;for(const a of x(n)){const c=o[a],l=n[a],u=e.getScaleComponent(a),f=fe(r[a]),d=c[t],g=u.get("type"),p=u.get("padding"),h=u.get("paddingInner"),m=Qs(g,t),y=Wu(a,t);if(d!==void 0&&(m?y&&S(y):S(Eu(g,t,a))),m&&y===void 0)if(d!==void 0){const b=f.timeUnit,C=f.type;switch(t){case"domainMax":case"domainMin":In(c[t])||C==="temporal"||b?l.set(t,{signal:es(c[t],{type:C,timeUnit:b})},!0):l.set(t,c[t],!0);break;default:l.copyKeyFromObject(t,c);}}else {const b=t in al?al[t]({model:e,channel:a,fieldOrDatumDef:f,scaleType:g,scalePadding:p,scalePaddingInner:h,domain:c.domain,domainMin:c.domainMin,domainMax:c.domainMax,markDef:s,config:i,hasNestedOffsetScale:yf(r,a),hasSecondaryRangeChannel:!!r[xt(a)]}):i.scale[t];b!==void 0&&l.set(t,b,!1);}}}const al={bins:({model:e,fieldOrDatumDef:t})=>v(t)?pv(e,t):void 0,interpolate:({channel:e,fieldOrDatumDef:t})=>gv(e,t.type),nice:({scaleType:e,channel:t,domain:n,domainMin:i,domainMax:r,fieldOrDatumDef:s})=>hv(e,t,n,i,r,s),padding:({channel:e,scaleType:t,fieldOrDatumDef:n,markDef:i,config:r})=>mv(e,t,r.scale,n,i,r.bar),paddingInner:({scalePadding:e,channel:t,markDef:n,scaleType:i,config:r,hasNestedOffsetScale:s})=>yv(e,t,n.type,i,r.scale,s),paddingOuter:({scalePadding:e,channel:t,scaleType:n,scalePaddingInner:i,config:r,hasNestedOffsetScale:s})=>bv(e,t,n,i,r.scale,s),reverse:({fieldOrDatumDef:e,scaleType:t,channel:n,config:i})=>{const r=v(e)?e.sort:void 0;return xv(t,r,n,i.scale)},zero:({channel:e,fieldOrDatumDef:t,domain:n,markDef:i,scaleType:r,config:s,hasSecondaryRangeChannel:o})=>Sv(e,t,n,i,r,s.scale,o)};function ep(e){ae(e)?rv(e):tp(e,"range");}function tp(e,t){const n=e.component.scales;for(const i of e.children)t==="range"?ep(i):Zd(i,t);for(const i of x(n)){let r;for(const s of e.children){const o=s.component.scales[i];if(o){const a=o.getWithExplicit(t);r=qt(r,a,t,"scale",Xf((c,l)=>{switch(t){case"range":return c.step&&l.step?c.step-l.step:0}return 0}));}}n[i].setWithExplicit(t,r);}}function pv(e,t){const n=t.bin;if(ee(n)){const i=Oa(e,t.field,n);return new ge(()=>e.getSignalName(i))}else if(xe(n)&&Rn(n)&&n.step!==void 0)return {step:n.step}}function gv(e,t){if(G([Ae,yt,bt],e)&&t!=="nominal")return "hcl"}function hv(e,t,n,i,r,s){if(!(gt(s)?.bin||U(n)||r!=null||i!=null||G([Te.TIME,Te.UTC],e)))return ue(t)?!0:void 0}function mv(e,t,n,i,r,s){if(ue(e)){if(Ye(t)){if(n.continuousPadding!==void 0)return n.continuousPadding;const{type:o,orient:a}=r;if(o==="bar"&&!(v(i)&&(i.bin||i.timeUnit))&&(a==="vertical"&&e==="x"||a==="horizontal"&&e==="y"))return s.continuousBandSize}if(t===Te.POINT)return n.pointPadding}}function yv(e,t,n,i,r,s=!1){if(e===void 0){if(ue(t)){const{bandPaddingInner:o,barBandPaddingInner:a,rectBandPaddingInner:c,bandWithNestedOffsetPaddingInner:l}=r;return s?l:le(o,n==="bar"?a:c)}else if(qi(t)&&i===Te.BAND)return r.offsetBandPaddingInner}}function bv(e,t,n,i,r,s=!1){if(e===void 0){if(ue(t)){const{bandPaddingOuter:o,bandWithNestedOffsetPaddingOuter:a}=r;if(s)return a;if(n===Te.BAND)return le(o,T(i)?{signal:`${i.signal}/2`}:i/2)}else if(qi(t)){if(n===Te.POINT)return .5;if(n===Te.BAND)return r.offsetBandPaddingOuter}}}function xv(e,t,n,i){if(n==="x"&&i.xReverse!==void 0)return De(e)&&t==="descending"?T(i.xReverse)?{signal:`!${i.xReverse.signal}`}:!i.xReverse:i.xReverse;if(De(e)&&t==="descending")return !0}function Sv(e,t,n,i,r,s,o){if(!!n&&n!=="unaggregated"&&De(r)){if(U(n)){const c=n[0],l=n[n.length-1];if(Mr$1(c)&&c<=0&&Mr$1(l)&&l>=0)return !0}return !1}if(e==="size"&&t.type==="quantitative"&&!ni(r))return !0;if(!(v(t)&&t.bin)&&G([...St,...yg],e)){const{orient:c,type:l}=i;return G(["bar","area","line","trail"],l)&&(c==="horizontal"&&e==="y"||c==="vertical"&&e==="x")?!1:G(["bar","area"],l)&&!o?!0:s?.zero}return !1}function vv(e,t,n,i,r=!1){const s=Ev(t,n,i,r),{type:o}=e;return Pt(t)?o!==void 0?vm(t,o)?v(n)&&!Sm(o,n.type)?(S(Eh(o,s)),s):o:(S(vh(t,o,s)),s):s:null}function Ev(e,t,n,i){switch(t.type){case"nominal":case"ordinal":{if(qn(e)||Fs(e)==="discrete")return e==="shape"&&t.type==="ordinal"&&S(ks(e,"ordinal")),"ordinal";if(ue(e)||qi(e)){if(G(["rect","bar","image","rule"],n.type)||i)return "band"}else if(n.type==="arc"&&e in Ro)return "band";const r=n[_e(e)];return Cn(r)||ri(t)&&t.axis?.tickBand?"band":"point"}case"temporal":return qn(e)?"time":Fs(e)==="discrete"?(S(ks(e,"temporal")),"ordinal"):v(t)&&t.timeUnit&&me(t.timeUnit).utc?"utc":"time";case"quantitative":return qn(e)?v(t)&&ee(t.bin)?"bin-ordinal":"linear":Fs(e)==="discrete"?(S(ks(e,"quantitative")),"ordinal"):"linear";case"geojson":return}throw new Error(Su(t.type))}function $v(e,{ignoreRange:t}={}){np(e),Hd(e);for(const n of xm)Zd(e,n);t||ep(e);}function np(e){ae(e)?e.component.scales=wv(e):e.component.scales=Nv(e);}function wv(e){const{encoding:t,mark:n,markDef:i}=e,r={};for(const s of Ur){const o=fe(t[s]);if(o&&n===qu&&s===Oe&&o.type===hi)continue;let a=o&&o.scale;if(o&&a!==null&&a!==!1){a??(a={});const c=yf(t,s),l=vv(a,s,o,i,c);r[s]=new Vd(e.scaleName(`${s}`,!0),{value:l,explicit:a.type===l});}}return r}const Cv=Xf((e,t)=>pc(e)-pc(t));function Nv(e){var t;const n=e.component.scales={},i={},r=e.component.resolve;for(const s of e.children){np(s);for(const o of x(s.component.scales))if((t=r.scale)[o]??(t[o]=_d(o,e)),r.scale[o]==="shared"){const a=i[o],c=s.component.scales[o].getWithExplicit("type");a?lm(a.value,c.value)?i[o]=qt(a,c,"type","scale",Cv):(r.scale[o]="independent",delete i[o]):i[o]=c;}}for(const s of x(i)){const o=e.scaleName(s,!0),a=i[s];n[s]=new Vd(o,a);for(const c of e.children){const l=c.component.scales[s];l&&(c.renameScale(l.get("name"),o),l.merged=!0);}}return n}class zs{constructor(){this.nameMap={};}rename(t,n){this.nameMap[t]=n;}has(t){return this.nameMap[t]!==void 0}get(t){for(;this.nameMap[t]&&t!==this.nameMap[t];)t=this.nameMap[t];return t}}function ae(e){return e?.type==="unit"}function ze(e){return e?.type==="facet"}function Pa(e){return e?.type==="concat"}function Si(e){return e?.type==="layer"}class za{constructor(t,n,i,r,s,o,a){this.type=n,this.parent=i,this.config=s,this.correctDataNames=c=>(c.from?.data&&(c.from.data=this.lookupDataSource(c.from.data)),c.from?.facet?.data&&(c.from.facet.data=this.lookupDataSource(c.from.facet.data)),c),this.parent=i,this.config=s,this.view=Fe(a),this.name=t.name??r,this.title=jt(t.title)?{text:t.title}:t.title?Fe(t.title):void 0,this.scaleNameMap=i?i.scaleNameMap:new zs,this.projectionNameMap=i?i.projectionNameMap:new zs,this.signalNameMap=i?i.signalNameMap:new zs,this.data=t.data,this.description=t.description,this.transforms=Rb(t.transform??[]),this.layout=n==="layer"||n==="unit"?{}:zy(t,n,s),this.component={data:{sources:i?i.component.data.sources:[],outputNodes:i?i.component.data.outputNodes:{},outputNodeRefCounts:i?i.component.data.outputNodeRefCounts:{},isFaceted:Kr(t)||i?.component.data.isFaceted&&t.data===void 0},layoutSize:new Dt,layoutHeaders:{row:{},column:{},facet:{}},mark:null,resolve:{scale:{},axis:{},legend:{},...o?z(o):{}},selection:null,scales:null,projection:null,axes:{},legends:{}};}get width(){return this.getSizeSignalRef("width")}get height(){return this.getSizeSignalRef("height")}parse(){this.parseScale(),this.parseLayoutSize(),this.renameTopLevelLayoutSizeSignal(),this.parseSelections(),this.parseProjection(),this.parseData(),this.parseAxesAndHeaders(),this.parseLegends(),this.parseMarkGroup();}parseScale(){$v(this);}parseProjection(){Bd(this);}renameTopLevelLayoutSizeSignal(){this.getName("width")!=="width"&&this.renameSignal(this.getName("width"),"width"),this.getName("height")!=="height"&&this.renameSignal(this.getName("height"),"height");}parseLegends(){zd(this);}assembleEncodeFromView(t){const{style:n,...i}=t,r={};for(const s of x(i)){const o=i[s];o!==void 0&&(r[s]=ne(o));}return r}assembleGroupEncodeEntry(t){let n={};return this.view&&(n=this.assembleEncodeFromView(this.view)),!t&&(this.description&&(n.description=ne(this.description)),this.type==="unit"||this.type==="layer")?{width:this.getSizeSignalRef("width"),height:this.getSizeSignalRef("height"),...n}:K(n)?void 0:n}assembleLayout(){if(!this.layout)return;const{spacing:t,...n}=this.layout,{component:i,config:r}=this,s=Vx(i.layoutHeaders,r);return {padding:t,...this.assembleDefaultLayout(),...n,...s?{titleBand:s}:{}}}assembleDefaultLayout(){return {}}assembleHeaderMarks(){const{layoutHeaders:t}=this.component;let n=[];for(const i of je)t[i].title&&n.push(Ux(this,i));for(const i of Fa)n=n.concat(Bx(this,i));return n}assembleAxes(){return kx(this.component.axes,this.config)}assembleLegends(){return Md(this)}assembleProjections(){return mS(this)}assembleTitle(){const{encoding:t,...n}=this.title??{},i={...fu(this.config.title).nonMarkTitleProperties,...n,...t?{encode:{update:t}}:{}};if(i.text)return G(["unit","layer"],this.type)?G(["middle",void 0],i.anchor)&&(i.frame??(i.frame="group")):i.anchor??(i.anchor="start"),K(i)?void 0:i}assembleGroup(t=[]){const n={};t=t.concat(this.assembleSignals()),t.length>0&&(n.signals=t);const i=this.assembleLayout();i&&(n.layout=i),n.marks=[].concat(this.assembleHeaderMarks(),this.assembleMarks());const r=!this.parent||ze(this.parent)?qd(this):[];r.length>0&&(n.scales=r);const s=this.assembleAxes();s.length>0&&(n.axes=s);const o=this.assembleLegends();return o.length>0&&(n.legends=o),n}getName(t){return re((this.name?`${this.name}_`:"")+t)}getDataName(t){return this.getName(Z[t].toLowerCase())}requestDataName(t){const n=this.getDataName(t),i=this.component.data.outputNodeRefCounts;return i[n]=(i[n]||0)+1,n}getSizeSignalRef(t){if(ze(this.parent)){const n=Ad(t),i=jr(n),r=this.component.scales[i];if(r&&!r.merged){const s=r.get("type"),o=r.get("range");if(ye(s)&&nn(o)){const a=r.get("name"),c=ds(this,i),l=La(c);if(l){const u=E({aggregate:"distinct",field:l},{expr:"datum"});return {signal:Td(a,r,u)}}else return S(Po(i)),null}}}return {signal:this.signalNameMap.get(this.getName(t))}}lookupDataSource(t){const n=this.component.data.outputNodes[t];return n?n.getSource():t}getSignalName(t){return this.signalNameMap.get(t)}renameSignal(t,n){this.signalNameMap.rename(t,n);}renameScale(t,n){this.scaleNameMap.rename(t,n);}renameProjection(t,n){this.projectionNameMap.rename(t,n);}scaleName(t,n){if(n)return this.getName(t);if(nu(t)&&Pt(t)&&this.component.scales[t]||this.scaleNameMap.has(this.getName(t)))return this.scaleNameMap.get(this.getName(t))}projectionName(t){if(t)return this.getName("projection");if(this.component.projection&&!this.component.projection.merged||this.projectionNameMap.has(this.getName("projection")))return this.projectionNameMap.get(this.getName("projection"))}getScaleComponent(t){if(!this.component.scales)throw new Error("getScaleComponent cannot be called before parseScale(). Make sure you have called parseScale or use parseUnitModelWithScale().");const n=this.component.scales[t];return n&&!n.merged?n:this.parent?this.parent.getScaleComponent(t):void 0}getSelectionComponent(t,n){let i=this.component.selection[t];if(!i&&this.parent&&(i=this.parent.getSelectionComponent(t,n)),!i)throw new Error(jg(n));return i}hasAxisOrientSignalRef(){return this.component.axes.x?.some(t=>t.hasOrientSignalRef())||this.component.axes.y?.some(t=>t.hasOrientSignalRef())}}class ip extends za{vgField(t,n={}){const i=this.fieldDef(t);if(i)return E(i,n)}reduceFieldDef(t,n){return dy(this.getMapping(),(i,r,s)=>{const o=gt(r);return o?t(i,o,s):i},n)}forEachFieldDef(t,n){la(this.getMapping(),(i,r)=>{const s=gt(i);s&&t(s,r);},n);}}class ps extends Y{clone(){return new ps(null,z(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=z(n);const i=this.transform.as??[void 0,void 0];this.transform.as=[i[0]??"value",i[1]??"density"];}dependentFields(){return new Set([this.transform.density,...this.transform.groupby??[]])}producedFields(){return new Set(this.transform.as)}hash(){return `DensityTransform ${W(this.transform)}`}assemble(){const{density:t,...n}=this.transform,i={type:"kde",field:t,...n};return this.transform.groupby&&(i.resolve="shared"),i}}class gs extends Y{clone(){return new gs(null,z(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=z(n);}dependentFields(){return new Set([this.transform.extent])}producedFields(){return new Set([])}hash(){return `ExtentTransform ${W(this.transform)}`}assemble(){const{extent:t,param:n}=this.transform;return {type:"extent",field:t,signal:n}}}class Mi extends Y{clone(){return new Mi(null,{...this.filter})}constructor(t,n){super(t),this.filter=n;}static make(t,n){const{config:i,mark:r,markDef:s}=n;if(X("invalid",s,i)!=="filter")return null;const a=n.reduceFieldDef((c,l,u)=>{const f=Pt(u)&&n.getScaleComponent(u);if(f){const d=f.get("type");De(d)&&l.aggregate!=="count"&&!rn(r)&&(c[l.field]=l);}return c},{});return x(a).length?new Mi(t,a):null}dependentFields(){return new Set(x(this.filter))}producedFields(){return new Set}hash(){return `FilterInvalid ${W(this.filter)}`}assemble(){const t=x(this.filter).reduce((n,i)=>{const r=this.filter[i],s=E(r,{expr:"datum"});return r!==null&&(r.type==="temporal"?n.push(`(isDate(${s}) || (isValid(${s}) && isFinite(+${s})))`):r.type==="quantitative"&&(n.push(`isValid(${s})`),n.push(`isFinite(+${s})`))),n},[]);return t.length>0?{type:"filter",expr:t.join(" && ")}:null}}class hs extends Y{clone(){return new hs(this.parent,z(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=z(n);const{flatten:i,as:r=[]}=this.transform;this.transform.as=i.map((s,o)=>r[o]??s);}dependentFields(){return new Set(this.transform.flatten)}producedFields(){return new Set(this.transform.as)}hash(){return `FlattenTransform ${W(this.transform)}`}assemble(){const{flatten:t,as:n}=this.transform;return {type:"flatten",fields:t,as:n}}}class ms extends Y{clone(){return new ms(null,z(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=z(n);const i=this.transform.as??[void 0,void 0];this.transform.as=[i[0]??"key",i[1]??"value"];}dependentFields(){return new Set(this.transform.fold)}producedFields(){return new Set(this.transform.as)}hash(){return `FoldTransform ${W(this.transform)}`}assemble(){const{fold:t,as:n}=this.transform;return {type:"fold",fields:t,as:n}}}class Yn extends Y{clone(){return new Yn(null,z(this.fields),this.geojson,this.signal)}static parseAll(t,n){if(n.component.projection&&!n.component.projection.isFit)return t;let i=0;for(const r of [[it,nt],[Be,rt]]){const s=r.map(o=>{const a=fe(n.encoding[o]);return v(a)?a.field:vt(a)?{expr:`${a.datum}`}:Qe(a)?{expr:`${a.value}`}:void 0});(s[0]||s[1])&&(t=new Yn(t,s,null,n.getName(`geojson_${i++}`)));}if(n.channelHasField(Oe)){const r=n.typedFieldDef(Oe);r.type===hi&&(t=new Yn(t,null,r.field,n.getName(`geojson_${i++}`)));}return t}constructor(t,n,i,r){super(t),this.fields=n,this.geojson=i,this.signal=r;}dependentFields(){const t=(this.fields??[]).filter(xt$1);return new Set([...this.geojson?[this.geojson]:[],...t])}producedFields(){return new Set}hash(){return `GeoJSON ${this.geojson} ${this.signal} ${W(this.fields)}`}assemble(){return [...this.geojson?[{type:"filter",expr:`isValid(datum["${this.geojson}"])`}]:[],{type:"geojson",...this.fields?{fields:this.fields}:{},...this.geojson?{geojson:this.geojson}:{},signal:this.signal}]}}class ji extends Y{clone(){return new ji(null,this.projection,z(this.fields),z(this.as))}constructor(t,n,i,r){super(t),this.projection=n,this.fields=i,this.as=r;}static parseAll(t,n){if(!n.projectionName())return t;for(const i of [[it,nt],[Be,rt]]){const r=i.map(o=>{const a=fe(n.encoding[o]);return v(a)?a.field:vt(a)?{expr:`${a.datum}`}:Qe(a)?{expr:`${a.value}`}:void 0}),s=i[0]===Be?"2":"";(r[0]||r[1])&&(t=new ji(t,n.projectionName(),r,[n.getName(`x${s}`),n.getName(`y${s}`)]));}return t}dependentFields(){return new Set(this.fields.filter(xt$1))}producedFields(){return new Set(this.as)}hash(){return `Geopoint ${this.projection} ${W(this.fields)} ${W(this.as)}`}assemble(){return {type:"geopoint",projection:this.projection,fields:this.fields,as:this.as}}}class xn extends Y{clone(){return new xn(null,z(this.transform))}constructor(t,n){super(t),this.transform=n;}dependentFields(){return new Set([this.transform.impute,this.transform.key,...this.transform.groupby??[]])}producedFields(){return new Set([this.transform.impute])}processSequence(t){const{start:n=0,stop:i,step:r}=t;return {signal:`sequence(${[n,i,...r?[r]:[]].join(",")})`}}static makeFromTransform(t,n){return new xn(t,n)}static makeFromEncoding(t,n){const i=n.encoding,r=i.x,s=i.y;if(v(r)&&v(s)){const o=r.impute?r:s.impute?s:void 0;if(o===void 0)return;const a=r.impute?s:s.impute?r:void 0,{method:c,value:l,frame:u,keyvals:f}=o.impute,d=xf(n.mark,i);return new xn(t,{impute:o.field,key:a.field,...c?{method:c}:{},...l!==void 0?{value:l}:{},...u?{frame:u}:{},...f!==void 0?{keyvals:f}:{},...d.length?{groupby:d}:{}})}return null}hash(){return `Impute ${W(this.transform)}`}assemble(){const{impute:t,key:n,keyvals:i,method:r,groupby:s,value:o,frame:a=[null,null]}=this.transform,c={type:"impute",field:t,key:n,...i?{keyvals:gb(i)?this.processSequence(i):i}:{},method:"value",...s?{groupby:s}:{},value:!r||r==="value"?o:null};if(r&&r!=="value"){const l={type:"window",as:[`imputed_${t}_value`],ops:[r],fields:[t],frame:a,ignorePeers:!1,...s?{groupby:s}:{}},u={type:"formula",expr:`datum.${t} === null ? datum.imputed_${t}_value : datum.${t}`,as:t};return [c,l,u]}else return [c]}}class ys extends Y{clone(){return new ys(null,z(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=z(n);const i=this.transform.as??[void 0,void 0];this.transform.as=[i[0]??n.on,i[1]??n.loess];}dependentFields(){return new Set([this.transform.loess,this.transform.on,...this.transform.groupby??[]])}producedFields(){return new Set(this.transform.as)}hash(){return `LoessTransform ${W(this.transform)}`}assemble(){const{loess:t,on:n,...i}=this.transform;return {type:"loess",x:n,y:t,...i}}}class Ui extends Y{clone(){return new Ui(null,z(this.transform),this.secondary)}constructor(t,n,i){super(t),this.transform=n,this.secondary=i;}static make(t,n,i,r){const s=n.component.data.sources,{from:o}=i;let a=null;if(hb(o)){let c=op(o.data,s);c||(c=new Tn(o.data),s.push(c));const l=n.getName(`lookup_${r}`);a=new we(c,l,Z.Lookup,n.component.data.outputNodeRefCounts),n.component.data.outputNodes[l]=a;}else if(mb(o)){const c=o.param;i={as:c,...i};let l;try{l=n.getSelectionComponent(re(c),c);}catch{throw new Error(Gg(c))}if(a=l.materialized,!a)throw new Error(Hg(c))}return new Ui(t,i,a.getSource())}dependentFields(){return new Set([this.transform.lookup])}producedFields(){return new Set(this.transform.as?H(this.transform.as):this.transform.from.fields)}hash(){return `Lookup ${W({transform:this.transform,secondary:this.secondary})}`}assemble(){let t;if(this.transform.from.fields)t={values:this.transform.from.fields,...this.transform.as?{as:H(this.transform.as)}:{}};else {let n=this.transform.as;xt$1(n)||(S(Zg),n="_lookup"),t={as:[n]};}return {type:"lookup",from:this.secondary,key:this.transform.from.key,fields:[this.transform.lookup],...t,...this.transform.default?{default:this.transform.default}:{}}}}class bs extends Y{clone(){return new bs(null,z(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=z(n);const i=this.transform.as??[void 0,void 0];this.transform.as=[i[0]??"prob",i[1]??"value"];}dependentFields(){return new Set([this.transform.quantile,...this.transform.groupby??[]])}producedFields(){return new Set(this.transform.as)}hash(){return `QuantileTransform ${W(this.transform)}`}assemble(){const{quantile:t,...n}=this.transform;return {type:"quantile",field:t,...n}}}class xs extends Y{clone(){return new xs(null,z(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=z(n);const i=this.transform.as??[void 0,void 0];this.transform.as=[i[0]??n.on,i[1]??n.regression];}dependentFields(){return new Set([this.transform.regression,this.transform.on,...this.transform.groupby??[]])}producedFields(){return new Set(this.transform.as)}hash(){return `RegressionTransform ${W(this.transform)}`}assemble(){const{regression:t,on:n,...i}=this.transform;return {type:"regression",x:n,y:t,...i}}}class Ss extends Y{clone(){return new Ss(null,z(this.transform))}constructor(t,n){super(t),this.transform=n;}addDimensions(t){this.transform.groupby=lt((this.transform.groupby??[]).concat(t),n=>n);}producedFields(){}dependentFields(){return new Set([this.transform.pivot,this.transform.value,...this.transform.groupby??[]])}hash(){return `PivotTransform ${W(this.transform)}`}assemble(){const{pivot:t,value:n,groupby:i,limit:r,op:s}=this.transform;return {type:"pivot",field:t,value:n,...r!==void 0?{limit:r}:{},...s!==void 0?{op:s}:{},...i!==void 0?{groupby:i}:{}}}}class vs extends Y{clone(){return new vs(null,z(this.transform))}constructor(t,n){super(t),this.transform=n;}dependentFields(){return new Set}producedFields(){return new Set}hash(){return `SampleTransform ${W(this.transform)}`}assemble(){return {type:"sample",size:this.transform.sample}}}function rp(e){let t=0;function n(i,r){if(i instanceof Tn&&!i.isGenerator&&!oi(i.data)&&(e.push(r),r={name:null,source:r.name,transform:[]}),i instanceof $e&&(i.parent instanceof Tn&&!r.source?(r.format={...r.format,parse:i.assembleFormatParse()},r.transform.push(...i.assembleTransforms(!0))):r.transform.push(...i.assembleTransforms())),i instanceof bi){r.name||(r.name=`data_${t++}`),!r.source||r.transform.length>0?(e.push(r),i.data=r.name):i.data=r.source,e.push(...i.assemble());return}switch((i instanceof tr||i instanceof nr||i instanceof Mi||i instanceof yi||i instanceof ci||i instanceof ji||i instanceof Je||i instanceof Ui||i instanceof xi||i instanceof Dn||i instanceof ms||i instanceof hs||i instanceof ps||i instanceof ys||i instanceof bs||i instanceof xs||i instanceof Yt||i instanceof vs||i instanceof Ss||i instanceof gs)&&r.transform.push(i.assemble()),(i instanceof dt||i instanceof ft||i instanceof xn||i instanceof Tt||i instanceof Yn)&&r.transform.push(...i.assemble()),i instanceof we&&(r.source&&r.transform.length===0?i.setSource(r.source):i.parent instanceof we?i.setSource(r.name):(r.name||(r.name=`data_${t++}`),i.setSource(r.name),i.numChildren()===1&&(e.push(r),r={name:null,source:r.name,transform:[]}))),i.numChildren()){case 0:i instanceof we&&(!r.source||r.transform.length>0)&&e.push(r);break;case 1:n(i.children[0],r);break;default:{r.name||(r.name=`data_${t++}`);let s=r.name;!r.source||r.transform.length>0?e.push(r):s=r.source;for(const o of i.children)n(o,{name:null,source:s,transform:[]});break}}}return n}function Fv(e){const t=[],n=rp(t);for(const i of e.children)n(i,{source:e.name,name:null,transform:[]});return t}function kv(e,t){const n=[],i=rp(n);let r=0;for(const o of e.sources){o.hasName()||(o.dataName=`source_${r++}`);const a=o.assemble();i(o,a);}for(const o of n)o.transform.length===0&&delete o.transform;let s=0;for(const[o,a]of n.entries())(a.transform??[]).length===0&&!a.source&&n.splice(s++,0,n.splice(o,1)[0]);for(const o of n)for(const a of o.transform??[])a.type==="lookup"&&(a.from=e.outputNodes[a.from].getSource());for(const o of n)o.name in t&&(o.values=t[o.name]);return n}function Tv(e){return e==="top"||e==="left"||T(e)?"header":"footer"}function Av(e){for(const t of je)Ov(e,t);cl(e,"x"),cl(e,"y");}function Ov(e,t){const{facet:n,config:i,child:r,component:s}=e;if(e.channelHasField(t)){const o=n[t],a=ui("title",null,i,t);let c=Vn(o,i,{allowDisabling:!0,includeDefault:a===void 0||!!a});r.component.layoutHeaders[t].title&&(c=U(c)?c.join(", "):c,c+=` / ${r.component.layoutHeaders[t].title}`,r.component.layoutHeaders[t].title=null);const l=ui("labelOrient",o.header,i,t),u=o.header!==null?le(o.header?.labels,i.header.labels,!0):!1,f=G(["bottom","right"],l)?"footer":"header";s.layoutHeaders[t]={title:o.header!==null?c:null,facetFieldDef:o,[f]:t==="facet"?[]:[sp(e,t,u)]};}}function sp(e,t,n){const i=t==="row"?"height":"width";return {labels:n,sizeSignal:e.child.component.layoutSize.get(i)?e.child.getSizeSignalRef(i):void 0,axes:[]}}function cl(e,t){const{child:n}=e;if(n.component.axes[t]){const{layoutHeaders:i,resolve:r}=e.component;if(r.axis[t]=Aa(r,t),r.axis[t]==="shared"){const s=t==="x"?"column":"row",o=i[s];for(const a of n.component.axes[t]){const c=Tv(a.get("orient"));o[c]??(o[c]=[sp(e,s,!1)]);const l=ki(a,"main",e.config,{header:!0});l&&o[c][0].axes.push(l),a.mainExtracted=!0;}}}}function _v(e){Da(e),Ar(e,"width"),Ar(e,"height");}function Rv(e){Da(e);const t=e.layout.columns===1?"width":"childWidth",n=e.layout.columns===void 0?"height":"childHeight";Ar(e,t),Ar(e,n);}function Da(e){for(const t of e.children)t.parseLayoutSize();}function Ar(e,t){const n=Ad(t),i=jr(n),r=e.component.resolve,s=e.component.layoutSize;let o;for(const a of e.children){const c=a.component.layoutSize.getWithExplicit(n),l=r.scale[i]??_d(i,e);if(l==="independent"&&c.value==="step"){o=void 0;break}if(o){if(l==="independent"&&o.value!==c.value){o=void 0;break}o=qt(o,c,n,"");}else o=c;}if(o){for(const a of e.children)e.renameSignal(a.getName(n),e.getName(t)),a.component.layoutSize.set(n,"merged",!1);s.setWithExplicit(t,o);}else s.setWithExplicit(t,{explicit:!1,value:void 0});}function Iv(e){const{size:t,component:n}=e;for(const i of St){const r=_e(i);if(t[r]){const s=t[r];n.layoutSize.set(r,ht(s)?"step":s,!0);}else {const s=Lv(e,r);n.layoutSize.set(r,s,!1);}}}function Lv(e,t){const n=t==="width"?"x":"y",i=e.config,r=e.getScaleComponent(n);if(r){const s=r.get("type"),o=r.get("range");if(ye(s)){const a=Nr(i.view,t);return nn(o)||ht(a)?"step":a}else return to(i.view,t)}else {if(e.hasProjection||e.mark==="arc")return to(i.view,t);{const s=Nr(i.view,t);return ht(s)?s.step:s}}}function mo(e,t,n){return E(t,{suffix:`by_${E(e)}`,...n})}class Ri extends ip{constructor(t,n,i,r){super(t,"facet",n,i,r,t.resolve),this.child=Wa(t.spec,this,this.getName("child"),void 0,r),this.children=[this.child],this.facet=this.initFacet(t.facet);}initFacet(t){if(!Ki(t))return {facet:this.initFacetFieldDef(t,"facet")};const n=x(t),i={};for(const r of n){if(![Nt,Ft].includes(r)){S(Wr(r,"facet"));break}const s=t[r];if(s.field===void 0){S(Ks(s,r));break}i[r]=this.initFacetFieldDef(s,r);}return i}initFacetFieldDef(t,n){const i=aa(t,n);return i.header?i.header=Fe(i.header):i.header===null&&(i.header=null),i}channelHasField(t){return !!this.facet[t]}fieldDef(t){return this.facet[t]}parseData(){this.component.data=Es(this),this.child.parseData();}parseLayoutSize(){Da(this);}parseSelections(){this.child.parseSelections(),this.component.selection=this.child.component.selection;}parseMarkGroup(){this.child.parseMarkGroup();}parseAxesAndHeaders(){this.child.parseAxesAndHeaders(),Av(this);}assembleSelectionTopLevelSignals(t){return this.child.assembleSelectionTopLevelSignals(t)}assembleSignals(){return this.child.assembleSignals(),[]}assembleSelectionData(t){return this.child.assembleSelectionData(t)}getHeaderLayoutMixins(){const t={};for(const n of je)for(const i of ka){const r=this.component.layoutHeaders[n],s=r[i],{facetFieldDef:o}=r;if(o){const a=ui("titleOrient",o.header,this.config,n);if(["right","bottom"].includes(a)){const c=us(n,a);t.titleAnchor??(t.titleAnchor={}),t.titleAnchor[c]="end";}}if(s?.[0]){const a=n==="row"?"height":"width",c=i==="header"?"headerBand":"footerBand";n!=="facet"&&!this.child.component.layoutSize.get(a)&&(t[c]??(t[c]={}),t[c][n]=.5),r.title&&(t.offset??(t.offset={}),t.offset[n==="row"?"rowTitle":"columnTitle"]=10);}}return t}assembleDefaultLayout(){const{column:t,row:n}=this.facet,i=t?this.columnDistinctSignal():n?1:void 0;let r="all";return (!n&&this.component.resolve.scale.x==="independent"||!t&&this.component.resolve.scale.y==="independent")&&(r="none"),{...this.getHeaderLayoutMixins(),...i?{columns:i}:{},bounds:"full",align:r}}assembleLayoutSignals(){return this.child.assembleLayoutSignals()}columnDistinctSignal(){if(!(this.parent&&this.parent instanceof Ri))return {signal:`length(data('${this.getName("column_domain")}'))`}}assembleGroupStyle(){}assembleGroup(t){return this.parent&&this.parent instanceof Ri?{...this.channelHasField("column")?{encode:{update:{columns:{field:E(this.facet.column,{prefix:"distinct"})}}}}:{},...super.assembleGroup(t)}:super.assembleGroup(t)}getCardinalityAggregateForChild(){const t=[],n=[],i=[];if(this.child instanceof Ri){if(this.child.channelHasField("column")){const r=E(this.child.facet.column);t.push(r),n.push("distinct"),i.push(`distinct_${r}`);}}else for(const r of St){const s=this.child.component.scales[r];if(s&&!s.merged){const o=s.get("type"),a=s.get("range");if(ye(o)&&nn(a)){const c=ds(this.child,r),l=La(c);l?(t.push(l),n.push("distinct"),i.push(`distinct_${l}`)):S(Po(r));}}}return {fields:t,ops:n,as:i}}assembleFacet(){const{name:t,data:n}=this.component.data.facetRoot,{row:i,column:r}=this.facet,{fields:s,ops:o,as:a}=this.getCardinalityAggregateForChild(),c=[];for(const u of je){const f=this.facet[u];if(f){c.push(E(f));const{bin:d,sort:g}=f;if(ee(d)&&c.push(E(f,{binSuffix:"end"})),ut(g)){const{field:p,op:h=Yr}=g,m=mo(f,g);i&&r?(s.push(m),o.push("max"),a.push(m)):(s.push(p),o.push(h),a.push(m));}else if(U(g)){const p=li(f,u);s.push(p),o.push("max"),a.push(p);}}}const l=!!i&&!!r;return {name:t,data:n,groupby:c,...l||s.length>0?{aggregate:{...l?{cross:l}:{},...s.length?{fields:s,ops:o,as:a}:{}}}:{}}}facetSortFields(t){const{facet:n}=this,i=n[t];return i?ut(i.sort)?[mo(i,i.sort,{expr:"datum"})]:U(i.sort)?[li(i,t,{expr:"datum"})]:[E(i,{expr:"datum"})]:[]}facetSortOrder(t){const{facet:n}=this,i=n[t];if(i){const{sort:r}=i;return [(ut(r)?r.order:!U(r)&&r)||"ascending"]}return []}assembleLabelTitle(){const{facet:t,config:n}=this;if(t.facet)return lo(t.facet,"facet",n);const i={row:["top","bottom"],column:["left","right"]};for(const r of Fa)if(t[r]){const s=ui("labelOrient",t[r]?.header,n,r);if(i[r].includes(s))return lo(t[r],r,n)}}assembleMarks(){const{child:t}=this,n=this.component.data.facetRoot,i=Fv(n),r=t.assembleGroupEncodeEntry(!1),s=this.assembleLabelTitle()||t.assembleTitle(),o=t.assembleGroupStyle();return [{name:this.getName("cell"),type:"group",...s?{title:s}:{},...o?{style:o}:{},from:{facet:this.assembleFacet()},sort:{field:je.map(c=>this.facetSortFields(c)).flat(),order:je.map(c=>this.facetSortOrder(c)).flat()},...i.length>0?{data:i}:{},...r?{encode:{update:r}}:{},...t.assembleGroup(qb(this,[]))}]}getMapping(){return this.facet}}function Pv(e,t){const{row:n,column:i}=t;if(n&&i){let r=null;for(const s of [n,i])if(ut(s.sort)){const{field:o,op:a=Yr}=s.sort;e=r=new Dn(e,{joinaggregate:[{op:a,field:o,as:mo(s,s.sort,{forAs:!0})}],groupby:[E(s)]});}return r}return null}function op(e,t){for(const n of t){const i=n.data;if(e.name&&n.hasName()&&e.name!==n.dataName)continue;const r=e.format?.mesh,s=i.format?.feature;if(r&&s)continue;const o=e.format?.feature;if((o||s)&&o!==s)continue;const a=i.format?.mesh;if(!((r||a)&&r!==a)){if(Di(e)&&Di(i)){if(Pe(e.values,i.values))return n}else if(oi(e)&&oi(i)){if(e.url===i.url)return n}else if(Yf(e)&&e.name===n.dataName)return n}}return null}function zv(e,t){if(e.data||!e.parent){if(e.data===null){const i=new Tn({values:[]});return t.push(i),i}const n=op(e.data,t);if(n)return Bt(e.data)||(n.data.format=Gl({},e.data.format,n.data.format)),!n.hasName()&&e.data.name&&(n.dataName=e.data.name),n;{const i=new Tn(e.data);return t.push(i),i}}else return e.parent.component.data.facetRoot?e.parent.component.data.facetRoot:e.parent.component.data.main}function Dv(e,t,n){let i=0;for(const r of t.transforms){let s,o;if(Nb(r))o=e=new ci(e,r),s="derived";else if(Sa(r)){const a=TS(r);o=e=$e.makeWithAncestors(e,{},a,n)??e,e=new yi(e,t,r.filter);}else if(Gf(r))o=e=dt.makeFromTransform(e,r,t),s="number";else if(kb(r))s="date",n.getWithExplicit(r.field).value===void 0&&(e=new $e(e,{[r.field]:s}),n.set(r.field,s,!1)),o=e=ft.makeFromTransform(e,r);else if(Tb(r))o=e=Je.makeFromTransform(e,r),s="number",Na(t)&&(e=new Yt(e));else if(Wf(r))o=e=Ui.make(e,t,r,i++),s="derived";else if($b(r))o=e=new xi(e,r),s="number";else if(wb(r))o=e=new Dn(e,r),s="number";else if(Ab(r))o=e=Tt.makeFromTransform(e,r),s="derived";else if(Ob(r))o=e=new ms(e,r),s="derived";else if(_b(r))o=e=new gs(e,r),s="derived";else if(Cb(r))o=e=new hs(e,r),s="derived";else if(yb(r))o=e=new Ss(e,r),s="derived";else if(Eb(r))e=new vs(e,r);else if(Fb(r))o=e=xn.makeFromTransform(e,r),s="derived";else if(bb(r))o=e=new ps(e,r),s="derived";else if(xb(r))o=e=new bs(e,r),s="derived";else if(Sb(r))o=e=new xs(e,r),s="derived";else if(vb(r))o=e=new ys(e,r),s="derived";else {S(Qg(r));continue}if(o&&s!==void 0)for(const a of o.producedFields()??[])n.set(a,s,!1);}return e}function Es(e){let t=zv(e,e.component.data.sources);const{outputNodes:n,outputNodeRefCounts:i}=e.component.data,r=e.data,o=!(r&&(Bt(r)||oi(r)||Di(r)))&&e.parent?e.parent.component.data.ancestorParse.clone():new Gb;Bt(r)?(Kf(r)?t=new nr(t,r.sequence):va(r)&&(t=new tr(t,r.graticule)),o.parseNothing=!0):r?.format?.parse===null&&(o.parseNothing=!0),t=$e.makeExplicit(t,e,o)??t,t=new Yt(t);const a=e.parent&&Si(e.parent);(ae(e)||ze(e))&&a&&(t=dt.makeFromEncoding(t,e)??t),e.transforms.length>0&&(t=Dv(t,e,o));const c=OS(e),l=AS(e);t=$e.makeWithAncestors(t,{},{...c,...l},o)??t,ae(e)&&(t=Yn.parseAll(t,e),t=ji.parseAll(t,e)),(ae(e)||ze(e))&&(a||(t=dt.makeFromEncoding(t,e)??t),t=ft.makeFromEncoding(t,e)??t,t=ci.parseAllForSortIndex(t,e));const u=e.getDataName(Z.Raw),f=new we(t,u,Z.Raw,i);if(n[u]=f,t=f,ae(e)){const h=Je.makeFromEncoding(t,e);h&&(t=h,Na(e)&&(t=new Yt(t))),t=xn.makeFromEncoding(t,e)??t,t=Tt.makeFromEncoding(t,e)??t;}ae(e)&&(t=Mi.make(t,e)??t);const d=e.getDataName(Z.Main),g=new we(t,d,Z.Main,i);n[d]=g,t=g,ae(e)&&Nx(e,g);let p=null;if(ze(e)){const h=e.getName("facet");t=Pv(t,e.facet)??t,p=new bi(t,e,h,g.getSource()),n[h]=p;}return {...e.component.data,outputNodes:n,outputNodeRefCounts:i,raw:f,main:g,facetRoot:p,ancestorParse:o}}class Mv extends za{constructor(t,n,i,r){super(t,"concat",n,i,r,t.resolve),(t.resolve?.axis?.x==="shared"||t.resolve?.axis?.y==="shared")&&S(Yg),this.children=this.getChildren(t).map((s,o)=>Wa(s,this,this.getName(`concat_${o}`),void 0,r));}parseData(){this.component.data=Es(this);for(const t of this.children)t.parseData();}parseSelections(){this.component.selection={};for(const t of this.children){t.parseSelections();for(const n of x(t.component.selection))this.component.selection[n]=t.component.selection[n];}}parseMarkGroup(){for(const t of this.children)t.parseMarkGroup();}parseAxesAndHeaders(){for(const t of this.children)t.parseAxesAndHeaders();}getChildren(t){return is(t)?t.vconcat:ba(t)?t.hconcat:t.concat}parseLayoutSize(){Rv(this);}parseAxisGroup(){return null}assembleSelectionTopLevelSignals(t){return this.children.reduce((n,i)=>i.assembleSelectionTopLevelSignals(n),t)}assembleSignals(){return this.children.forEach(t=>t.assembleSignals()),[]}assembleLayoutSignals(){const t=Ta(this);for(const n of this.children)t.push(...n.assembleLayoutSignals());return t}assembleSelectionData(t){return this.children.reduce((n,i)=>i.assembleSelectionData(n),t)}assembleMarks(){return this.children.map(t=>{const n=t.assembleTitle(),i=t.assembleGroupStyle(),r=t.assembleGroupEncodeEntry(!1);return {type:"group",name:t.getName("group"),...n?{title:n}:{},...i?{style:i}:{},...r?{encode:{update:r}}:{},...t.assembleGroup()}})}assembleGroupStyle(){}assembleDefaultLayout(){const t=this.layout.columns;return {...t!=null?{columns:t}:{},bounds:"full",align:"each"}}}function jv(e){return e===!1||e===null}const Uv={disable:1,gridScale:1,scale:1,...gf,labelExpr:1,encode:1},ap=x(Uv);class Ma extends Dt{constructor(t={},n={},i=!1){super(),this.explicit=t,this.implicit=n,this.mainExtracted=i;}clone(){return new Ma(z(this.explicit),z(this.implicit),this.mainExtracted)}hasAxisPart(t){return t==="axis"?!0:t==="grid"||t==="title"?!!this.get(t):!jv(this.get(t))}hasOrientSignalRef(){return T(this.explicit.orient)}}function Bv(e,t,n){const{encoding:i,config:r}=e,s=fe(i[t])??fe(i[xt(t)]),o=e.axis(t)||{},{format:a,formatType:c}=o;if(Nn(c))return {text:Ke({fieldOrDatumDef:s,field:"datum.value",format:a,formatType:c,config:r}),...n};if(a===void 0&&c===void 0&&r.customFormatTypes){if(ii(s)==="quantitative"){if(ri(s)&&s.stack==="normalize"&&r.normalizedNumberFormatType)return {text:Ke({fieldOrDatumDef:s,field:"datum.value",format:r.normalizedNumberFormat,formatType:r.normalizedNumberFormatType,config:r}),...n};if(r.numberFormatType)return {text:Ke({fieldOrDatumDef:s,field:"datum.value",format:r.numberFormat,formatType:r.numberFormatType,config:r}),...n}}if(ii(s)==="temporal"&&r.timeFormatType&&v(s)&&!s.timeUnit)return {text:Ke({fieldOrDatumDef:s,field:"datum.value",format:r.timeFormat,formatType:r.timeFormatType,config:r}),...n}}return n}function Wv(e){return St.reduce((t,n)=>(e.component.scales[n]&&(t[n]=[Kv(n,e)]),t),{})}const Gv={bottom:"top",top:"bottom",left:"right",right:"left"};function Hv(e){const{axes:t,resolve:n}=e.component,i={top:0,bottom:0,right:0,left:0};for(const r of e.children){r.parseAxesAndHeaders();for(const s of x(r.component.axes))n.axis[s]=Aa(e.component.resolve,s),n.axis[s]==="shared"&&(t[s]=qv(t[s],r.component.axes[s]),t[s]||(n.axis[s]="independent",delete t[s]));}for(const r of St){for(const s of e.children)if(s.component.axes[r]){if(n.axis[r]==="independent"){t[r]=(t[r]??[]).concat(s.component.axes[r]);for(const o of s.component.axes[r]){const{value:a,explicit:c}=o.getWithExplicit("orient");if(!T(a)){if(i[a]>0&&!c){const l=Gv[a];i[a]>i[l]&&o.set("orient",l,!1);}i[a]++;}}}delete s.component.axes[r];}if(n.axis[r]==="independent"&&t[r]&&t[r].length>1)for(const[s,o]of (t[r]||[]).entries())s>0&&o.get("grid")&&!o.explicit.grid&&(o.implicit.grid=!1);}}function qv(e,t){if(e){if(e.length!==t.length)return;const n=e.length;for(let i=0;in.clone());return e}function Vv(e,t){for(const n of ap){const i=qt(e.getWithExplicit(n),t.getWithExplicit(n),n,"axis",(r,s)=>{switch(n){case"title":return bu(r,s);case"gridScale":return {explicit:r.explicit,value:le(r.value,s.value)}}return ss(r,s,n,"axis")});e.setWithExplicit(n,i);}return e}function Xv(e,t,n,i,r){if(t==="disable")return n!==void 0;switch(n=n||{},t){case"titleAngle":case"labelAngle":return e===(T(n.labelAngle)?n.labelAngle:Pi(n.labelAngle));case"values":return !!n.values;case"encode":return !!n.encoding||!!n.labelAngle;case"title":if(e===Cd(i,r))return !0}return e===n[t]}const Yv=new Set(["grid","translate","format","formatType","orient","labelExpr","tickCount","position","tickMinStep"]);function Kv(e,t){let n=t.axis(e);const i=new Ma,r=fe(t.encoding[e]),{mark:s,config:o}=t,a=n?.orient||o[e==="x"?"axisX":"axisY"]?.orient||o.axis?.orient||Px(e),c=t.getScaleComponent(e).get("type"),l=Tx(e,c,a,t.config),u=n!==void 0?!n:ao("disable",o.style,n?.style,l).configValue;if(i.set("disable",u,n!==void 0),u)return i;n=n||{};const f=Rx(r,n,e,o.style,l),d=Qu(n.formatType,r,c),g=Ju(r,r.type,n.format,n.formatType,o,!0),p={fieldOrDatumDef:r,axis:n,channel:e,model:t,scaleType:c,orient:a,labelAngle:f,format:g,formatType:d,mark:s,config:o};for(const y of ap){const b=y in Vc?Vc[y](p):Sc(y)?n[y]:void 0,C=b!==void 0,k=Xv(b,y,n,t,e);if(C&&k)i.set(y,b,k);else {const{configValue:N=void 0,configFrom:_=void 0}=Sc(y)&&y!=="values"?ao(y,o.style,n.style,l):{},L=N!==void 0;C&&!L?i.set(y,b,k):(_!=="vgAxisConfig"||Yv.has(y)&&L||Zi(N)||T(N))&&i.set(y,N,!1);}}const h=n.encoding??{},m=pf.reduce((y,b)=>{if(!i.hasAxisPart(b))return y;const C=Od(h[b]??{},t),k=b==="labels"?Bv(t,e,C):C;return k!==void 0&&!K(k)&&(y[b]={update:k}),y},{});return K(m)||i.set("encode",m,!!n.encoding||n.labelAngle!==void 0),i}function Jv({encoding:e,size:t}){for(const n of St){const i=_e(n);ht(t[i])&&Ut(e[n])&&(delete t[i],S($u(i)));}return t}const Qv={vgMark:"arc",encodeEntry:e=>({...Ge(e,{align:"ignore",baseline:"ignore",color:"include",size:"ignore",orient:"ignore",theta:"ignore"}),...Ee("x",e,{defaultPos:"mid"}),...Ee("y",e,{defaultPos:"mid"}),...Vt(e,"radius"),...Vt(e,"theta")})},Zv={vgMark:"area",encodeEntry:e=>({...Ge(e,{align:"ignore",baseline:"ignore",color:"include",orient:"include",size:"ignore",theta:"ignore"}),...Fr("x",e,{defaultPos:"zeroOrMin",defaultPos2:"zeroOrMin",range:e.markDef.orient==="horizontal"}),...Fr("y",e,{defaultPos:"zeroOrMin",defaultPos2:"zeroOrMin",range:e.markDef.orient==="vertical"}),...Ca(e)})},eE={vgMark:"rect",encodeEntry:e=>({...Ge(e,{align:"ignore",baseline:"ignore",color:"include",orient:"ignore",size:"ignore",theta:"ignore"}),...Vt(e,"x"),...Vt(e,"y")})},tE={vgMark:"shape",encodeEntry:e=>({...Ge(e,{align:"ignore",baseline:"ignore",color:"include",size:"ignore",orient:"ignore",theta:"ignore"})}),postEncodingTransform:e=>{const{encoding:t}=e,n=t.shape;return [{type:"geoshape",projection:e.projectionName(),...n&&v(n)&&n.type===hi?{field:E(n,{expr:"datum"})}:{}}]}},nE={vgMark:"image",encodeEntry:e=>({...Ge(e,{align:"ignore",baseline:"ignore",color:"ignore",orient:"ignore",size:"ignore",theta:"ignore"}),...Vt(e,"x"),...Vt(e,"y"),...$a(e,"url")})},iE={vgMark:"line",encodeEntry:e=>({...Ge(e,{align:"ignore",baseline:"ignore",color:"include",size:"ignore",orient:"ignore",theta:"ignore"}),...Ee("x",e,{defaultPos:"mid"}),...Ee("y",e,{defaultPos:"mid"}),...he("size",e,{vgChannel:"strokeWidth"}),...Ca(e)})},rE={vgMark:"trail",encodeEntry:e=>({...Ge(e,{align:"ignore",baseline:"ignore",color:"include",size:"include",orient:"ignore",theta:"ignore"}),...Ee("x",e,{defaultPos:"mid"}),...Ee("y",e,{defaultPos:"mid"}),...he("size",e),...Ca(e)})};function ja(e,t){const{config:n}=e;return {...Ge(e,{align:"ignore",baseline:"ignore",color:"include",size:"include",orient:"ignore",theta:"ignore"}),...Ee("x",e,{defaultPos:"mid"}),...Ee("y",e,{defaultPos:"mid"}),...he("size",e),...he("angle",e),...sE(e,n,t)}}function sE(e,t,n){return n?{shape:{value:n}}:he("shape",e)}const oE={vgMark:"symbol",encodeEntry:e=>ja(e)},aE={vgMark:"symbol",encodeEntry:e=>ja(e,"circle")},cE={vgMark:"symbol",encodeEntry:e=>ja(e,"square")},lE={vgMark:"rect",encodeEntry:e=>({...Ge(e,{align:"ignore",baseline:"ignore",color:"include",orient:"ignore",size:"ignore",theta:"ignore"}),...Vt(e,"x"),...Vt(e,"y")})},uE={vgMark:"rule",encodeEntry:e=>{const{markDef:t}=e,n=t.orient;return !e.encoding.x&&!e.encoding.y&&!e.encoding.latitude&&!e.encoding.longitude?{}:{...Ge(e,{align:"ignore",baseline:"ignore",color:"include",orient:"ignore",size:"ignore",theta:"ignore"}),...Fr("x",e,{defaultPos:n==="horizontal"?"zeroOrMax":"mid",defaultPos2:"zeroOrMin",range:n!=="vertical"}),...Fr("y",e,{defaultPos:n==="vertical"?"zeroOrMax":"mid",defaultPos2:"zeroOrMin",range:n!=="horizontal"}),...he("size",e,{vgChannel:"strokeWidth"})}}},fE={vgMark:"text",encodeEntry:e=>{const{config:t,encoding:n}=e;return {...Ge(e,{align:"include",baseline:"include",color:"include",size:"ignore",orient:"ignore",theta:"include"}),...Ee("x",e,{defaultPos:"mid"}),...Ee("y",e,{defaultPos:"mid"}),...$a(e),...he("size",e,{vgChannel:"fontSize"}),...he("angle",e),...Wc("align",dE(e.markDef,n,t)),...Wc("baseline",pE(e.markDef,n,t)),...Ee("radius",e,{defaultPos:null}),...Ee("theta",e,{defaultPos:null})}}};function dE(e,t,n){if(X("align",e,n)===void 0)return "center"}function pE(e,t,n){if(X("baseline",e,n)===void 0)return "middle"}const gE={vgMark:"rect",encodeEntry:e=>{const{config:t,markDef:n}=e,i=n.orient,r=i==="horizontal"?"width":"height",s=i==="horizontal"?"height":"width";return {...Ge(e,{align:"ignore",baseline:"ignore",color:"include",orient:"ignore",size:"ignore",theta:"ignore"}),...Ee("x",e,{defaultPos:"mid",vgChannel:"xc"}),...Ee("y",e,{defaultPos:"mid",vgChannel:"yc"}),...he("size",e,{defaultValue:hE(e),vgChannel:r}),[s]:ne(X("thickness",n,t))}}};function hE(e){const{config:t,markDef:n}=e,{orient:i}=n,r=i==="horizontal"?"width":"height",s=e.getScaleComponent(i==="horizontal"?"x":"y"),o=X("size",n,t,{vgChannel:r})??t.tick.bandSize;if(o!==void 0)return o;{const a=s?s.get("range"):void 0;return a&&nn(a)&&Mr$1(a.step)?a.step*3/4:Cr(t.view,r)*3/4}}const cr={arc:Qv,area:Zv,bar:eE,circle:aE,geoshape:tE,image:nE,line:iE,point:oE,rect:lE,rule:uE,square:cE,text:fE,tick:gE,trail:rE};function mE(e){if(G([Vr,Hr,wm],e.mark)){const t=xf(e.mark,e.encoding);if(t.length>0)return yE(e,t)}else if(e.mark===qr){const t=Ys.some(n=>X(n,e.markDef,e.config));if(e.stack&&!e.fieldDef("size")&&t)return bE(e)}return Ua(e)}const ll="faceted_path_";function yE(e,t){return [{name:e.getName("pathgroup"),type:"group",from:{facet:{name:ll+e.requestDataName(Z.Main),data:e.requestDataName(Z.Main),groupby:t}},encode:{update:{width:{field:{group:"width"}},height:{field:{group:"height"}}}},marks:Ua(e,{fromPrefix:ll})}]}const ul="stack_group_";function bE(e){const[t]=Ua(e,{fromPrefix:ul}),n=e.scaleName(e.stack.fieldChannel),i=(l={})=>e.vgField(e.stack.fieldChannel,l),r=(l,u)=>{const f=[i({prefix:"min",suffix:"start",expr:u}),i({prefix:"max",suffix:"start",expr:u}),i({prefix:"min",suffix:"end",expr:u}),i({prefix:"max",suffix:"end",expr:u})];return `${l}(${f.map(d=>`scale('${n}',${d})`).join(",")})`};let s,o;e.stack.fieldChannel==="x"?(s={...Jn(t.encode.update,["y","yc","y2","height",...Ys]),x:{signal:r("min","datum")},x2:{signal:r("max","datum")},clip:{value:!0}},o={x:{field:{group:"x"},mult:-1},height:{field:{group:"height"}}},t.encode.update={...ke(t.encode.update,["y","yc","y2"]),height:{field:{group:"height"}}}):(s={...Jn(t.encode.update,["x","xc","x2","width"]),y:{signal:r("min","datum")},y2:{signal:r("max","datum")},clip:{value:!0}},o={y:{field:{group:"y"},mult:-1},width:{field:{group:"width"}}},t.encode.update={...ke(t.encode.update,["x","xc","x2"]),width:{field:{group:"width"}}});for(const l of Ys){const u=Ot(l,e.markDef,e.config);t.encode.update[l]?(s[l]=t.encode.update[l],delete t.encode.update[l]):u&&(s[l]=ne(u)),u&&(t.encode.update[l]={value:0});}const a=[];if(e.stack.groupbyChannels?.length>0)for(const l of e.stack.groupbyChannels){const u=e.fieldDef(l),f=E(u);f&&a.push(f),(u?.bin||u?.timeUnit)&&a.push(E(u,{binSuffix:"end"}));}return s=["stroke","strokeWidth","strokeJoin","strokeCap","strokeDash","strokeDashOffset","strokeMiterLimit","strokeOpacity"].reduce((l,u)=>{if(t.encode.update[u])return {...l,[u]:t.encode.update[u]};{const f=Ot(u,e.markDef,e.config);return f!==void 0?{...l,[u]:ne(f)}:l}},s),s.stroke&&(s.strokeForeground={value:!0},s.strokeOffset={value:0}),[{type:"group",from:{facet:{data:e.requestDataName(Z.Main),name:ul+e.requestDataName(Z.Main),groupby:a,aggregate:{fields:[i({suffix:"start"}),i({suffix:"start"}),i({suffix:"end"}),i({suffix:"end"})],ops:["min","max","min","max"]}}},encode:{update:s},marks:[{type:"group",encode:{update:o},marks:[t]}]}]}function xE(e){const{encoding:t,stack:n,mark:i,markDef:r,config:s}=e,o=t.order;if(!(!U(o)&&Qe(o)&&Vs(o.value)||!o&&Vs(X("order",r,s)))){if((U(o)||v(o))&&!n)return hu(o,{expr:"datum"});if(rn(i)){const a=r.orient==="horizontal"?"y":"x",c=t[a];if(v(c)){const l=c.sort;if(U(l))return {field:E(c,{prefix:a,suffix:"sort_index",expr:"datum"})};if(ut(l))return {field:E({aggregate:ca(e.encoding)?l.op:void 0,field:l.field},{expr:"datum"})};if(ef(l)){const u=e.fieldDef(l.encoding);return {field:E(u,{expr:"datum"}),order:l.order}}else return l===null?void 0:{field:E(c,{binSuffix:e.stack?.impute?"mid":void 0,expr:"datum"})}}return}}}function Ua(e,t={fromPrefix:""}){const{mark:n,markDef:i,encoding:r,config:s}=e,o=le(i.clip,SE(e),vE(e)),a=pu(i),c=r.key,l=xE(e),u=EE(e),f=X("aria",i,s),d=cr[n].postEncodingTransform?cr[n].postEncodingTransform(e):null;return [{name:e.getName("marks"),type:cr[n].vgMark,...o?{clip:o}:{},...a?{style:a}:{},...c?{key:c.field}:{},...l?{sort:l}:{},...u||{},...f===!1?{aria:f}:{},from:{data:t.fromPrefix+e.requestDataName(Z.Main)},encode:{update:cr[n].encodeEntry(e)},...d?{transform:d}:{}}]}function SE(e){const t=e.getScaleComponent("x"),n=e.getScaleComponent("y");return t?.get("selectionExtent")||n?.get("selectionExtent")?!0:void 0}function vE(e){const t=e.component.projection;return t&&!t.isFit?!0:void 0}function EE(e){if(!e.component.selection)return null;const t=x(e.component.selection).length;let n=t,i=e.parent;for(;i&&n===0;)n=x(i.component.selection).length,i=i.parent;return n?{interactive:t>0||e.mark==="geoshape"||!!e.encoding.tooltip||!!e.markDef.tooltip}:null}class cp extends ip{constructor(t,n,i,r={},s){super(t,"unit",n,i,s,void 0,Ec(t)?t.view:void 0),this.specifiedScales={},this.specifiedAxes={},this.specifiedLegends={},this.specifiedProjection={},this.selection=[],this.children=[];const o=pt(t.mark)?{...t.mark}:{type:t.mark},a=o.type;o.filled===void 0&&(o.filled=ob(o,s,{graticule:t.data&&va(t.data)}));const c=this.encoding=uy(t.encoding||{},a,o.filled,s);this.markDef=jf(o,c,s),this.size=Jv({encoding:c,size:Ec(t)?{...r,...t.width?{width:t.width}:{},...t.height?{height:t.height}:{}}:r}),this.stack=Mf(this.markDef,c),this.specifiedScales=this.initScales(a,c),this.specifiedAxes=this.initAxes(c),this.specifiedLegends=this.initLegends(c),this.specifiedProjection=t.projection,this.selection=(t.params??[]).filter(l=>ma(l));}get hasProjection(){const{encoding:t}=this,n=this.mark===qu,i=t&&cg.some(r=>D(t[r]));return n||i}scaleDomain(t){const n=this.specifiedScales[t];return n?n.domain:void 0}axis(t){return this.specifiedAxes[t]}legend(t){return this.specifiedLegends[t]}initScales(t,n){return Ur.reduce((i,r)=>{const s=fe(n[r]);return s&&(i[r]=this.initScale(s.scale??{})),i},{})}initScale(t){const{domain:n,range:i}=t,r=Fe(t);return U(n)&&(r.domain=n.map(Le)),U(i)&&(r.range=i.map(Le)),r}initAxes(t){return St.reduce((n,i)=>{const r=t[i];if(D(r)||i===se&&D(t.x2)||i===be&&D(t.y2)){const s=D(r)?r.axis:void 0;n[i]=s&&this.initAxis({...s});}return n},{})}initAxis(t){const n=x(t),i={};for(const r of n){const s=t[r];i[r]=Zi(s)?du(s):Le(s);}return i}initLegends(t){return bg.reduce((n,i)=>{const r=fe(t[i]);if(r&&Sg(i)){const s=r.legend;n[i]=s&&Fe(s);}return n},{})}parseData(){this.component.data=Es(this);}parseLayoutSize(){Iv(this);}parseSelections(){this.component.selection=Cx(this,this.selection);}parseMarkGroup(){this.component.mark=mE(this);}parseAxesAndHeaders(){this.component.axes=Wv(this);}assembleSelectionTopLevelSignals(t){return Vb(this,t)}assembleSignals(){return [...Ed(this),...Hb(this,[])]}assembleSelectionData(t){return Xb(this,t)}assembleLayout(){return null}assembleLayoutSignals(){return Ta(this)}assembleMarks(){let t=this.component.mark??[];return (!this.parent||!Si(this.parent))&&(t=Zf(this,t)),t.map(this.correctDataNames)}assembleGroupStyle(){const{style:t}=this.view||{};return t!==void 0?t:this.encoding.x||this.encoding.y?"cell":"view"}getMapping(){return this.encoding}get mark(){return this.markDef.type}channelHasField(t){return yn(this.encoding,t)}fieldDef(t){const n=this.encoding[t];return gt(n)}typedFieldDef(t){const n=this.fieldDef(t);return Ce(n)?n:null}}class Ba extends za{constructor(t,n,i,r,s){super(t,"layer",n,i,s,t.resolve,t.view);const o={...r,...t.width?{width:t.width}:{},...t.height?{height:t.height}:{}};this.children=t.layer.map((a,c)=>{if(rs(a))return new Ba(a,this,this.getName(`layer_${c}`),o,s);if(zt(a))return new cp(a,this,this.getName(`layer_${c}`),o,s);throw new Error(Lo(a))});}parseData(){this.component.data=Es(this);for(const t of this.children)t.parseData();}parseLayoutSize(){_v(this);}parseSelections(){this.component.selection={};for(const t of this.children){t.parseSelections();for(const n of x(t.component.selection))this.component.selection[n]=t.component.selection[n];}}parseMarkGroup(){for(const t of this.children)t.parseMarkGroup();}parseAxesAndHeaders(){Hv(this);}assembleSelectionTopLevelSignals(t){return this.children.reduce((n,i)=>i.assembleSelectionTopLevelSignals(n),t)}assembleSignals(){return this.children.reduce((t,n)=>t.concat(n.assembleSignals()),Ed(this))}assembleLayoutSignals(){return this.children.reduce((t,n)=>t.concat(n.assembleLayoutSignals()),Ta(this))}assembleSelectionData(t){return this.children.reduce((n,i)=>i.assembleSelectionData(n),t)}assembleGroupStyle(){const t=new Set;for(const i of this.children)for(const r of H(i.assembleGroupStyle()))t.add(r);const n=Array.from(t);return n.length>1?n:n.length===1?n[0]:void 0}assembleTitle(){let t=super.assembleTitle();if(t)return t;for(const n of this.children)if(t=n.assembleTitle(),t)return t}assembleLayout(){return null}assembleMarks(){return Yb(this,this.children.flatMap(t=>t.assembleMarks()))}assembleLegends(){return this.children.reduce((t,n)=>t.concat(n.assembleLegends()),Md(this))}}function Wa(e,t,n,i,r){if(Kr(e))return new Ri(e,t,n,r);if(rs(e))return new Ba(e,t,n,i,r);if(zt(e))return new cp(e,t,n,i,r);if(Iy(e))return new Mv(e,t,n,r);throw new Error(Lo(e))}function $E(e,t={}){t.logger&&Mh(t.logger),t.fieldTitle&&uf(t.fieldTitle);try{const n=Df(v3(t.config,e.config)),i=Vf(e,n),r=Wa(i,null,"",void 0,n);return r.parse(),VS(r.component.data,r),{spec:CE(r,wE(e,i.autosize,n,r),e.datasets,e.usermeta),normalized:i}}finally{t.logger&&jh(),t.fieldTitle&&ty();}}function wE(e,t,n,i){const r=i.component.layoutSize.get("width"),s=i.component.layoutSize.get("height");if(t===void 0?(t={type:"pad"},i.hasAxisOrientSignalRef()&&(t.resize=!0)):xt$1(t)&&(t={type:t}),r&&s&&Ub(t.type)){if(r==="step"&&s==="step")S(oc()),t.type="pad";else if(r==="step"||s==="step"){const o=r==="step"?"width":"height";S(oc(jr(o)));const a=o==="width"?"height":"width";t.type=Bb(a);}}return {...x(t).length===1&&t.type?t.type==="pad"?{}:{autosize:t.type}:{autosize:t},...Ic(n,!1),...Ic(e,!0)}}function CE(e,t,n={},i){const r=e.config?Xy(e.config):void 0,s=[].concat(e.assembleSelectionData([]),kv(e.component.data,n)),o=e.assembleProjections(),a=e.assembleTitle(),c=e.assembleGroupStyle(),l=e.assembleGroupEncodeEntry(!0);let u=e.assembleLayoutSignals();u=u.filter(g=>(g.name==="width"||g.name==="height")&&g.value!==void 0?(t[g.name]=+g.value,!1):!0);const{params:f,...d}=t;return {$schema:"https://vega.github.io/schema/vega/v5.json",...e.description?{description:e.description}:{},...d,...a?{title:a}:{},...c?{style:c}:{},...l?{encode:{update:l}}:{},data:s,...o.length>0?{projections:o}:{},...e.assembleGroup([...u,...e.assembleSelectionTopLevelSignals([]),...If(f)]),...r?{config:r}:{},...i?{usermeta:i}:{}}}const NE=ng.version,FE=Object.freeze(Object.defineProperty({__proto__:null,accessPathDepth:Qn,accessPathWithDatum:Co,compile:$E,contains:G,deepEqual:Pe,deleteNestedProperty:hr,duplicate:z,entries:Wt,every:Eo,fieldIntersection:wo,flatAccessWithDatum:ql,getFirstDefined:le,hasIntersection:$o,hash:W,internalField:Yl,isBoolean:Li,isEmpty:K,isEqual:rg,isInternalField:Kl,isNullOrFalse:Vs,isNumeric:Ir,keys:x,logicalExpr:Oi,mergeDeep:Gl,never:Wl,normalize:Vf,normalizeAngle:Pi,omit:ke,pick:Jn,prefixGenerator:Xs,removePathFromField:No,replaceAll:vn,replacePathInField:Ue,resetIdCounter:og,setEqual:Hl,some:Sn,stringify:J,titleCase:Wi,unique:lt,uniqueId:Xl,vals:Se,varName:re,version:NE},Symbol.toStringTag,{value:"Module"}));function lp(e){const[t,n]=/schema\/([\w-]+)\/([\w\.\-]+)\.json$/g.exec(e).slice(1,3);return {library:t,version:n}}var kE="vega-themes",TE="2.14.0",AE="Themes for stylized Vega and Vega-Lite visualizations.",OE=["vega","vega-lite","themes","style"],_E="BSD-3-Clause",RE={name:"UW Interactive Data Lab",url:"https://idl.cs.washington.edu"},IE=[{name:"Emily Gu",url:"https://github.com/emilygu"},{name:"Arvind Satyanarayan",url:"http://arvindsatya.com"},{name:"Jeffrey Heer",url:"https://idl.cs.washington.edu"},{name:"Dominik Moritz",url:"https://www.domoritz.de"}],LE="build/vega-themes.js",PE="build/vega-themes.module.js",zE="build/vega-themes.min.js",DE="build/vega-themes.min.js",ME="build/vega-themes.module.d.ts",jE={type:"git",url:"https://github.com/vega/vega-themes.git"},UE=["src","build"],BE={prebuild:"yarn clean",build:"rollup -c",clean:"rimraf build && rimraf examples/build","copy:data":"rsync -r node_modules/vega-datasets/data/* examples/data","copy:build":"rsync -r build/* examples/build","deploy:gh":"yarn build && mkdir -p examples/build && rsync -r build/* examples/build && gh-pages -d examples",preversion:"yarn lint",serve:"browser-sync start -s -f build examples --serveStatic examples",start:"yarn build && concurrently --kill-others -n Server,Rollup 'yarn serve' 'rollup -c -w'",format:"eslint . --fix",lint:"eslint .",release:"release-it"},WE={"@babel/core":"^7.22.9","@babel/plugin-proposal-async-generator-functions":"^7.20.7","@babel/plugin-proposal-json-strings":"^7.18.6","@babel/plugin-proposal-object-rest-spread":"^7.20.7","@babel/plugin-proposal-optional-catch-binding":"^7.18.6","@babel/plugin-transform-runtime":"^7.22.9","@babel/preset-env":"^7.22.9","@babel/preset-typescript":"^7.22.5","@release-it/conventional-changelog":"^7.0.0","@rollup/plugin-json":"^6.0.0","@rollup/plugin-node-resolve":"^15.1.0","@rollup/plugin-terser":"^0.4.3","@typescript-eslint/eslint-plugin":"^6.0.0","@typescript-eslint/parser":"^6.0.0","browser-sync":"^2.29.3",concurrently:"^8.2.0",eslint:"^8.45.0","eslint-config-prettier":"^8.8.0","eslint-plugin-prettier":"^5.0.0","gh-pages":"^5.0.0",prettier:"^3.0.0","release-it":"^16.1.0",rollup:"^3.26.2","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-ts":"^3.2.0",typescript:"^5.1.6",vega:"^5.25.0","vega-lite":"^5.9.3"},GE={vega:"*","vega-lite":"*"},HE={},qE={name:kE,version:TE,description:AE,keywords:OE,license:_E,author:RE,contributors:IE,main:LE,module:PE,unpkg:zE,jsdelivr:DE,types:ME,repository:jE,files:UE,scripts:BE,devDependencies:WE,peerDependencies:GE,dependencies:HE};const Un="#fff",fl="#888",VE={background:"#333",view:{stroke:fl},title:{color:Un,subtitleColor:Un},style:{"guide-label":{fill:Un},"guide-title":{fill:Un}},axis:{domainColor:Un,gridColor:fl,tickColor:Un}},an="#4572a7",XE={background:"#fff",arc:{fill:an},area:{fill:an},line:{stroke:an,strokeWidth:2},path:{stroke:an},rect:{fill:an},shape:{stroke:an},symbol:{fill:an,strokeWidth:1.5,size:50},axis:{bandPosition:.5,grid:!0,gridColor:"#000000",gridOpacity:1,gridWidth:.5,labelPadding:10,tickSize:5,tickWidth:.5},axisBand:{grid:!1,tickExtra:!0},legend:{labelBaseline:"middle",labelFontSize:11,symbolSize:50,symbolType:"square"},range:{category:["#4572a7","#aa4643","#8aa453","#71598e","#4598ae","#d98445","#94aace","#d09393","#b9cc98","#a99cbc"]}},cn="#30a2da",Ds="#cbcbcb",YE="#999",KE="#333",dl="#f0f0f0",pl="#333",JE={arc:{fill:cn},area:{fill:cn},axis:{domainColor:Ds,grid:!0,gridColor:Ds,gridWidth:1,labelColor:YE,labelFontSize:10,titleColor:KE,tickColor:Ds,tickSize:10,titleFontSize:14,titlePadding:10,labelPadding:4},axisBand:{grid:!1},background:dl,group:{fill:dl},legend:{labelColor:pl,labelFontSize:11,padding:1,symbolSize:30,symbolType:"square",titleColor:pl,titleFontSize:14,titlePadding:10},line:{stroke:cn,strokeWidth:2},path:{stroke:cn,strokeWidth:.5},rect:{fill:cn},range:{category:["#30a2da","#fc4f30","#e5ae38","#6d904f","#8b8b8b","#b96db8","#ff9e27","#56cc60","#52d2ca","#52689e","#545454","#9fe4f8"],diverging:["#cc0020","#e77866","#f6e7e1","#d6e8ed","#91bfd9","#1d78b5"],heatmap:["#d6e8ed","#cee0e5","#91bfd9","#549cc6","#1d78b5"]},point:{filled:!0,shape:"circle"},shape:{stroke:cn},bar:{binSpacing:2,fill:cn,stroke:null},title:{anchor:"start",fontSize:24,fontWeight:600,offset:20}},ln="#000",QE={group:{fill:"#e5e5e5"},arc:{fill:ln},area:{fill:ln},line:{stroke:ln},path:{stroke:ln},rect:{fill:ln},shape:{stroke:ln},symbol:{fill:ln,size:40},axis:{domain:!1,grid:!0,gridColor:"#FFFFFF",gridOpacity:1,labelColor:"#7F7F7F",labelPadding:4,tickColor:"#7F7F7F",tickSize:5.67,titleFontSize:16,titleFontWeight:"normal"},legend:{labelBaseline:"middle",labelFontSize:11,symbolSize:40},range:{category:["#000000","#7F7F7F","#1A1A1A","#999999","#333333","#B0B0B0","#4D4D4D","#C9C9C9","#666666","#DCDCDC"]}},ZE=22,e$="normal",gl="Benton Gothic, sans-serif",hl=11.5,t$="normal",un="#82c6df",Ms="Benton Gothic Bold, sans-serif",ml="normal",yl=13,$i={"category-6":["#ec8431","#829eb1","#c89d29","#3580b1","#adc839","#ab7fb4"],"fire-7":["#fbf2c7","#f9e39c","#f8d36e","#f4bb6a","#e68a4f","#d15a40","#ab4232"],"fireandice-6":["#e68a4f","#f4bb6a","#f9e39c","#dadfe2","#a6b7c6","#849eae"],"ice-7":["#edefee","#dadfe2","#c4ccd2","#a6b7c6","#849eae","#607785","#47525d"]},n$={background:"#ffffff",title:{anchor:"start",color:"#000000",font:Ms,fontSize:ZE,fontWeight:e$},arc:{fill:un},area:{fill:un},line:{stroke:un,strokeWidth:2},path:{stroke:un},rect:{fill:un},shape:{stroke:un},symbol:{fill:un,size:30},axis:{labelFont:gl,labelFontSize:hl,labelFontWeight:t$,titleFont:Ms,titleFontSize:yl,titleFontWeight:ml},axisX:{labelAngle:0,labelPadding:4,tickSize:3},axisY:{labelBaseline:"middle",maxExtent:45,minExtent:45,tickSize:2,titleAlign:"left",titleAngle:0,titleX:-45,titleY:-11},legend:{labelFont:gl,labelFontSize:hl,symbolType:"square",titleFont:Ms,titleFontSize:yl,titleFontWeight:ml},range:{category:$i["category-6"],diverging:$i["fireandice-6"],heatmap:$i["fire-7"],ordinal:$i["fire-7"],ramp:$i["fire-7"]}},fn="#ab5787",lr="#979797",i$={background:"#f9f9f9",arc:{fill:fn},area:{fill:fn},line:{stroke:fn},path:{stroke:fn},rect:{fill:fn},shape:{stroke:fn},symbol:{fill:fn,size:30},axis:{domainColor:lr,domainWidth:.5,gridWidth:.2,labelColor:lr,tickColor:lr,tickWidth:.2,titleColor:lr},axisBand:{grid:!1},axisX:{grid:!0,tickSize:10},axisY:{domain:!1,grid:!0,tickSize:0},legend:{labelFontSize:11,padding:1,symbolSize:30,symbolType:"square"},range:{category:["#ab5787","#51b2e5","#703c5c","#168dd9","#d190b6","#00609f","#d365ba","#154866","#666666","#c4c4c4"]}},dn="#3e5c69",r$={background:"#fff",arc:{fill:dn},area:{fill:dn},line:{stroke:dn},path:{stroke:dn},rect:{fill:dn},shape:{stroke:dn},symbol:{fill:dn},axis:{domainWidth:.5,grid:!0,labelPadding:2,tickSize:5,tickWidth:.5,titleFontWeight:"normal"},axisBand:{grid:!1},axisX:{gridWidth:.2},axisY:{gridDash:[3],gridWidth:.4},legend:{labelFontSize:11,padding:1,symbolType:"square"},range:{category:["#3e5c69","#6793a6","#182429","#0570b0","#3690c0","#74a9cf","#a6bddb","#e2ddf2"]}},Me="#1696d2",bl="#000000",s$="#FFFFFF",ur="Lato",js="Lato",o$="Lato",a$="#DEDDDD",c$=18,wi={"main-colors":["#1696d2","#d2d2d2","#000000","#fdbf11","#ec008b","#55b748","#5c5859","#db2b27"],"shades-blue":["#CFE8F3","#A2D4EC","#73BFE2","#46ABDB","#1696D2","#12719E","#0A4C6A","#062635"],"shades-gray":["#F5F5F5","#ECECEC","#E3E3E3","#DCDBDB","#D2D2D2","#9D9D9D","#696969","#353535"],"shades-yellow":["#FFF2CF","#FCE39E","#FDD870","#FCCB41","#FDBF11","#E88E2D","#CA5800","#843215"],"shades-magenta":["#F5CBDF","#EB99C2","#E46AA7","#E54096","#EC008B","#AF1F6B","#761548","#351123"],"shades-green":["#DCEDD9","#BCDEB4","#98CF90","#78C26D","#55B748","#408941","#2C5C2D","#1A2E19"],"shades-black":["#D5D5D4","#ADABAC","#848081","#5C5859","#332D2F","#262223","#1A1717","#0E0C0D"],"shades-red":["#F8D5D4","#F1AAA9","#E9807D","#E25552","#DB2B27","#A4201D","#6E1614","#370B0A"],"one-group":["#1696d2","#000000"],"two-groups-cat-1":["#1696d2","#000000"],"two-groups-cat-2":["#1696d2","#fdbf11"],"two-groups-cat-3":["#1696d2","#db2b27"],"two-groups-seq":["#a2d4ec","#1696d2"],"three-groups-cat":["#1696d2","#fdbf11","#000000"],"three-groups-seq":["#a2d4ec","#1696d2","#0a4c6a"],"four-groups-cat-1":["#000000","#d2d2d2","#fdbf11","#1696d2"],"four-groups-cat-2":["#1696d2","#ec0008b","#fdbf11","#5c5859"],"four-groups-seq":["#cfe8f3","#73bf42","#1696d2","#0a4c6a"],"five-groups-cat-1":["#1696d2","#fdbf11","#d2d2d2","#ec008b","#000000"],"five-groups-cat-2":["#1696d2","#0a4c6a","#d2d2d2","#fdbf11","#332d2f"],"five-groups-seq":["#cfe8f3","#73bf42","#1696d2","#0a4c6a","#000000"],"six-groups-cat-1":["#1696d2","#ec008b","#fdbf11","#000000","#d2d2d2","#55b748"],"six-groups-cat-2":["#1696d2","#d2d2d2","#ec008b","#fdbf11","#332d2f","#0a4c6a"],"six-groups-seq":["#cfe8f3","#a2d4ec","#73bfe2","#46abdb","#1696d2","#12719e"],"diverging-colors":["#ca5800","#fdbf11","#fdd870","#fff2cf","#cfe8f3","#73bfe2","#1696d2","#0a4c6a"]},l$={background:s$,title:{anchor:"start",fontSize:c$,font:ur},axisX:{domain:!0,domainColor:bl,domainWidth:1,grid:!1,labelFontSize:12,labelFont:js,labelAngle:0,tickColor:bl,tickSize:5,titleFontSize:12,titlePadding:10,titleFont:ur},axisY:{domain:!1,domainWidth:1,grid:!0,gridColor:a$,gridWidth:1,labelFontSize:12,labelFont:js,labelPadding:8,ticks:!1,titleFontSize:12,titlePadding:10,titleFont:ur,titleAngle:0,titleY:-10,titleX:18},legend:{labelFontSize:12,labelFont:js,symbolSize:100,titleFontSize:12,titlePadding:10,titleFont:ur,orient:"right",offset:10},view:{stroke:"transparent"},range:{category:wi["six-groups-cat-1"],diverging:wi["diverging-colors"],heatmap:wi["diverging-colors"],ordinal:wi["six-groups-seq"],ramp:wi["shades-blue"]},area:{fill:Me},rect:{fill:Me},line:{color:Me,stroke:Me,strokeWidth:5},trail:{color:Me,stroke:Me,strokeWidth:0,size:1},path:{stroke:Me,strokeWidth:.5},point:{filled:!0},text:{font:o$,color:Me,fontSize:11,align:"center",fontWeight:400,size:11},style:{bar:{fill:Me,stroke:null}},arc:{fill:Me},shape:{stroke:Me},symbol:{fill:Me,size:30}},pn="#3366CC",xl="#ccc",fr="Arial, sans-serif",u$={arc:{fill:pn},area:{fill:pn},path:{stroke:pn},rect:{fill:pn},shape:{stroke:pn},symbol:{stroke:pn},circle:{fill:pn},background:"#fff",padding:{top:10,right:10,bottom:10,left:10},style:{"guide-label":{font:fr,fontSize:12},"guide-title":{font:fr,fontSize:12},"group-title":{font:fr,fontSize:12}},title:{font:fr,fontSize:14,fontWeight:"bold",dy:-3,anchor:"start"},axis:{gridColor:xl,tickColor:xl,domain:!1,grid:!0},range:{category:["#4285F4","#DB4437","#F4B400","#0F9D58","#AB47BC","#00ACC1","#FF7043","#9E9D24","#5C6BC0","#F06292","#00796B","#C2185B"],heatmap:["#c6dafc","#5e97f6","#2a56c6"]}},Ga=e=>e*(1/3+1),Sl=Ga(9),vl=Ga(10),El=Ga(12),Ci="Segoe UI",$l="wf_standard-font, helvetica, arial, sans-serif",wl="#252423",Ni="#605E5C",Cl="transparent",f$="#C8C6C4",qe="#118DFF",d$="#12239E",p$="#E66C37",g$="#6B007B",h$="#E044A7",m$="#744EC2",y$="#D9B300",b$="#D64550",up=qe,fp="#DEEFFF",Nl=[fp,up],x$=[fp,"#c7e4ff","#b0d9ff","#9aceff","#83c3ff","#6cb9ff","#55aeff","#3fa3ff","#2898ff",up],S$={view:{stroke:Cl},background:Cl,font:Ci,header:{titleFont:$l,titleFontSize:El,titleColor:wl,labelFont:Ci,labelFontSize:vl,labelColor:Ni},axis:{ticks:!1,grid:!1,domain:!1,labelColor:Ni,labelFontSize:Sl,titleFont:$l,titleColor:wl,titleFontSize:El,titleFontWeight:"normal"},axisQuantitative:{tickCount:3,grid:!0,gridColor:f$,gridDash:[1,5],labelFlush:!1},axisBand:{tickExtra:!0},axisX:{labelPadding:5},axisY:{labelPadding:10},bar:{fill:qe},line:{stroke:qe,strokeWidth:3,strokeCap:"round",strokeJoin:"round"},text:{font:Ci,fontSize:Sl,fill:Ni},arc:{fill:qe},area:{fill:qe,line:!0,opacity:.6},path:{stroke:qe},rect:{fill:qe},point:{fill:qe,filled:!0,size:75},shape:{stroke:qe},symbol:{fill:qe,strokeWidth:1.5,size:50},legend:{titleFont:Ci,titleFontWeight:"bold",titleColor:Ni,labelFont:Ci,labelFontSize:vl,labelColor:Ni,symbolType:"circle",symbolSize:75},range:{category:[qe,d$,p$,g$,h$,m$,y$,b$],diverging:Nl,heatmap:Nl,ordinal:x$}},Us='IBM Plex Sans,system-ui,-apple-system,BlinkMacSystemFont,".sfnstext-regular",sans-serif',Fl=400,v$=["#8a3ffc","#33b1ff","#007d79","#ff7eb6","#fa4d56","#fff1f1","#6fdc8c","#4589ff","#d12771","#d2a106","#08bdba","#bae6ff","#ba4e00","#d4bbff"],E$=["#6929c4","#1192e8","#005d5d","#9f1853","#fa4d56","#570408","#198038","#002d9c","#ee538b","#b28600","#009d9a","#012749","#8a3800","#a56eff"];function $s({type:e,background:t}){const n=e==="dark"?"#161616":"#ffffff",i=e==="dark"?"#f4f4f4":"#161616",r=e==="dark"?v$:E$,s=e==="dark"?"#d4bbff":"#6929c4";return {background:t,arc:{fill:s},area:{fill:s},path:{stroke:s},rect:{fill:s},shape:{stroke:s},symbol:{stroke:s},circle:{fill:s},view:{fill:n,stroke:n},group:{fill:n},title:{color:i,anchor:"start",dy:-15,fontSize:16,font:Us,fontWeight:600},axis:{labelColor:i,labelFontSize:12,grid:!0,gridColor:"#525252",titleColor:i,labelAngle:0},style:{"guide-label":{font:Us,fill:i,fontWeight:Fl},"guide-title":{font:Us,fill:i,fontWeight:Fl}},range:{category:r,diverging:["#750e13","#a2191f","#da1e28","#fa4d56","#ff8389","#ffb3b8","#ffd7d9","#fff1f1","#e5f6ff","#bae6ff","#82cfff","#33b1ff","#1192e8","#0072c3","#00539a","#003a6d"],heatmap:["#f6f2ff","#e8daff","#d4bbff","#be95ff","#a56eff","#8a3ffc","#6929c4","#491d8b","#31135e","#1c0f30"]}}}const $$=$s({type:"light",background:"#ffffff"}),w$=$s({type:"light",background:"#f4f4f4"}),C$=$s({type:"dark",background:"#262626"}),N$=$s({type:"dark",background:"#161616"}),F$=qE.version,k$=Object.freeze(Object.defineProperty({__proto__:null,carbong10:w$,carbong100:N$,carbong90:C$,carbonwhite:$$,dark:VE,excel:XE,fivethirtyeight:JE,ggplot2:QE,googlecharts:u$,latimes:n$,powerbi:S$,quartz:i$,urbaninstitute:l$,version:F$,vox:r$},Symbol.toStringTag,{value:"Module"}));function T$(e,t,n,i){if(U(e))return `[${e.map(r=>t(xt$1(r)?r:kl(r,n))).join(", ")}]`;if(et$1(e)){let r="";const{title:s,image:o,...a}=e;s&&(r+=`

${t(s)}

`),o&&(r+=``);const c=Object.keys(a);if(c.length>0){r+="";for(const l of c){let u=a[l];u!==void 0&&(et$1(u)&&(u=kl(u,n)),r+=``);}r+="
${t(l)}${t(u)}
";}return r||"{}"}return t(e)}function A$(e){const t=[];return function(n,i){if(typeof i!="object"||i===null)return i;const r=t.indexOf(this)+1;return t.length=r,t.length>e?"[Object]":t.indexOf(i)>=0?"[Circular]":(t.push(i),i)}}function kl(e,t){return JSON.stringify(e,A$(t))}var O$=`#vg-tooltip-element { + visibility: hidden; + padding: 8px; + position: fixed; + z-index: 1000; + font-family: sans-serif; + font-size: 11px; + border-radius: 3px; + box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); + /* The default theme is the light theme. */ + background-color: rgba(255, 255, 255, 0.95); + border: 1px solid #d9d9d9; + color: black; +} +#vg-tooltip-element.visible { + visibility: visible; +} +#vg-tooltip-element h2 { + margin-top: 0; + margin-bottom: 10px; + font-size: 13px; +} +#vg-tooltip-element table { + border-spacing: 0; +} +#vg-tooltip-element table tr { + border: none; +} +#vg-tooltip-element table tr td { + overflow: hidden; + text-overflow: ellipsis; + padding-top: 2px; + padding-bottom: 2px; +} +#vg-tooltip-element table tr td.key { + color: #808080; + max-width: 150px; + text-align: right; + padding-right: 4px; +} +#vg-tooltip-element table tr td.value { + display: block; + max-width: 300px; + max-height: 7em; + text-align: left; +} +#vg-tooltip-element.dark-theme { + background-color: rgba(32, 32, 32, 0.9); + border: 1px solid #f5f5f5; + color: white; +} +#vg-tooltip-element.dark-theme td.key { + color: #bfbfbf; +} +`;const dp="vg-tooltip-element",_$={offsetX:10,offsetY:10,id:dp,styleId:"vega-tooltip-style",theme:"light",disableDefaultStyle:!1,sanitize:R$,maxDepth:2,formatTooltip:T$,baseURL:""};function R$(e){return String(e).replace(/&/g,"&").replace(/window.innerWidth&&(r=+e.clientX-n-t.width);let s=e.clientY+i;return s+t.height>window.innerHeight&&(s=+e.clientY-i-t.height),{x:r,y:s}}class P${constructor(t){this.options={..._$,...t};const n=this.options.id;if(this.el=null,this.call=this.tooltipHandler.bind(this),!this.options.disableDefaultStyle&&!document.getElementById(this.options.styleId)){const i=document.createElement("style");i.setAttribute("id",this.options.styleId),i.innerHTML=I$(n);const r=document.head;r.childNodes.length>0?r.insertBefore(i,r.childNodes[0]):r.appendChild(i);}}tooltipHandler(t,n,i,r){if(this.el=document.getElementById(this.options.id),this.el||(this.el=document.createElement("div"),this.el.setAttribute("id",this.options.id),this.el.classList.add("vg-tooltip"),(document.fullscreenElement??document.body).appendChild(this.el)),r==null||r===""){this.el.classList.remove("visible",`${this.options.theme}-theme`);return}this.el.innerHTML=this.options.formatTooltip(r,this.options.sanitize,this.options.maxDepth,this.options.baseURL),this.el.classList.add("visible",`${this.options.theme}-theme`);const{x:s,y:o}=L$(n,this.el.getBoundingClientRect(),this.options.offsetX,this.options.offsetY);this.el.style.top=`${o}px`,this.el.style.left=`${s}px`;}}function z$(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Bs,Tl;function D$(){return Tl||(Tl=1,Bs=function(e){e.prototype[Symbol.iterator]=function*(){for(let t=this.head;t;t=t.next)yield t.value;};}),Bs}var M$=q;q.Node=An;q.create=q;function q(e){var t=this;if(t instanceof q||(t=new q),t.tail=null,t.head=null,t.length=0,e&&typeof e.forEach=="function")e.forEach(function(r){t.push(r);});else if(arguments.length>0)for(var n=0,i=arguments.length;n1)n=t;else if(this.head)i=this.head.next,n=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var r=0;i!==null;r++)n=e(n,i.value,r),i=i.next;return n};q.prototype.reduceReverse=function(e,t){var n,i=this.tail;if(arguments.length>1)n=t;else if(this.tail)i=this.tail.prev,n=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(var r=this.length-1;i!==null;r--)n=e(n,i.value,r),i=i.prev;return n};q.prototype.toArray=function(){for(var e=new Array(this.length),t=0,n=this.head;n!==null;t++)e[t]=n.value,n=n.next;return e};q.prototype.toArrayReverse=function(){for(var e=new Array(this.length),t=0,n=this.tail;n!==null;t++)e[t]=n.value,n=n.prev;return e};q.prototype.slice=function(e,t){t=t||this.length,t<0&&(t+=this.length),e=e||0,e<0&&(e+=this.length);var n=new q;if(tthis.length&&(t=this.length);for(var i=0,r=this.head;r!==null&&ithis.length&&(t=this.length);for(var i=this.length,r=this.tail;r!==null&&i>t;i--)r=r.prev;for(;r!==null&&i>e;i--,r=r.prev)n.push(r.value);return n};q.prototype.splice=function(e,t,...n){e>this.length&&(e=this.length-1),e<0&&(e=this.length+e);for(var i=0,r=this.head;r!==null&&i1;class G${constructor(t){if(typeof t=="number"&&(t={max:t}),t||(t={}),t.max&&(typeof t.max!="number"||t.max<0))throw new TypeError("max must be a non-negative number");this[gn]=t.max||1/0;const n=t.length||Ws;if(this[Bn]=typeof n!="function"?Ws:n,this[Ii]=t.stale||!1,t.maxAge&&typeof t.maxAge!="number")throw new TypeError("maxAge must be a number");this[hn]=t.maxAge||0,this[$t]=t.dispose,this[Al]=t.noDisposeOnSet||!1,this[pp]=t.updateAgeOnGet||!1,this.reset();}set max(t){if(typeof t!="number"||t<0)throw new TypeError("max must be a non-negative number");this[gn]=t||1/0,Fi(this);}get max(){return this[gn]}set allowStale(t){this[Ii]=!!t;}get allowStale(){return this[Ii]}set maxAge(t){if(typeof t!="number")throw new TypeError("maxAge must be a non-negative number");this[hn]=t,Fi(this);}get maxAge(){return this[hn]}set lengthCalculator(t){typeof t!="function"&&(t=Ws),t!==this[Bn]&&(this[Bn]=t,this[wt]=0,this[pe].forEach(n=>{n.length=this[Bn](n.value,n.key),this[wt]+=n.length;})),Fi(this);}get lengthCalculator(){return this[Bn]}get length(){return this[wt]}get itemCount(){return this[pe].length}rforEach(t,n){n=n||this;for(let i=this[pe].tail;i!==null;){const r=i.prev;Ol(this,t,i,n),i=r;}}forEach(t,n){n=n||this;for(let i=this[pe].head;i!==null;){const r=i.next;Ol(this,t,i,n),i=r;}}keys(){return this[pe].toArray().map(t=>t.key)}values(){return this[pe].toArray().map(t=>t.value)}reset(){this[$t]&&this[pe]&&this[pe].length&&this[pe].forEach(t=>this[$t](t.key,t.value)),this[Ve]=new Map,this[pe]=new W$,this[wt]=0;}dump(){return this[pe].map(t=>Or(this,t)?!1:{k:t.key,v:t.value,e:t.now+(t.maxAge||0)}).toArray().filter(t=>t)}dumpLru(){return this[pe]}set(t,n,i){if(i=i||this[hn],i&&typeof i!="number")throw new TypeError("maxAge must be a number");const r=i?Date.now():0,s=this[Bn](n,t);if(this[Ve].has(t)){if(s>this[gn])return Kn(this,this[Ve].get(t)),!1;const c=this[Ve].get(t).value;return this[$t]&&(this[Al]||this[$t](t,c.value)),c.now=r,c.maxAge=i,c.value=n,this[wt]+=s-c.length,c.length=s,this.get(t),Fi(this),!0}const o=new H$(t,n,s,r,i);return o.length>this[gn]?(this[$t]&&this[$t](t,n),!1):(this[wt]+=o.length,this[pe].unshift(o),this[Ve].set(t,this[pe].head),Fi(this),!0)}has(t){if(!this[Ve].has(t))return !1;const n=this[Ve].get(t).value;return !Or(this,n)}get(t){return Gs(this,t,!0)}peek(t){return Gs(this,t,!1)}pop(){const t=this[pe].tail;return t?(Kn(this,t),t.value):null}del(t){Kn(this,this[Ve].get(t));}load(t){this.reset();const n=Date.now();for(let i=t.length-1;i>=0;i--){const r=t[i],s=r.e||0;if(s===0)this.set(r.k,r.v);else {const o=s-n;o>0&&this.set(r.k,r.v,o);}}}prune(){this[Ve].forEach((t,n)=>Gs(this,n,!1));}}const Gs=(e,t,n)=>{const i=e[Ve].get(t);if(i){const r=i.value;if(Or(e,r)){if(Kn(e,i),!e[Ii])return}else n&&(e[pp]&&(i.value.now=Date.now()),e[pe].unshiftNode(i));return r.value}},Or=(e,t)=>{if(!t||!t.maxAge&&!e[hn])return !1;const n=Date.now()-t.now;return t.maxAge?n>t.maxAge:e[hn]&&n>e[hn]},Fi=e=>{if(e[wt]>e[gn])for(let t=e[pe].tail;e[wt]>e[gn]&&t!==null;){const n=t.prev;Kn(e,t),t=n;}},Kn=(e,t)=>{if(t){const n=t.value;e[$t]&&e[$t](n.key,n.value),e[wt]-=n.length,e[Ve].delete(n.key),e[pe].removeNode(t);}};class H${constructor(t,n,i,r,s){this.key=t,this.value=n,this.length=i,this.now=r,this.maxAge=s||0;}}const Ol=(e,t,n,i)=>{let r=n.value;Or(e,r)&&(Kn(e,n),e[Ii]||(r=void 0)),r&&t.call(i,r.value,r.key,e);};var q$=G$;const V$=Object.freeze({loose:!0}),X$=Object.freeze({}),Y$=e=>e?typeof e!="object"?V$:e:X$;var Ha=Y$,yo={exports:{}};const K$="2.0.0",gp=256,J$=Number.MAX_SAFE_INTEGER||9007199254740991,Q$=16,Z$=gp-6,e1=["major","premajor","minor","preminor","patch","prepatch","prerelease"];var qa={MAX_LENGTH:gp,MAX_SAFE_COMPONENT_LENGTH:Q$,MAX_SAFE_BUILD_LENGTH:Z$,MAX_SAFE_INTEGER:J$,RELEASE_TYPES:e1,SEMVER_SPEC_VERSION:K$,FLAG_INCLUDE_PRERELEASE:1,FLAG_LOOSE:2};const t1=typeof process=="object"&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...e)=>console.error("SEMVER",...e):()=>{};var ws=t1;(function(e,t){const{MAX_SAFE_COMPONENT_LENGTH:n,MAX_SAFE_BUILD_LENGTH:i,MAX_LENGTH:r}=qa,s=ws;t=e.exports={};const o=t.re=[],a=t.safeRe=[],c=t.src=[],l=t.t={};let u=0;const f="[a-zA-Z0-9-]",d=[["\\s",1],["\\d",r],[f,i]],g=h=>{for(const[m,y]of d)h=h.split(`${m}*`).join(`${m}{0,${y}}`).split(`${m}+`).join(`${m}{1,${y}}`);return h},p=(h,m,y)=>{const b=g(m),C=u++;s(h,C,m),l[h]=C,c[C]=m,o[C]=new RegExp(m,y?"g":void 0),a[C]=new RegExp(b,y?"g":void 0);};p("NUMERICIDENTIFIER","0|[1-9]\\d*"),p("NUMERICIDENTIFIERLOOSE","\\d+"),p("NONNUMERICIDENTIFIER",`\\d*[a-zA-Z-]${f}*`),p("MAINVERSION",`(${c[l.NUMERICIDENTIFIER]})\\.(${c[l.NUMERICIDENTIFIER]})\\.(${c[l.NUMERICIDENTIFIER]})`),p("MAINVERSIONLOOSE",`(${c[l.NUMERICIDENTIFIERLOOSE]})\\.(${c[l.NUMERICIDENTIFIERLOOSE]})\\.(${c[l.NUMERICIDENTIFIERLOOSE]})`),p("PRERELEASEIDENTIFIER",`(?:${c[l.NUMERICIDENTIFIER]}|${c[l.NONNUMERICIDENTIFIER]})`),p("PRERELEASEIDENTIFIERLOOSE",`(?:${c[l.NUMERICIDENTIFIERLOOSE]}|${c[l.NONNUMERICIDENTIFIER]})`),p("PRERELEASE",`(?:-(${c[l.PRERELEASEIDENTIFIER]}(?:\\.${c[l.PRERELEASEIDENTIFIER]})*))`),p("PRERELEASELOOSE",`(?:-?(${c[l.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${c[l.PRERELEASEIDENTIFIERLOOSE]})*))`),p("BUILDIDENTIFIER",`${f}+`),p("BUILD",`(?:\\+(${c[l.BUILDIDENTIFIER]}(?:\\.${c[l.BUILDIDENTIFIER]})*))`),p("FULLPLAIN",`v?${c[l.MAINVERSION]}${c[l.PRERELEASE]}?${c[l.BUILD]}?`),p("FULL",`^${c[l.FULLPLAIN]}$`),p("LOOSEPLAIN",`[v=\\s]*${c[l.MAINVERSIONLOOSE]}${c[l.PRERELEASELOOSE]}?${c[l.BUILD]}?`),p("LOOSE",`^${c[l.LOOSEPLAIN]}$`),p("GTLT","((?:<|>)?=?)"),p("XRANGEIDENTIFIERLOOSE",`${c[l.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`),p("XRANGEIDENTIFIER",`${c[l.NUMERICIDENTIFIER]}|x|X|\\*`),p("XRANGEPLAIN",`[v=\\s]*(${c[l.XRANGEIDENTIFIER]})(?:\\.(${c[l.XRANGEIDENTIFIER]})(?:\\.(${c[l.XRANGEIDENTIFIER]})(?:${c[l.PRERELEASE]})?${c[l.BUILD]}?)?)?`),p("XRANGEPLAINLOOSE",`[v=\\s]*(${c[l.XRANGEIDENTIFIERLOOSE]})(?:\\.(${c[l.XRANGEIDENTIFIERLOOSE]})(?:\\.(${c[l.XRANGEIDENTIFIERLOOSE]})(?:${c[l.PRERELEASELOOSE]})?${c[l.BUILD]}?)?)?`),p("XRANGE",`^${c[l.GTLT]}\\s*${c[l.XRANGEPLAIN]}$`),p("XRANGELOOSE",`^${c[l.GTLT]}\\s*${c[l.XRANGEPLAINLOOSE]}$`),p("COERCEPLAIN",`(^|[^\\d])(\\d{1,${n}})(?:\\.(\\d{1,${n}}))?(?:\\.(\\d{1,${n}}))?`),p("COERCE",`${c[l.COERCEPLAIN]}(?:$|[^\\d])`),p("COERCEFULL",c[l.COERCEPLAIN]+`(?:${c[l.PRERELEASE]})?(?:${c[l.BUILD]})?(?:$|[^\\d])`),p("COERCERTL",c[l.COERCE],!0),p("COERCERTLFULL",c[l.COERCEFULL],!0),p("LONETILDE","(?:~>?)"),p("TILDETRIM",`(\\s*)${c[l.LONETILDE]}\\s+`,!0),t.tildeTrimReplace="$1~",p("TILDE",`^${c[l.LONETILDE]}${c[l.XRANGEPLAIN]}$`),p("TILDELOOSE",`^${c[l.LONETILDE]}${c[l.XRANGEPLAINLOOSE]}$`),p("LONECARET","(?:\\^)"),p("CARETTRIM",`(\\s*)${c[l.LONECARET]}\\s+`,!0),t.caretTrimReplace="$1^",p("CARET",`^${c[l.LONECARET]}${c[l.XRANGEPLAIN]}$`),p("CARETLOOSE",`^${c[l.LONECARET]}${c[l.XRANGEPLAINLOOSE]}$`),p("COMPARATORLOOSE",`^${c[l.GTLT]}\\s*(${c[l.LOOSEPLAIN]})$|^$`),p("COMPARATOR",`^${c[l.GTLT]}\\s*(${c[l.FULLPLAIN]})$|^$`),p("COMPARATORTRIM",`(\\s*)${c[l.GTLT]}\\s*(${c[l.LOOSEPLAIN]}|${c[l.XRANGEPLAIN]})`,!0),t.comparatorTrimReplace="$1$2$3",p("HYPHENRANGE",`^\\s*(${c[l.XRANGEPLAIN]})\\s+-\\s+(${c[l.XRANGEPLAIN]})\\s*$`),p("HYPHENRANGELOOSE",`^\\s*(${c[l.XRANGEPLAINLOOSE]})\\s+-\\s+(${c[l.XRANGEPLAINLOOSE]})\\s*$`),p("STAR","(<|>)?=?\\s*\\*"),p("GTE0","^\\s*>=\\s*0\\.0\\.0\\s*$"),p("GTE0PRE","^\\s*>=\\s*0\\.0\\.0-0\\s*$");})(yo,yo.exports);var Va=yo.exports;const _l=/^[0-9]+$/,hp=(e,t)=>{const n=_l.test(e),i=_l.test(t);return n&&i&&(e=+e,t=+t),e===t?0:n&&!i?-1:i&&!n?1:ehp(t,e);var i1={compareIdentifiers:hp,rcompareIdentifiers:n1};const dr=ws,{MAX_LENGTH:Rl,MAX_SAFE_INTEGER:pr}=qa,{safeRe:Il,t:Ll}=Va,r1=Ha,{compareIdentifiers:Wn}=i1;let s1=class ot{constructor(t,n){if(n=r1(n),t instanceof ot){if(t.loose===!!n.loose&&t.includePrerelease===!!n.includePrerelease)return t;t=t.version;}else if(typeof t!="string")throw new TypeError(`Invalid version. Must be a string. Got type "${typeof t}".`);if(t.length>Rl)throw new TypeError(`version is longer than ${Rl} characters`);dr("SemVer",t,n),this.options=n,this.loose=!!n.loose,this.includePrerelease=!!n.includePrerelease;const i=t.trim().match(n.loose?Il[Ll.LOOSE]:Il[Ll.FULL]);if(!i)throw new TypeError(`Invalid Version: ${t}`);if(this.raw=t,this.major=+i[1],this.minor=+i[2],this.patch=+i[3],this.major>pr||this.major<0)throw new TypeError("Invalid major version");if(this.minor>pr||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>pr||this.patch<0)throw new TypeError("Invalid patch version");i[4]?this.prerelease=i[4].split(".").map(r=>{if(/^[0-9]+$/.test(r)){const s=+r;if(s>=0&&s=0;)typeof this.prerelease[s]=="number"&&(this.prerelease[s]++,s=-2);if(s===-1){if(n===this.prerelease.join(".")&&i===!1)throw new Error("invalid increment argument: identifier already exists");this.prerelease.push(r);}}if(n){let s=[n,r];i===!1&&(s=[n]),Wn(this.prerelease[0],n)===0?isNaN(this.prerelease[1])&&(this.prerelease=s):this.prerelease=s;}break}default:throw new Error(`invalid increment argument: ${t}`)}return this.raw=this.format(),this.build.length&&(this.raw+=`+${this.build.join(".")}`),this}};var Xa=s1;const Pl=Xa,o1=(e,t,n)=>new Pl(e,n).compare(new Pl(t,n));var vi=o1;const a1=vi,c1=(e,t,n)=>a1(e,t,n)===0;var l1=c1;const u1=vi,f1=(e,t,n)=>u1(e,t,n)!==0;var d1=f1;const p1=vi,g1=(e,t,n)=>p1(e,t,n)>0;var h1=g1;const m1=vi,y1=(e,t,n)=>m1(e,t,n)>=0;var b1=y1;const x1=vi,S1=(e,t,n)=>x1(e,t,n)<0;var v1=S1;const E1=vi,$1=(e,t,n)=>E1(e,t,n)<=0;var w1=$1;const C1=l1,N1=d1,F1=h1,k1=b1,T1=v1,A1=w1,O1=(e,t,n,i)=>{switch(t){case"===":return typeof e=="object"&&(e=e.version),typeof n=="object"&&(n=n.version),e===n;case"!==":return typeof e=="object"&&(e=e.version),typeof n=="object"&&(n=n.version),e!==n;case"":case"=":case"==":return C1(e,n,i);case"!=":return N1(e,n,i);case">":return F1(e,n,i);case">=":return k1(e,n,i);case"<":return T1(e,n,i);case"<=":return A1(e,n,i);default:throw new TypeError(`Invalid operator: ${t}`)}};var _1=O1,Hs,zl;function R1(){if(zl)return Hs;zl=1;const e=Symbol("SemVer ANY");class t{static get ANY(){return e}constructor(u,f){if(f=n(f),u instanceof t){if(u.loose===!!f.loose)return u;u=u.value;}u=u.trim().split(/\s+/).join(" "),o("comparator",u,f),this.options=f,this.loose=!!f.loose,this.parse(u),this.semver===e?this.value="":this.value=this.operator+this.semver.version,o("comp",this);}parse(u){const f=this.options.loose?i[r.COMPARATORLOOSE]:i[r.COMPARATOR],d=u.match(f);if(!d)throw new TypeError(`Invalid comparator: ${u}`);this.operator=d[1]!==void 0?d[1]:"",this.operator==="="&&(this.operator=""),d[2]?this.semver=new a(d[2],this.options.loose):this.semver=e;}toString(){return this.value}test(u){if(o("Comparator.test",u,this.options.loose),this.semver===e||u===e)return !0;if(typeof u=="string")try{u=new a(u,this.options);}catch{return !1}return s(u,this.operator,this.semver,this.options)}intersects(u,f){if(!(u instanceof t))throw new TypeError("a Comparator is required");return this.operator===""?this.value===""?!0:new c(u.value,f).test(this.value):u.operator===""?u.value===""?!0:new c(this.value,f).test(u.semver):(f=n(f),f.includePrerelease&&(this.value==="<0.0.0-0"||u.value==="<0.0.0-0")||!f.includePrerelease&&(this.value.startsWith("<0.0.0")||u.value.startsWith("<0.0.0"))?!1:!!(this.operator.startsWith(">")&&u.operator.startsWith(">")||this.operator.startsWith("<")&&u.operator.startsWith("<")||this.semver.version===u.semver.version&&this.operator.includes("=")&&u.operator.includes("=")||s(this.semver,"<",u.semver,f)&&this.operator.startsWith(">")&&u.operator.startsWith("<")||s(this.semver,">",u.semver,f)&&this.operator.startsWith("<")&&u.operator.startsWith(">")))}}Hs=t;const n=Ha,{safeRe:i,t:r}=Va,s=_1,o=ws,a=Xa,c=mp();return Hs}var qs,Dl;function mp(){if(Dl)return qs;Dl=1;class e{constructor($,I){if(I=i(I),$ instanceof e)return $.loose===!!I.loose&&$.includePrerelease===!!I.includePrerelease?$:new e($.raw,I);if($ instanceof r)return this.raw=$.value,this.set=[[$]],this.format(),this;if(this.options=I,this.loose=!!I.loose,this.includePrerelease=!!I.includePrerelease,this.raw=$.trim().split(/\s+/).join(" "),this.set=this.raw.split("||").map(O=>this.parseRange(O.trim())).filter(O=>O.length),!this.set.length)throw new TypeError(`Invalid SemVer Range: ${this.raw}`);if(this.set.length>1){const O=this.set[0];if(this.set=this.set.filter(P=>!p(P[0])),this.set.length===0)this.set=[O];else if(this.set.length>1){for(const P of this.set)if(P.length===1&&h(P[0])){this.set=[P];break}}}this.format();}format(){return this.range=this.set.map($=>$.join(" ").trim()).join("||").trim(),this.range}toString(){return this.range}parseRange($){const O=((this.options.includePrerelease&&d)|(this.options.loose&&g))+":"+$,P=n.get(O);if(P)return P;const A=this.options.loose,M=A?a[c.HYPHENRANGELOOSE]:a[c.HYPHENRANGE];$=$.replace(M,Re(this.options.includePrerelease)),s("hyphen replace",$),$=$.replace(a[c.COMPARATORTRIM],l),s("comparator trim",$),$=$.replace(a[c.TILDETRIM],u),s("tilde trim",$),$=$.replace(a[c.CARETTRIM],f),s("caret trim",$);let V=$.split(" ").map(te=>y(te,this.options)).join(" ").split(/\s+/).map(te=>de(te,this.options));A&&(V=V.filter(te=>(s("loose invalid filter",te,this.options),!!te.match(a[c.COMPARATORLOOSE])))),s("range list",V);const j=new Map,Q=V.map(te=>new r(te,this.options));for(const te of Q){if(p(te))return [te];j.set(te.value,te);}j.size>1&&j.has("")&&j.delete("");const ve=[...j.values()];return n.set(O,ve),ve}intersects($,I){if(!($ instanceof e))throw new TypeError("a Range is required");return this.set.some(O=>m(O,I)&&$.set.some(P=>m(P,I)&&O.every(A=>P.every(M=>A.intersects(M,I)))))}test($){if(!$)return !1;if(typeof $=="string")try{$=new o($,this.options);}catch{return !1}for(let I=0;Iw.value==="<0.0.0-0",h=w=>w.value==="",m=(w,$)=>{let I=!0;const O=w.slice();let P=O.pop();for(;I&&O.length;)I=O.every(A=>P.intersects(A,$)),P=O.pop();return I},y=(w,$)=>(s("comp",w,$),w=N(w,$),s("caret",w),w=C(w,$),s("tildes",w),w=L(w,$),s("xrange",w),w=oe(w,$),s("stars",w),w),b=w=>!w||w.toLowerCase()==="x"||w==="*",C=(w,$)=>w.trim().split(/\s+/).map(I=>k(I,$)).join(" "),k=(w,$)=>{const I=$.loose?a[c.TILDELOOSE]:a[c.TILDE];return w.replace(I,(O,P,A,M,V)=>{s("tilde",w,O,P,A,M,V);let j;return b(P)?j="":b(A)?j=`>=${P}.0.0 <${+P+1}.0.0-0`:b(M)?j=`>=${P}.${A}.0 <${P}.${+A+1}.0-0`:V?(s("replaceTilde pr",V),j=`>=${P}.${A}.${M}-${V} <${P}.${+A+1}.0-0`):j=`>=${P}.${A}.${M} <${P}.${+A+1}.0-0`,s("tilde return",j),j})},N=(w,$)=>w.trim().split(/\s+/).map(I=>_(I,$)).join(" "),_=(w,$)=>{s("caret",w,$);const I=$.loose?a[c.CARETLOOSE]:a[c.CARET],O=$.includePrerelease?"-0":"";return w.replace(I,(P,A,M,V,j)=>{s("caret",w,P,A,M,V,j);let Q;return b(A)?Q="":b(M)?Q=`>=${A}.0.0${O} <${+A+1}.0.0-0`:b(V)?A==="0"?Q=`>=${A}.${M}.0${O} <${A}.${+M+1}.0-0`:Q=`>=${A}.${M}.0${O} <${+A+1}.0.0-0`:j?(s("replaceCaret pr",j),A==="0"?M==="0"?Q=`>=${A}.${M}.${V}-${j} <${A}.${M}.${+V+1}-0`:Q=`>=${A}.${M}.${V}-${j} <${A}.${+M+1}.0-0`:Q=`>=${A}.${M}.${V}-${j} <${+A+1}.0.0-0`):(s("no pr"),A==="0"?M==="0"?Q=`>=${A}.${M}.${V}${O} <${A}.${M}.${+V+1}-0`:Q=`>=${A}.${M}.${V}${O} <${A}.${+M+1}.0-0`:Q=`>=${A}.${M}.${V} <${+A+1}.0.0-0`),s("caret return",Q),Q})},L=(w,$)=>(s("replaceXRanges",w,$),w.split(/\s+/).map(I=>U(I,$)).join(" ")),U=(w,$)=>{w=w.trim();const I=$.loose?a[c.XRANGELOOSE]:a[c.XRANGE];return w.replace(I,(O,P,A,M,V,j)=>{s("xRange",w,O,P,A,M,V,j);const Q=b(A),ve=Q||b(M),te=ve||b(V),on=te;return P==="="&&on&&(P=""),j=$.includePrerelease?"-0":"",Q?P===">"||P==="<"?O="<0.0.0-0":O="*":P&&on?(ve&&(M=0),V=0,P===">"?(P=">=",ve?(A=+A+1,M=0,V=0):(M=+M+1,V=0)):P==="<="&&(P="<",ve?A=+A+1:M=+M+1),P==="<"&&(j="-0"),O=`${P+A}.${M}.${V}${j}`):ve?O=`>=${A}.0.0${j} <${+A+1}.0.0-0`:te&&(O=`>=${A}.${M}.0${j} <${A}.${+M+1}.0-0`),s("xRange return",O),O})},oe=(w,$)=>(s("replaceStars",w,$),w.trim().replace(a[c.STAR],"")),de=(w,$)=>(s("replaceGTE0",w,$),w.trim().replace(a[$.includePrerelease?c.GTE0PRE:c.GTE0],"")),Re=w=>($,I,O,P,A,M,V,j,Q,ve,te,on,Cs)=>(b(O)?I="":b(P)?I=`>=${O}.0.0${w?"-0":""}`:b(A)?I=`>=${O}.${P}.0${w?"-0":""}`:M?I=`>=${I}`:I=`>=${I}${w?"-0":""}`,b(Q)?j="":b(ve)?j=`<${+Q+1}.0.0-0`:b(te)?j=`<${Q}.${+ve+1}.0-0`:on?j=`<=${Q}.${ve}.${te}-${on}`:w?j=`<${Q}.${ve}.${+te+1}-0`:j=`<=${j}`,`${I} ${j}`.trim()),sn=(w,$,I)=>{for(let O=0;O0){const P=w[O].semver;if(P.major===$.major&&P.minor===$.minor&&P.patch===$.patch)return !0}return !1}return !0};return qs}const I1=mp(),L1=(e,t,n)=>{try{t=new I1(t,n);}catch{return !1}return t.test(e)};var P1=L1,yp=z$(P1);function z1(e,t,n){const i=e.open(t),r=1e4,s=250,{origin:o}=new URL(t);let a=~~(r/s);function c(u){u.source===i&&(a=0,e.removeEventListener("message",c,!1));}e.addEventListener("message",c,!1);function l(){a<=0||(i.postMessage(n,o),setTimeout(l,s),a-=1);}setTimeout(l,s);}var D1=`.vega-embed { + position: relative; + display: inline-block; + box-sizing: border-box; +} +.vega-embed.has-actions { + padding-right: 38px; +} +.vega-embed details:not([open]) > :not(summary) { + display: none !important; +} +.vega-embed summary { + list-style: none; + position: absolute; + top: 0; + right: 0; + padding: 6px; + z-index: 1000; + background: white; + box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1); + color: #1b1e23; + border: 1px solid #aaa; + border-radius: 999px; + opacity: 0.2; + transition: opacity 0.4s ease-in; + cursor: pointer; + line-height: 0px; +} +.vega-embed summary::-webkit-details-marker { + display: none; +} +.vega-embed summary:active { + box-shadow: #aaa 0px 0px 0px 1px inset; +} +.vega-embed summary svg { + width: 14px; + height: 14px; +} +.vega-embed details[open] summary { + opacity: 0.7; +} +.vega-embed:hover summary, .vega-embed:focus-within summary { + opacity: 1 !important; + transition: opacity 0.2s ease; +} +.vega-embed .vega-actions { + position: absolute; + z-index: 1001; + top: 35px; + right: -9px; + display: flex; + flex-direction: column; + padding-bottom: 8px; + padding-top: 8px; + border-radius: 4px; + box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2); + border: 1px solid #d9d9d9; + background: white; + animation-duration: 0.15s; + animation-name: scale-in; + animation-timing-function: cubic-bezier(0.2, 0, 0.13, 1.5); + text-align: left; +} +.vega-embed .vega-actions a { + padding: 8px 16px; + font-family: sans-serif; + font-size: 14px; + font-weight: 600; + white-space: nowrap; + color: #434a56; + text-decoration: none; +} +.vega-embed .vega-actions a:hover, .vega-embed .vega-actions a:focus { + background-color: #f7f7f9; + color: black; +} +.vega-embed .vega-actions::before, .vega-embed .vega-actions::after { + content: ""; + display: inline-block; + position: absolute; +} +.vega-embed .vega-actions::before { + left: auto; + right: 14px; + top: -16px; + border: 8px solid rgba(0, 0, 0, 0); + border-bottom-color: #d9d9d9; +} +.vega-embed .vega-actions::after { + left: auto; + right: 15px; + top: -14px; + border: 7px solid rgba(0, 0, 0, 0); + border-bottom-color: #fff; +} +.vega-embed .chart-wrapper.fit-x { + width: 100%; +} +.vega-embed .chart-wrapper.fit-y { + height: 100%; +} + +.vega-embed-wrapper { + max-width: 100%; + overflow: auto; + padding-right: 14px; +} + +@keyframes scale-in { + from { + opacity: 0; + transform: scale(0.6); + } + to { + opacity: 1; + transform: scale(1); + } +} +`;function bp(e,...t){for(const n of t)M1(e,n);return e}function M1(e,t){for(const n of Object.keys(t))fg$1(e,n,t[n],!0);}const at=LH;let Bi=FE;const Ml=typeof window<"u"?window:void 0;Bi===void 0&&Ml?.vl?.compile&&(Bi=Ml.vl);const j1={export:{svg:!0,png:!0},source:!0,compiled:!0,editor:!0},U1={CLICK_TO_VIEW_ACTIONS:"Click to view actions",COMPILED_ACTION:"View Compiled Vega",EDITOR_ACTION:"Open in Vega Editor",PNG_ACTION:"Save as PNG",SOURCE_ACTION:"View Source",SVG_ACTION:"Save as SVG"},Ai={vega:"Vega","vega-lite":"Vega-Lite"},_r={vega:at.version,"vega-lite":Bi?Bi.version:"not available"},B1={vega:e=>e,"vega-lite":(e,t)=>Bi.compile(e,{config:t}).spec},W1=` + + + + +`,G1="chart-wrapper";function H1(e){return typeof e=="function"}function jl(e,t,n,i){const r=`${t}
`,s=`
${n}`,o=window.open("");o.document.write(r+e+s),o.document.title=`${Ai[i]} JSON Source`;}function q1(e,t){if(e.$schema){const n=lp(e.$schema);t&&t!==n.library&&console.warn(`The given visualization spec is written in ${Ai[n.library]}, but mode argument sets ${Ai[t]??t}.`);const i=n.library;return yp(_r[i],`^${n.version.slice(1)}`)||console.warn(`The input spec uses ${Ai[i]} ${n.version}, but the current version of ${Ai[i]} is v${_r[i]}.`),i}return "mark"in e||"encoding"in e||"layer"in e||"hconcat"in e||"vconcat"in e||"facet"in e||"repeat"in e?"vega-lite":"marks"in e||"signals"in e||"scales"in e||"axes"in e?"vega":t??"vega"}function xp(e){return !!(e&&"load"in e)}function Ul(e){return xp(e)?e:at.loader(e)}function V1(e){const t=e.usermeta?.embedOptions??{};return xt$1(t.defaultStyle)&&(t.defaultStyle=!1),t}async function Iw(e,t,n={}){let i,r;xt$1(t)?(r=Ul(n.loader),i=JSON.parse(await r.load(t))):i=t;const s=V1(i),o=s.loader;(!r||o)&&(r=Ul(n.loader??o));const a=await Bl(s,r),c=await Bl(n,r),l={...bp(c,a),config:v3(c.config??{},a.config??{})};return await Y1(e,i,l,r)}async function Bl(e,t){const n=xt$1(e.config)?JSON.parse(await t.load(e.config)):e.config??{},i=xt$1(e.patch)?JSON.parse(await t.load(e.patch)):e.patch;return {...e,...i?{patch:i}:{},...n?{config:n}:{}}}function X1(e){const t=e.getRootNode?e.getRootNode():document;return t instanceof ShadowRoot?{root:t,rootContainer:t}:{root:document,rootContainer:document.head??document.body}}async function Y1(e,t,n={},i){const r=n.theme?v3(k$[n.theme],n.config??{}):n.config,s=Ag$1(n.actions)?n.actions:bp({},j1,n.actions??{}),o={...U1,...n.i18n},a=n.renderer??"canvas",c=n.logLevel??at.Warn,l=n.downloadFileName??"visualization",u=typeof e=="string"?document.querySelector(e):e;if(!u)throw new Error(`${e} does not exist`);if(n.defaultStyle!==!1){const N="vega-embed-style",{root:_,rootContainer:L}=X1(u);if(!_.getElementById(N)){const U=document.createElement("style");U.id=N,U.innerHTML=n.defaultStyle===void 0||n.defaultStyle===!0?D1.toString():n.defaultStyle,L.appendChild(U);}}const f=q1(t,n.mode);let d=B1[f](t,r);if(f==="vega-lite"&&d.$schema){const N=lp(d.$schema);yp(_r.vega,`^${N.version.slice(1)}`)||console.warn(`The compiled spec uses Vega ${N.version}, but current version is v${_r.vega}.`);}u.classList.add("vega-embed"),s&&u.classList.add("has-actions"),u.innerHTML="";let g=u;if(s){const N=document.createElement("div");N.classList.add(G1),u.appendChild(N),g=N;}const p=n.patch;if(p&&(d=p instanceof Function?p(d):ug$1(d,p,!0,!1).newDocument),n.formatLocale&&at.formatLocale(n.formatLocale),n.timeFormatLocale&&at.timeFormatLocale(n.timeFormatLocale),n.expressionFunctions)for(const N in n.expressionFunctions){const _=n.expressionFunctions[N];"fn"in _?at.expressionFunction(N,_.fn,_.visitor):_ instanceof Function&&at.expressionFunction(N,_);}const{ast:h}=n,m=at.parse(d,f==="vega-lite"?{}:r,{ast:h}),y=new(n.viewClass||at.View)(m,{loader:i,logLevel:c,renderer:a,...h?{expr:at.expressionInterpreter??n.expr??PH}:{}});if(y.addSignalListener("autosize",(N,_)=>{const{type:L}=_;L=="fit-x"?(g.classList.add("fit-x"),g.classList.remove("fit-y")):L=="fit-y"?(g.classList.remove("fit-x"),g.classList.add("fit-y")):L=="fit"?g.classList.add("fit-x","fit-y"):g.classList.remove("fit-x","fit-y");}),n.tooltip!==!1){const{loader:N,tooltip:_}=n,L=N&&!xp(N)?N?.baseURL:void 0,U=H1(_)?_:new P$({baseURL:L,..._===!0?{}:_}).call;y.tooltip(U);}let{hover:b}=n;if(b===void 0&&(b=f==="vega"),b){const{hoverSet:N,updateSet:_}=typeof b=="boolean"?{}:b;y.hover(N,_);}n&&(n.width!=null&&y.width(n.width),n.height!=null&&y.height(n.height),n.padding!=null&&y.padding(n.padding)),await y.initialize(g,n.bind).runAsync();let C;if(s!==!1){let N=u;if(n.defaultStyle!==!1||n.forceActionsMenu){const L=document.createElement("details");L.title=o.CLICK_TO_VIEW_ACTIONS,u.append(L),N=L;const U=document.createElement("summary");U.innerHTML=W1,L.append(U),C=oe=>{L.contains(oe.target)||L.removeAttribute("open");},document.addEventListener("click",C);}const _=document.createElement("div");if(N.append(_),_.classList.add("vega-actions"),s===!0||s.export!==!1){for(const L of ["svg","png"])if(s===!0||s.export===!0||s.export[L]){const U=o[`${L.toUpperCase()}_ACTION`],oe=document.createElement("a"),de=et$1(n.scaleFactor)?n.scaleFactor[L]:n.scaleFactor;oe.text=U,oe.href="#",oe.target="_blank",oe.download=`${l}.${L}`,oe.addEventListener("mousedown",async function(Re){Re.preventDefault();const sn=await y.toImageURL(L,de);this.href=sn;}),_.append(oe);}}if(s===!0||s.source!==!1){const L=document.createElement("a");L.text=o.SOURCE_ACTION,L.href="#",L.addEventListener("click",function(U){jl(Ns(t),n.sourceHeader??"",n.sourceFooter??"",f),U.preventDefault();}),_.append(L);}if(f==="vega-lite"&&(s===!0||s.compiled!==!1)){const L=document.createElement("a");L.text=o.COMPILED_ACTION,L.href="#",L.addEventListener("click",function(U){jl(Ns(d),n.sourceHeader??"",n.sourceFooter??"","vega"),U.preventDefault();}),_.append(L);}if(s===!0||s.editor!==!1){const L=n.editorUrl??"https://vega.github.io/editor/",U=document.createElement("a");U.text=o.EDITOR_ACTION,U.href="#",U.addEventListener("click",function(oe){z1(window,L,{config:r,mode:f,renderer:a,spec:Ns(t)}),oe.preventDefault();}),_.append(U);}}function k(){C&&document.removeEventListener("click",C),y.finalize();}return {view:y,spec:t,vgSpec:d,finalize:k,embedOptions:n}} + +export { j1 as DEFAULT_ACTIONS, Iw as default, q1 as guessMode, at as vega, Bi as vegaLite }; +//# sourceMappingURL=vega-embed.module-DsI9BZ1D.js.map diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/vega-embed.module-DsI9BZ1D.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/vega-embed.module-DsI9BZ1D.js.map new file mode 100644 index 0000000000000000000000000000000000000000..26605d9fb20469393d7aa246f0229ff439bc1d93 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/vega-embed.module-DsI9BZ1D.js.map @@ -0,0 +1 @@ +{"version":3,"file":"vega-embed.module-DsI9BZ1D.js","sources":["../../../../../../js/app/.svelte-kit/adapter-node/chunks/vega-embed.module.js"],"sourcesContent":["import{h as Gn,i as ie,a as R,w as bo,s as fi,$ as B,b as H,c as di,d as F,e as ce,l as $p,W as wp,f as Cp,m as Rr,g as pi,j as Np,p as Fp,k as kp,n as Tp,v as Ap}from\"./vega-interpreter.module.js\";import{j as Op}from\"./client.js\";var _p=/(\"(?:[^\\\\\"]|\\\\.)*\")|[:,]/g,Rp=function(t,n){var i,r,s;return n=n||{},i=JSON.stringify([1],void 0,n.indent===void 0?2:n.indent).slice(2,-3),r=i===\"\"?1/0:n.maxLength===void 0?80:n.maxLength,s=n.replacer,function o(a,c,l){var u,f,d,g,p,h,m,y,b,C,k,N;if(a&&typeof a.toJSON==\"function\"&&(a=a.toJSON()),k=JSON.stringify(a,s),k===void 0)return k;if(m=r-c.length-l,k.length<=m&&(b=k.replace(_p,function(_,L){return L||_+\" \"}),b.length<=m))return b;if(s!=null&&(a=JSON.parse(k),s=void 0),typeof a==\"object\"&&a!==null){if(y=c+i,d=[],f=0,Array.isArray(a))for(C=\"[\",u=\"]\",m=a.length;f0)return[C,i+d.join(`,\n`+y),u].join(`\n`+c)}return k}(t,\"\",0)};const Ns=Op(Rp),Ip=\"vega-lite\",Lp='Dominik Moritz, Kanit \"Ham\" Wongsuphasawat, Arvind Satyanarayan, Jeffrey Heer',Pp=\"5.17.0\",zp=[\"Kanit Wongsuphasawat (http://kanitw.yellowpigz.com)\",\"Dominik Moritz (https://www.domoritz.de)\",\"Arvind Satyanarayan (https://arvindsatya.com)\",\"Jeffrey Heer (https://jheer.org)\"],Dp=\"https://vega.github.io/vega-lite/\",Mp=\"Vega-Lite is a concise high-level language for interactive visualization.\",jp=[\"vega\",\"chart\",\"visualization\"],Up=\"build/vega-lite.js\",Bp=\"build/vega-lite.min.js\",Wp=\"build/vega-lite.min.js\",Gp=\"build/src/index\",Hp=\"build/src/index.d.ts\",qp={vl2pdf:\"./bin/vl2pdf\",vl2png:\"./bin/vl2png\",vl2svg:\"./bin/vl2svg\",vl2vg:\"./bin/vl2vg\"},Vp=[\"bin\",\"build\",\"src\",\"vega-lite*\",\"tsconfig.json\"],Xp={changelog:\"conventional-changelog -p angular -r 2\",prebuild:\"yarn clean:build\",build:\"yarn build:only\",\"build:only\":\"tsc -p tsconfig.build.json && rollup -c\",\"prebuild:examples\":\"yarn build:only\",\"build:examples\":\"yarn data && TZ=America/Los_Angeles scripts/build-examples.sh\",\"prebuild:examples-full\":\"yarn build:only\",\"build:examples-full\":\"TZ=America/Los_Angeles scripts/build-examples.sh 1\",\"build:example\":\"TZ=America/Los_Angeles scripts/build-example.sh\",\"build:toc\":\"yarn build:jekyll && scripts/generate-toc\",\"build:site\":\"rollup -c site/rollup.config.mjs\",\"build:jekyll\":\"pushd site && bundle exec jekyll build -q && popd\",\"build:versions\":\"scripts/update-version.sh\",clean:\"yarn clean:build && del-cli 'site/data/*' 'examples/compiled/*.png' && find site/examples ! -name 'index.md' ! -name 'data' -type f -delete\",\"clean:build\":\"del-cli 'build/*' !build/vega-lite-schema.json\",data:\"rsync -r node_modules/vega-datasets/data/* site/data\",schema:\"mkdir -p build && ts-json-schema-generator -f tsconfig.json -p src/index.ts -t TopLevelSpec --no-type-check --no-ref-encode > build/vega-lite-schema.json && yarn renameschema && cp build/vega-lite-schema.json site/_data/\",renameschema:\"scripts/rename-schema.sh\",presite:\"yarn data && yarn schema && yarn build:site && yarn build:versions && scripts/create-example-pages.sh\",site:\"yarn site:only\",\"site:only\":\"pushd site && bundle exec jekyll serve -I -l && popd\",prettierbase:\"prettier '**/*.{md,css,yml}'\",format:\"eslint . --fix && yarn prettierbase --write\",lint:\"eslint . && yarn prettierbase --check\",test:\"yarn jest test/ && yarn lint && yarn schema && yarn jest examples/ && yarn test:runtime\",\"test:cover\":\"yarn jest --collectCoverage test/\",\"test:inspect\":\"node --inspect-brk ./node_modules/.bin/jest --runInBand test\",\"test:runtime\":\"TZ=America/Los_Angeles npx jest test-runtime/ --config test-runtime/jest-config.json\",\"test:runtime:generate\":\"yarn build:only && del-cli test-runtime/resources && VL_GENERATE_TESTS=true yarn test:runtime\",watch:\"tsc -p tsconfig.build.json -w\",\"watch:site\":\"yarn build:site -w\",\"watch:test\":\"yarn jest --watch test/\",\"watch:test:runtime\":\"TZ=America/Los_Angeles npx jest --watch test-runtime/ --config test-runtime/jest-config.json\",release:\"release-it\"},Yp={type:\"git\",url:\"https://github.com/vega/vega-lite.git\"},Kp=\"BSD-3-Clause\",Jp={url:\"https://github.com/vega/vega-lite/issues\"},Qp={\"@babel/core\":\"^7.23.9\",\"@babel/preset-env\":\"^7.23.9\",\"@babel/preset-typescript\":\"^7.23.3\",\"@release-it/conventional-changelog\":\"^8.0.1\",\"@rollup/plugin-alias\":\"^5.1.0\",\"@rollup/plugin-babel\":\"^6.0.4\",\"@rollup/plugin-commonjs\":\"^25.0.7\",\"@rollup/plugin-json\":\"^6.1.0\",\"@rollup/plugin-node-resolve\":\"^15.2.3\",\"@rollup/plugin-terser\":\"^0.4.4\",\"@types/d3\":\"^7.4.3\",\"@types/jest\":\"^29.5.11\",\"@types/pako\":\"^2.0.3\",\"@typescript-eslint/eslint-plugin\":\"^6.20.0\",\"@typescript-eslint/parser\":\"^6.20.0\",ajv:\"^8.12.0\",\"ajv-formats\":\"^2.1.1\",cheerio:\"^1.0.0-rc.12\",\"conventional-changelog-cli\":\"^4.1.0\",d3:\"^7.8.5\",\"del-cli\":\"^5.1.0\",eslint:\"^8.56.0\",\"eslint-config-prettier\":\"^9.1.0\",\"eslint-plugin-jest\":\"^27.6.3\",\"eslint-plugin-prettier\":\"^5.1.3\",\"fast-json-stable-stringify\":\"~2.1.0\",\"highlight.js\":\"^11.9.0\",jest:\"^29.7.0\",\"jest-dev-server\":\"^9.0.2\",mkdirp:\"^3.0.1\",pako:\"^2.1.0\",prettier:\"^3.2.4\",puppeteer:\"^15.0.0\",\"release-it\":\"^17.0.3\",rollup:\"^4.9.6\",\"rollup-plugin-bundle-size\":\"^1.0.3\",serve:\"^14.2.1\",terser:\"^5.27.0\",\"ts-jest\":\"^29.1.2\",\"ts-json-schema-generator\":\"^1.5.0\",typescript:\"~5.3.3\",\"vega-cli\":\"^5.27.0\",\"vega-datasets\":\"^2.8.0\",\"vega-embed\":\"^6.24.0\",\"vega-tooltip\":\"^0.34.0\",\"yaml-front-matter\":\"^4.1.1\"},Zp={\"json-stringify-pretty-compact\":\"~3.0.0\",tslib:\"~2.6.2\",\"vega-event-selector\":\"~3.0.1\",\"vega-expression\":\"~5.1.0\",\"vega-util\":\"~1.17.2\",yargs:\"~17.7.2\"},eg={vega:\"^5.24.0\"},tg={node:\">=18\"},ng={name:Ip,author:Lp,version:Pp,collaborators:zp,homepage:Dp,description:Mp,keywords:jp,main:Up,unpkg:Bp,jsdelivr:Wp,module:Gp,types:Hp,bin:qp,files:Vp,scripts:Xp,repository:Yp,license:Kp,bugs:Jp,devDependencies:Qp,dependencies:Zp,peerDependencies:eg,engines:tg};function xo(e){return!!e.or}function So(e){return!!e.and}function vo(e){return!!e.not}function gr(e,t){if(vo(e))gr(e.not,t);else if(So(e))for(const n of e.and)gr(n,t);else if(xo(e))for(const n of e.or)gr(n,t);else t(e)}function Hn(e,t){return vo(e)?{not:Hn(e.not,t)}:So(e)?{and:e.and.map(n=>Hn(n,t))}:xo(e)?{or:e.or.map(n=>Hn(n,t))}:t(e)}const z=structuredClone;function Wl(e){throw new Error(e)}function Jn(e,t){const n={};for(const i of t)Gn(e,i)&&(n[i]=e[i]);return n}function ke(e,t){const n={...e};for(const i of t)delete n[i];return n}Set.prototype.toJSON=function(){return`Set(${[...this].map(e=>J(e)).join(\",\")})`};function W(e){if(ie(e))return e;const t=R(e)?e:J(e);if(t.length<250)return t;let n=0;for(let i=0;ia===0?o:`[${o}]`),s=r.map((o,a)=>r.slice(0,a+1).join(\"\"));for(const o of s)t.add(o)}return t}function wo(e,t){return e===void 0||t===void 0?!0:$o(Xs(e),Xs(t))}function K(e){return x(e).length===0}const x=Object.keys,Se=Object.values,Wt=Object.entries;function Li(e){return e===!0||e===!1}function re(e){const t=e.replace(/\\W/g,\"_\");return(e.match(/^\\d+/)?\"_\":\"\")+t}function Oi(e,t){return vo(e)?`!(${Oi(e.not,t)})`:So(e)?`(${e.and.map(n=>Oi(n,t)).join(\") && (\")})`:xo(e)?`(${e.or.map(n=>Oi(n,t)).join(\") || (\")})`:t(e)}function hr(e,t){if(t.length===0)return!0;const n=t.shift();return n in e&&hr(e[n],t)&&delete e[n],K(e)}function Wi(e){return e.charAt(0).toUpperCase()+e.substr(1)}function Co(e,t=\"datum\"){const n=fi(e),i=[];for(let r=1;r<=n.length;r++){const s=`[${n.slice(0,r).map(B).join(\"][\")}]`;i.push(`${t}${s}`)}return i.join(\" && \")}function ql(e,t=\"datum\"){return`${t}[${B(fi(e).join(\".\"))}]`}function sg(e){return e.replace(/(\\[|\\]|\\.|'|\")/g,\"\\\\$1\")}function Ue(e){return`${fi(e).map(sg).join(\"\\\\.\")}`}function vn(e,t,n){return e.replace(new RegExp(t.replace(/[-/\\\\^$*+?.()|[\\]{}]/g,\"\\\\$&\"),\"g\"),n)}function No(e){return`${fi(e).join(\".\")}`}function Qn(e){return e?fi(e).length:0}function le(...e){for(const t of e)if(t!==void 0)return t}let Vl=42;function Xl(e){const t=++Vl;return e?String(e)+t:t}function og(){Vl=42}function Yl(e){return Kl(e)?e:`__${e}`}function Kl(e){return e.startsWith(\"__\")}function Pi(e){if(e!==void 0)return(e%360+360)%360}function Ir(e){return ie(e)?!0:!isNaN(e)&&!isNaN(parseFloat(e))}const ec=Object.getPrototypeOf(structuredClone({}));function Pe(e,t){if(e===t)return!0;if(e&&t&&typeof e==\"object\"&&typeof t==\"object\"){if(e.constructor.name!==t.constructor.name)return!1;let n,i;if(Array.isArray(e)){if(n=e.length,n!=t.length)return!1;for(i=n;i--!==0;)if(!Pe(e[i],t[i]))return!1;return!0}if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(i of e.entries())if(!t.has(i[0]))return!1;for(i of e.entries())if(!Pe(i[1],t.get(i[0])))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(i of e.entries())if(!t.has(i[0]))return!1;return!0}if(ArrayBuffer.isView(e)&&ArrayBuffer.isView(t)){if(n=e.length,n!=t.length)return!1;for(i=n;i--!==0;)if(e[i]!==t[i])return!1;return!0}if(e.constructor===RegExp)return e.source===t.source&&e.flags===t.flags;if(e.valueOf!==Object.prototype.valueOf&&e.valueOf!==ec.valueOf)return e.valueOf()===t.valueOf();if(e.toString!==Object.prototype.toString&&e.toString!==ec.toString)return e.toString()===t.toString();const r=Object.keys(e);if(n=r.length,n!==Object.keys(t).length)return!1;for(i=n;i--!==0;)if(!Object.prototype.hasOwnProperty.call(t,r[i]))return!1;for(i=n;i--!==0;){const s=r[i];if(!Pe(e[s],t[s]))return!1}return!0}return e!==e&&t!==t}function J(e){const t=[];return function n(i){if(i&&i.toJSON&&typeof i.toJSON==\"function\"&&(i=i.toJSON()),i===void 0)return;if(typeof i==\"number\")return isFinite(i)?\"\"+i:\"null\";if(typeof i!=\"object\")return JSON.stringify(i);let r,s;if(Array.isArray(i)){for(s=\"[\",r=0;rBr(e[t])?re(`_${t}_${Wt(e[t])}`):re(`_${t}_${e[t]}`)).join(\"\")}function ee(e){return e===!0||Rn(e)&&!e.binned}function xe(e){return e===\"binned\"||Rn(e)&&e.binned===!0}function Rn(e){return H(e)}function Br(e){return e?.param}function tc(e){switch(e){case Nt:case Ft:case It:case Ae:case yt:case bt:case Zt:case Lt:case Jt:case Qt:case Oe:return 6;case en:return 4;default:return 10}}function Vi(e){return!!e?.expr}function Fe(e){const t=x(e||{}),n={};for(const i of t)n[i]=Le(e[i]);return n}function fu(e){const{anchor:t,frame:n,offset:i,orient:r,angle:s,limit:o,color:a,subtitleColor:c,subtitleFont:l,subtitleFontSize:u,subtitleFontStyle:f,subtitleFontWeight:d,subtitleLineHeight:g,subtitlePadding:p,...h}=e,m={...h,...a?{fill:a}:{}},y={...t?{anchor:t}:{},...n?{frame:n}:{},...i?{offset:i}:{},...r?{orient:r}:{},...s!==void 0?{angle:s}:{},...o!==void 0?{limit:o}:{}},b={...c?{subtitleColor:c}:{},...l?{subtitleFont:l}:{},...u?{subtitleFontSize:u}:{},...f?{subtitleFontStyle:f}:{},...d?{subtitleFontWeight:d}:{},...g?{subtitleLineHeight:g}:{},...p?{subtitlePadding:p}:{}},C=Jn(e,[\"align\",\"baseline\",\"dx\",\"dy\",\"limit\"]);return{titleMarkConfig:m,subtitleMarkConfig:C,nonMarkTitleProperties:y,subtitle:b}}function jt(e){return R(e)||F(e)&&R(e[0])}function T(e){return!!e?.signal}function nn(e){return!!e.step}function Ag(e){return F(e)?!1:\"fields\"in e&&!(\"data\"in e)}function Og(e){return F(e)?!1:\"fields\"in e&&\"data\"in e}function Ct(e){return F(e)?!1:\"field\"in e&&\"data\"in e}const _g={aria:1,description:1,ariaRole:1,ariaRoleDescription:1,blend:1,opacity:1,fill:1,fillOpacity:1,stroke:1,strokeCap:1,strokeWidth:1,strokeOpacity:1,strokeDash:1,strokeDashOffset:1,strokeJoin:1,strokeOffset:1,strokeMiterLimit:1,startAngle:1,endAngle:1,padAngle:1,innerRadius:1,outerRadius:1,size:1,shape:1,interpolate:1,tension:1,orient:1,align:1,baseline:1,text:1,dir:1,dx:1,dy:1,ellipsis:1,limit:1,radius:1,theta:1,angle:1,font:1,fontSize:1,fontWeight:1,fontStyle:1,lineBreak:1,lineHeight:1,cursor:1,href:1,tooltip:1,cornerRadius:1,cornerRadiusTopLeft:1,cornerRadiusTopRight:1,cornerRadiusBottomLeft:1,cornerRadiusBottomRight:1,aspect:1,width:1,height:1,url:1,smooth:1},Rg=x(_g),Ig={arc:1,area:1,group:1,image:1,line:1,path:1,rect:1,rule:1,shape:1,symbol:1,text:1,trail:1},Ys=[\"cornerRadius\",\"cornerRadiusTopLeft\",\"cornerRadiusTopRight\",\"cornerRadiusBottomLeft\",\"cornerRadiusBottomRight\"];function du(e){const t=F(e.condition)?e.condition.map(nc):nc(e.condition);return{...Le(e),condition:t}}function Le(e){if(Vi(e)){const{expr:t,...n}=e;return{signal:t,...n}}return e}function nc(e){if(Vi(e)){const{expr:t,...n}=e;return{signal:t,...n}}return e}function ne(e){if(Vi(e)){const{expr:t,...n}=e;return{signal:t,...n}}return T(e)?e:e!==void 0?{value:e}:void 0}function Lg(e){return T(e)?e.signal:B(e)}function ic(e){return T(e)?e.signal:B(e.value)}function Xe(e){return T(e)?e.signal:e==null?null:B(e)}function Pg(e,t,n){for(const i of n){const r=Ot(i,t.markDef,t.config);r!==void 0&&(e[i]=ne(r))}return e}function pu(e){return[].concat(e.type,e.style??[])}function X(e,t,n,i={}){const{vgChannel:r,ignoreVgConfig:s}=i;return r&&t[r]!==void 0?t[r]:t[e]!==void 0?t[e]:s&&(!r||r===e)?void 0:Ot(e,t,n,i)}function Ot(e,t,n,{vgChannel:i}={}){return le(i?mr(e,t,n.style):void 0,mr(e,t,n.style),i?n[t.type][i]:void 0,n[t.type][e],i?n.mark[i]:n.mark[e])}function mr(e,t,n){return gu(e,pu(t),n)}function gu(e,t,n){t=ce(t);let i;for(const r of t){const s=n[r];s&&s[e]!==void 0&&(i=s[e])}return i}function hu(e,t){return ce(e).reduce((n,i)=>(n.field.push(E(i,t)),n.order.push(i.sort??\"ascending\"),n),{field:[],order:[]})}function mu(e,t){const n=[...e];return t.forEach(i=>{for(const r of n)if(Pe(r,i))return;n.push(i)}),n}function yu(e,t){return Pe(e,t)||!t?e:e?[...ce(e),...ce(t)].join(\", \"):t}function bu(e,t){const n=e.value,i=t.value;if(n==null||i===null)return{explicit:e.explicit,value:null};if((jt(n)||T(n))&&(jt(i)||T(i)))return{explicit:e.explicit,value:yu(n,i)};if(jt(n)||T(n))return{explicit:e.explicit,value:n};if(jt(i)||T(i))return{explicit:e.explicit,value:i};if(!jt(n)&&!T(n)&&!jt(i)&&!T(i))return{explicit:e.explicit,value:mu(n,i)};throw new Error(\"It should never reach here\")}function Lo(e){return`Invalid specification ${J(e)}. Make sure the specification includes at least one of the following properties: \"mark\", \"layer\", \"facet\", \"hconcat\", \"vconcat\", \"concat\", or \"repeat\".`}const zg='Autosize \"fit\" only works for single views and layered views.';function rc(e){return`${e==\"width\"?\"Width\":\"Height\"} \"container\" only works for single views and layered views.`}function sc(e){const t=e==\"width\"?\"Width\":\"Height\",n=e==\"width\"?\"x\":\"y\";return`${t} \"container\" only works well with autosize \"fit\" or \"fit-${n}\".`}function oc(e){return e?`Dropping \"fit-${e}\" because spec has discrete ${_e(e)}.`:'Dropping \"fit\" because spec has discrete size.'}function Po(e){return`Unknown field for ${e}. Cannot calculate view size.`}function ac(e){return`Cannot project a selection on encoding channel \"${e}\", which has no field.`}function Dg(e,t){return`Cannot project a selection on encoding channel \"${e}\" as it uses an aggregate function (\"${t}\").`}function Mg(e){return`The \"nearest\" transform is not supported for ${e} marks.`}function xu(e){return`Selection not supported for ${e} yet.`}function jg(e){return`Cannot find a selection named \"${e}\".`}const Ug=\"Scale bindings are currently only supported for scales with unbinned, continuous domains.\",Bg=\"Sequntial scales are deprecated. The available quantitative scale type values are linear, log, pow, sqrt, symlog, time and utc\",Wg=\"Legend bindings are only supported for selections over an individual field or encoding channel.\";function Gg(e){return`Lookups can only be performed on selection parameters. \"${e}\" is a variable parameter.`}function Hg(e){return`Cannot define and lookup the \"${e}\" selection in the same view. Try moving the lookup into a second, layered view?`}const qg=\"The same selection must be used to override scale domains in a layered view.\",Vg='Interval selections should be initialized using \"x\", \"y\", \"longitude\", or \"latitude\" keys.';function Xg(e){return`Unknown repeated value \"${e}\".`}function cc(e){return`The \"columns\" property cannot be used when \"${e}\" has nested row/column.`}const Yg=\"Axes cannot be shared in concatenated or repeated views yet (https://github.com/vega/vega-lite/issues/2415).\";function Kg(e){return`Unrecognized parse \"${e}\".`}function lc(e,t,n){return`An ancestor parsed field \"${e}\" as ${n} but a child wants to parse the field as ${t}.`}const Jg=\"Attempt to add the same child twice.\";function Qg(e){return`Ignoring an invalid transform: ${J(e)}.`}const Zg='If \"from.fields\" is not specified, \"as\" has to be a string that specifies the key to be used for the data from the secondary source.';function uc(e){return`Config.customFormatTypes is not true, thus custom format type and format for channel ${e} are dropped.`}function eh(e){const{parentProjection:t,projection:n}=e;return`Layer's shared projection ${J(t)} is overridden by a child projection ${J(n)}.`}const th=\"Arc marks uses theta channel rather than angle, replacing angle with theta.\";function nh(e){return`${e}Offset dropped because ${e} is continuous`}function ih(e,t,n){return`Channel ${e} is a ${t}. Converted to {value: ${J(n)}}.`}function Su(e){return`Invalid field type \"${e}\".`}function rh(e,t){return`Invalid field type \"${e}\" for aggregate: \"${t}\", using \"quantitative\" instead.`}function sh(e){return`Invalid aggregation operator \"${e}\".`}function vu(e,t){const{fill:n,stroke:i}=t;return`Dropping color ${e} as the plot also has ${n&&i?\"fill and stroke\":n?\"fill\":\"stroke\"}.`}function oh(e){return`Position range does not support relative band size for ${e}.`}function Ks(e,t){return`Dropping ${J(e)} from channel \"${t}\" since it does not contain any data field, datum, value, or signal.`}const ah=\"Line marks cannot encode size with a non-groupby field. You may want to use trail marks instead.\";function Wr(e,t,n){return`${e} dropped as it is incompatible with \"${t}\".`}function ch(e){return`${e}-encoding is dropped as ${e} is not a valid encoding channel.`}function lh(e){return`${e} encoding should be discrete (ordinal / nominal / binned).`}function uh(e){return`${e} encoding should be discrete (ordinal / nominal / binned) or use a discretizing scale (e.g. threshold).`}function fh(e){return`Facet encoding dropped as ${e.join(\" and \")} ${e.length>1?\"are\":\"is\"} also specified.`}function ks(e,t){return`Using discrete channel \"${e}\" to encode \"${t}\" field can be misleading as it does not encode ${t===\"ordinal\"?\"order\":\"magnitude\"}.`}function dh(e){return`The ${e} for range marks cannot be an expression`}function ph(e,t){return`Line mark is for continuous lines and thus cannot be used with ${e&&t?\"x2 and y2\":e?\"x2\":\"y2\"}. We will use the rule mark (line segments) instead.`}function gh(e,t){return`Specified orient \"${e}\" overridden with \"${t}\".`}function hh(e){return`Cannot use the scale property \"${e}\" with non-color channel.`}function mh(e){return`Cannot use the relative band size with ${e} scale.`}function yh(e){return`Using unaggregated domain with raw field has no effect (${J(e)}).`}function bh(e){return`Unaggregated domain not applicable for \"${e}\" since it produces values outside the origin domain of the source data.`}function xh(e){return`Unaggregated domain is currently unsupported for log scale (${J(e)}).`}function Sh(e){return`Cannot apply size to non-oriented mark \"${e}\".`}function vh(e,t,n){return`Channel \"${e}\" does not work with \"${t}\" scale. We are using \"${n}\" scale instead.`}function Eh(e,t){return`FieldDef does not work with \"${e}\" scale. We are using \"${t}\" scale instead.`}function Eu(e,t,n){return`${n}-scale's \"${t}\" is dropped as it does not work with ${e} scale.`}function $u(e){return`The step for \"${e}\" is dropped because the ${e===\"width\"?\"x\":\"y\"} is continuous.`}function $h(e,t,n,i){return`Conflicting ${t.toString()} property \"${e.toString()}\" (${J(n)} and ${J(i)}). Using ${J(n)}.`}function wh(e,t,n,i){return`Conflicting ${t.toString()} property \"${e.toString()}\" (${J(n)} and ${J(i)}). Using the union of the two domains.`}function Ch(e){return`Setting the scale to be independent for \"${e}\" means we also have to set the guide (axis or legend) to be independent.`}function Nh(e){return`Dropping sort property ${J(e)} as unioned domains only support boolean or op \"count\", \"min\", and \"max\".`}const fc=\"Domains that should be unioned has conflicting sort properties. Sort will be set to true.\",Fh=\"Detected faceted independent scales that union domain of multiple fields from different data sources. We will use the first field. The result view size may be incorrect.\",kh=\"Detected faceted independent scales that union domain of the same fields from different source. We will assume that this is the same field from a different fork of the same data source. However, if this is not the case, the result view size may be incorrect.\",Th=\"Detected faceted independent scales that union domain of multiple fields from the same data source. We will use the first field. The result view size may be incorrect.\";function Ah(e){return`Cannot stack \"${e}\" if there is already \"${e}2\".`}function Oh(e){return`Cannot stack non-linear scale (${e}).`}function _h(e){return`Stacking is applied even though the aggregate function is non-summative (\"${e}\").`}function yr(e,t){return`Invalid ${e}: ${J(t)}.`}function Rh(e){return`Dropping day from datetime ${J(e)} as day cannot be combined with other units.`}function Ih(e,t){return`${t?\"extent \":\"\"}${t&&e?\"and \":\"\"}${e?\"center \":\"\"}${t&&e?\"are \":\"is \"}not needed when data are aggregated.`}function Lh(e,t,n){return`${e} is not usually used with ${t} for ${n}.`}function Ph(e,t){return`Continuous axis should not have customized aggregation function ${e}; ${t} already agregates the axis.`}function dc(e){return`1D error band does not support ${e}.`}function wu(e){return`Channel ${e} is required for \"binned\" bin.`}function zh(e){return`Channel ${e} should not be used with \"binned\" bin.`}function Dh(e){return`Domain for ${e} is required for threshold scale.`}const Cu=$p(wp);let ei=Cu;function Mh(e){return ei=e,ei}function jh(){return ei=Cu,ei}function S(...e){ei.warn(...e)}function Uh(...e){ei.debug(...e)}function In(e){if(e&&H(e)){for(const t of Do)if(t in e)return!0}return!1}const Nu=[\"january\",\"february\",\"march\",\"april\",\"may\",\"june\",\"july\",\"august\",\"september\",\"october\",\"november\",\"december\"],Bh=Nu.map(e=>e.substr(0,3)),Fu=[\"sunday\",\"monday\",\"tuesday\",\"wednesday\",\"thursday\",\"friday\",\"saturday\"],Wh=Fu.map(e=>e.substr(0,3));function Gh(e){if(Ir(e)&&(e=+e),ie(e))return e>4&&S(yr(\"quarter\",e)),e-1;throw new Error(yr(\"quarter\",e))}function Hh(e){if(Ir(e)&&(e=+e),ie(e))return e-1;{const t=e.toLowerCase(),n=Nu.indexOf(t);if(n!==-1)return n;const i=t.substr(0,3),r=Bh.indexOf(i);if(r!==-1)return r;throw new Error(yr(\"month\",e))}}function qh(e){if(Ir(e)&&(e=+e),ie(e))return e%7;{const t=e.toLowerCase(),n=Fu.indexOf(t);if(n!==-1)return n;const i=t.substr(0,3),r=Wh.indexOf(i);if(r!==-1)return r;throw new Error(yr(\"day\",e))}}function zo(e,t){const n=[];if(t&&e.day!==void 0&&x(e).length>1&&(S(Rh(e)),e=z(e),delete e.day),e.year!==void 0?n.push(e.year):n.push(2012),e.month!==void 0){const i=t?Hh(e.month):e.month;n.push(i)}else if(e.quarter!==void 0){const i=t?Gh(e.quarter):e.quarter;n.push(ie(i)?i*3:`${i}*3`)}else n.push(0);if(e.date!==void 0)n.push(e.date);else if(e.day!==void 0){const i=t?qh(e.day):e.day;n.push(ie(i)?i+1:`${i}+1`)}else n.push(1);for(const i of[\"hours\",\"minutes\",\"seconds\",\"milliseconds\"]){const r=e[i];n.push(typeof r>\"u\"?0:r)}return n}function $n(e){const n=zo(e,!0).join(\", \");return e.utc?`utc(${n})`:`datetime(${n})`}function Vh(e){const n=zo(e,!1).join(\", \");return e.utc?`utc(${n})`:`datetime(${n})`}function Xh(e){const t=zo(e,!0);return e.utc?+new Date(Date.UTC(...t)):+new Date(...t)}const ku={year:1,quarter:1,month:1,week:1,day:1,dayofyear:1,date:1,hours:1,minutes:1,seconds:1,milliseconds:1},Do=x(ku);function Yh(e){return!!ku[e]}function Ln(e){return H(e)?e.binned:Tu(e)}function Tu(e){return e&&e.startsWith(\"binned\")}function Mo(e){return e.startsWith(\"utc\")}function Kh(e){return e.substring(3)}const Jh={\"year-month\":\"%b %Y \",\"year-month-date\":\"%b %d, %Y \"};function Gr(e){return Do.filter(t=>Ou(e,t))}function Au(e){const t=Gr(e);return t[t.length-1]}function Ou(e,t){const n=e.indexOf(t);return!(n<0||n>0&&t===\"seconds\"&&e.charAt(n-1)===\"i\"||e.length>n+3&&t===\"day\"&&e.charAt(n+3)===\"o\"||n>0&&t===\"year\"&&e.charAt(n-1)===\"f\")}function Qh(e,t,{end:n}={end:!1}){const i=Co(t),r=Mo(e)?\"utc\":\"\";function s(c){return c===\"quarter\"?`(${r}quarter(${i})-1)`:`${r}${c}(${i})`}let o;const a={};for(const c of Do)Ou(e,c)&&(a[c]=s(c),o=c);return n&&(a[o]+=\"+1\"),Vh(a)}function _u(e){if(!e)return;const t=Gr(e);return`timeUnitSpecifier(${J(t)}, ${J(Jh)})`}function Zh(e,t,n){if(!e)return;const i=_u(e);return`${n||Mo(e)?\"utc\":\"time\"}Format(${t}, ${i})`}function me(e){if(!e)return;let t;return R(e)?Tu(e)?t={unit:e.substring(6),binned:!0}:t={unit:e}:H(e)&&(t={...e,...e.unit?{unit:e.unit}:{}}),Mo(t.unit)&&(t.utc=!0,t.unit=Kh(t.unit)),t}function em(e){const{utc:t,...n}=me(e);return n.unit?(t?\"utc\":\"\")+x(n).map(i=>re(`${i===\"unit\"?\"\":`_${i}_`}${n[i]}`)).join(\"\"):(t?\"utc\":\"\")+\"timeunit\"+x(n).map(i=>re(`_${i}_${n[i]}`)).join(\"\")}function Ru(e,t=n=>n){const n=me(e),i=Au(n.unit);if(i&&i!==\"day\"){const r={year:2001,month:1,date:1,hours:0,minutes:0,seconds:0,milliseconds:0},{step:s,part:o}=Iu(i,n.step),a={...r,[o]:+r[o]+s};return`${t($n(a))} - ${t($n(r))}`}}const tm={year:1,month:1,date:1,hours:1,minutes:1,seconds:1,milliseconds:1};function nm(e){return!!tm[e]}function Iu(e,t=1){if(nm(e))return{part:e,step:t};switch(e){case\"day\":case\"dayofyear\":return{part:\"date\",step:t};case\"quarter\":return{part:\"month\",step:t*3};case\"week\":return{part:\"date\",step:t*7}}}function im(e){return e?.param}function jo(e){return!!e?.field&&e.equal!==void 0}function Uo(e){return!!e?.field&&e.lt!==void 0}function Bo(e){return!!e?.field&&e.lte!==void 0}function Wo(e){return!!e?.field&&e.gt!==void 0}function Go(e){return!!e?.field&&e.gte!==void 0}function Ho(e){if(e?.field){if(F(e.range)&&e.range.length===2)return!0;if(T(e.range))return!0}return!1}function qo(e){return!!e?.field&&(F(e.oneOf)||F(e.in))}function rm(e){return!!e?.field&&e.valid!==void 0}function Lu(e){return qo(e)||jo(e)||Ho(e)||Uo(e)||Wo(e)||Bo(e)||Go(e)}function st(e,t){return es(e,{timeUnit:t,wrapTime:!0})}function sm(e,t){return e.map(n=>st(n,t))}function Pu(e,t=!0){const{field:n}=e,i=me(e.timeUnit),{unit:r,binned:s}=i||{},o=E(e,{expr:\"datum\"}),a=r?`time(${s?o:Qh(r,n)})`:o;if(jo(e))return`${a}===${st(e.equal,r)}`;if(Uo(e)){const c=e.lt;return`${a}<${st(c,r)}`}else if(Wo(e)){const c=e.gt;return`${a}>${st(c,r)}`}else if(Bo(e)){const c=e.lte;return`${a}<=${st(c,r)}`}else if(Go(e)){const c=e.gte;return`${a}>=${st(c,r)}`}else{if(qo(e))return`indexof([${sm(e.oneOf,r).join(\",\")}], ${a}) !== -1`;if(rm(e))return Vo(a,e.valid);if(Ho(e)){const{range:c}=e,l=T(c)?{signal:`${c.signal}[0]`}:c[0],u=T(c)?{signal:`${c.signal}[1]`}:c[1];if(l!==null&&u!==null&&t)return\"inrange(\"+a+\", [\"+st(l,r)+\", \"+st(u,r)+\"])\";const f=[];return l!==null&&f.push(`${a} >= ${st(l,r)}`),u!==null&&f.push(`${a} <= ${st(u,r)}`),f.length>0?f.join(\" && \"):\"true\"}}throw new Error(`Invalid field predicate: ${J(e)}`)}function Vo(e,t=!0){return t?`isValid(${e}) && isFinite(+${e})`:`!isValid(${e}) || !isFinite(+${e})`}function om(e){return Lu(e)&&e.timeUnit?{...e,timeUnit:me(e.timeUnit)}:e}const Xi={quantitative:\"quantitative\",ordinal:\"ordinal\",temporal:\"temporal\",nominal:\"nominal\",geojson:\"geojson\"};function am(e){return e===\"quantitative\"||e===\"temporal\"}function zu(e){return e===\"ordinal\"||e===\"nominal\"}const wn=Xi.quantitative,Xo=Xi.ordinal,ti=Xi.temporal,Yo=Xi.nominal,hi=Xi.geojson;function cm(e){if(e)switch(e=e.toLowerCase(),e){case\"q\":case wn:return\"quantitative\";case\"t\":case ti:return\"temporal\";case\"o\":case Xo:return\"ordinal\";case\"n\":case Yo:return\"nominal\";case hi:return\"geojson\"}}const Te={LINEAR:\"linear\",LOG:\"log\",POW:\"pow\",SQRT:\"sqrt\",SYMLOG:\"symlog\",IDENTITY:\"identity\",SEQUENTIAL:\"sequential\",TIME:\"time\",UTC:\"utc\",QUANTILE:\"quantile\",QUANTIZE:\"quantize\",THRESHOLD:\"threshold\",BIN_ORDINAL:\"bin-ordinal\",ORDINAL:\"ordinal\",POINT:\"point\",BAND:\"band\"},Js={linear:\"numeric\",log:\"numeric\",pow:\"numeric\",sqrt:\"numeric\",symlog:\"numeric\",identity:\"numeric\",sequential:\"numeric\",time:\"time\",utc:\"time\",ordinal:\"ordinal\",\"bin-ordinal\":\"bin-ordinal\",point:\"ordinal-position\",band:\"ordinal-position\",quantile:\"discretizing\",quantize:\"discretizing\",threshold:\"discretizing\"};function lm(e,t){const n=Js[e],i=Js[t];return n===i||n===\"ordinal-position\"&&i===\"time\"||i===\"ordinal-position\"&&n===\"time\"}const um={linear:0,log:1,pow:1,sqrt:1,symlog:1,identity:1,sequential:1,time:0,utc:0,point:10,band:11,ordinal:0,\"bin-ordinal\":0,quantile:0,quantize:0,threshold:0};function pc(e){return um[e]}const Du=new Set([\"linear\",\"log\",\"pow\",\"sqrt\",\"symlog\"]),Mu=new Set([...Du,\"time\",\"utc\"]);function ju(e){return Du.has(e)}const Uu=new Set([\"quantile\",\"quantize\",\"threshold\"]),fm=new Set([...Mu,...Uu,\"sequential\",\"identity\"]),dm=new Set([\"ordinal\",\"bin-ordinal\",\"point\",\"band\"]);function ye(e){return dm.has(e)}function De(e){return fm.has(e)}function Ye(e){return Mu.has(e)}function ni(e){return Uu.has(e)}const pm={pointPadding:.5,barBandPaddingInner:.1,rectBandPaddingInner:0,bandWithNestedOffsetPaddingInner:.2,bandWithNestedOffsetPaddingOuter:.2,minBandSize:2,minFontSize:8,maxFontSize:40,minOpacity:.3,maxOpacity:.8,minSize:9,minStrokeWidth:1,maxStrokeWidth:4,quantileCount:4,quantizeCount:4,zero:!0};function gm(e){return!R(e)&&!!e.name}function Bu(e){return e?.param}function hm(e){return e?.unionWith}function mm(e){return H(e)&&\"field\"in e}const ym={type:1,domain:1,domainMax:1,domainMin:1,domainMid:1,domainRaw:1,align:1,range:1,rangeMax:1,rangeMin:1,scheme:1,bins:1,reverse:1,round:1,clamp:1,nice:1,base:1,exponent:1,constant:1,interpolate:1,zero:1,padding:1,paddingInner:1,paddingOuter:1},{type:kw,domain:Tw,range:Aw,rangeMax:Ow,rangeMin:_w,scheme:Rw,...bm}=ym,xm=x(bm);function Qs(e,t){switch(t){case\"type\":case\"domain\":case\"reverse\":case\"range\":return!0;case\"scheme\":case\"interpolate\":return![\"point\",\"band\",\"identity\"].includes(e);case\"bins\":return![\"point\",\"band\",\"identity\",\"ordinal\"].includes(e);case\"round\":return Ye(e)||e===\"band\"||e===\"point\";case\"padding\":case\"rangeMin\":case\"rangeMax\":return Ye(e)||[\"point\",\"band\"].includes(e);case\"paddingOuter\":case\"align\":return[\"point\",\"band\"].includes(e);case\"paddingInner\":return e===\"band\";case\"domainMax\":case\"domainMid\":case\"domainMin\":case\"domainRaw\":case\"clamp\":return Ye(e);case\"nice\":return Ye(e)||e===\"quantize\"||e===\"threshold\";case\"exponent\":return e===\"pow\";case\"base\":return e===\"log\";case\"constant\":return e===\"symlog\";case\"zero\":return De(e)&&!G([\"log\",\"time\",\"utc\",\"threshold\",\"quantile\"],e)}}function Wu(e,t){switch(t){case\"interpolate\":case\"scheme\":case\"domainMid\":return qn(e)?void 0:hh(t);case\"align\":case\"type\":case\"bins\":case\"domain\":case\"domainMax\":case\"domainMin\":case\"domainRaw\":case\"range\":case\"base\":case\"exponent\":case\"constant\":case\"nice\":case\"padding\":case\"paddingInner\":case\"paddingOuter\":case\"rangeMax\":case\"rangeMin\":case\"reverse\":case\"round\":case\"clamp\":case\"zero\":return}}function Sm(e,t){return G([Xo,Yo],t)?e===void 0||ye(e):t===ti?G([Te.TIME,Te.UTC,void 0],e):t===wn?ju(e)||ni(e)||e===void 0:!0}function vm(e,t,n=!1){if(!Pt(e))return!1;switch(e){case se:case be:case Kt:case gi:case We:case tt:return Ye(t)||t===\"band\"?!0:t===\"point\"?!n:!1;case It:case Zt:case Lt:case Jt:case Qt:case On:return Ye(t)||ni(t)||G([\"band\",\"point\",\"ordinal\"],t);case Ae:case yt:case bt:return t!==\"band\";case en:case Oe:return t===\"ordinal\"||ni(t)}}const Ne={arc:\"arc\",area:\"area\",bar:\"bar\",image:\"image\",line:\"line\",point:\"point\",rect:\"rect\",rule:\"rule\",text:\"text\",tick:\"tick\",trail:\"trail\",circle:\"circle\",square:\"square\",geoshape:\"geoshape\"},Gu=Ne.arc,Hr=Ne.area,qr=Ne.bar,Em=Ne.image,Vr=Ne.line,Xr=Ne.point,$m=Ne.rect,br=Ne.rule,Hu=Ne.text,Ko=Ne.tick,wm=Ne.trail,Jo=Ne.circle,Qo=Ne.square,qu=Ne.geoshape;function rn(e){return[\"line\",\"area\",\"trail\"].includes(e)}function zi(e){return[\"rect\",\"bar\",\"image\",\"arc\"].includes(e)}const Cm=new Set(x(Ne));function pt(e){return e.type}const Nm=[\"stroke\",\"strokeWidth\",\"strokeDash\",\"strokeDashOffset\",\"strokeOpacity\",\"strokeJoin\",\"strokeMiterLimit\"],Fm=[\"fill\",\"fillOpacity\"],km=[...Nm,...Fm],Tm={color:1,filled:1,invalid:1,order:1,radius2:1,theta2:1,timeUnitBandSize:1,timeUnitBandPosition:1},gc=x(Tm),Am={area:[\"line\",\"point\"],bar:[\"binSpacing\",\"continuousBandSize\",\"discreteBandSize\",\"minBandSize\"],rect:[\"binSpacing\",\"continuousBandSize\",\"discreteBandSize\",\"minBandSize\"],line:[\"point\"],tick:[\"bandSize\",\"thickness\"]},Om={color:\"#4c78a8\",invalid:\"filter\",timeUnitBandSize:1},_m={mark:1,arc:1,area:1,bar:1,circle:1,image:1,line:1,point:1,rect:1,rule:1,square:1,text:1,tick:1,trail:1,geoshape:1},Vu=x(_m);function Cn(e){return e&&e.band!=null}const Rm={horizontal:[\"cornerRadiusTopRight\",\"cornerRadiusBottomRight\"],vertical:[\"cornerRadiusTopLeft\",\"cornerRadiusTopRight\"]},Xu=5,Im={binSpacing:1,continuousBandSize:Xu,minBandSize:.25,timeUnitBandPosition:.5},Lm={binSpacing:0,continuousBandSize:Xu,minBandSize:.25,timeUnitBandPosition:.5},Pm={thickness:1};function zm(e){return pt(e)?e.type:e}function Zo(e){const{channel:t,channelDef:n,markDef:i,scale:r,config:s}=e,o=ta(e);return v(n)&&!lu(n.aggregate)&&r&&Ye(r.get(\"type\"))?Dm({fieldDef:n,channel:t,markDef:i,ref:o,config:s}):o}function Dm({fieldDef:e,channel:t,markDef:n,ref:i,config:r}){return rn(n.type)?i:X(\"invalid\",n,r)===null?[Mm(e,t),i]:i}function Mm(e,t){const n=ea(e,!0),r=_n(t)===\"y\"?{field:{group:\"height\"}}:{value:0};return{test:n,...r}}function ea(e,t=!0){return Vo(R(e)?e:E(e,{expr:\"datum\"}),!t)}function jm(e){const{datum:t}=e;return In(t)?$n(t):`${J(t)}`}function mn(e,t,n,i){const r={};if(t&&(r.scale=t),vt(e)){const{datum:s}=e;In(s)?r.signal=$n(s):T(s)?r.signal=s.signal:Vi(s)?r.signal=s.expr:r.value=s}else r.field=E(e,n);if(i){const{offset:s,band:o}=i;s&&(r.offset=s),o&&(r.band=o)}return r}function xr({scaleName:e,fieldOrDatumDef:t,fieldOrDatumDef2:n,offset:i,startSuffix:r,endSuffix:s=\"end\",bandPosition:o=.5}){const a=!T(o)&&0{switch(t.fieldTitle){case\"plain\":return e.field;case\"functional\":return ey(e);default:return Zm(e,t)}};let lf=cf;function uf(e){lf=e}function ty(){uf(cf)}function Vn(e,t,{allowDisabling:n,includeDefault:i=!0}){const r=sa(e)?.title;if(!v(e))return r??e.title;const s=e,o=i?oa(s,t):void 0;return n?le(r,s.title,o):r??s.title??o}function sa(e){if(ri(e)&&e.axis)return e.axis;if(of(e)&&e.legend)return e.legend;if(ia(e)&&e.header)return e.header}function oa(e,t){return lf(e,t)}function Er(e){if(af(e)){const{format:t,formatType:n}=e;return{format:t,formatType:n}}else{const t=sa(e)??{},{format:n,formatType:i}=t;return{format:n,formatType:i}}}function ny(e,t){switch(t){case\"latitude\":case\"longitude\":return\"quantitative\";case\"row\":case\"column\":case\"facet\":case\"shape\":case\"strokeDash\":return\"nominal\";case\"order\":return\"ordinal\"}if(ra(e)&&F(e.sort))return\"ordinal\";const{aggregate:n,bin:i,timeUnit:r}=e;if(r)return\"temporal\";if(i||n&&!tn(n)&&!At(n))return\"quantitative\";if(Pn(e)&&e.scale?.type)switch(Js[e.scale.type]){case\"numeric\":case\"discretizing\":return\"quantitative\";case\"time\":return\"temporal\"}return\"nominal\"}function gt(e){if(v(e))return e;if(Qr(e))return e.condition}function fe(e){if(D(e))return e;if(Ji(e))return e.condition}function ff(e,t,n,i={}){if(R(e)||ie(e)||di(e)){const r=R(e)?\"string\":ie(e)?\"number\":\"boolean\";return S(ih(t,r,e)),{value:e}}return D(e)?$r(e,t,n,i):Ji(e)?{...e,condition:$r(e.condition,t,n,i)}:e}function $r(e,t,n,i){if(af(e)){const{format:r,formatType:s,...o}=e;if(Nn(s)&&!n.customFormatTypes)return S(uc(t)),$r(o,t,n,i)}else{const r=ri(e)?\"axis\":of(e)?\"legend\":ia(e)?\"header\":null;if(r&&e[r]){const{format:s,formatType:o,...a}=e[r];if(Nn(o)&&!n.customFormatTypes)return S(uc(t)),$r({...e,[r]:a},t,n,i)}}return v(e)?aa(e,t,i):iy(e)}function iy(e){let t=e.type;if(t)return e;const{datum:n}=e;return t=ie(n)?\"quantitative\":R(n)?\"nominal\":In(n)?\"temporal\":void 0,{...e,type:t}}function aa(e,t,{compositeMark:n=!1}={}){const{aggregate:i,timeUnit:r,bin:s,field:o}=e,a={...e};if(!n&&i&&!Io(i)&&!tn(i)&&!At(i)&&(S(sh(i)),delete a.aggregate),r&&(a.timeUnit=me(r)),o&&(a.field=`${o}`),ee(s)&&(a.bin=Zr(s,t)),xe(s)&&!ue(t)&&S(zh(t)),Ce(a)){const{type:c}=a,l=cm(c);c!==l&&(a.type=l),c!==\"quantitative\"&&lu(i)&&(S(rh(c,i)),a.type=\"quantitative\")}else if(!iu(t)){const c=ny(a,t);a.type=c}if(Ce(a)){const{compatible:c,warning:l}=ry(a,t)||{};c===!1&&S(l)}if(ra(a)&&R(a.sort)){const{sort:c}=a;if(mc(c))return{...a,sort:{encoding:c}};const l=c.substr(1);if(c.charAt(0)===\"-\"&&mc(l))return{...a,sort:{encoding:l,order:\"descending\"}}}if(ia(a)){const{header:c}=a;if(c){const{orient:l,...u}=c;if(l)return{...a,header:{...u,labelOrient:c.labelOrient||l,titleOrient:c.titleOrient||l}}}}return a}function Zr(e,t){return di(e)?{maxbins:tc(t)}:e===\"binned\"?{binned:!0}:!e.maxbins&&!e.step?{...e,maxbins:tc(t)}:e}const Mn={compatible:!0};function ry(e,t){const n=e.type;if(n===\"geojson\"&&t!==\"shape\")return{compatible:!1,warning:`Channel ${t} should not be used with a geojson data.`};switch(t){case Nt:case Ft:case Lr:return vr(e)?Mn:{compatible:!1,warning:lh(t)};case se:case be:case Kt:case gi:case Ae:case yt:case bt:case Gi:case Hi:case Pr:case En:case zr:case Dr:case On:case We:case tt:case Mr:return Mn;case it:case Be:case nt:case rt:return n!==wn?{compatible:!1,warning:`Channel ${t} should be used with a quantitative field only, not ${e.type} field.`}:Mn;case Lt:case Jt:case Qt:case Zt:case It:case Rt:case _t:case et:case mt:return n===\"nominal\"&&!e.sort?{compatible:!1,warning:`Channel ${t} should not be used with an unsorted discrete field.`}:Mn;case Oe:case en:return!vr(e)&&!Jm(e)?{compatible:!1,warning:uh(t)}:Mn;case Zn:return e.type===\"nominal\"&&!(\"sort\"in e)?{compatible:!1,warning:\"Channel order is inappropriate for nominal field, which has no inherent order.\"}:Mn}}function si(e){const{formatType:t}=Er(e);return t===\"time\"||!t&&sy(e)}function sy(e){return e&&(e.type===\"temporal\"||v(e)&&!!e.timeUnit)}function es(e,{timeUnit:t,type:n,wrapTime:i,undefinedIfExprNotRequired:r}){const s=t&&me(t)?.unit;let o=s||n===\"temporal\",a;return Vi(e)?a=e.expr:T(e)?a=e.signal:In(e)?(o=!0,a=$n(e)):(R(e)||ie(e))&&o&&(a=`datetime(${J(e)})`,Yh(s)&&(ie(e)&&e<1e4||R(e)&&isNaN(Date.parse(e)))&&(a=$n({[s]:e}))),a?i&&o?`time(${a})`:a:r?void 0:J(e)}function df(e,t){const{type:n}=e;return t.map(i=>{const r=v(e)&&!Ln(e.timeUnit)?e.timeUnit:void 0,s=es(i,{timeUnit:r,type:n,undefinedIfExprNotRequired:!0});return s!==void 0?{signal:s}:i})}function Qi(e,t){return ee(e.bin)?Pt(t)&&[\"ordinal\",\"nominal\"].includes(e.type):(console.warn(\"Only call this method for binned field defs.\"),!1)}const xc={labelAlign:{part:\"labels\",vgProp:\"align\"},labelBaseline:{part:\"labels\",vgProp:\"baseline\"},labelColor:{part:\"labels\",vgProp:\"fill\"},labelFont:{part:\"labels\",vgProp:\"font\"},labelFontSize:{part:\"labels\",vgProp:\"fontSize\"},labelFontStyle:{part:\"labels\",vgProp:\"fontStyle\"},labelFontWeight:{part:\"labels\",vgProp:\"fontWeight\"},labelOpacity:{part:\"labels\",vgProp:\"opacity\"},labelOffset:null,labelPadding:null,gridColor:{part:\"grid\",vgProp:\"stroke\"},gridDash:{part:\"grid\",vgProp:\"strokeDash\"},gridDashOffset:{part:\"grid\",vgProp:\"strokeDashOffset\"},gridOpacity:{part:\"grid\",vgProp:\"opacity\"},gridWidth:{part:\"grid\",vgProp:\"strokeWidth\"},tickColor:{part:\"ticks\",vgProp:\"stroke\"},tickDash:{part:\"ticks\",vgProp:\"strokeDash\"},tickDashOffset:{part:\"ticks\",vgProp:\"strokeDashOffset\"},tickOpacity:{part:\"ticks\",vgProp:\"opacity\"},tickSize:null,tickWidth:{part:\"ticks\",vgProp:\"strokeWidth\"}};function Zi(e){return e?.condition}const pf=[\"domain\",\"grid\",\"labels\",\"ticks\",\"title\"],oy={grid:\"grid\",gridCap:\"grid\",gridColor:\"grid\",gridDash:\"grid\",gridDashOffset:\"grid\",gridOpacity:\"grid\",gridScale:\"grid\",gridWidth:\"grid\",orient:\"main\",bandPosition:\"both\",aria:\"main\",description:\"main\",domain:\"main\",domainCap:\"main\",domainColor:\"main\",domainDash:\"main\",domainDashOffset:\"main\",domainOpacity:\"main\",domainWidth:\"main\",format:\"main\",formatType:\"main\",labelAlign:\"main\",labelAngle:\"main\",labelBaseline:\"main\",labelBound:\"main\",labelColor:\"main\",labelFlush:\"main\",labelFlushOffset:\"main\",labelFont:\"main\",labelFontSize:\"main\",labelFontStyle:\"main\",labelFontWeight:\"main\",labelLimit:\"main\",labelLineHeight:\"main\",labelOffset:\"main\",labelOpacity:\"main\",labelOverlap:\"main\",labelPadding:\"main\",labels:\"main\",labelSeparation:\"main\",maxExtent:\"main\",minExtent:\"main\",offset:\"both\",position:\"main\",tickCap:\"main\",tickColor:\"main\",tickDash:\"main\",tickDashOffset:\"main\",tickMinStep:\"both\",tickOffset:\"both\",tickOpacity:\"main\",tickRound:\"both\",ticks:\"main\",tickSize:\"main\",tickWidth:\"both\",title:\"main\",titleAlign:\"main\",titleAnchor:\"main\",titleAngle:\"main\",titleBaseline:\"main\",titleColor:\"main\",titleFont:\"main\",titleFontSize:\"main\",titleFontStyle:\"main\",titleFontWeight:\"main\",titleLimit:\"main\",titleLineHeight:\"main\",titleOpacity:\"main\",titlePadding:\"main\",titleX:\"main\",titleY:\"main\",encode:\"both\",scale:\"both\",tickBand:\"both\",tickCount:\"both\",tickExtra:\"both\",translate:\"both\",values:\"both\",zindex:\"both\"},gf={orient:1,aria:1,bandPosition:1,description:1,domain:1,domainCap:1,domainColor:1,domainDash:1,domainDashOffset:1,domainOpacity:1,domainWidth:1,format:1,formatType:1,grid:1,gridCap:1,gridColor:1,gridDash:1,gridDashOffset:1,gridOpacity:1,gridWidth:1,labelAlign:1,labelAngle:1,labelBaseline:1,labelBound:1,labelColor:1,labelFlush:1,labelFlushOffset:1,labelFont:1,labelFontSize:1,labelFontStyle:1,labelFontWeight:1,labelLimit:1,labelLineHeight:1,labelOffset:1,labelOpacity:1,labelOverlap:1,labelPadding:1,labels:1,labelSeparation:1,maxExtent:1,minExtent:1,offset:1,position:1,tickBand:1,tickCap:1,tickColor:1,tickCount:1,tickDash:1,tickDashOffset:1,tickExtra:1,tickMinStep:1,tickOffset:1,tickOpacity:1,tickRound:1,ticks:1,tickSize:1,tickWidth:1,title:1,titleAlign:1,titleAnchor:1,titleAngle:1,titleBaseline:1,titleColor:1,titleFont:1,titleFontSize:1,titleFontStyle:1,titleFontWeight:1,titleLimit:1,titleLineHeight:1,titleOpacity:1,titlePadding:1,titleX:1,titleY:1,translate:1,values:1,zindex:1},ay={...gf,style:1,labelExpr:1,encoding:1};function Sc(e){return!!ay[e]}const cy={axis:1,axisBand:1,axisBottom:1,axisDiscrete:1,axisLeft:1,axisPoint:1,axisQuantitative:1,axisRight:1,axisTemporal:1,axisTop:1,axisX:1,axisXBand:1,axisXDiscrete:1,axisXPoint:1,axisXQuantitative:1,axisXTemporal:1,axisY:1,axisYBand:1,axisYDiscrete:1,axisYPoint:1,axisYQuantitative:1,axisYTemporal:1},hf=x(cy);function zt(e){return\"mark\"in e}class ts{constructor(t,n){this.name=t,this.run=n}hasMatchingType(t){return zt(t)?zm(t.mark)===this.name:!1}}function yn(e,t){const n=e&&e[t];return n?F(n)?Sn(n,i=>!!i.field):v(n)||Qr(n):!1}function mf(e,t){const n=e&&e[t];return n?F(n)?Sn(n,i=>!!i.field):v(n)||vt(n)||Ji(n):!1}function yf(e,t){if(ue(t)){const n=e[t];if((v(n)||vt(n))&&(zu(n.type)||v(n)&&n.timeUnit)){const i=Ao(t);return mf(e,i)}}return!1}function ca(e){return Sn(lg,t=>{if(yn(e,t)){const n=e[t];if(F(n))return Sn(n,i=>!!i.aggregate);{const i=gt(n);return i&&!!i.aggregate}}return!1})}function bf(e,t){const n=[],i=[],r=[],s=[],o={};return la(e,(a,c)=>{if(v(a)){const{field:l,aggregate:u,bin:f,timeUnit:d,...g}=a;if(u||d||f){const h=sa(a)?.title;let m=E(a,{forAs:!0});const y={...h?[]:{title:Vn(a,t,{allowDisabling:!0})},...g,field:m};if(u){let b;if(tn(u)?(b=\"argmax\",m=E({op:\"argmax\",field:u.argmax},{forAs:!0}),y.field=`${m}.${l}`):At(u)?(b=\"argmin\",m=E({op:\"argmin\",field:u.argmin},{forAs:!0}),y.field=`${m}.${l}`):u!==\"boxplot\"&&u!==\"errorbar\"&&u!==\"errorband\"&&(b=u),b){const C={op:b,as:m};l&&(C.field=l),s.push(C)}}else if(n.push(m),Ce(a)&&ee(f)){if(i.push({bin:f,field:l,as:m}),n.push(E(a,{binSuffix:\"end\"})),Qi(a,c)&&n.push(E(a,{binSuffix:\"range\"})),ue(c)){const b={field:`${m}_end`};o[`${c}2`]=b}y.bin=\"binned\",iu(c)||(y.type=wn)}else if(d&&!Ln(d)){r.push({timeUnit:d,field:l,as:m});const b=Ce(a)&&a.type!==ti&&\"time\";b&&(c===Gi||c===En?y.formatType=b:xg(c)?y.legend={formatType:b,...y.legend}:ue(c)&&(y.axis={formatType:b,...y.axis}))}o[c]=y}else n.push(l),o[c]=e[c]}else o[c]=e[c]}),{bins:i,timeUnits:r,aggregate:s,groupby:n,encoding:o}}function ly(e,t,n){const i=vg(t,n);if(i){if(i===\"binned\"){const r=e[t===et?se:be];return!!(v(r)&&v(e[t])&&xe(r.bin))}}else return!1;return!0}function uy(e,t,n,i){const r={};for(const s of x(e))nu(s)||S(ch(s));for(let s of hg){if(!e[s])continue;const o=e[s];if(qi(s)){const a=gg(s),c=r[a];if(v(c)&&am(c.type)&&v(o)&&!c.timeUnit){S(nh(a));continue}}if(s===\"angle\"&&t===\"arc\"&&!e.theta&&(S(th),s=We),!ly(e,s,t)){S(Wr(s,t));continue}if(s===It&&t===\"line\"&>(e[s])?.aggregate){S(ah);continue}if(s===Ae&&(n?\"fill\"in e:\"stroke\"in e)){S(vu(\"encoding\",{fill:\"fill\"in e,stroke:\"stroke\"in e}));continue}if(s===Hi||s===Zn&&!F(o)&&!Qe(o)||s===En&&F(o)){if(o){if(s===Zn){const a=e[s];if(sf(a)){r[s]=a;continue}}r[s]=ce(o).reduce((a,c)=>(v(c)?a.push(aa(c,s)):S(Ks(c,s)),a),[])}}else{if(s===En&&o===null)r[s]=null;else if(!v(o)&&!vt(o)&&!Qe(o)&&!Jr(o)&&!T(o)){S(Ks(o,s));continue}r[s]=ff(o,s,i)}}return r}function ns(e,t){const n={};for(const i of x(e)){const r=ff(e[i],i,t,{compositeMark:!0});n[i]=r}return n}function fy(e){const t=[];for(const n of x(e))if(yn(e,n)){const i=e[n],r=ce(i);for(const s of r)v(s)?t.push(s):Qr(s)&&t.push(s.condition)}return t}function la(e,t,n){if(e)for(const i of x(e)){const r=e[i];if(F(r))for(const s of r)t.call(n,s,i);else t.call(n,r,i)}}function dy(e,t,n,i){return e?x(e).reduce((r,s)=>{const o=e[s];return F(o)?o.reduce((a,c)=>t.call(i,a,c,s),r):t.call(i,r,o,s)},n):n}function xf(e,t){return x(t).reduce((n,i)=>{switch(i){case se:case be:case zr:case Mr:case Dr:case et:case mt:case Kt:case gi:case We:case Rt:case tt:case _t:case nt:case it:case rt:case Be:case Gi:case Oe:case On:case En:return n;case Zn:if(e===\"line\"||e===\"trail\")return n;case Hi:case Pr:{const r=t[i];if(F(r)||v(r))for(const s of ce(r))s.aggregate||n.push(E(s,{}));return n}case It:if(e===\"trail\")return n;case Ae:case yt:case bt:case Lt:case Jt:case Qt:case en:case Zt:{const r=gt(t[i]);return r&&!r.aggregate&&n.push(E(r,{})),n}}},[])}function py(e){const{tooltip:t,...n}=e;if(!t)return{filteredEncoding:n};let i,r;if(F(t)){for(const s of t)s.aggregate?(i||(i=[]),i.push(s)):(r||(r=[]),r.push(s));i&&(n.tooltip=i)}else t.aggregate?n.tooltip=t:r=t;return F(r)&&r.length===1&&(r=r[0]),{customTooltipWithoutAggregatedField:r,filteredEncoding:n}}function eo(e,t,n,i=!0){if(\"tooltip\"in n)return{tooltip:n.tooltip};const r=e.map(({fieldPrefix:o,titlePrefix:a})=>{const c=i?` of ${ua(t)}`:\"\";return{field:o+t.field,type:t.type,title:T(a)?{signal:`${a}\"${escape(c)}\"`}:a+c}}),s=fy(n).map(Ym);return{tooltip:[...r,...lt(s,W)]}}function ua(e){const{title:t,field:n}=e;return le(t,n)}function fa(e,t,n,i,r){const{scale:s,axis:o}=n;return({partName:a,mark:c,positionPrefix:l,endPositionPrefix:u=void 0,extraEncoding:f={}})=>{const d=ua(n);return Sf(e,a,r,{mark:c,encoding:{[t]:{field:`${l}_${n.field}`,type:n.type,...d!==void 0?{title:d}:{},...s!==void 0?{scale:s}:{},...o!==void 0?{axis:o}:{}},...R(u)?{[`${t}2`]:{field:`${u}_${n.field}`}}:{},...i,...f}})}}function Sf(e,t,n,i){const{clip:r,color:s,opacity:o}=e,a=e.type;return e[t]||e[t]===void 0&&n[t]?[{...i,mark:{...n[t],...r?{clip:r}:{},...s?{color:s}:{},...o?{opacity:o}:{},...pt(i.mark)?i.mark:{type:i.mark},style:`${a}-${String(t)}`,...di(e[t])?{}:e[t]}}]:[]}function vf(e,t,n){const{encoding:i}=e,r=t===\"vertical\"?\"y\":\"x\",s=i[r],o=i[`${r}2`],a=i[`${r}Error`],c=i[`${r}Error2`];return{continuousAxisChannelDef:rr(s,n),continuousAxisChannelDef2:rr(o,n),continuousAxisChannelDefError:rr(a,n),continuousAxisChannelDefError2:rr(c,n),continuousAxis:r}}function rr(e,t){if(e?.aggregate){const{aggregate:n,...i}=e;return n!==t&&S(Ph(n,t)),i}else return e}function Ef(e,t){const{mark:n,encoding:i}=e,{x:r,y:s}=i;if(pt(n)&&n.orient)return n.orient;if(Ut(r)){if(Ut(s)){const o=v(r)&&r.aggregate,a=v(s)&&s.aggregate;if(!o&&a===t)return\"vertical\";if(!a&&o===t)return\"horizontal\";if(o===t&&a===t)throw new Error(\"Both x and y cannot have aggregate\");return si(s)&&!si(r)?\"horizontal\":\"vertical\"}return\"horizontal\"}else{if(Ut(s))return\"vertical\";throw new Error(`Need a valid continuous axis for ${t}s`)}}const wr=\"boxplot\",gy=[\"box\",\"median\",\"outliers\",\"rule\",\"ticks\"],hy=new ts(wr,wf);function $f(e){return ie(e)?\"tukey\":e}function wf(e,{config:t}){e={...e,encoding:ns(e.encoding,t)};const{mark:n,encoding:i,params:r,projection:s,...o}=e,a=pt(n)?n:{type:n};r&&S(xu(\"boxplot\"));const c=a.extent??t.boxplot.extent,l=X(\"size\",a,t),u=a.invalid,f=$f(c),{bins:d,timeUnits:g,transform:p,continuousAxisChannelDef:h,continuousAxis:m,groupby:y,aggregate:b,encodingWithoutContinuousAxis:C,ticksOrient:k,boxOrient:N,customTooltipWithoutAggregatedField:_}=my(e,c,t),{color:L,size:U,...oe}=C,de=Ep=>fa(a,m,h,Ep,t.boxplot),Re=de(oe),sn=de(C),w=de({...oe,...U?{size:U}:{}}),$=eo([{fieldPrefix:f===\"min-max\"?\"upper_whisker_\":\"max_\",titlePrefix:\"Max\"},{fieldPrefix:\"upper_box_\",titlePrefix:\"Q3\"},{fieldPrefix:\"mid_box_\",titlePrefix:\"Median\"},{fieldPrefix:\"lower_box_\",titlePrefix:\"Q1\"},{fieldPrefix:f===\"min-max\"?\"lower_whisker_\":\"min_\",titlePrefix:\"Min\"}],h,C),I={type:\"tick\",color:\"black\",opacity:1,orient:k,invalid:u,aria:!1},O=f===\"min-max\"?$:eo([{fieldPrefix:\"upper_whisker_\",titlePrefix:\"Upper Whisker\"},{fieldPrefix:\"lower_whisker_\",titlePrefix:\"Lower Whisker\"}],h,C),P=[...Re({partName:\"rule\",mark:{type:\"rule\",invalid:u,aria:!1},positionPrefix:\"lower_whisker\",endPositionPrefix:\"lower_box\",extraEncoding:O}),...Re({partName:\"rule\",mark:{type:\"rule\",invalid:u,aria:!1},positionPrefix:\"upper_box\",endPositionPrefix:\"upper_whisker\",extraEncoding:O}),...Re({partName:\"ticks\",mark:I,positionPrefix:\"lower_whisker\",extraEncoding:O}),...Re({partName:\"ticks\",mark:I,positionPrefix:\"upper_whisker\",extraEncoding:O})],A=[...f!==\"tukey\"?P:[],...sn({partName:\"box\",mark:{type:\"bar\",...l?{size:l}:{},orient:N,invalid:u,ariaRoleDescription:\"box\"},positionPrefix:\"lower_box\",endPositionPrefix:\"upper_box\",extraEncoding:$}),...w({partName:\"median\",mark:{type:\"tick\",invalid:u,...H(t.boxplot.median)&&t.boxplot.median.color?{color:t.boxplot.median.color}:{},...l?{size:l}:{},orient:k,aria:!1},positionPrefix:\"mid_box\",extraEncoding:$})];if(f===\"min-max\")return{...o,transform:(o.transform??[]).concat(p),layer:A};const M=`datum[\"lower_box_${h.field}\"]`,V=`datum[\"upper_box_${h.field}\"]`,j=`(${V} - ${M})`,Q=`${M} - ${c} * ${j}`,ve=`${V} + ${c} * ${j}`,te=`datum[\"${h.field}\"]`,on={joinaggregate:Cf(h.field),groupby:y},Cs={transform:[{filter:`(${Q} <= ${te}) && (${te} <= ${ve})`},{aggregate:[{op:\"min\",field:h.field,as:`lower_whisker_${h.field}`},{op:\"max\",field:h.field,as:`upper_whisker_${h.field}`},{op:\"min\",field:`lower_box_${h.field}`,as:`lower_box_${h.field}`},{op:\"max\",field:`upper_box_${h.field}`,as:`upper_box_${h.field}`},...b],groupby:y}],layer:P},{tooltip:K1,...Sp}=oe,{scale:Ya,axis:vp}=h,Ka=ua(h),Ja=ke(vp,[\"title\"]),Qa=Sf(a,\"outliers\",t.boxplot,{transform:[{filter:`(${te} < ${Q}) || (${te} > ${ve})`}],mark:\"point\",encoding:{[m]:{field:h.field,type:h.type,...Ka!==void 0?{title:Ka}:{},...Ya!==void 0?{scale:Ya}:{},...K(Ja)?{}:{axis:Ja}},...Sp,...L?{color:L}:{},..._?{tooltip:_}:{}}})[0];let ir;const Za=[...d,...g,on];return Qa?ir={transform:Za,layer:[Qa,Cs]}:(ir=Cs,ir.transform.unshift(...Za)),{...o,layer:[ir,{transform:p,layer:A}]}}function Cf(e){return[{op:\"q1\",field:e,as:`lower_box_${e}`},{op:\"q3\",field:e,as:`upper_box_${e}`}]}function my(e,t,n){const i=Ef(e,wr),{continuousAxisChannelDef:r,continuousAxis:s}=vf(e,i,wr),o=r.field,a=$f(t),c=[...Cf(o),{op:\"median\",field:o,as:`mid_box_${o}`},{op:\"min\",field:o,as:(a===\"min-max\"?\"lower_whisker_\":\"min_\")+o},{op:\"max\",field:o,as:(a===\"min-max\"?\"upper_whisker_\":\"max_\")+o}],l=a===\"min-max\"||a===\"tukey\"?[]:[{calculate:`datum[\"upper_box_${o}\"] - datum[\"lower_box_${o}\"]`,as:`iqr_${o}`},{calculate:`min(datum[\"upper_box_${o}\"] + datum[\"iqr_${o}\"] * ${t}, datum[\"max_${o}\"])`,as:`upper_whisker_${o}`},{calculate:`max(datum[\"lower_box_${o}\"] - datum[\"iqr_${o}\"] * ${t}, datum[\"min_${o}\"])`,as:`lower_whisker_${o}`}],{[s]:u,...f}=e.encoding,{customTooltipWithoutAggregatedField:d,filteredEncoding:g}=py(f),{bins:p,timeUnits:h,aggregate:m,groupby:y,encoding:b}=bf(g,n),C=i===\"vertical\"?\"horizontal\":\"vertical\",k=i,N=[...p,...h,{aggregate:[...m,...c],groupby:y},...l];return{bins:p,timeUnits:h,transform:N,groupby:y,aggregate:m,continuousAxisChannelDef:r,continuousAxis:s,encodingWithoutContinuousAxis:b,ticksOrient:C,boxOrient:k,customTooltipWithoutAggregatedField:d}}const da=\"errorbar\",yy=[\"ticks\",\"rule\"],by=new ts(da,Nf);function Nf(e,{config:t}){e={...e,encoding:ns(e.encoding,t)};const{transform:n,continuousAxisChannelDef:i,continuousAxis:r,encodingWithoutContinuousAxis:s,ticksOrient:o,markDef:a,outerSpec:c,tooltipEncoding:l}=Ff(e,da,t);delete s.size;const u=fa(a,r,i,s,t.errorbar),f=a.thickness,d=a.size,g={type:\"tick\",orient:o,aria:!1,...f!==void 0?{thickness:f}:{},...d!==void 0?{size:d}:{}},p=[...u({partName:\"ticks\",mark:g,positionPrefix:\"lower\",extraEncoding:l}),...u({partName:\"ticks\",mark:g,positionPrefix:\"upper\",extraEncoding:l}),...u({partName:\"rule\",mark:{type:\"rule\",ariaRoleDescription:\"errorbar\",...f!==void 0?{size:f}:{}},positionPrefix:\"lower\",endPositionPrefix:\"upper\",extraEncoding:l})];return{...c,transform:n,...p.length>1?{layer:p}:{...p[0]}}}function xy(e,t){const{encoding:n}=e;if(Sy(n))return{orient:Ef(e,t),inputType:\"raw\"};const i=vy(n),r=Ey(n),s=n.x,o=n.y;if(i){if(r)throw new Error(`${t} cannot be both type aggregated-upper-lower and aggregated-error`);const a=n.x2,c=n.y2;if(D(a)&&D(c))throw new Error(`${t} cannot have both x2 and y2`);if(D(a)){if(Ut(s))return{orient:\"horizontal\",inputType:\"aggregated-upper-lower\"};throw new Error(`Both x and x2 have to be quantitative in ${t}`)}else if(D(c)){if(Ut(o))return{orient:\"vertical\",inputType:\"aggregated-upper-lower\"};throw new Error(`Both y and y2 have to be quantitative in ${t}`)}throw new Error(\"No ranged axis\")}else{const a=n.xError,c=n.xError2,l=n.yError,u=n.yError2;if(D(c)&&!D(a))throw new Error(`${t} cannot have xError2 without xError`);if(D(u)&&!D(l))throw new Error(`${t} cannot have yError2 without yError`);if(D(a)&&D(l))throw new Error(`${t} cannot have both xError and yError with both are quantiative`);if(D(a)){if(Ut(s))return{orient:\"horizontal\",inputType:\"aggregated-error\"};throw new Error(\"All x, xError, and xError2 (if exist) have to be quantitative\")}else if(D(l)){if(Ut(o))return{orient:\"vertical\",inputType:\"aggregated-error\"};throw new Error(\"All y, yError, and yError2 (if exist) have to be quantitative\")}throw new Error(\"No ranged axis\")}}function Sy(e){return(D(e.x)||D(e.y))&&!D(e.x2)&&!D(e.y2)&&!D(e.xError)&&!D(e.xError2)&&!D(e.yError)&&!D(e.yError2)}function vy(e){return D(e.x2)||D(e.y2)}function Ey(e){return D(e.xError)||D(e.xError2)||D(e.yError)||D(e.yError2)}function Ff(e,t,n){const{mark:i,encoding:r,params:s,projection:o,...a}=e,c=pt(i)?i:{type:i};s&&S(xu(t));const{orient:l,inputType:u}=xy(e,t),{continuousAxisChannelDef:f,continuousAxisChannelDef2:d,continuousAxisChannelDefError:g,continuousAxisChannelDefError2:p,continuousAxis:h}=vf(e,l,t),{errorBarSpecificAggregate:m,postAggregateCalculates:y,tooltipSummary:b,tooltipTitleWithFieldName:C}=$y(c,f,d,g,p,u,t,n),{[h]:k,[h===\"x\"?\"x2\":\"y2\"]:N,[h===\"x\"?\"xError\":\"yError\"]:_,[h===\"x\"?\"xError2\":\"yError2\"]:L,...U}=r,{bins:oe,timeUnits:de,aggregate:Re,groupby:sn,encoding:w}=bf(U,n),$=[...Re,...m],I=u!==\"raw\"?[]:sn,O=eo(b,f,w,C);return{transform:[...a.transform??[],...oe,...de,...$.length===0?[]:[{aggregate:$,groupby:I}],...y],groupby:I,continuousAxisChannelDef:f,continuousAxis:h,encodingWithoutContinuousAxis:w,ticksOrient:l===\"vertical\"?\"horizontal\":\"vertical\",markDef:c,outerSpec:a,tooltipEncoding:O}}function $y(e,t,n,i,r,s,o,a){let c=[],l=[];const u=t.field;let f,d=!1;if(s===\"raw\"){const g=e.center?e.center:e.extent?e.extent===\"iqr\"?\"median\":\"mean\":a.errorbar.center,p=e.extent?e.extent:g===\"mean\"?\"stderr\":\"iqr\";if(g===\"median\"!=(p===\"iqr\")&&S(Lh(g,p,o)),p===\"stderr\"||p===\"stdev\")c=[{op:p,field:u,as:`extent_${u}`},{op:g,field:u,as:`center_${u}`}],l=[{calculate:`datum[\"center_${u}\"] + datum[\"extent_${u}\"]`,as:`upper_${u}`},{calculate:`datum[\"center_${u}\"] - datum[\"extent_${u}\"]`,as:`lower_${u}`}],f=[{fieldPrefix:\"center_\",titlePrefix:Wi(g)},{fieldPrefix:\"upper_\",titlePrefix:vc(g,p,\"+\")},{fieldPrefix:\"lower_\",titlePrefix:vc(g,p,\"-\")}],d=!0;else{let h,m,y;p===\"ci\"?(h=\"mean\",m=\"ci0\",y=\"ci1\"):(h=\"median\",m=\"q1\",y=\"q3\"),c=[{op:m,field:u,as:`lower_${u}`},{op:y,field:u,as:`upper_${u}`},{op:h,field:u,as:`center_${u}`}],f=[{fieldPrefix:\"upper_\",titlePrefix:Vn({field:u,aggregate:y,type:\"quantitative\"},a,{allowDisabling:!1})},{fieldPrefix:\"lower_\",titlePrefix:Vn({field:u,aggregate:m,type:\"quantitative\"},a,{allowDisabling:!1})},{fieldPrefix:\"center_\",titlePrefix:Vn({field:u,aggregate:h,type:\"quantitative\"},a,{allowDisabling:!1})}]}}else{(e.center||e.extent)&&S(Ih(e.center,e.extent)),s===\"aggregated-upper-lower\"?(f=[],l=[{calculate:`datum[\"${n.field}\"]`,as:`upper_${u}`},{calculate:`datum[\"${u}\"]`,as:`lower_${u}`}]):s===\"aggregated-error\"&&(f=[{fieldPrefix:\"\",titlePrefix:u}],l=[{calculate:`datum[\"${u}\"] + datum[\"${i.field}\"]`,as:`upper_${u}`}],r?l.push({calculate:`datum[\"${u}\"] + datum[\"${r.field}\"]`,as:`lower_${u}`}):l.push({calculate:`datum[\"${u}\"] - datum[\"${i.field}\"]`,as:`lower_${u}`}));for(const g of l)f.push({fieldPrefix:g.as.substring(0,6),titlePrefix:vn(vn(g.calculate,'datum[\"',\"\"),'\"]',\"\")})}return{postAggregateCalculates:l,errorBarSpecificAggregate:c,tooltipSummary:f,tooltipTitleWithFieldName:d}}function vc(e,t,n){return`${Wi(e)} ${n} ${t}`}const pa=\"errorband\",wy=[\"band\",\"borders\"],Cy=new ts(pa,kf);function kf(e,{config:t}){e={...e,encoding:ns(e.encoding,t)};const{transform:n,continuousAxisChannelDef:i,continuousAxis:r,encodingWithoutContinuousAxis:s,markDef:o,outerSpec:a,tooltipEncoding:c}=Ff(e,pa,t),l=o,u=fa(l,r,i,s,t.errorband),f=e.encoding.x!==void 0&&e.encoding.y!==void 0;let d={type:f?\"area\":\"rect\"},g={type:f?\"line\":\"rule\"};const p={...l.interpolate?{interpolate:l.interpolate}:{},...l.tension&&l.interpolate?{tension:l.tension}:{}};return f?(d={...d,...p,ariaRoleDescription:\"errorband\"},g={...g,...p,aria:!1}):l.interpolate?S(dc(\"interpolate\")):l.tension&&S(dc(\"tension\")),{...a,transform:n,layer:[...u({partName:\"band\",mark:d,positionPrefix:\"lower\",endPositionPrefix:\"upper\",extraEncoding:c}),...u({partName:\"borders\",mark:g,positionPrefix:\"lower\",extraEncoding:c}),...u({partName:\"borders\",mark:g,positionPrefix:\"upper\",extraEncoding:c})]}}const Tf={};function ga(e,t,n){const i=new ts(e,t);Tf[e]={normalizer:i,parts:n}}function Ny(){return x(Tf)}ga(wr,wf,gy);ga(da,Nf,yy);ga(pa,kf,wy);const Fy=[\"gradientHorizontalMaxLength\",\"gradientHorizontalMinLength\",\"gradientVerticalMaxLength\",\"gradientVerticalMinLength\",\"unselectedOpacity\"],Af={titleAlign:\"align\",titleAnchor:\"anchor\",titleAngle:\"angle\",titleBaseline:\"baseline\",titleColor:\"color\",titleFont:\"font\",titleFontSize:\"fontSize\",titleFontStyle:\"fontStyle\",titleFontWeight:\"fontWeight\",titleLimit:\"limit\",titleLineHeight:\"lineHeight\",titleOrient:\"orient\",titlePadding:\"offset\"},Of={labelAlign:\"align\",labelAnchor:\"anchor\",labelAngle:\"angle\",labelBaseline:\"baseline\",labelColor:\"color\",labelFont:\"font\",labelFontSize:\"fontSize\",labelFontStyle:\"fontStyle\",labelFontWeight:\"fontWeight\",labelLimit:\"limit\",labelLineHeight:\"lineHeight\",labelOrient:\"orient\",labelPadding:\"offset\"},ky=x(Af),Ty=x(Of),Ay={header:1,headerRow:1,headerColumn:1,headerFacet:1},_f=x(Ay),Rf=[\"size\",\"shape\",\"fill\",\"stroke\",\"strokeDash\",\"strokeWidth\",\"opacity\"],Oy={gradientHorizontalMaxLength:200,gradientHorizontalMinLength:100,gradientVerticalMaxLength:200,gradientVerticalMinLength:64,unselectedOpacity:.35},_y={aria:1,clipHeight:1,columnPadding:1,columns:1,cornerRadius:1,description:1,direction:1,fillColor:1,format:1,formatType:1,gradientLength:1,gradientOpacity:1,gradientStrokeColor:1,gradientStrokeWidth:1,gradientThickness:1,gridAlign:1,labelAlign:1,labelBaseline:1,labelColor:1,labelFont:1,labelFontSize:1,labelFontStyle:1,labelFontWeight:1,labelLimit:1,labelOffset:1,labelOpacity:1,labelOverlap:1,labelPadding:1,labelSeparation:1,legendX:1,legendY:1,offset:1,orient:1,padding:1,rowPadding:1,strokeColor:1,symbolDash:1,symbolDashOffset:1,symbolFillColor:1,symbolLimit:1,symbolOffset:1,symbolOpacity:1,symbolSize:1,symbolStrokeColor:1,symbolStrokeWidth:1,symbolType:1,tickCount:1,tickMinStep:1,title:1,titleAlign:1,titleAnchor:1,titleBaseline:1,titleColor:1,titleFont:1,titleFontSize:1,titleFontStyle:1,titleFontWeight:1,titleLimit:1,titleLineHeight:1,titleOpacity:1,titleOrient:1,titlePadding:1,type:1,values:1,zindex:1},Ze=\"_vgsid_\",Ry={point:{on:\"click\",fields:[Ze],toggle:\"event.shiftKey\",resolve:\"global\",clear:\"dblclick\"},interval:{on:\"[pointerdown, window:pointerup] > window:pointermove!\",encodings:[\"x\",\"y\"],translate:\"[pointerdown, window:pointerup] > window:pointermove!\",zoom:\"wheel!\",mark:{fill:\"#333\",fillOpacity:.125,stroke:\"white\"},resolve:\"global\",clear:\"dblclick\"}};function ha(e){return e===\"legend\"||!!e?.legend}function Ts(e){return ha(e)&&H(e)}function ma(e){return!!e?.select}function If(e){const t=[];for(const n of e||[]){if(ma(n))continue;const{expr:i,bind:r,...s}=n;if(r&&i){const o={...s,bind:r,init:i};t.push(o)}else{const o={...s,...i?{update:i}:{},...r?{bind:r}:{}};t.push(o)}}return t}function Iy(e){return is(e)||ba(e)||ya(e)}function ya(e){return\"concat\"in e}function is(e){return\"vconcat\"in e}function ba(e){return\"hconcat\"in e}function Lf({step:e,offsetIsDiscrete:t}){return t?e.for??\"offset\":\"position\"}function ht(e){return H(e)&&e.step!==void 0}function Ec(e){return e.view||e.width||e.height}const $c=20,Ly={align:1,bounds:1,center:1,columns:1,spacing:1},Py=x(Ly);function zy(e,t,n){const i=n[t],r={},{spacing:s,columns:o}=i;s!==void 0&&(r.spacing=s),o!==void 0&&(Kr(e)&&!Ki(e.facet)||ya(e))&&(r.columns=o),is(e)&&(r.columns=1);for(const a of Py)if(e[a]!==void 0)if(a===\"spacing\"){const c=e[a];r[a]=ie(c)?c:{row:c.row??s,column:c.column??s}}else r[a]=e[a];return r}function to(e,t){return e[t]??e[t===\"width\"?\"continuousWidth\":\"continuousHeight\"]}function Cr(e,t){const n=Nr(e,t);return ht(n)?n.step:Pf}function Nr(e,t){const n=e[t]??e[t===\"width\"?\"discreteWidth\":\"discreteHeight\"];return le(n,{step:e.step})}const Pf=20,Dy={continuousWidth:200,continuousHeight:200,step:Pf},My={background:\"white\",padding:5,timeFormat:\"%b %d, %Y\",countTitle:\"Count of Records\",view:Dy,mark:Om,arc:{},area:{},bar:Im,circle:{},geoshape:{},image:{},line:{},point:{},rect:Lm,rule:{color:\"black\"},square:{},text:{color:\"black\"},tick:Pm,trail:{},boxplot:{size:14,extent:1.5,box:{},median:{color:\"white\"},outliers:{},rule:{},ticks:null},errorbar:{center:\"mean\",rule:!0,ticks:!1},errorband:{band:{opacity:.3},borders:!1},scale:pm,projection:{},legend:Oy,header:{titlePadding:10,labelPadding:10},headerColumn:{},headerRow:{},headerFacet:{},selection:Ry,style:{},title:{},facet:{spacing:$c},concat:{spacing:$c},normalizedNumberFormat:\".0%\"},Et=[\"#4c78a8\",\"#f58518\",\"#e45756\",\"#72b7b2\",\"#54a24b\",\"#eeca3b\",\"#b279a2\",\"#ff9da6\",\"#9d755d\",\"#bab0ac\"],wc={text:11,guideLabel:10,guideTitle:11,groupTitle:13,groupSubtitle:12},Cc={blue:Et[0],orange:Et[1],red:Et[2],teal:Et[3],green:Et[4],yellow:Et[5],purple:Et[6],pink:Et[7],brown:Et[8],gray0:\"#000\",gray1:\"#111\",gray2:\"#222\",gray3:\"#333\",gray4:\"#444\",gray5:\"#555\",gray6:\"#666\",gray7:\"#777\",gray8:\"#888\",gray9:\"#999\",gray10:\"#aaa\",gray11:\"#bbb\",gray12:\"#ccc\",gray13:\"#ddd\",gray14:\"#eee\",gray15:\"#fff\"};function jy(e={}){return{signals:[{name:\"color\",value:H(e)?{...Cc,...e}:Cc}],mark:{color:{signal:\"color.blue\"}},rule:{color:{signal:\"color.gray0\"}},text:{color:{signal:\"color.gray0\"}},style:{\"guide-label\":{fill:{signal:\"color.gray0\"}},\"guide-title\":{fill:{signal:\"color.gray0\"}},\"group-title\":{fill:{signal:\"color.gray0\"}},\"group-subtitle\":{fill:{signal:\"color.gray0\"}},cell:{stroke:{signal:\"color.gray8\"}}},axis:{domainColor:{signal:\"color.gray13\"},gridColor:{signal:\"color.gray8\"},tickColor:{signal:\"color.gray13\"}},range:{category:[{signal:\"color.blue\"},{signal:\"color.orange\"},{signal:\"color.red\"},{signal:\"color.teal\"},{signal:\"color.green\"},{signal:\"color.yellow\"},{signal:\"color.purple\"},{signal:\"color.pink\"},{signal:\"color.brown\"},{signal:\"color.grey8\"}]}}}function Uy(e){return{signals:[{name:\"fontSize\",value:H(e)?{...wc,...e}:wc}],text:{fontSize:{signal:\"fontSize.text\"}},style:{\"guide-label\":{fontSize:{signal:\"fontSize.guideLabel\"}},\"guide-title\":{fontSize:{signal:\"fontSize.guideTitle\"}},\"group-title\":{fontSize:{signal:\"fontSize.groupTitle\"}},\"group-subtitle\":{fontSize:{signal:\"fontSize.groupSubtitle\"}}}}}function By(e){return{text:{font:e},style:{\"guide-label\":{font:e},\"guide-title\":{font:e},\"group-title\":{font:e},\"group-subtitle\":{font:e}}}}function zf(e){const t=x(e||{}),n={};for(const i of t){const r=e[i];n[i]=Zi(r)?du(r):Le(r)}return n}function Wy(e){const t=x(e),n={};for(const i of t)n[i]=zf(e[i]);return n}const Gy=[...Vu,...hf,..._f,\"background\",\"padding\",\"legend\",\"lineBreak\",\"scale\",\"style\",\"title\",\"view\"];function Df(e={}){const{color:t,font:n,fontSize:i,selection:r,...s}=e,o=Rr({},z(My),n?By(n):{},t?jy(t):{},i?Uy(i):{},s||{});r&&bo(o,\"selection\",r,!0);const a=ke(o,Gy);for(const c of[\"background\",\"lineBreak\",\"padding\"])o[c]&&(a[c]=Le(o[c]));for(const c of Vu)o[c]&&(a[c]=Fe(o[c]));for(const c of hf)o[c]&&(a[c]=zf(o[c]));for(const c of _f)o[c]&&(a[c]=Fe(o[c]));return o.legend&&(a.legend=Fe(o.legend)),o.scale&&(a.scale=Fe(o.scale)),o.style&&(a.style=Wy(o.style)),o.title&&(a.title=Fe(o.title)),o.view&&(a.view=Fe(o.view)),a}const Hy=new Set([\"view\",...Cm]),qy=[\"color\",\"fontSize\",\"background\",\"padding\",\"facet\",\"concat\",\"numberFormat\",\"numberFormatType\",\"normalizedNumberFormat\",\"normalizedNumberFormatType\",\"timeFormat\",\"countTitle\",\"header\",\"axisQuantitative\",\"axisTemporal\",\"axisDiscrete\",\"axisPoint\",\"axisXBand\",\"axisXPoint\",\"axisXDiscrete\",\"axisXQuantitative\",\"axisXTemporal\",\"axisYBand\",\"axisYPoint\",\"axisYDiscrete\",\"axisYQuantitative\",\"axisYTemporal\",\"scale\",\"selection\",\"overlay\"],Vy={view:[\"continuousWidth\",\"continuousHeight\",\"discreteWidth\",\"discreteHeight\",\"step\"],...Am};function Xy(e){e=z(e);for(const t of qy)delete e[t];if(e.axis)for(const t in e.axis)Zi(e.axis[t])&&delete e.axis[t];if(e.legend)for(const t of Fy)delete e.legend[t];if(e.mark){for(const t of gc)delete e.mark[t];e.mark.tooltip&&H(e.mark.tooltip)&&delete e.mark.tooltip}e.params&&(e.signals=(e.signals||[]).concat(If(e.params)),delete e.params);for(const t of Hy){for(const i of gc)delete e[t][i];const n=Vy[t];if(n)for(const i of n)delete e[t][i];Ky(e,t)}for(const t of Ny())delete e[t];Yy(e);for(const t in e)H(e[t])&&K(e[t])&&delete e[t];return K(e)?void 0:e}function Yy(e){const{titleMarkConfig:t,subtitleMarkConfig:n,subtitle:i}=fu(e.title);K(t)||(e.style[\"group-title\"]={...e.style[\"group-title\"],...t}),K(n)||(e.style[\"group-subtitle\"]={...e.style[\"group-subtitle\"],...n}),K(i)?delete e.title:e.title=i}function Ky(e,t,n,i){const r=e[t];t===\"view\"&&(n=\"cell\");const s={...r,...e.style[n??t]};K(s)||(e.style[n??t]=s),delete e[t]}function rs(e){return\"layer\"in e}function Jy(e){return\"repeat\"in e}function Qy(e){return!F(e.repeat)&&e.repeat.layer}class xa{map(t,n){return Kr(t)?this.mapFacet(t,n):Jy(t)?this.mapRepeat(t,n):ba(t)?this.mapHConcat(t,n):is(t)?this.mapVConcat(t,n):ya(t)?this.mapConcat(t,n):this.mapLayerOrUnit(t,n)}mapLayerOrUnit(t,n){if(rs(t))return this.mapLayer(t,n);if(zt(t))return this.mapUnit(t,n);throw new Error(Lo(t))}mapLayer(t,n){return{...t,layer:t.layer.map(i=>this.mapLayerOrUnit(i,n))}}mapHConcat(t,n){return{...t,hconcat:t.hconcat.map(i=>this.map(i,n))}}mapVConcat(t,n){return{...t,vconcat:t.vconcat.map(i=>this.map(i,n))}}mapConcat(t,n){const{concat:i,...r}=t;return{...r,concat:i.map(s=>this.map(s,n))}}mapFacet(t,n){return{...t,spec:this.map(t.spec,n)}}mapRepeat(t,n){return{...t,spec:this.map(t.spec,n)}}}const Zy={zero:1,center:1,normalize:1};function eb(e){return e in Zy}const tb=new Set([Gu,qr,Hr,br,Xr,Jo,Qo,Vr,Hu,Ko]),nb=new Set([qr,Hr,Gu]);function jn(e){return v(e)&&ii(e)===\"quantitative\"&&!e.bin}function Nc(e,t,{orient:n,type:i}){const r=t===\"x\"?\"y\":\"radius\",s=t===\"x\"&&[\"bar\",\"area\"].includes(i),o=e[t],a=e[r];if(v(o)&&v(a))if(jn(o)&&jn(a)){if(o.stack)return t;if(a.stack)return r;const c=v(o)&&!!o.aggregate,l=v(a)&&!!a.aggregate;if(c!==l)return c?t:r;if(s){if(n===\"vertical\")return r;if(n===\"horizontal\")return t}}else{if(jn(o))return t;if(jn(a))return r}else{if(jn(o))return s&&n===\"vertical\"?void 0:t;if(jn(a))return s&&n===\"horizontal\"?void 0:r}}function ib(e){switch(e){case\"x\":return\"y\";case\"y\":return\"x\";case\"theta\":return\"radius\";case\"radius\":return\"theta\"}}function Mf(e,t){const n=pt(e)?e:{type:e},i=n.type;if(!tb.has(i))return null;const r=Nc(t,\"x\",n)||Nc(t,\"theta\",n);if(!r)return null;const s=t[r],o=v(s)?E(s,{}):void 0,a=ib(r),c=[],l=new Set;if(t[a]){const h=t[a],m=v(h)?E(h,{}):void 0;m&&m!==o&&(c.push(a),l.add(m))}const u=a===\"x\"?\"xOffset\":\"yOffset\",f=t[u],d=v(f)?E(f,{}):void 0;d&&d!==o&&(c.push(u),l.add(d));const g=mg.reduce((h,m)=>{if(m!==\"tooltip\"&&yn(t,m)){const y=t[m];for(const b of ce(y)){const C=gt(b);if(C.aggregate)continue;const k=E(C,{});(!k||!l.has(k))&&h.push({channel:m,fieldDef:C})}}return h},[]);let p;return s.stack!==void 0?di(s.stack)?p=s.stack?\"zero\":null:p=s.stack:nb.has(i)&&(p=\"zero\"),!p||!eb(p)||ca(t)&&g.length===0?null:s?.scale?.type&&s?.scale?.type!==Te.LINEAR?(s?.stack&&S(Oh(s.scale.type)),null):D(t[xt(r)])?(s.stack!==void 0&&S(Ah(r)),null):(v(s)&&s.aggregate&&!kg.has(s.aggregate)&&S(_h(s.aggregate)),{groupbyChannels:c,groupbyFields:l,fieldChannel:r,impute:s.impute===null?!1:rn(i),stackBy:g,offset:p})}function jf(e,t,n){const i=Fe(e),r=X(\"orient\",i,n);if(i.orient=ab(i.type,t,r),r!==void 0&&r!==i.orient&&S(gh(i.orient,r)),i.type===\"bar\"&&i.orient){const c=X(\"cornerRadiusEnd\",i,n);if(c!==void 0){const l=i.orient===\"horizontal\"&&t.x2||i.orient===\"vertical\"&&t.y2?[\"cornerRadius\"]:Rm[i.orient];for(const u of l)i[u]=c;i.cornerRadiusEnd!==void 0&&delete i.cornerRadiusEnd}}const s=X(\"opacity\",i,n),o=X(\"fillOpacity\",i,n);return s===void 0&&o===void 0&&(i.opacity=sb(i.type,t)),X(\"cursor\",i,n)===void 0&&(i.cursor=rb(i,t,n)),i}function rb(e,t,n){return t.href||e.href||X(\"href\",e,n)?\"pointer\":e.cursor}function sb(e,t){if(G([Xr,Ko,Jo,Qo],e)&&!ca(t))return .7}function ob(e,t,{graticule:n}){if(n)return!1;const i=Ot(\"filled\",e,t),r=e.type;return le(i,r!==Xr&&r!==Vr&&r!==br)}function ab(e,t,n){switch(e){case Xr:case Jo:case Qo:case Hu:case $m:case Em:return}const{x:i,y:r,x2:s,y2:o}=t;switch(e){case qr:if(v(i)&&(xe(i.bin)||v(r)&&r.aggregate&&!i.aggregate))return\"vertical\";if(v(r)&&(xe(r.bin)||v(i)&&i.aggregate&&!r.aggregate))return\"horizontal\";if(o||s){if(n)return n;if(!s)return(v(i)&&i.type===wn&&!ee(i.bin)||Sr(i))&&v(r)&&xe(r.bin)?\"horizontal\":\"vertical\";if(!o)return(v(r)&&r.type===wn&&!ee(r.bin)||Sr(r))&&v(i)&&xe(i.bin)?\"vertical\":\"horizontal\"}case br:if(s&&!(v(i)&&xe(i.bin))&&o&&!(v(r)&&xe(r.bin)))return;case Hr:if(o)return v(r)&&xe(r.bin)?\"horizontal\":\"vertical\";if(s)return v(i)&&xe(i.bin)?\"vertical\":\"horizontal\";if(e===br){if(i&&!r)return\"vertical\";if(r&&!i)return\"horizontal\"}case Vr:case Ko:{const a=bc(i),c=bc(r);if(n)return n;if(a&&!c)return e!==\"tick\"?\"horizontal\":\"vertical\";if(!a&&c)return e!==\"tick\"?\"vertical\":\"horizontal\";if(a&&c)return\"vertical\";{const l=Ce(i)&&i.type===ti,u=Ce(r)&&r.type===ti;if(l&&!u)return\"vertical\";if(!l&&u)return\"horizontal\"}return}}return\"vertical\"}function cb(e){const{point:t,line:n,...i}=e;return x(i).length>1?i:i.type}function lb(e){for(const t of[\"line\",\"area\",\"rule\",\"trail\"])e[t]&&(e={...e,[t]:ke(e[t],[\"point\",\"line\"])});return e}function As(e,t={},n){return e.point===\"transparent\"?{opacity:0}:e.point?H(e.point)?e.point:{}:e.point!==void 0?null:t.point||n.shape?H(t.point)?t.point:{}:void 0}function Fc(e,t={}){return e.line?e.line===!0?{}:e.line:e.line!==void 0?null:t.line?t.line===!0?{}:t.line:void 0}class ub{constructor(){this.name=\"path-overlay\"}hasMatchingType(t,n){if(zt(t)){const{mark:i,encoding:r}=t,s=pt(i)?i:{type:i};switch(s.type){case\"line\":case\"rule\":case\"trail\":return!!As(s,n[s.type],r);case\"area\":return!!As(s,n[s.type],r)||!!Fc(s,n[s.type])}}return!1}run(t,n,i){const{config:r}=n,{params:s,projection:o,mark:a,name:c,encoding:l,...u}=t,f=ns(l,r),d=pt(a)?a:{type:a},g=As(d,r[d.type],f),p=d.type===\"area\"&&Fc(d,r[d.type]),h=[{name:c,...s?{params:s}:{},mark:cb({...d.type===\"area\"&&d.opacity===void 0&&d.fillOpacity===void 0?{opacity:.7}:{},...d}),encoding:ke(f,[\"shape\"])}],m=Mf(jf(d,f,r),f);let y=f;if(m){const{fieldChannel:b,offset:C}=m;y={...f,[b]:{...f[b],...C?{stack:C}:{}}}}return y=ke(y,[\"y2\",\"x2\"]),p&&h.push({...o?{projection:o}:{},mark:{type:\"line\",...Jn(d,[\"clip\",\"interpolate\",\"tension\",\"tooltip\"]),...p},encoding:y}),g&&h.push({...o?{projection:o}:{},mark:{type:\"point\",opacity:1,filled:!0,...Jn(d,[\"clip\",\"tooltip\"]),...g},encoding:y}),i({...u,layer:h},{...n,config:lb(r)})}}function fb(e,t){return t?Ki(e)?Bf(e,t):Uf(e,t):e}function Os(e,t){return t?Bf(e,t):e}function no(e,t,n){const i=t[e];if(Vm(i)){if(i.repeat in n)return{...t,[e]:n[i.repeat]};S(Xg(i.repeat));return}return t}function Uf(e,t){if(e=no(\"field\",e,t),e!==void 0){if(e===null)return null;if(ra(e)&&ut(e.sort)){const n=no(\"field\",e.sort,t);e={...e,...n?{sort:n}:{}}}return e}}function kc(e,t){if(v(e))return Uf(e,t);{const n=no(\"datum\",e,t);return n!==e&&!n.type&&(n.type=\"nominal\"),n}}function Tc(e,t){if(D(e)){const n=kc(e,t);if(n)return n;if(Jr(e))return{condition:e.condition}}else{if(Ji(e)){const n=kc(e.condition,t);if(n)return{...e,condition:n};{const{condition:i,...r}=e;return r}}return e}}function Bf(e,t){const n={};for(const i in e)if(Gn(e,i)){const r=e[i];if(F(r))n[i]=r.map(s=>Tc(s,t)).filter(s=>s);else{const s=Tc(r,t);s!==void 0&&(n[i]=s)}}return n}class db{constructor(){this.name=\"RuleForRangedLine\"}hasMatchingType(t){if(zt(t)){const{encoding:n,mark:i}=t;if(i===\"line\"||pt(i)&&i.type===\"line\")for(const r of pg){const s=_n(r),o=n[s];if(n[r]&&(v(o)&&!xe(o.bin)||vt(o)))return!0}}return!1}run(t,n,i){const{encoding:r,mark:s}=t;return S(ph(!!r.x2,!!r.y2)),i({...t,mark:H(s)?{...s,type:\"rule\"}:\"rule\"},n)}}class pb extends xa{constructor(){super(...arguments),this.nonFacetUnitNormalizers=[hy,by,Cy,new ub,new db]}map(t,n){if(zt(t)){const i=yn(t.encoding,Nt),r=yn(t.encoding,Ft),s=yn(t.encoding,Lr);if(i||r||s)return this.mapFacetedUnit(t,n)}return super.map(t,n)}mapUnit(t,n){const{parentEncoding:i,parentProjection:r}=n,s=Os(t.encoding,n.repeater),o={...t,...t.name?{name:[n.repeaterPrefix,t.name].filter(c=>c).join(\"_\")}:{},...s?{encoding:s}:{}};if(i||r)return this.mapUnitWithParentEncodingOrProjection(o,n);const a=this.mapLayerOrUnit.bind(this);for(const c of this.nonFacetUnitNormalizers)if(c.hasMatchingType(o,n.config))return c.run(o,n,a);return o}mapRepeat(t,n){return Qy(t)?this.mapLayerRepeat(t,n):this.mapNonLayerRepeat(t,n)}mapLayerRepeat(t,n){const{repeat:i,spec:r,...s}=t,{row:o,column:a,layer:c}=i,{repeater:l={},repeaterPrefix:u=\"\"}=n;return o||a?this.mapRepeat({...t,repeat:{...o?{row:o}:{},...a?{column:a}:{}},spec:{repeat:{layer:c},spec:r}},n):{...s,layer:c.map(f=>{const d={...l,layer:f},g=`${(r.name?`${r.name}_`:\"\")+u}child__layer_${re(f)}`,p=this.mapLayerOrUnit(r,{...n,repeater:d,repeaterPrefix:g});return p.name=g,p})}}mapNonLayerRepeat(t,n){const{repeat:i,spec:r,data:s,...o}=t;!F(i)&&t.columns&&(t=ke(t,[\"columns\"]),S(cc(\"repeat\")));const a=[],{repeater:c={},repeaterPrefix:l=\"\"}=n,u=!F(i)&&i.row||[c?c.row:null],f=!F(i)&&i.column||[c?c.column:null],d=F(i)&&i||[c?c.repeat:null];for(const p of d)for(const h of u)for(const m of f){const y={repeat:p,row:h,column:m,layer:c.layer},b=(r.name?`${r.name}_`:\"\")+l+\"child__\"+(F(i)?`${re(p)}`:(i.row?`row_${re(h)}`:\"\")+(i.column?`column_${re(m)}`:\"\")),C=this.map(r,{...n,repeater:y,repeaterPrefix:b});C.name=b,a.push(ke(C,[\"data\"]))}const g=F(i)?t.columns:i.column?i.column.length:1;return{data:r.data??s,align:\"all\",...o,columns:g,concat:a}}mapFacet(t,n){const{facet:i}=t;return Ki(i)&&t.columns&&(t=ke(t,[\"columns\"]),S(cc(\"facet\"))),super.mapFacet(t,n)}mapUnitWithParentEncodingOrProjection(t,n){const{encoding:i,projection:r}=t,{parentEncoding:s,parentProjection:o,config:a}=n,c=Oc({parentProjection:o,projection:r}),l=Ac({parentEncoding:s,encoding:Os(i,n.repeater)});return this.mapUnit({...t,...c?{projection:c}:{},...l?{encoding:l}:{}},{config:a})}mapFacetedUnit(t,n){const{row:i,column:r,facet:s,...o}=t.encoding,{mark:a,width:c,projection:l,height:u,view:f,params:d,encoding:g,...p}=t,{facetMapping:h,layout:m}=this.getFacetMappingAndLayout({row:i,column:r,facet:s},n),y=Os(o,n.repeater);return this.mapFacet({...p,...m,facet:h,spec:{...c?{width:c}:{},...u?{height:u}:{},...f?{view:f}:{},...l?{projection:l}:{},mark:a,encoding:y,...d?{params:d}:{}}},n)}getFacetMappingAndLayout(t,n){const{row:i,column:r,facet:s}=t;if(i||r){s&&S(fh([...i?[Nt]:[],...r?[Ft]:[]]));const o={},a={};for(const c of[Nt,Ft]){const l=t[c];if(l){const{align:u,center:f,spacing:d,columns:g,...p}=l;o[c]=p;for(const h of[\"align\",\"center\",\"spacing\"])l[h]!==void 0&&(a[h]??(a[h]={}),a[h][c]=l[h])}}return{facetMapping:o,layout:a}}else{const{align:o,center:a,spacing:c,columns:l,...u}=s;return{facetMapping:fb(u,n.repeater),layout:{...o?{align:o}:{},...a?{center:a}:{},...c?{spacing:c}:{},...l?{columns:l}:{}}}}}mapLayer(t,{parentEncoding:n,parentProjection:i,...r}){const{encoding:s,projection:o,...a}=t,c={...r,parentEncoding:Ac({parentEncoding:n,encoding:s,layer:!0}),parentProjection:Oc({parentProjection:i,projection:o})};return super.mapLayer({...a,...t.name?{name:[c.repeaterPrefix,t.name].filter(l=>l).join(\"_\")}:{}},c)}}function Ac({parentEncoding:e,encoding:t={},layer:n}){let i={};if(e){const r=new Set([...x(e),...x(t)]);for(const s of r){const o=t[s],a=e[s];if(D(o)){const c={...a,...o};i[s]=c}else Ji(o)?i[s]={...o,condition:{...a,...o.condition}}:o||o===null?i[s]=o:(n||Qe(a)||T(a)||D(a)||F(a))&&(i[s]=a)}}else i=t;return!i||K(i)?void 0:i}function Oc(e){const{parentProjection:t,projection:n}=e;return t&&n&&S(eh({parentProjection:t,projection:n})),n??t}function Sa(e){return\"filter\"in e}function gb(e){return e?.stop!==void 0}function Wf(e){return\"lookup\"in e}function hb(e){return\"data\"in e}function mb(e){return\"param\"in e}function yb(e){return\"pivot\"in e}function bb(e){return\"density\"in e}function xb(e){return\"quantile\"in e}function Sb(e){return\"regression\"in e}function vb(e){return\"loess\"in e}function Eb(e){return\"sample\"in e}function $b(e){return\"window\"in e}function wb(e){return\"joinaggregate\"in e}function Cb(e){return\"flatten\"in e}function Nb(e){return\"calculate\"in e}function Gf(e){return\"bin\"in e}function Fb(e){return\"impute\"in e}function kb(e){return\"timeUnit\"in e}function Tb(e){return\"aggregate\"in e}function Ab(e){return\"stack\"in e}function Ob(e){return\"fold\"in e}function _b(e){return\"extent\"in e&&!(\"density\"in e)}function Rb(e){return e.map(t=>Sa(t)?{filter:Hn(t.filter,om)}:t)}class Ib extends xa{map(t,n){return n.emptySelections??(n.emptySelections={}),n.selectionPredicates??(n.selectionPredicates={}),t=_c(t,n),super.map(t,n)}mapLayerOrUnit(t,n){if(t=_c(t,n),t.encoding){const i={};for(const[r,s]of Wt(t.encoding))i[r]=Hf(s,n);t={...t,encoding:i}}return super.mapLayerOrUnit(t,n)}mapUnit(t,n){const{selection:i,...r}=t;return i?{...r,params:Wt(i).map(([s,o])=>{const{init:a,bind:c,empty:l,...u}=o;u.type===\"single\"?(u.type=\"point\",u.toggle=!1):u.type===\"multi\"&&(u.type=\"point\"),n.emptySelections[s]=l!==\"none\";for(const f of Se(n.selectionPredicates[s]??{}))f.empty=l!==\"none\";return{name:s,value:a,select:u,bind:c}})}:t}}function _c(e,t){const{transform:n,...i}=e;if(n){const r=n.map(s=>{if(Sa(s))return{filter:io(s,t)};if(Gf(s)&&Rn(s.bin))return{...s,bin:qf(s.bin)};if(Wf(s)){const{selection:o,...a}=s.from;return o?{...s,from:{param:o,...a}}:s}return s});return{...i,transform:r}}return e}function Hf(e,t){const n=z(e);if(v(n)&&Rn(n.bin)&&(n.bin=qf(n.bin)),Pn(n)&&n.scale?.domain?.selection){const{selection:i,...r}=n.scale.domain;n.scale.domain={...r,...i?{param:i}:{}}}if(Jr(n))if(F(n.condition))n.condition=n.condition.map(i=>{const{selection:r,param:s,test:o,...a}=i;return s?i:{...a,test:io(i,t)}});else{const{selection:i,param:r,test:s,...o}=Hf(n.condition,t);n.condition=r?n.condition:{...o,test:io(n.condition,t)}}return n}function qf(e){const t=e.extent;if(t?.selection){const{selection:n,...i}=t;return{...e,extent:{...i,param:n}}}return e}function io(e,t){const n=i=>Hn(i,r=>{var s;const o=t.emptySelections[r]??!0,a={param:r,empty:o};return(s=t.selectionPredicates)[r]??(s[r]=[]),t.selectionPredicates[r].push(a),a});return e.selection?n(e.selection):Hn(e.test||e.filter,i=>i.selection?n(i.selection):i)}class ro extends xa{map(t,n){const i=n.selections??[];if(t.params&&!zt(t)){const r=[];for(const s of t.params)ma(s)?i.push(s):r.push(s);t.params=r}return n.selections=i,super.map(t,n)}mapUnit(t,n){const i=n.selections;if(!i||!i.length)return t;const r=(n.path??[]).concat(t.name),s=[];for(const o of i)if(!o.views||!o.views.length)s.push(o);else for(const a of o.views)(R(a)&&(a===t.name||r.includes(a))||F(a)&&a.map(c=>r.indexOf(c)).every((c,l,u)=>c!==-1&&(l===0||c>u[l-1])))&&s.push(o);return s.length&&(t.params=s),t}}for(const e of[\"mapFacet\",\"mapRepeat\",\"mapHConcat\",\"mapVConcat\",\"mapLayer\"]){const t=ro.prototype[e];ro.prototype[e]=function(n,i){return t.call(this,n,Lb(n,i))}}function Lb(e,t){return e.name?{...t,path:(t.path??[]).concat(e.name)}:t}function Vf(e,t){t===void 0&&(t=Df(e.config));const n=Mb(e,t),{width:i,height:r}=e,s=jb(n,{width:i,height:r,autosize:e.autosize},t);return{...n,...s?{autosize:s}:{}}}const Pb=new pb,zb=new Ib,Db=new ro;function Mb(e,t={}){const n={config:t};return Db.map(Pb.map(zb.map(e,n),n),n)}function Rc(e){return R(e)?{type:e}:e??{}}function jb(e,t,n){let{width:i,height:r}=t;const s=zt(e)||rs(e),o={};s?i==\"container\"&&r==\"container\"?(o.type=\"fit\",o.contains=\"padding\"):i==\"container\"?(o.type=\"fit-x\",o.contains=\"padding\"):r==\"container\"&&(o.type=\"fit-y\",o.contains=\"padding\"):(i==\"container\"&&(S(rc(\"width\")),i=void 0),r==\"container\"&&(S(rc(\"height\")),r=void 0));const a={type:\"pad\",...o,...n?Rc(n.autosize):{},...Rc(e.autosize)};if(a.type===\"fit\"&&!s&&(S(zg),a.type=\"pad\"),i==\"container\"&&!(a.type==\"fit\"||a.type==\"fit-x\")&&S(sc(\"width\")),r==\"container\"&&!(a.type==\"fit\"||a.type==\"fit-y\")&&S(sc(\"height\")),!Pe(a,{type:\"pad\"}))return a}function Ub(e){return e===\"fit\"||e===\"fit-x\"||e===\"fit-y\"}function Bb(e){return e?`fit-${jr(e)}`:\"fit\"}const Wb=[\"background\",\"padding\"];function Ic(e,t){const n={};for(const i of Wb)e&&e[i]!==void 0&&(n[i]=Le(e[i]));return t&&(n.params=e.params),n}class Dt{constructor(t={},n={}){this.explicit=t,this.implicit=n}clone(){return new Dt(z(this.explicit),z(this.implicit))}combine(){return{...this.explicit,...this.implicit}}get(t){return le(this.explicit[t],this.implicit[t])}getWithExplicit(t){return this.explicit[t]!==void 0?{explicit:!0,value:this.explicit[t]}:this.implicit[t]!==void 0?{explicit:!1,value:this.implicit[t]}:{explicit:!1,value:void 0}}setWithExplicit(t,{value:n,explicit:i}){n!==void 0&&this.set(t,n,i)}set(t,n,i){return delete this[i?\"implicit\":\"explicit\"][t],this[i?\"explicit\":\"implicit\"][t]=n,this}copyKeyFromSplit(t,{explicit:n,implicit:i}){n[t]!==void 0?this.set(t,n[t],!0):i[t]!==void 0&&this.set(t,i[t],!1)}copyKeyFromObject(t,n){n[t]!==void 0&&this.set(t,n[t],!0)}copyAll(t){for(const n of x(t.combine())){const i=t.getWithExplicit(n);this.setWithExplicit(n,i)}}}function ct(e){return{explicit:!0,value:e}}function Ie(e){return{explicit:!1,value:e}}function Xf(e){return(t,n,i,r)=>{const s=e(t.value,n.value);return s>0?t:s<0?n:ss(t,n,i,r)}}function ss(e,t,n,i){return e.explicit&&t.explicit&&S($h(n,i,e.value,t.value)),e}function qt(e,t,n,i,r=ss){return e===void 0||e.value===void 0?t:e.explicit&&!t.explicit?e:t.explicit&&!e.explicit?t:Pe(e.value,t.value)?e:r(e,t,n,i)}class Gb extends Dt{constructor(t={},n={},i=!1){super(t,n),this.explicit=t,this.implicit=n,this.parseNothing=i}clone(){const t=super.clone();return t.parseNothing=this.parseNothing,t}}function oi(e){return\"url\"in e}function Di(e){return\"values\"in e}function Yf(e){return\"name\"in e&&!oi(e)&&!Di(e)&&!Bt(e)}function Bt(e){return e&&(Kf(e)||Jf(e)||va(e))}function Kf(e){return\"sequence\"in e}function Jf(e){return\"sphere\"in e}function va(e){return\"graticule\"in e}var Z;(function(e){e[e.Raw=0]=\"Raw\",e[e.Main=1]=\"Main\",e[e.Row=2]=\"Row\",e[e.Column=3]=\"Column\",e[e.Lookup=4]=\"Lookup\"})(Z||(Z={}));function Qf(e){const{signals:t,hasLegend:n,index:i,...r}=e;return r.field=Ue(r.field),r}function Fn(e,t=!0,n=Np){if(F(e)){const i=e.map(r=>Fn(r,t,n));return t?`[${i.join(\", \")}]`:i}else if(In(e))return n(t?$n(e):Xh(e));return t?n(J(e)):e}function Hb(e,t){for(const n of Se(e.component.selection??{})){const i=n.name;let r=`${i}${Xt}, ${n.resolve===\"global\"?\"true\":`{unit: ${bn(e)}}`}`;for(const s of ls)s.defined(n)&&(s.signals&&(t=s.signals(e,n,t)),s.modifyExpr&&(r=s.modifyExpr(e,n,r)));t.push({name:i+$x,on:[{events:{signal:n.name+Xt},update:`modify(${B(n.name+kn)}, ${r})`}]})}return Ea(t)}function qb(e,t){if(e.component.selection&&x(e.component.selection).length){const n=B(e.getName(\"cell\"));t.unshift({name:\"facet\",value:{},on:[{events:pi(\"pointermove\",\"scope\"),update:`isTuple(facet) ? facet : group(${n}).datum`}]})}return Ea(t)}function Vb(e,t){let n=!1;for(const i of Se(e.component.selection??{})){const r=i.name,s=B(r+kn);if(t.filter(a=>a.name===r).length===0){const a=i.resolve===\"global\"?\"union\":i.resolve,c=i.type===\"point\"?\", true, true)\":\")\";t.push({name:i.name,update:`${md}(${s}, ${B(a)}${c}`})}n=!0;for(const a of ls)a.defined(i)&&a.topLevelSignals&&(t=a.topLevelSignals(e,i,t))}return n&&t.filter(r=>r.name===\"unit\").length===0&&t.unshift({name:\"unit\",value:{},on:[{events:\"pointermove\",update:\"isTuple(group()) ? group() : unit\"}]}),Ea(t)}function Xb(e,t){const n=[...t],i=bn(e,{escape:!1});for(const r of Se(e.component.selection??{})){const s={name:r.name+kn};if(r.project.hasSelectionId&&(s.transform=[{type:\"collect\",sort:{field:Ze}}]),r.init){const a=r.project.items.map(Qf);s.values=r.project.hasSelectionId?r.init.map(c=>({unit:i,[Ze]:Fn(c,!1)[0]})):r.init.map(c=>({unit:i,fields:a,values:Fn(c,!1)}))}n.filter(a=>a.name===r.name+kn).length||n.push(s)}return n}function Zf(e,t){for(const n of Se(e.component.selection??{}))for(const i of ls)i.defined(n)&&i.marks&&(t=i.marks(e,n,t));return t}function Yb(e,t){for(const n of e.children)ae(n)&&(t=Zf(n,t));return t}function Kb(e,t,n,i){const r=vd(e,t.param,t);return{signal:De(n.get(\"type\"))&&F(i)&&i[0]>i[1]?`isValid(${r}) && reverse(${r})`:r}}function Ea(e){return e.map(t=>(t.on&&!t.on.length&&delete t.on,t))}class Y{constructor(t,n){this.debugName=n,this._children=[],this._parent=null,t&&(this.parent=t)}clone(){throw new Error(\"Cannot clone node\")}get parent(){return this._parent}set parent(t){this._parent=t,t&&t.addChild(this)}get children(){return this._children}numChildren(){return this._children.length}addChild(t,n){if(this._children.includes(t)){S(Jg);return}n!==void 0?this._children.splice(n,0,t):this._children.push(t)}removeChild(t){const n=this._children.indexOf(t);return this._children.splice(n,1),n}remove(){let t=this._parent.removeChild(this);for(const n of this._children)n._parent=this._parent,this._parent.addChild(n,t++)}insertAsParentOf(t){const n=t.parent;n.removeChild(this),this.parent=n,t.parent=this}swapWithParent(){const t=this._parent,n=t.parent;for(const r of this._children)r.parent=t;this._children=[],t.removeChild(this);const i=t.parent.removeChild(t);this._parent=n,n.addChild(this,i),t.parent=this}}class we extends Y{clone(){const t=new this.constructor;return t.debugName=`clone_${this.debugName}`,t._source=this._source,t._name=`clone_${this._name}`,t.type=this.type,t.refCounts=this.refCounts,t.refCounts[t._name]=0,t}constructor(t,n,i,r){super(t,n),this.type=i,this.refCounts=r,this._source=this._name=n,this.refCounts&&!(this._name in this.refCounts)&&(this.refCounts[this._name]=0)}dependentFields(){return new Set}producedFields(){return new Set}hash(){return this._hash===void 0&&(this._hash=`Output ${Xl()}`),this._hash}getSource(){return this.refCounts[this._name]++,this._source}isRequired(){return!!this.refCounts[this._name]}setSource(t){this._source=t}}function _s(e){return e.as!==void 0}function Lc(e){return`${e}_end`}class ft extends Y{clone(){return new ft(null,z(this.timeUnits))}constructor(t,n){super(t),this.timeUnits=n}static makeFromEncoding(t,n){const i=n.reduceFieldDef((r,s,o)=>{const{field:a,timeUnit:c}=s;if(c){let l;if(Ln(c)){if(ae(n)){const{mark:u,markDef:f,config:d}=n,g=Ht({fieldDef:s,markDef:f,config:d});(zi(u)||g)&&(l={timeUnit:me(c),field:a})}}else l={as:E(s,{forAs:!0}),field:a,timeUnit:c};if(ae(n)){const{mark:u,markDef:f,config:d}=n,g=Ht({fieldDef:s,markDef:f,config:d});zi(u)&&ue(o)&&g!==.5&&(l.rectBandPosition=g)}l&&(r[W(l)]=l)}return r},{});return K(i)?null:new ft(t,i)}static makeFromTransform(t,n){const{timeUnit:i,...r}={...n},s=me(i),o={...r,timeUnit:s};return new ft(t,{[W(o)]:o})}merge(t){this.timeUnits={...this.timeUnits};for(const n in t.timeUnits)this.timeUnits[n]||(this.timeUnits[n]=t.timeUnits[n]);for(const n of t.children)t.removeChild(n),n.parent=this;t.remove()}removeFormulas(t){const n={};for(const[i,r]of Wt(this.timeUnits)){const s=_s(r)?r.as:`${r.field}_end`;t.has(s)||(n[i]=r)}this.timeUnits=n}producedFields(){return new Set(Se(this.timeUnits).map(t=>_s(t)?t.as:Lc(t.field)))}dependentFields(){return new Set(Se(this.timeUnits).map(t=>t.field))}hash(){return`TimeUnit ${W(this.timeUnits)}`}assemble(){const t=[];for(const n of Se(this.timeUnits)){const{rectBandPosition:i}=n,r=me(n.timeUnit);if(_s(n)){const{field:s,as:o}=n,{unit:a,utc:c,...l}=r,u=[o,`${o}_end`];t.push({field:Ue(s),type:\"timeunit\",...a?{units:Gr(a)}:{},...c?{timezone:\"utc\"}:{},...l,as:u}),t.push(...Pc(u,i,r))}else if(n){const{field:s}=n,o=s.replaceAll(\"\\\\.\",\".\"),a=ed({timeUnit:r,field:o}),c=Lc(o);t.push({type:\"formula\",expr:a,as:c}),t.push(...Pc([o,c],i,r))}}return t}}const os=\"offsetted_rect_start\",as=\"offsetted_rect_end\";function ed({timeUnit:e,field:t,reverse:n}){const{unit:i,utc:r}=e,s=Au(i),{part:o,step:a}=Iu(s,e.step);return`${r?\"utcOffset\":\"timeOffset\"}('${o}', datum['${t}'], ${n?-a:a})`}function Pc([e,t],n,i){if(n!==void 0&&n!==.5){const r=`datum['${e}']`,s=`datum['${t}']`;return[{type:\"formula\",expr:zc([ed({timeUnit:i,field:e,reverse:!0}),r],n+.5),as:`${e}_${os}`},{type:\"formula\",expr:zc([r,s],n+.5),as:`${e}_${as}`}]}return[]}function zc([e,t],n){return`${1-n} * ${e} + ${n} * ${t}`}const er=\"_tuple_fields\";class Jb{constructor(...t){this.items=t,this.hasChannel={},this.hasField={},this.hasSelectionId=!1}}const Qb={defined:()=>!0,parse:(e,t,n)=>{const i=t.name,r=t.project??(t.project=new Jb),s={},o={},a=new Set,c=(p,h)=>{const m=h===\"visual\"?p.channel:p.field;let y=re(`${i}_${m}`);for(let b=1;a.has(y);b++)y=re(`${i}_${m}_${b}`);return a.add(y),{[h]:y}},l=t.type,u=e.config.selection[l],f=n.value!==void 0?ce(n.value):null;let{fields:d,encodings:g}=H(n.select)?n.select:{};if(!d&&!g&&f){for(const p of f)if(H(p))for(const h of x(p))dg(h)?(g||(g=[])).push(h):l===\"interval\"?(S(Vg),g=u.encodings):(d??(d=[])).push(h)}!d&&!g&&(g=u.encodings,\"fields\"in u&&(d=u.fields));for(const p of g??[]){const h=e.fieldDef(p);if(h){let m=h.field;if(h.aggregate){S(Dg(p,h.aggregate));continue}else if(!m){S(ac(p));continue}if(h.timeUnit&&!Ln(h.timeUnit)){m=e.vgField(p);const y={timeUnit:h.timeUnit,as:m,field:h.field};o[W(y)]=y}if(!s[m]){const y=l===\"interval\"&&Pt(p)&&De(e.getScaleComponent(p).get(\"type\"))?\"R\":h.bin?\"R-RE\":\"E\",b={field:m,channel:p,type:y,index:r.items.length};b.signals={...c(b,\"data\"),...c(b,\"visual\")},r.items.push(s[m]=b),r.hasField[m]=s[m],r.hasSelectionId=r.hasSelectionId||m===Ze,eu(p)?(b.geoChannel=p,b.channel=Zl(p),r.hasChannel[b.channel]=s[m]):r.hasChannel[p]=s[m]}}else S(ac(p))}for(const p of d??[]){if(r.hasField[p])continue;const h={type:\"E\",field:p,index:r.items.length};h.signals={...c(h,\"data\")},r.items.push(h),r.hasField[p]=h,r.hasSelectionId=r.hasSelectionId||p===Ze}f&&(t.init=f.map(p=>r.items.map(h=>H(p)?p[h.geoChannel||h.channel]!==void 0?p[h.geoChannel||h.channel]:p[h.field]:p))),K(o)||(r.timeUnit=new ft(null,o))},signals:(e,t,n)=>{const i=t.name+er;return n.filter(s=>s.name===i).length>0||t.project.hasSelectionId?n:n.concat({name:i,value:t.project.items.map(Qf)})}},kt={defined:e=>e.type===\"interval\"&&e.resolve===\"global\"&&e.bind&&e.bind===\"scales\",parse:(e,t)=>{const n=t.scales=[];for(const i of t.project.items){const r=i.channel;if(!Pt(r))continue;const s=e.getScaleComponent(r),o=s?s.get(\"type\"):void 0;if(o==\"sequential\"&&S(Bg),!s||!De(o)){S(Ug);continue}s.set(\"selectionExtent\",{param:t.name,field:i.field},!0),n.push(i)}},topLevelSignals:(e,t,n)=>{const i=t.scales.filter(o=>n.filter(a=>a.name===o.signals.data).length===0);if(!e.parent||Dc(e)||i.length===0)return n;const r=n.filter(o=>o.name===t.name)[0];let s=r.update;if(s.indexOf(md)>=0)r.update=`{${i.map(o=>`${B(Ue(o.field))}: ${o.signals.data}`).join(\", \")}}`;else{for(const o of i){const a=`${B(Ue(o.field))}: ${o.signals.data}`;s.includes(a)||(s=`${s.substring(0,s.length-1)}, ${a}}`)}r.update=s}return n.concat(i.map(o=>({name:o.signals.data})))},signals:(e,t,n)=>{if(e.parent&&!Dc(e))for(const i of t.scales){const r=n.find(s=>s.name===i.signals.data);r.push=\"outer\",delete r.value,delete r.update}return n}};function so(e,t){return`domain(${B(e.scaleName(t))})`}function Dc(e){return e.parent&&Si(e.parent)&&!e.parent.parent}const Xn=\"_brush\",td=\"_scale_trigger\",Ei=\"geo_interval_init_tick\",nd=\"_init\",Zb=\"_center\",ex={defined:e=>e.type===\"interval\",parse:(e,t,n)=>{var i;if(e.hasProjection){const r={...H(n.select)?n.select:{}};r.fields=[Ze],r.encodings||(r.encodings=n.value?x(n.value):[it,nt]),n.select={type:\"interval\",...r}}if(t.translate&&!kt.defined(t)){const r=`!event.item || event.item.mark.name !== ${B(t.name+Xn)}`;for(const s of t.events){if(!s.between){S(`${s} is not an ordered event stream for interval selections.`);continue}const o=ce((i=s.between[0]).filter??(i.filter=[]));o.indexOf(r)<0&&o.push(r)}}},signals:(e,t,n)=>{const i=t.name,r=i+Xt,s=Se(t.project.hasChannel).filter(a=>a.channel===se||a.channel===be),o=t.init?t.init[0]:null;if(n.push(...s.reduce((a,c)=>a.concat(tx(e,t,c,o&&o[c.index])),[])),e.hasProjection){const a=B(e.projectionName()),c=e.projectionName()+Zb,{x:l,y:u}=t.project.hasChannel,f=l&&l.signals.visual,d=u&&u.signals.visual,g=l?o&&o[l.index]:`${c}[0]`,p=u?o&&o[u.index]:`${c}[1]`,h=N=>e.getSizeSignalRef(N).signal,m=`[[${f?f+\"[0]\":\"0\"}, ${d?d+\"[0]\":\"0\"}],[${f?f+\"[1]\":h(\"width\")}, ${d?d+\"[1]\":h(\"height\")}]]`;o&&(n.unshift({name:i+nd,init:`[scale(${a}, [${l?g[0]:g}, ${u?p[0]:p}]), scale(${a}, [${l?g[1]:g}, ${u?p[1]:p}])]`}),(!l||!u)&&(n.find(_=>_.name===c)||n.unshift({name:c,update:`invert(${a}, [${h(\"width\")}/2, ${h(\"height\")}/2])`})));const y=`intersect(${m}, {markname: ${B(e.getName(\"marks\"))}}, unit.mark)`,b=`{unit: ${bn(e)}}`,C=`vlSelectionTuples(${y}, ${b})`,k=s.map(N=>N.signals.visual);return n.concat({name:r,on:[{events:[...k.length?[{signal:k.join(\" || \")}]:[],...o?[{signal:Ei}]:[]],update:C}]})}else{if(!kt.defined(t)){const l=i+td,u=s.map(f=>{const d=f.channel,{data:g,visual:p}=f.signals,h=B(e.scaleName(d)),m=e.getScaleComponent(d).get(\"type\"),y=De(m)?\"+\":\"\";return`(!isArray(${g}) || (${y}invert(${h}, ${p})[0] === ${y}${g}[0] && ${y}invert(${h}, ${p})[1] === ${y}${g}[1]))`});u.length&&n.push({name:l,value:{},on:[{events:s.map(f=>({scale:e.scaleName(f.channel)})),update:u.join(\" && \")+` ? ${l} : {}`}]})}const a=s.map(l=>l.signals.data),c=`unit: ${bn(e)}, fields: ${i+er}, values`;return n.concat({name:r,...o?{init:`{${c}: ${Fn(o)}}`}:{},...a.length?{on:[{events:[{signal:a.join(\" || \")}],update:`${a.join(\" && \")} ? {${c}: [${a}]} : null`}]}:{}})}},topLevelSignals:(e,t,n)=>(ae(e)&&e.hasProjection&&t.init&&(n.filter(r=>r.name===Ei).length||n.unshift({name:Ei,value:null,on:[{events:\"timer{1}\",update:`${Ei} === null ? {} : ${Ei}`}]})),n),marks:(e,t,n)=>{const i=t.name,{x:r,y:s}=t.project.hasChannel,o=r?.signals.visual,a=s?.signals.visual,c=`data(${B(t.name+kn)})`;if(kt.defined(t)||!r&&!s)return n;const l={x:r!==void 0?{signal:`${o}[0]`}:{value:0},y:s!==void 0?{signal:`${a}[0]`}:{value:0},x2:r!==void 0?{signal:`${o}[1]`}:{field:{group:\"width\"}},y2:s!==void 0?{signal:`${a}[1]`}:{field:{group:\"height\"}}};if(t.resolve===\"global\")for(const m of x(l))l[m]=[{test:`${c}.length && ${c}[0].unit === ${bn(e)}`,...l[m]},{value:0}];const{fill:u,fillOpacity:f,cursor:d,...g}=t.mark,p=x(g).reduce((m,y)=>(m[y]=[{test:[r!==void 0&&`${o}[0] !== ${o}[1]`,s!==void 0&&`${a}[0] !== ${a}[1]`].filter(b=>b).join(\" && \"),value:g[y]},{value:null}],m),{}),h=d??(t.translate?\"move\":null);return[{name:`${i+Xn}_bg`,type:\"rect\",clip:!0,encode:{enter:{fill:{value:u},fillOpacity:{value:f}},update:l}},...n,{name:i+Xn,type:\"rect\",clip:!0,encode:{enter:{...h?{cursor:{value:h}}:{},fill:{value:\"transparent\"}},update:{...l,...p}}}]}};function tx(e,t,n,i){const r=!e.hasProjection,s=n.channel,o=n.signals.visual,a=B(r?e.scaleName(s):e.projectionName()),c=d=>`scale(${a}, ${d})`,l=e.getSizeSignalRef(s===se?\"width\":\"height\").signal,u=`${s}(unit)`,f=t.events.reduce((d,g)=>[...d,{events:g.between[0],update:`[${u}, ${u}]`},{events:g,update:`[${o}[0], clamp(${u}, 0, ${l})]`}],[]);if(r){const d=n.signals.data,g=kt.defined(t),p=e.getScaleComponent(s),h=p?p.get(\"type\"):void 0,m=i?{init:Fn(i,!0,c)}:{value:[]};return f.push({events:{signal:t.name+td},update:De(h)?`[${c(`${d}[0]`)}, ${c(`${d}[1]`)}]`:\"[0, 0]\"}),g?[{name:d,on:[]}]:[{name:o,...m,on:f},{name:d,...i?{init:Fn(i)}:{},on:[{events:{signal:o},update:`${o}[0] === ${o}[1] ? null : invert(${a}, ${o})`}]}]}else{const d=s===se?0:1,g=t.name+nd,p=i?{init:`[${g}[0][${d}], ${g}[1][${d}]]`}:{value:[]};return[{name:o,...p,on:f}]}}const nx={defined:e=>e.type===\"point\",signals:(e,t,n)=>{const i=t.name,r=i+er,s=t.project,o=\"(item().isVoronoi ? datum.datum : datum)\",a=Se(e.component.selection??{}).reduce((f,d)=>d.type===\"interval\"?f.concat(d.name+Xn):f,[]).map(f=>`indexof(item().mark.name, '${f}') < 0`).join(\" && \"),c=`datum && item().mark.marktype !== 'group' && indexof(item().mark.role, 'legend') < 0${a?` && ${a}`:\"\"}`;let l=`unit: ${bn(e)}, `;if(t.project.hasSelectionId)l+=`${Ze}: ${o}[${B(Ze)}]`;else{const f=s.items.map(d=>e.fieldDef(d.channel)?.bin?`[${o}[${B(e.vgField(d.channel,{}))}], ${o}[${B(e.vgField(d.channel,{binSuffix:\"end\"}))}]]`:`${o}[${B(d.field)}]`).join(\", \");l+=`fields: ${r}, values: [${f}]`}const u=t.events;return n.concat([{name:i+Xt,on:u?[{events:u,update:`${c} ? {${l}} : null`,force:!0}]:[]}])}};function mi(e,t,n,i){const r=Jr(t)&&t.condition,s=i(t);if(r){const a=ce(r).map(c=>{const l=i(c);if(qm(c)){const{param:u,empty:f}=c;return{test:Sd(e,{param:u,empty:f}),...l}}else return{test:Tr(e,c.test),...l}});return{[n]:[...a,...s!==void 0?[s]:[]]}}else return s!==void 0?{[n]:s}:{}}function $a(e,t=\"text\"){const n=e.encoding[t];return mi(e,n,t,i=>cs(i,e.config))}function cs(e,t,n=\"datum\"){if(e){if(Qe(e))return ne(e.value);if(D(e)){const{format:i,formatType:r}=Er(e);return na({fieldOrDatumDef:e,format:i,formatType:r,expr:n,config:t})}}}function id(e,t={}){const{encoding:n,markDef:i,config:r,stack:s}=e,o=n.tooltip;if(F(o))return{tooltip:Mc({tooltip:o},s,r,t)};{const a=t.reactiveGeom?\"datum.datum\":\"datum\";return mi(e,o,\"tooltip\",c=>{const l=cs(c,r,a);if(l)return l;if(c===null)return;let u=X(\"tooltip\",i,r);if(u===!0&&(u={content:\"encoding\"}),R(u))return{value:u};if(H(u))return T(u)?u:u.content===\"encoding\"?Mc(n,s,r,t):{signal:a}})}}function rd(e,t,n,{reactiveGeom:i}={}){const r={...n,...n.tooltipFormat},s={},o=i?\"datum.datum\":\"datum\",a=[];function c(u,f){const d=_n(f),g=Ce(u)?u:{...u,type:e[d].type},p=g.title||oa(g,r),h=ce(p).join(\", \").replaceAll(/\"/g,'\\\\\"');let m;if(ue(f)){const y=f===\"x\"?\"x2\":\"y2\",b=gt(e[y]);if(xe(g.bin)&&b){const C=E(g,{expr:o}),k=E(b,{expr:o}),{format:N,formatType:_}=Er(g);m=Yi(C,k,N,_,r),s[y]=!0}}if((ue(f)||f===We||f===tt)&&t&&t.fieldChannel===f&&t.offset===\"normalize\"){const{format:y,formatType:b}=Er(g);m=na({fieldOrDatumDef:g,format:y,formatType:b,expr:o,config:r,normalizeStack:!0}).signal}m??(m=cs(g,r,o).signal),a.push({channel:f,key:h,value:m})}la(e,(u,f)=>{v(u)?c(u,f):Qr(u)&&c(u.condition,f)});const l={};for(const{channel:u,key:f,value:d}of a)!s[u]&&!l[f]&&(l[f]=d);return l}function Mc(e,t,n,{reactiveGeom:i}={}){const r=rd(e,t,n,{reactiveGeom:i}),s=Wt(r).map(([o,a])=>`\"${o}\": ${a}`);return s.length>0?{signal:`{${s.join(\", \")}}`}:void 0}function ix(e){const{markDef:t,config:n}=e,i=X(\"aria\",t,n);return i===!1?{}:{...i?{aria:i}:{},...rx(e),...sx(e)}}function rx(e){const{mark:t,markDef:n,config:i}=e;if(i.aria===!1)return{};const r=X(\"ariaRoleDescription\",n,i);return r!=null?{ariaRoleDescription:{value:r}}:t in Ig?{}:{ariaRoleDescription:{value:t}}}function sx(e){const{encoding:t,markDef:n,config:i,stack:r}=e,s=t.description;if(s)return mi(e,s,\"description\",c=>cs(c,e.config));const o=X(\"description\",n,i);if(o!=null)return{description:ne(o)};if(i.aria===!1)return{};const a=rd(t,r,i);if(!K(a))return{description:{signal:Wt(a).map(([c,l],u)=>`\"${u>0?\"; \":\"\"}${c}: \" + (${l})`).join(\" + \")}}}function he(e,t,n={}){const{markDef:i,encoding:r,config:s}=t,{vgChannel:o}=n;let{defaultRef:a,defaultValue:c}=n;a===void 0&&(c??(c=X(e,i,s,{vgChannel:o,ignoreVgConfig:!0})),c!==void 0&&(a=ne(c)));const l=r[e];return mi(t,l,o??e,u=>ta({channel:e,channelDef:u,markDef:i,config:s,scaleName:t.scaleName(e),scale:t.getScaleComponent(e),stack:null,defaultRef:a}))}function sd(e,t={filled:void 0}){const{markDef:n,encoding:i,config:r}=e,{type:s}=n,o=t.filled??X(\"filled\",n,r),a=G([\"bar\",\"point\",\"circle\",\"square\",\"geoshape\"],s)?\"transparent\":void 0,c=X(o===!0?\"color\":void 0,n,r,{vgChannel:\"fill\"})??r.mark[o===!0&&\"color\"]??a,l=X(o===!1?\"color\":void 0,n,r,{vgChannel:\"stroke\"})??r.mark[o===!1&&\"color\"],u=o?\"fill\":\"stroke\",f={...c?{fill:ne(c)}:{},...l?{stroke:ne(l)}:{}};return n.color&&(o?n.fill:n.stroke)&&S(vu(\"property\",{fill:\"fill\"in n,stroke:\"stroke\"in n})),{...f,...he(\"color\",e,{vgChannel:u,defaultValue:o?c:l}),...he(\"fill\",e,{defaultValue:i.fill?c:void 0}),...he(\"stroke\",e,{defaultValue:i.stroke?l:void 0})}}function ox(e){const{encoding:t,mark:n}=e,i=t.order;return!rn(n)&&Qe(i)?mi(e,i,\"zindex\",r=>ne(r.value)):{}}function ai({channel:e,markDef:t,encoding:n={},model:i,bandPosition:r}){const s=`${e}Offset`,o=t[s],a=n[s];if((s===\"xOffset\"||s===\"yOffset\")&&a)return{offsetType:\"encoding\",offset:ta({channel:s,channelDef:a,markDef:t,config:i?.config,scaleName:i.scaleName(s),scale:i.getScaleComponent(s),stack:null,defaultRef:ne(o),bandPosition:r})};const c=t[s];return c?{offsetType:\"visual\",offset:c}:{}}function Ee(e,t,{defaultPos:n,vgChannel:i}){const{encoding:r,markDef:s,config:o,stack:a}=t,c=r[e],l=r[xt(e)],u=t.scaleName(e),f=t.getScaleComponent(e),{offset:d,offsetType:g}=ai({channel:e,markDef:s,encoding:r,model:t,bandPosition:.5}),p=wa({model:t,defaultPos:n,channel:e,scaleName:u,scale:f}),h=!c&&ue(e)&&(r.latitude||r.longitude)?{field:t.getName(e)}:ax({channel:e,channelDef:c,channel2Def:l,markDef:s,config:o,scaleName:u,scale:f,stack:a,offset:d,defaultRef:p,bandPosition:g===\"encoding\"?0:void 0});return h?{[i||e]:h}:void 0}function ax(e){const{channel:t,channelDef:n,scaleName:i,stack:r,offset:s,markDef:o}=e;if(D(n)&&r&&t===r.fieldChannel){if(v(n)){let a=n.bandPosition;if(a===void 0&&o.type===\"text\"&&(t===\"radius\"||t===\"theta\")&&(a=.5),a!==void 0)return xr({scaleName:i,fieldOrDatumDef:n,startSuffix:\"start\",bandPosition:a,offset:s})}return mn(n,i,{suffix:\"end\"},{offset:s})}return Zo(e)}function wa({model:e,defaultPos:t,channel:n,scaleName:i,scale:r}){const{markDef:s,config:o}=e;return()=>{const a=_n(n),c=Gt(n),l=X(n,s,o,{vgChannel:c});if(l!==void 0)return _i(n,l);switch(t){case\"zeroOrMin\":case\"zeroOrMax\":if(i){const u=r.get(\"type\");if(!G([Te.LOG,Te.TIME,Te.UTC],u)){if(r.domainDefinitelyIncludesZero())return{scale:i,value:0}}}if(t===\"zeroOrMin\")return a===\"y\"?{field:{group:\"height\"}}:{value:0};switch(a){case\"radius\":return{signal:`min(${e.width.signal},${e.height.signal})/2`};case\"theta\":return{signal:\"2*PI\"};case\"x\":return{field:{group:\"width\"}};case\"y\":return{value:0}}break;case\"mid\":return{...e[_e(n)],mult:.5}}}}const cx={left:\"x\",center:\"xc\",right:\"x2\"},lx={top:\"y\",middle:\"yc\",bottom:\"y2\"};function od(e,t,n,i=\"middle\"){if(e===\"radius\"||e===\"theta\")return Gt(e);const r=e===\"x\"?\"align\":\"baseline\",s=X(r,t,n);let o;return T(s)?(S(dh(r)),o=void 0):o=s,e===\"x\"?cx[o||(i===\"top\"?\"left\":\"center\")]:lx[o||i]}function Fr(e,t,{defaultPos:n,defaultPos2:i,range:r}){return r?ad(e,t,{defaultPos:n,defaultPos2:i}):Ee(e,t,{defaultPos:n})}function ad(e,t,{defaultPos:n,defaultPos2:i}){const{markDef:r,config:s}=t,o=xt(e),a=_e(e),c=ux(t,i,o),l=c[a]?od(e,r,s):Gt(e);return{...Ee(e,t,{defaultPos:n,vgChannel:l}),...c}}function ux(e,t,n){const{encoding:i,mark:r,markDef:s,stack:o,config:a}=e,c=_n(n),l=_e(n),u=Gt(n),f=i[c],d=e.scaleName(c),g=e.getScaleComponent(c),{offset:p}=n in i||n in s?ai({channel:n,markDef:s,encoding:i,model:e}):ai({channel:c,markDef:s,encoding:i,model:e});if(!f&&(n===\"x2\"||n===\"y2\")&&(i.latitude||i.longitude)){const m=_e(n),y=e.markDef[m];return y!=null?{[m]:{value:y}}:{[u]:{field:e.getName(n)}}}const h=fx({channel:n,channelDef:f,channel2Def:i[n],markDef:s,config:a,scaleName:d,scale:g,stack:o,offset:p,defaultRef:void 0});return h!==void 0?{[u]:h}:sr(n,s)||sr(n,{[n]:mr(n,s,a.style),[l]:mr(l,s,a.style)})||sr(n,a[r])||sr(n,a.mark)||{[u]:wa({model:e,defaultPos:t,channel:n,scaleName:d,scale:g})()}}function fx({channel:e,channelDef:t,channel2Def:n,markDef:i,config:r,scaleName:s,scale:o,stack:a,offset:c,defaultRef:l}){return D(t)&&a&&e.charAt(0)===a.fieldChannel.charAt(0)?mn(t,s,{suffix:\"start\"},{offset:c}):Zo({channel:e,channelDef:n,scaleName:s,scale:o,stack:a,markDef:i,config:r,offset:c,defaultRef:l})}function sr(e,t){const n=_e(e),i=Gt(e);if(t[i]!==void 0)return{[i]:_i(e,t[i])};if(t[e]!==void 0)return{[i]:_i(e,t[e])};if(t[n]){const r=t[n];if(Cn(r))S(oh(n));else return{[n]:_i(e,r)}}}function Vt(e,t){const{config:n,encoding:i,markDef:r}=e,s=r.type,o=xt(t),a=_e(t),c=i[t],l=i[o],u=e.getScaleComponent(t),f=u?u.get(\"type\"):void 0,d=r.orient,g=i[a]??i.size??X(\"size\",r,n,{vgChannel:a}),p=ru(t),h=s===\"bar\"&&(t===\"x\"?d===\"vertical\":d===\"horizontal\");return v(c)&&(ee(c.bin)||xe(c.bin)||c.timeUnit&&!l)&&!(g&&!Cn(g))&&!i[p]&&!ye(f)?gx({fieldDef:c,fieldDef2:l,channel:t,model:e}):(D(c)&&ye(f)||h)&&!l?px(c,t,e):ad(t,e,{defaultPos:\"zeroOrMax\",defaultPos2:\"zeroOrMin\"})}function dx(e,t,n,i,r,s,o){if(Cn(r))if(n){const c=n.get(\"type\");if(c===\"band\"){let l=`bandwidth('${t}')`;r.band!==1&&(l=`${r.band} * ${l}`);const u=Ot(\"minBandSize\",{type:o},i);return{signal:u?`max(${Xe(u)}, ${l})`:l}}else r.band!==1&&(S(mh(c)),r=void 0)}else return{mult:r.band,field:{group:e}};else{if(T(r))return r;if(r)return{value:r}}if(n){const c=n.get(\"range\");if(nn(c)&&ie(c.step))return{value:c.step-2}}if(!s){const{bandPaddingInner:c,barBandPaddingInner:l,rectBandPaddingInner:u}=i.scale,f=le(c,o===\"bar\"?l:u);if(T(f))return{signal:`(1 - (${f.signal})) * ${e}`};if(ie(f))return{signal:`${1-f} * ${e}`}}return{value:Cr(i.view,e)-2}}function px(e,t,n){const{markDef:i,encoding:r,config:s,stack:o}=n,a=i.orient,c=n.scaleName(t),l=n.getScaleComponent(t),u=_e(t),f=xt(t),d=ru(t),g=n.scaleName(d),p=n.getScaleComponent(Ao(t)),h=a===\"horizontal\"&&t===\"y\"||a===\"vertical\"&&t===\"x\";let m;(r.size||i.size)&&(h?m=he(\"size\",n,{vgChannel:u,defaultRef:ne(i.size)}):S(Sh(i.type)));const y=!!m,b=nf({channel:t,fieldDef:e,markDef:i,config:s,scaleType:(l||p)?.get(\"type\"),useVlSizeChannel:h});m=m||{[u]:dx(u,g||c,p||l,s,b,!!e,i.type)};const C=(l||p)?.get(\"type\")===\"band\"&&Cn(b)&&!y?\"top\":\"middle\",k=od(t,i,s,C),N=k===\"xc\"||k===\"yc\",{offset:_,offsetType:L}=ai({channel:t,markDef:i,encoding:r,model:n,bandPosition:N?.5:0}),U=Zo({channel:t,channelDef:e,markDef:i,config:s,scaleName:c,scale:l,stack:o,offset:_,defaultRef:wa({model:n,defaultPos:\"mid\",channel:t,scaleName:c,scale:l}),bandPosition:N?L===\"encoding\"?0:.5:T(b)?{signal:`(1-${b})/2`}:Cn(b)?(1-b.band)/2:0});if(u)return{[k]:U,...m};{const oe=Gt(f),de=m[u],Re=_?{...de,offset:_}:de;return{[k]:U,[oe]:F(U)?[U[0],{...U[1],offset:Re}]:{...U,offset:Re}}}}function jc(e,t,n,i,r,s,o){if(Ql(e))return 0;const a=e===\"x\"||e===\"y2\",c=a?-t/2:t/2;if(T(n)||T(r)||T(i)||s){const l=Xe(n),u=Xe(r),f=Xe(i),d=Xe(s),p=s?`(${o} < ${d} ? ${a?\"\":\"-\"}0.5 * (${d} - (${o})) : ${c})`:c,h=f?`${f} + `:\"\",m=l?`(${l} ? -1 : 1) * `:\"\",y=u?`(${u} + ${p})`:p;return{signal:h+m+y}}else return r=r||0,i+(n?-r-c:+r+c)}function gx({fieldDef:e,fieldDef2:t,channel:n,model:i}){const{config:r,markDef:s,encoding:o}=i,a=i.getScaleComponent(n),c=i.scaleName(n),l=a?a.get(\"type\"):void 0,u=a.get(\"reverse\"),f=nf({channel:n,fieldDef:e,markDef:s,config:r,scaleType:l}),g=i.component.axes[n]?.[0]?.get(\"translate\")??.5,p=ue(n)?X(\"binSpacing\",s,r)??0:0,h=xt(n),m=Gt(n),y=Gt(h),b=Ot(\"minBandSize\",s,r),{offset:C}=ai({channel:n,markDef:s,encoding:o,model:i,bandPosition:0}),{offset:k}=ai({channel:h,markDef:s,encoding:o,model:i,bandPosition:0}),N=Um({fieldDef:e,scaleName:c}),_=jc(n,p,u,g,C,b,N),L=jc(h,p,u,g,k??C,b,N),U=T(f)?{signal:`(1-${f.signal})/2`}:Cn(f)?(1-f.band)/2:.5,oe=Ht({fieldDef:e,fieldDef2:t,markDef:s,config:r});if(ee(e.bin)||e.timeUnit){const de=e.timeUnit&&oe!==.5;return{[y]:Uc({fieldDef:e,scaleName:c,bandPosition:U,offset:L,useRectOffsetField:de}),[m]:Uc({fieldDef:e,scaleName:c,bandPosition:T(U)?{signal:`1-${U.signal}`}:1-U,offset:_,useRectOffsetField:de})}}else if(xe(e.bin)){const de=mn(e,c,{},{offset:L});if(v(t))return{[y]:de,[m]:mn(t,c,{},{offset:_})};if(Rn(e.bin)&&e.bin.step)return{[y]:de,[m]:{signal:`scale(\"${c}\", ${E(e,{expr:\"datum\"})} + ${e.bin.step})`,offset:_}}}S(wu(h))}function Uc({fieldDef:e,scaleName:t,bandPosition:n,offset:i,useRectOffsetField:r}){return xr({scaleName:t,fieldOrDatumDef:e,bandPosition:n,offset:i,...r?{startSuffix:os,endSuffix:as}:{}})}const hx=new Set([\"aria\",\"width\",\"height\"]);function Ge(e,t){const{fill:n=void 0,stroke:i=void 0}=t.color===\"include\"?sd(e):{};return{...mx(e.markDef,t),...Bc(e,\"fill\",n),...Bc(e,\"stroke\",i),...he(\"opacity\",e),...he(\"fillOpacity\",e),...he(\"strokeOpacity\",e),...he(\"strokeWidth\",e),...he(\"strokeDash\",e),...ox(e),...id(e),...$a(e,\"href\"),...ix(e)}}function Bc(e,t,n){const{config:i,mark:r,markDef:s}=e;if(X(\"invalid\",s,i)===\"hide\"&&n&&!rn(r)){const a=yx(e,{invalid:!0,channels:Ur});if(a)return{[t]:[{test:a,value:null},...ce(n)]}}return n?{[t]:n}:{}}function mx(e,t){return Rg.reduce((n,i)=>(!hx.has(i)&&e[i]!==void 0&&t[i]!==\"ignore\"&&(n[i]=ne(e[i])),n),{})}function yx(e,{invalid:t=!1,channels:n}){const i=n.reduce((s,o)=>{const a=e.getScaleComponent(o);if(a){const c=a.get(\"type\"),l=e.vgField(o,{expr:\"datum\"});l&&De(c)&&(s[l]=!0)}return s},{}),r=x(i);if(r.length>0){const s=t?\"||\":\"&&\";return r.map(o=>ea(o,t)).join(` ${s} `)}}function Ca(e){const{config:t,markDef:n}=e;if(X(\"invalid\",n,t)){const r=bx(e,{channels:St});if(r)return{defined:{signal:r}}}return{}}function bx(e,{invalid:t=!1,channels:n}){const i=n.reduce((s,o)=>{const a=e.getScaleComponent(o);if(a){const c=a.get(\"type\"),l=e.vgField(o,{expr:\"datum\",binSuffix:e.stack?.impute?\"mid\":void 0});l&&De(c)&&(s[l]=!0)}return s},{}),r=x(i);if(r.length>0){const s=t?\"||\":\"&&\";return r.map(o=>ea(o,t)).join(` ${s} `)}}function Wc(e,t){if(t!==void 0)return{[e]:ne(t)}}const Rs=\"voronoi\",cd={defined:e=>e.type===\"point\"&&e.nearest,parse:(e,t)=>{if(t.events)for(const n of t.events)n.markname=e.getName(Rs)},marks:(e,t,n)=>{const{x:i,y:r}=t.project.hasChannel,s=e.mark;if(rn(s))return S(Mg(s)),n;const o={name:e.getName(Rs),type:\"path\",interactive:!0,from:{data:e.getName(\"marks\")},encode:{update:{fill:{value:\"transparent\"},strokeWidth:{value:.35},stroke:{value:\"transparent\"},isVoronoi:{value:!0},...id(e,{reactiveGeom:!0})}},transform:[{type:\"voronoi\",x:{expr:i||!r?\"datum.datum.x || 0\":\"0\"},y:{expr:r||!i?\"datum.datum.y || 0\":\"0\"},size:[e.getSizeSignalRef(\"width\"),e.getSizeSignalRef(\"height\")]}]};let a=0,c=!1;return n.forEach((l,u)=>{const f=l.name??\"\";f===e.component.mark[0].name?a=u:f.indexOf(Rs)>=0&&(c=!0)}),c||n.splice(a+1,0,o),n}},ld={defined:e=>e.type===\"point\"&&e.resolve===\"global\"&&e.bind&&e.bind!==\"scales\"&&!ha(e.bind),parse:(e,t,n)=>yd(t,n),topLevelSignals:(e,t,n)=>{const i=t.name,r=t.project,s=t.bind,o=t.init&&t.init[0],a=cd.defined(t)?\"(item().isVoronoi ? datum.datum : datum)\":\"datum\";return r.items.forEach((c,l)=>{const u=re(`${i}_${c.field}`);n.filter(d=>d.name===u).length||n.unshift({name:u,...o?{init:Fn(o[l])}:{value:null},on:t.events?[{events:t.events,update:`datum && item().mark.marktype !== 'group' ? ${a}[${B(c.field)}] : null`}]:[],bind:s[c.field]??s[c.channel]??s})}),n},signals:(e,t,n)=>{const i=t.name,r=t.project,s=n.filter(l=>l.name===i+Xt)[0],o=i+er,a=r.items.map(l=>re(`${i}_${l.field}`)),c=a.map(l=>`${l} !== null`).join(\" && \");return a.length&&(s.update=`${c} ? {fields: ${o}, values: [${a.join(\", \")}]} : null`),delete s.value,delete s.on,n}},kr=\"_toggle\",ud={defined:e=>e.type===\"point\"&&!!e.toggle,signals:(e,t,n)=>n.concat({name:t.name+kr,value:!1,on:[{events:t.events,update:t.toggle}]}),modifyExpr:(e,t)=>{const n=t.name+Xt,i=t.name+kr;return`${i} ? null : ${n}, `+(t.resolve===\"global\"?`${i} ? null : true, `:`${i} ? null : {unit: ${bn(e)}}, `)+`${i} ? ${n} : null`}},xx={defined:e=>e.clear!==void 0&&e.clear!==!1,parse:(e,t)=>{t.clear&&(t.clear=R(t.clear)?pi(t.clear,\"view\"):t.clear)},topLevelSignals:(e,t,n)=>{if(ld.defined(t))for(const i of t.project.items){const r=n.findIndex(s=>s.name===re(`${t.name}_${i.field}`));r!==-1&&n[r].on.push({events:t.clear,update:\"null\"})}return n},signals:(e,t,n)=>{function i(r,s){r!==-1&&n[r].on&&n[r].on.push({events:t.clear,update:s})}if(t.type===\"interval\")for(const r of t.project.items){const s=n.findIndex(o=>o.name===r.signals.visual);if(i(s,\"[0, 0]\"),s===-1){const o=n.findIndex(a=>a.name===r.signals.data);i(o,\"null\")}}else{let r=n.findIndex(s=>s.name===t.name+Xt);i(r,\"null\"),ud.defined(t)&&(r=n.findIndex(s=>s.name===t.name+kr),i(r,\"false\"))}return n}},fd={defined:e=>{const t=e.resolve===\"global\"&&e.bind&&ha(e.bind),n=e.project.items.length===1&&e.project.items[0].field!==Ze;return t&&!n&&S(Wg),t&&n},parse:(e,t,n)=>{const i=z(n);if(i.select=R(i.select)?{type:i.select,toggle:t.toggle}:{...i.select,toggle:t.toggle},yd(t,i),H(n.select)&&(n.select.on||n.select.clear)){const o='event.item && indexof(event.item.mark.role, \"legend\") < 0';for(const a of t.events)a.filter=ce(a.filter??[]),a.filter.includes(o)||a.filter.push(o)}const r=Ts(t.bind)?t.bind.legend:\"click\",s=R(r)?pi(r,\"view\"):ce(r);t.bind={legend:{merge:s}}},topLevelSignals:(e,t,n)=>{const i=t.name,r=Ts(t.bind)&&t.bind.legend,s=o=>a=>{const c=z(a);return c.markname=o,c};for(const o of t.project.items){if(!o.hasLegend)continue;const a=`${re(o.field)}_legend`,c=`${i}_${a}`;if(n.filter(u=>u.name===c).length===0){const u=r.merge.map(s(`${a}_symbols`)).concat(r.merge.map(s(`${a}_labels`))).concat(r.merge.map(s(`${a}_entries`)));n.unshift({name:c,...t.init?{}:{value:null},on:[{events:u,update:\"isDefined(datum.value) ? datum.value : item().items[0].items[0].datum.value\",force:!0},{events:r.merge,update:`!event.item || !datum ? null : ${c}`,force:!0}]})}}return n},signals:(e,t,n)=>{const i=t.name,r=t.project,s=n.find(d=>d.name===i+Xt),o=i+er,a=r.items.filter(d=>d.hasLegend).map(d=>re(`${i}_${re(d.field)}_legend`)),l=`${a.map(d=>`${d} !== null`).join(\" && \")} ? {fields: ${o}, values: [${a.join(\", \")}]} : null`;t.events&&a.length>0?s.on.push({events:a.map(d=>({signal:d})),update:l}):a.length>0&&(s.update=l,delete s.value,delete s.on);const u=n.find(d=>d.name===i+kr),f=Ts(t.bind)&&t.bind.legend;return u&&(t.events?u.on.push({...u.on[0],events:f}):u.on[0].events=f),n}};function Sx(e,t,n){const i=e.fieldDef(t)?.field;for(const r of Se(e.component.selection??{})){const s=r.project.hasField[i]??r.project.hasChannel[t];if(s&&fd.defined(r)){const o=n.get(\"selections\")??[];o.push(r.name),n.set(\"selections\",o,!1),s.hasLegend=!0}}}const dd=\"_translate_anchor\",pd=\"_translate_delta\",vx={defined:e=>e.type===\"interval\"&&e.translate,signals:(e,t,n)=>{const i=t.name,r=kt.defined(t),s=i+dd,{x:o,y:a}=t.project.hasChannel;let c=pi(t.translate,\"scope\");return r||(c=c.map(l=>(l.between[0].markname=i+Xn,l))),n.push({name:s,value:{},on:[{events:c.map(l=>l.between[0]),update:\"{x: x(unit), y: y(unit)\"+(o!==void 0?`, extent_x: ${r?so(e,se):`slice(${o.signals.visual})`}`:\"\")+(a!==void 0?`, extent_y: ${r?so(e,be):`slice(${a.signals.visual})`}`:\"\")+\"}\"}]},{name:i+pd,value:{},on:[{events:c,update:`{x: ${s}.x - x(unit), y: ${s}.y - y(unit)}`}]}),o!==void 0&&Gc(e,t,o,\"width\",n),a!==void 0&&Gc(e,t,a,\"height\",n),n}};function Gc(e,t,n,i,r){const s=t.name,o=s+dd,a=s+pd,c=n.channel,l=kt.defined(t),u=r.filter(N=>N.name===n.signals[l?\"data\":\"visual\"])[0],f=e.getSizeSignalRef(i).signal,d=e.getScaleComponent(c),g=d&&d.get(\"type\"),p=d&&d.get(\"reverse\"),h=l?c===se?p?\"\":\"-\":p?\"-\":\"\":\"\",m=`${o}.extent_${c}`,y=`${h}${a}.${c} / ${l?`${f}`:`span(${m})`}`,b=!l||!d?\"panLinear\":g===\"log\"?\"panLog\":g===\"symlog\"?\"panSymlog\":g===\"pow\"?\"panPow\":\"panLinear\",C=l?g===\"pow\"?`, ${d.get(\"exponent\")??1}`:g===\"symlog\"?`, ${d.get(\"constant\")??1}`:\"\":\"\",k=`${b}(${m}, ${y}${C})`;u.on.push({events:{signal:a},update:l?k:`clampRange(${k}, 0, ${f})`})}const gd=\"_zoom_anchor\",hd=\"_zoom_delta\",Ex={defined:e=>e.type===\"interval\"&&e.zoom,signals:(e,t,n)=>{const i=t.name,r=kt.defined(t),s=i+hd,{x:o,y:a}=t.project.hasChannel,c=B(e.scaleName(se)),l=B(e.scaleName(be));let u=pi(t.zoom,\"scope\");return r||(u=u.map(f=>(f.markname=i+Xn,f))),n.push({name:i+gd,on:[{events:u,update:r?\"{\"+[c?`x: invert(${c}, x(unit))`:\"\",l?`y: invert(${l}, y(unit))`:\"\"].filter(f=>f).join(\", \")+\"}\":\"{x: x(unit), y: y(unit)}\"}]},{name:s,on:[{events:u,force:!0,update:\"pow(1.001, event.deltaY * pow(16, event.deltaMode))\"}]}),o!==void 0&&Hc(e,t,o,\"width\",n),a!==void 0&&Hc(e,t,a,\"height\",n),n}};function Hc(e,t,n,i,r){const s=t.name,o=n.channel,a=kt.defined(t),c=r.filter(b=>b.name===n.signals[a?\"data\":\"visual\"])[0],l=e.getSizeSignalRef(i).signal,u=e.getScaleComponent(o),f=u&&u.get(\"type\"),d=a?so(e,o):c.name,g=s+hd,p=`${s}${gd}.${o}`,h=!a||!u?\"zoomLinear\":f===\"log\"?\"zoomLog\":f===\"symlog\"?\"zoomSymlog\":f===\"pow\"?\"zoomPow\":\"zoomLinear\",m=a?f===\"pow\"?`, ${u.get(\"exponent\")??1}`:f===\"symlog\"?`, ${u.get(\"constant\")??1}`:\"\":\"\",y=`${h}(${d}, ${p}, ${g}${m})`;c.on.push({events:{signal:g},update:a?y:`clampRange(${y}, 0, ${l})`})}const kn=\"_store\",Xt=\"_tuple\",$x=\"_modify\",md=\"vlSelectionResolve\",ls=[nx,ex,Qb,ud,ld,kt,fd,xx,vx,Ex,cd];function wx(e){let t=e.parent;for(;t&&!ze(t);)t=t.parent;return t}function bn(e,{escape:t}={escape:!0}){let n=t?B(e.name):e.name;const i=wx(e);if(i){const{facet:r}=i;for(const s of je)r[s]&&(n+=` + '__facet_${s}_' + (facet[${B(i.vgField(s))}])`)}return n}function Na(e){return Se(e.component.selection??{}).reduce((t,n)=>t||n.project.hasSelectionId,!1)}function yd(e,t){(R(t.select)||!t.select.on)&&delete e.events,(R(t.select)||!t.select.clear)&&delete e.clear,(R(t.select)||!t.select.toggle)&&delete e.toggle}function oo(e){const t=[];return e.type===\"Identifier\"?[e.name]:e.type===\"Literal\"?[e.value]:(e.type===\"MemberExpression\"&&(t.push(...oo(e.object)),t.push(...oo(e.property))),t)}function bd(e){return e.object.type===\"MemberExpression\"?bd(e.object):e.object.name===\"datum\"}function xd(e){const t=Fp(e),n=new Set;return t.visit(i=>{i.type===\"MemberExpression\"&&bd(i)&&n.add(oo(i).slice(1).join(\".\"))}),n}class yi extends Y{clone(){return new yi(null,this.model,z(this.filter))}constructor(t,n,i){super(t),this.model=n,this.filter=i,this.expr=Tr(this.model,this.filter,this),this._dependentFields=xd(this.expr)}dependentFields(){return this._dependentFields}producedFields(){return new Set}assemble(){return{type:\"filter\",expr:this.expr}}hash(){return`Filter ${this.expr}`}}function Cx(e,t){const n={},i=e.config.selection;if(!t||!t.length)return n;for(const r of t){const s=re(r.name),o=r.select,a=R(o)?o:o.type,c=H(o)?z(o):{type:a},l=i[a];for(const d in l)d===\"fields\"||d===\"encodings\"||(d===\"mark\"&&(c[d]={...l[d],...c[d]}),(c[d]===void 0||c[d]===!0)&&(c[d]=z(l[d]??c[d])));const u=n[s]={...c,name:s,type:a,init:r.value,bind:r.bind,events:R(c.on)?pi(c.on,\"scope\"):ce(z(c.on))},f=z(r);for(const d of ls)d.defined(u)&&d.parse&&d.parse(e,u,f)}return n}function Sd(e,t,n,i=\"datum\"){const r=R(t)?t:t.param,s=re(r),o=B(s+kn);let a;try{a=e.getSelectionComponent(s,r)}catch{return`!!${s}`}if(a.project.timeUnit){const d=n??e.component.data.raw,g=a.project.timeUnit.clone();d.parent?g.insertAsParentOf(d):d.parent=g}const c=a.project.hasSelectionId?\"vlSelectionIdTest(\":\"vlSelectionTest(\",l=a.resolve===\"global\"?\")\":`, ${B(a.resolve)})`,u=`${c}${o}, ${i}${l}`,f=`length(data(${o}))`;return t.empty===!1?`${f} && ${u}`:`!${f} || ${u}`}function vd(e,t,n){const i=re(t),r=n.encoding;let s=n.field,o;try{o=e.getSelectionComponent(i,t)}catch{return i}if(!r&&!s)s=o.project.items[0].field,o.project.items.length>1&&S(`A \"field\" or \"encoding\" must be specified when using a selection as a scale domain. Using \"field\": ${B(s)}.`);else if(r&&!s){const a=o.project.items.filter(c=>c.channel===r);!a.length||a.length>1?(s=o.project.items[0].field,S((a.length?\"Multiple \":\"No \")+`matching ${B(r)} encoding found for selection ${B(n.param)}. Using \"field\": ${B(s)}.`)):s=a[0].field}return`${o.name}[${B(Ue(s))}]`}function Nx(e,t){for(const[n,i]of Wt(e.component.selection??{})){const r=e.getName(`lookup_${n}`);e.component.data.outputNodes[r]=i.materialized=new we(new yi(t,e,{param:n}),r,Z.Lookup,e.component.data.outputNodeRefCounts)}}function Tr(e,t,n){return Oi(t,i=>R(i)?i:im(i)?Sd(e,i,n):Pu(i))}function Fx(e,t){if(e)return F(e)&&!jt(e)?e.map(n=>oa(n,t)).join(\", \"):e}function Is(e,t,n,i){var r,s;e.encode??(e.encode={}),(r=e.encode)[t]??(r[t]={}),(s=e.encode[t]).update??(s.update={}),e.encode[t].update[n]=i}function ki(e,t,n,i={header:!1}){const{disable:r,orient:s,scale:o,labelExpr:a,title:c,zindex:l,...u}=e.combine();if(!r){for(const f in u){const d=oy[f],g=u[f];if(d&&d!==t&&d!==\"both\")delete u[f];else if(Zi(g)){const{condition:p,...h}=g,m=ce(p),y=xc[f];if(y){const{vgProp:b,part:C}=y,k=[...m.map(N=>{const{test:_,...L}=N;return{test:Tr(null,_),...L}}),h];Is(u,C,b,k),delete u[f]}else if(y===null){const b={signal:m.map(C=>{const{test:k,...N}=C;return`${Tr(null,k)} ? ${ic(N)} : `}).join(\"\")+ic(h)};u[f]=b}}else if(T(g)){const p=xc[f];if(p){const{vgProp:h,part:m}=p;Is(u,m,h,g),delete u[f]}}G([\"labelAlign\",\"labelBaseline\"],f)&&u[f]===null&&delete u[f]}if(t===\"grid\"){if(!u.grid)return;if(u.encode){const{grid:f}=u.encode;u.encode={...f?{grid:f}:{}},K(u.encode)&&delete u.encode}return{scale:o,orient:s,...u,domain:!1,labels:!1,aria:!1,maxExtent:0,minExtent:0,ticks:!1,zindex:le(l,0)}}else{if(!i.header&&e.mainExtracted)return;if(a!==void 0){let d=a;u.encode?.labels?.update&&T(u.encode.labels.update.text)&&(d=vn(a,\"datum.label\",u.encode.labels.update.text.signal)),Is(u,\"labels\",\"text\",{signal:d})}if(u.labelAlign===null&&delete u.labelAlign,u.encode){for(const d of pf)e.hasAxisPart(d)||delete u.encode[d];K(u.encode)&&delete u.encode}const f=Fx(c,n);return{scale:o,orient:s,grid:!1,...f?{title:f}:{},...u,...n.aria===!1?{aria:!1}:{},zindex:le(l,0)}}}}function Ed(e){const{axes:t}=e.component,n=[];for(const i of St)if(t[i]){for(const r of t[i])if(!r.get(\"disable\")&&!r.get(\"gridScale\")){const s=i===\"x\"?\"height\":\"width\",o=e.getSizeSignalRef(s).signal;s!==o&&n.push({name:s,update:o})}}return n}function kx(e,t){const{x:n=[],y:i=[]}=e;return[...n.map(r=>ki(r,\"grid\",t)),...i.map(r=>ki(r,\"grid\",t)),...n.map(r=>ki(r,\"main\",t)),...i.map(r=>ki(r,\"main\",t))].filter(r=>r)}function qc(e,t,n,i){return Object.assign.apply(null,[{},...e.map(r=>{if(r===\"axisOrient\"){const s=n===\"x\"?\"bottom\":\"left\",o=t[n===\"x\"?\"axisBottom\":\"axisLeft\"]||{},a=t[n===\"x\"?\"axisTop\":\"axisRight\"]||{},c=new Set([...x(o),...x(a)]),l={};for(const u of c.values())l[u]={signal:`${i.signal} === \"${s}\" ? ${Xe(o[u])} : ${Xe(a[u])}`};return l}return t[r]})])}function Tx(e,t,n,i){const r=t===\"band\"?[\"axisDiscrete\",\"axisBand\"]:t===\"point\"?[\"axisDiscrete\",\"axisPoint\"]:ju(t)?[\"axisQuantitative\"]:t===\"time\"||t===\"utc\"?[\"axisTemporal\"]:[],s=e===\"x\"?\"axisX\":\"axisY\",o=T(n)?\"axisOrient\":`axis${Wi(n)}`,a=[...r,...r.map(l=>s+l.substr(4))],c=[\"axis\",o,s];return{vlOnlyAxisConfig:qc(a,i,e,n),vgAxisConfig:qc(c,i,e,n),axisConfigStyle:Ax([...c,...a],i)}}function Ax(e,t){const n=[{}];for(const i of e){let r=t[i]?.style;if(r){r=ce(r);for(const s of r)n.push(t.style[s])}}return Object.assign.apply(null,n)}function ao(e,t,n,i={}){const r=gu(e,n,t);if(r!==void 0)return{configFrom:\"style\",configValue:r};for(const s of[\"vlOnlyAxisConfig\",\"vgAxisConfig\",\"axisConfigStyle\"])if(i[s]?.[e]!==void 0)return{configFrom:s,configValue:i[s][e]};return{}}const Vc={scale:({model:e,channel:t})=>e.scaleName(t),format:({format:e})=>e,formatType:({formatType:e})=>e,grid:({fieldOrDatumDef:e,axis:t,scaleType:n})=>t.grid??Ox(n,e),gridScale:({model:e,channel:t})=>_x(e,t),labelAlign:({axis:e,labelAngle:t,orient:n,channel:i})=>e.labelAlign||wd(t,n,i),labelAngle:({labelAngle:e})=>e,labelBaseline:({axis:e,labelAngle:t,orient:n,channel:i})=>e.labelBaseline||$d(t,n,i),labelFlush:({axis:e,fieldOrDatumDef:t,channel:n})=>e.labelFlush??Ix(t.type,n),labelOverlap:({axis:e,fieldOrDatumDef:t,scaleType:n})=>e.labelOverlap??Lx(t.type,n,v(t)&&!!t.timeUnit,v(t)?t.sort:void 0),orient:({orient:e})=>e,tickCount:({channel:e,model:t,axis:n,fieldOrDatumDef:i,scaleType:r})=>{const s=e===\"x\"?\"width\":e===\"y\"?\"height\":void 0,o=s?t.getSizeSignalRef(s):void 0;return n.tickCount??zx({fieldOrDatumDef:i,scaleType:r,size:o,values:n.values})},tickMinStep:Dx,title:({axis:e,model:t,channel:n})=>{if(e.title!==void 0)return e.title;const i=Cd(t,n);if(i!==void 0)return i;const r=t.typedFieldDef(n),s=n===\"x\"?\"x2\":\"y2\",o=t.fieldDef(s);return mu(r?[yc(r)]:[],v(o)?[yc(o)]:[])},values:({axis:e,fieldOrDatumDef:t})=>Mx(e,t),zindex:({axis:e,fieldOrDatumDef:t,mark:n})=>e.zindex??jx(n,t)};function Ox(e,t){return!ye(e)&&v(t)&&!ee(t?.bin)&&!xe(t?.bin)}function _x(e,t){const n=t===\"x\"?\"y\":\"x\";if(e.getScaleComponent(n))return e.scaleName(n)}function Rx(e,t,n,i,r){const s=t?.labelAngle;if(s!==void 0)return T(s)?s:Pi(s);{const{configValue:o}=ao(\"labelAngle\",i,t?.style,r);return o!==void 0?Pi(o):n===se&&G([Yo,Xo],e.type)&&!(v(e)&&e.timeUnit)?270:void 0}}function co(e){return`(((${e.signal} % 360) + 360) % 360)`}function $d(e,t,n,i){if(e!==void 0)if(n===\"x\"){if(T(e)){const r=co(e),s=T(t)?`(${t.signal} === \"top\")`:t===\"top\";return{signal:`(45 < ${r} && ${r} < 135) || (225 < ${r} && ${r} < 315) ? \"middle\" :(${r} <= 45 || 315 <= ${r}) === ${s} ? \"bottom\" : \"top\"`}}if(45{if(Pn(i)&&tf(i.sort)){const{field:s,timeUnit:o}=i,a=i.sort,c=a.map((l,u)=>`${Pu({field:s,timeUnit:o,equal:l})} ? ${u} : `).join(\"\")+a.length;t=new ci(t,{calculate:c,as:li(i,r,{forAs:!0})})}}),t}producedFields(){return new Set([this.transform.as])}dependentFields(){return this._dependentFields}assemble(){return{type:\"formula\",expr:this.transform.calculate,as:this.transform.as}}hash(){return`Calculate ${W(this.transform)}`}}function li(e,t,n){return E(e,{prefix:t,suffix:\"sort_index\",...n})}function us(e,t){return G([\"top\",\"bottom\"],t)?\"column\":G([\"left\",\"right\"],t)||e===\"row\"?\"row\":\"column\"}function ui(e,t,n,i){const r=i===\"row\"?n.headerRow:i===\"column\"?n.headerColumn:n.headerFacet;return le((t||{})[e],r[e],n.header[e])}function fs(e,t,n,i){const r={};for(const s of e){const o=ui(s,t||{},n,i);o!==void 0&&(r[s]=o)}return r}const Fa=[\"row\",\"column\"],ka=[\"header\",\"footer\"];function Ux(e,t){const n=e.component.layoutHeaders[t].title,i=e.config?e.config:void 0,r=e.component.layoutHeaders[t].facetFieldDef?e.component.layoutHeaders[t].facetFieldDef:void 0,{titleAnchor:s,titleAngle:o,titleOrient:a}=fs([\"titleAnchor\",\"titleAngle\",\"titleOrient\"],r.header,i,t),c=us(t,a),l=Pi(o);return{name:`${t}-title`,type:\"group\",role:`${c}-title`,title:{text:n,...t===\"row\"?{orient:\"left\"}:{},style:\"guide-title\",...Fd(l,c),...Nd(c,l,s),...kd(i,r,t,ky,Af)}}}function Nd(e,t,n=\"middle\"){switch(n){case\"start\":return{align:\"left\"};case\"end\":return{align:\"right\"}}const i=wd(t,e===\"row\"?\"left\":\"top\",e===\"row\"?\"y\":\"x\");return i?{align:i}:{}}function Fd(e,t){const n=$d(e,t===\"row\"?\"left\":\"top\",t===\"row\"?\"y\":\"x\",!0);return n?{baseline:n}:{}}function Bx(e,t){const n=e.component.layoutHeaders[t],i=[];for(const r of ka)if(n[r])for(const s of n[r]){const o=Gx(e,t,r,n,s);o!=null&&i.push(o)}return i}function Wx(e,t){const{sort:n}=e;return ut(n)?{field:E(n,{expr:\"datum\"}),order:n.order??\"ascending\"}:F(n)?{field:li(e,t,{expr:\"datum\"}),order:\"ascending\"}:{field:E(e,{expr:\"datum\"}),order:n??\"ascending\"}}function lo(e,t,n){const{format:i,formatType:r,labelAngle:s,labelAnchor:o,labelOrient:a,labelExpr:c}=fs([\"format\",\"formatType\",\"labelAngle\",\"labelAnchor\",\"labelOrient\",\"labelExpr\"],e.header,n,t),l=na({fieldOrDatumDef:e,format:i,formatType:r,expr:\"parent\",config:n}).signal,u=us(t,a);return{text:{signal:c?vn(vn(c,\"datum.label\",l),\"datum.value\",E(e,{expr:\"parent\"})):l},...t===\"row\"?{orient:\"left\"}:{},style:\"guide-label\",frame:\"group\",...Fd(s,u),...Nd(u,s,o),...kd(n,e,t,Ty,Of)}}function Gx(e,t,n,i,r){if(r){let s=null;const{facetFieldDef:o}=i,a=e.config?e.config:void 0;if(o&&r.labels){const{labelOrient:f}=fs([\"labelOrient\"],o.header,a,t);(t===\"row\"&&!G([\"top\",\"bottom\"],f)||t===\"column\"&&!G([\"left\",\"right\"],f))&&(s=lo(o,t,a))}const c=ze(e)&&!Ki(e.facet),l=r.axes,u=l?.length>0;if(s||u){const f=t===\"row\"?\"height\":\"width\";return{name:e.getName(`${t}_${n}`),type:\"group\",role:`${t}-${n}`,...i.facetFieldDef?{from:{data:e.getName(`${t}_domain`)},sort:Wx(o,t)}:{},...u&&c?{from:{data:e.getName(`facet_domain_${t}`)}}:{},...s?{title:s}:{},...r.sizeSignal?{encode:{update:{[f]:r.sizeSignal}}}:{},...u?{axes:l}:{}}}}return null}const Hx={column:{start:0,end:1},row:{start:1,end:0}};function qx(e,t){return Hx[t][e]}function Vx(e,t){const n={};for(const i of je){const r=e[i];if(r?.facetFieldDef){const{titleAnchor:s,titleOrient:o}=fs([\"titleAnchor\",\"titleOrient\"],r.facetFieldDef.header,t,i),a=us(i,o),c=qx(s,a);c!==void 0&&(n[a]=c)}}return K(n)?void 0:n}function kd(e,t,n,i,r){const s={};for(const o of i){if(!r[o])continue;const a=ui(o,t?.header,e,n);a!==void 0&&(s[r[o]]=a)}return s}function Ta(e){return[...or(e,\"width\"),...or(e,\"height\"),...or(e,\"childWidth\"),...or(e,\"childHeight\")]}function or(e,t){const n=t===\"width\"?\"x\":\"y\",i=e.component.layoutSize.get(t);if(!i||i===\"merged\")return[];const r=e.getSizeSignalRef(t).signal;if(i===\"step\"){const s=e.getScaleComponent(n);if(s){const o=s.get(\"type\"),a=s.get(\"range\");if(ye(o)&&nn(a)){const c=e.scaleName(n);return ze(e.parent)&&e.parent.component.resolve.scale[n]===\"independent\"?[Xc(c,a)]:[Xc(c,a),{name:r,update:Td(c,s,`domain('${c}').length`)}]}}throw new Error(\"layout size is step although width/height is not step.\")}else if(i==\"container\"){const s=r.endsWith(\"width\"),o=s?\"containerSize()[0]\":\"containerSize()[1]\",a=to(e.config.view,s?\"width\":\"height\"),c=`isFinite(${o}) ? ${o} : ${a}`;return[{name:r,init:c,on:[{update:c,events:\"window:resize\"}]}]}else return[{name:r,value:i}]}function Xc(e,t){const n=`${e}_step`;return T(t.step)?{name:n,update:t.step.signal}:{name:n,value:t.step}}function Td(e,t,n){const i=t.get(\"type\"),r=t.get(\"padding\"),s=le(t.get(\"paddingOuter\"),r);let o=t.get(\"paddingInner\");return o=i===\"band\"?o!==void 0?o:r:1,`bandspace(${n}, ${Xe(o)}, ${Xe(s)}) * ${e}_step`}function Ad(e){return e===\"childWidth\"?\"width\":e===\"childHeight\"?\"height\":e}function Od(e,t){return x(e).reduce((n,i)=>{const r=e[i];return{...n,...mi(t,r,i,s=>ne(s.value))}},{})}function _d(e,t){if(ze(t))return e===\"theta\"?\"independent\":\"shared\";if(Si(t))return\"shared\";if(Pa(t))return ue(e)||e===\"theta\"||e===\"radius\"?\"independent\":\"shared\";throw new Error(\"invalid model type for resolve\")}function Aa(e,t){const n=e.scale[t],i=ue(t)?\"axis\":\"legend\";return n===\"independent\"?(e[i][t]===\"shared\"&&S(Ch(t)),\"independent\"):e[i][t]||\"shared\"}const Xx={..._y,disable:1,labelExpr:1,selections:1,opacity:1,shape:1,stroke:1,fill:1,size:1,strokeWidth:1,strokeDash:1,encode:1},Rd=x(Xx);class Yx extends Dt{}const Yc={symbols:Kx,gradient:Jx,labels:Qx,entries:Zx};function Kx(e,{fieldOrDatumDef:t,model:n,channel:i,legendCmpt:r,legendType:s}){if(s!==\"symbol\")return;const{markDef:o,encoding:a,config:c,mark:l}=n,u=o.filled&&l!==\"trail\";let f={...Pg({},n,km),...sd(n,{filled:u})};const d=r.get(\"symbolOpacity\")??c.legend.symbolOpacity,g=r.get(\"symbolFillColor\")??c.legend.symbolFillColor,p=r.get(\"symbolStrokeColor\")??c.legend.symbolStrokeColor,h=d===void 0?Id(a.opacity)??o.opacity:void 0;if(f.fill){if(i===\"fill\"||u&&i===Ae)delete f.fill;else if(f.fill.field)g?delete f.fill:(f.fill=ne(c.legend.symbolBaseFillColor??\"black\"),f.fillOpacity=ne(h??1));else if(F(f.fill)){const m=uo(a.fill??a.color)??o.fill??(u&&o.color);m&&(f.fill=ne(m))}}if(f.stroke){if(i===\"stroke\"||!u&&i===Ae)delete f.stroke;else if(f.stroke.field||p)delete f.stroke;else if(F(f.stroke)){const m=le(uo(a.stroke||a.color),o.stroke,u?o.color:void 0);m&&(f.stroke={value:m})}}if(i!==Lt){const m=v(t)&&Pd(n,r,t);m?f.opacity=[{test:m,...ne(h??1)},ne(c.legend.unselectedOpacity)]:h&&(f.opacity=ne(h))}return f={...f,...e},K(f)?void 0:f}function Jx(e,{model:t,legendType:n,legendCmpt:i}){if(n!==\"gradient\")return;const{config:r,markDef:s,encoding:o}=t;let a={};const l=(i.get(\"gradientOpacity\")??r.legend.gradientOpacity)===void 0?Id(o.opacity)||s.opacity:void 0;return l&&(a.opacity=ne(l)),a={...a,...e},K(a)?void 0:a}function Qx(e,{fieldOrDatumDef:t,model:n,channel:i,legendCmpt:r}){const s=n.legend(i)||{},o=n.config,a=v(t)?Pd(n,r,t):void 0,c=a?[{test:a,value:1},{value:o.legend.unselectedOpacity}]:void 0,{format:l,formatType:u}=s;let f;Nn(u)?f=Ke({fieldOrDatumDef:t,field:\"datum.value\",format:l,formatType:u,config:o}):l===void 0&&u===void 0&&o.customFormatTypes&&(t.type===\"quantitative\"&&o.numberFormatType?f=Ke({fieldOrDatumDef:t,field:\"datum.value\",format:o.numberFormat,formatType:o.numberFormatType,config:o}):t.type===\"temporal\"&&o.timeFormatType&&v(t)&&t.timeUnit===void 0&&(f=Ke({fieldOrDatumDef:t,field:\"datum.value\",format:o.timeFormat,formatType:o.timeFormatType,config:o})));const d={...c?{opacity:c}:{},...f?{text:f}:{},...e};return K(d)?void 0:d}function Zx(e,{legendCmpt:t}){return t.get(\"selections\")?.length?{...e,fill:{value:\"transparent\"}}:e}function Id(e){return Ld(e,(t,n)=>Math.max(t,n.value))}function uo(e){return Ld(e,(t,n)=>le(t,n.value))}function Ld(e,t){if(Xm(e))return ce(e.condition).reduce(t,e.value);if(Qe(e))return e.value}function Pd(e,t,n){const i=t.get(\"selections\");if(!i?.length)return;const r=B(n.field);return i.map(s=>`(!length(data(${B(re(s)+kn)})) || (${s}[${r}] && indexof(${s}[${r}], datum.value) >= 0))`).join(\" || \")}const Kc={direction:({direction:e})=>e,format:({fieldOrDatumDef:e,legend:t,config:n})=>{const{format:i,formatType:r}=t;return Ju(e,e.type,i,r,n,!1)},formatType:({legend:e,fieldOrDatumDef:t,scaleType:n})=>{const{formatType:i}=e;return Qu(i,t,n)},gradientLength:e=>{const{legend:t,legendConfig:n}=e;return t.gradientLength??n.gradientLength??oS(e)},labelOverlap:({legend:e,legendConfig:t,scaleType:n})=>e.labelOverlap??t.labelOverlap??aS(n),symbolType:({legend:e,markDef:t,channel:n,encoding:i})=>e.symbolType??tS(t.type,n,i.shape,t.shape),title:({fieldOrDatumDef:e,config:t})=>Vn(e,t,{allowDisabling:!0}),type:({legendType:e,scaleType:t,channel:n})=>{if(qn(n)&&Ye(t)){if(e===\"gradient\")return}else if(e===\"symbol\")return;return e},values:({fieldOrDatumDef:e,legend:t})=>eS(t,e)};function eS(e,t){const n=e.values;if(F(n))return df(t,n);if(T(n))return n}function tS(e,t,n,i){if(t!==\"shape\"){const r=uo(n)??i;if(r)return r}switch(e){case\"bar\":case\"rect\":case\"image\":case\"square\":return\"square\";case\"line\":case\"trail\":case\"rule\":return\"stroke\";case\"arc\":case\"point\":case\"circle\":case\"tick\":case\"geoshape\":case\"area\":case\"text\":return\"circle\"}}function nS(e){const{legend:t}=e;return le(t.type,iS(e))}function iS({channel:e,timeUnit:t,scaleType:n}){if(qn(e)){if(G([\"quarter\",\"month\",\"day\"],t))return\"symbol\";if(Ye(n))return\"gradient\"}return\"symbol\"}function rS({legendConfig:e,legendType:t,orient:n,legend:i}){return i.direction??e[t?\"gradientDirection\":\"symbolDirection\"]??sS(n,t)}function sS(e,t){switch(e){case\"top\":case\"bottom\":return\"horizontal\";case\"left\":case\"right\":case\"none\":case void 0:return;default:return t===\"gradient\"?\"horizontal\":void 0}}function oS({legendConfig:e,model:t,direction:n,orient:i,scaleType:r}){const{gradientHorizontalMaxLength:s,gradientHorizontalMinLength:o,gradientVerticalMaxLength:a,gradientVerticalMinLength:c}=e;if(Ye(r))return n===\"horizontal\"?i===\"top\"||i===\"bottom\"?Jc(t,\"width\",o,s):o:Jc(t,\"height\",c,a)}function Jc(e,t,n,i){return{signal:`clamp(${e.getSizeSignalRef(t).signal}, ${n}, ${i})`}}function aS(e){if(G([\"quantile\",\"threshold\",\"log\",\"symlog\"],e))return\"greedy\"}function zd(e){const t=ae(e)?cS(e):dS(e);return e.component.legends=t,t}function cS(e){const{encoding:t}=e,n={};for(const i of[Ae,...Rf]){const r=fe(t[i]);!r||!e.getScaleComponent(i)||i===Oe&&v(r)&&r.type===hi||(n[i]=fS(e,i))}return n}function lS(e,t){const n=e.scaleName(t);if(e.mark===\"trail\"){if(t===\"color\")return{stroke:n};if(t===\"size\")return{strokeWidth:n}}return t===\"color\"?e.markDef.filled?{fill:n}:{stroke:n}:{[t]:n}}function uS(e,t,n,i){switch(t){case\"disable\":return n!==void 0;case\"values\":return!!n?.values;case\"title\":if(t===\"title\"&&e===i?.title)return!0}return e===(n||{})[t]}function fS(e,t){let n=e.legend(t);const{markDef:i,encoding:r,config:s}=e,o=s.legend,a=new Yx({},lS(e,t));Sx(e,t,a);const c=n!==void 0?!n:o.disable;if(a.set(\"disable\",c,n!==void 0),c)return a;n=n||{};const l=e.getScaleComponent(t).get(\"type\"),u=fe(r[t]),f=v(u)?me(u.timeUnit)?.unit:void 0,d=n.orient||s.legend.orient||\"right\",g=nS({legend:n,channel:t,timeUnit:f,scaleType:l}),p=rS({legend:n,legendType:g,orient:d,legendConfig:o}),h={legend:n,channel:t,model:e,markDef:i,encoding:r,fieldOrDatumDef:u,legendConfig:o,config:s,scaleType:l,orient:d,legendType:g,direction:p};for(const k of Rd){if(g===\"gradient\"&&k.startsWith(\"symbol\")||g===\"symbol\"&&k.startsWith(\"gradient\"))continue;const N=k in Kc?Kc[k](h):n[k];if(N!==void 0){const _=uS(N,k,n,e.fieldDef(t));(_||s.legend[k]===void 0)&&a.set(k,N,_)}}const m=n?.encoding??{},y=a.get(\"selections\"),b={},C={fieldOrDatumDef:u,model:e,channel:t,legendCmpt:a,legendType:g};for(const k of[\"labels\",\"legend\",\"title\",\"symbols\",\"gradient\",\"entries\"]){const N=Od(m[k]??{},e),_=k in Yc?Yc[k](N,C):N;_!==void 0&&!K(_)&&(b[k]={...y?.length&&v(u)?{name:`${re(u.field)}_legend_${k}`}:{},...y?.length?{interactive:!!y}:{},update:_})}return K(b)||a.set(\"encode\",b,!!n?.encoding),a}function dS(e){const{legends:t,resolve:n}=e.component;for(const i of e.children){zd(i);for(const r of x(i.component.legends))n.legend[r]=Aa(e.component.resolve,r),n.legend[r]===\"shared\"&&(t[r]=Dd(t[r],i.component.legends[r]),t[r]||(n.legend[r]=\"independent\",delete t[r]))}for(const i of x(t))for(const r of e.children)r.component.legends[i]&&n.legend[i]===\"shared\"&&delete r.component.legends[i];return t}function Dd(e,t){if(!e)return t.clone();const n=e.getWithExplicit(\"orient\"),i=t.getWithExplicit(\"orient\");if(n.explicit&&i.explicit&&n.value!==i.value)return;let r=!1;for(const s of Rd){const o=qt(e.getWithExplicit(s),t.getWithExplicit(s),s,\"legend\",(a,c)=>{switch(s){case\"symbolType\":return pS(a,c);case\"title\":return bu(a,c);case\"type\":return r=!0,Ie(\"symbol\")}return ss(a,c,s,\"legend\")});e.setWithExplicit(s,o)}return r&&(e.implicit?.encode?.gradient&&hr(e.implicit,[\"encode\",\"gradient\"]),e.explicit?.encode?.gradient&&hr(e.explicit,[\"encode\",\"gradient\"])),e}function pS(e,t){return t.value===\"circle\"?t:e}function gS(e,t,n,i){var r,s;e.encode??(e.encode={}),(r=e.encode)[t]??(r[t]={}),(s=e.encode[t]).update??(s.update={}),e.encode[t].update[n]=i}function Md(e){const t=e.component.legends,n={};for(const r of x(t)){const s=e.getScaleComponent(r),o=J(s.get(\"domains\"));if(n[o])for(const a of n[o])Dd(a,t[r])||n[o].push(t[r]);else n[o]=[t[r].clone()]}return Se(n).flat().map(r=>hS(r,e.config)).filter(r=>r!==void 0)}function hS(e,t){const{disable:n,labelExpr:i,selections:r,...s}=e.combine();if(!n){if(t.aria===!1&&s.aria==null&&(s.aria=!1),s.encode?.symbols){const o=s.encode.symbols.update;o.fill&&o.fill.value!==\"transparent\"&&!o.stroke&&!s.stroke&&(o.stroke={value:\"transparent\"});for(const a of Rf)s[a]&&delete o[a]}if(s.title||delete s.title,i!==void 0){let o=i;s.encode?.labels?.update&&T(s.encode.labels.update.text)&&(o=vn(i,\"datum.label\",s.encode.labels.update.text.signal)),gS(s,\"labels\",\"text\",{signal:o})}return s}}function mS(e){return Si(e)||Pa(e)?yS(e):jd(e)}function yS(e){return e.children.reduce((t,n)=>t.concat(n.assembleProjections()),jd(e))}function jd(e){const t=e.component.projection;if(!t||t.merged)return[];const n=t.combine(),{name:i}=n;if(t.data){const r={signal:`[${t.size.map(o=>o.signal).join(\", \")}]`},s=t.data.reduce((o,a)=>{const c=T(a)?a.signal:`data('${e.lookupDataSource(a)}')`;return G(o,c)||o.push(c),o},[]);if(s.length<=0)throw new Error(\"Projection's fit didn't find any data sources\");return[{name:i,size:r,fit:{signal:s.length>1?`[${s.join(\", \")}]`:s[0]},...n}]}else return[{name:i,translate:{signal:\"[width / 2, height / 2]\"},...n}]}const bS=[\"type\",\"clipAngle\",\"clipExtent\",\"center\",\"rotate\",\"precision\",\"reflectX\",\"reflectY\",\"coefficient\",\"distance\",\"fraction\",\"lobes\",\"parallel\",\"radius\",\"ratio\",\"spacing\",\"tilt\"];class Ud extends Dt{constructor(t,n,i,r){super({...n},{name:t}),this.specifiedProjection=n,this.size=i,this.data=r,this.merged=!1}get isFit(){return!!this.data}}function Bd(e){e.component.projection=ae(e)?xS(e):ES(e)}function xS(e){if(e.hasProjection){const t=Fe(e.specifiedProjection),n=!(t&&(t.scale!=null||t.translate!=null)),i=n?[e.getSizeSignalRef(\"width\"),e.getSizeSignalRef(\"height\")]:void 0,r=n?SS(e):void 0,s=new Ud(e.projectionName(!0),{...Fe(e.config.projection),...t},i,r);return s.get(\"type\")||s.set(\"type\",\"equalEarth\",!1),s}}function SS(e){const t=[],{encoding:n}=e;for(const i of[[it,nt],[Be,rt]])(fe(n[i[0]])||fe(n[i[1]]))&&t.push({signal:e.getName(`geojson_${t.length}`)});return e.channelHasField(Oe)&&e.typedFieldDef(Oe).type===hi&&t.push({signal:e.getName(`geojson_${t.length}`)}),t.length===0&&t.push(e.requestDataName(Z.Main)),t}function vS(e,t){const n=Eo(bS,r=>!!(!Gn(e.explicit,r)&&!Gn(t.explicit,r)||Gn(e.explicit,r)&&Gn(t.explicit,r)&&Pe(e.get(r),t.get(r))));if(Pe(e.size,t.size)){if(n)return e;if(Pe(e.explicit,{}))return t;if(Pe(t.explicit,{}))return e}return null}function ES(e){if(e.children.length===0)return;let t;for(const i of e.children)Bd(i);const n=Eo(e.children,i=>{const r=i.component.projection;if(r)if(t){const s=vS(t,r);return s&&(t=s),!!s}else return t=r,!0;else return!0});if(t&&n){const i=e.projectionName(!0),r=new Ud(i,t.specifiedProjection,t.size,z(t.data));for(const s of e.children){const o=s.component.projection;o&&(o.isFit&&r.data.push(...s.component.projection.data),s.renameProjection(o.get(\"name\"),i),o.merged=!0)}return r}}function $S(e,t,n,i){if(Qi(t,n)){const r=ae(e)?e.axis(n)??e.legend(n)??{}:{},s=E(t,{expr:\"datum\"}),o=E(t,{expr:\"datum\",binSuffix:\"end\"});return{formulaAs:E(t,{binSuffix:\"range\",forAs:!0}),formula:Yi(s,o,r.format,r.formatType,i)}}return{}}function Wd(e,t){return`${uu(e)}_${t}`}function wS(e,t){return{signal:e.getName(`${t}_bins`),extentSignal:e.getName(`${t}_extent`)}}function Oa(e,t,n){const i=Zr(n,void 0)??{},r=Wd(i,t);return e.getName(`${r}_bins`)}function CS(e){return\"as\"in e}function Qc(e,t,n){let i,r;CS(e)?i=R(e.as)?[e.as,`${e.as}_end`]:[e.as[0],e.as[1]]:i=[E(e,{forAs:!0}),E(e,{binSuffix:\"end\",forAs:!0})];const s={...Zr(t,void 0)},o=Wd(s,e.field),{signal:a,extentSignal:c}=wS(n,o);if(Br(s.extent)){const u=s.extent;r=vd(n,u.param,u),delete s.extent}const l={bin:s,field:e.field,as:[i],...a?{signal:a}:{},...c?{extentSignal:c}:{},...r?{span:r}:{}};return{key:o,binComponent:l}}class dt extends Y{clone(){return new dt(null,z(this.bins))}constructor(t,n){super(t),this.bins=n}static makeFromEncoding(t,n){const i=n.reduceFieldDef((r,s,o)=>{if(Ce(s)&&ee(s.bin)){const{key:a,binComponent:c}=Qc(s,s.bin,n);r[a]={...c,...r[a],...$S(n,s,o,n.config)}}return r},{});return K(i)?null:new dt(t,i)}static makeFromTransform(t,n,i){const{key:r,binComponent:s}=Qc(n,n.bin,i);return new dt(t,{[r]:s})}merge(t,n){for(const i of x(t.bins))i in this.bins?(n(t.bins[i].signal,this.bins[i].signal),this.bins[i].as=lt([...this.bins[i].as,...t.bins[i].as],W)):this.bins[i]=t.bins[i];for(const i of t.children)t.removeChild(i),i.parent=this;t.remove()}producedFields(){return new Set(Se(this.bins).map(t=>t.as).flat(2))}dependentFields(){return new Set(Se(this.bins).map(t=>t.field))}hash(){return`Bin ${W(this.bins)}`}assemble(){return Se(this.bins).flatMap(t=>{const n=[],[i,...r]=t.as,{extent:s,...o}=t.bin,a={type:\"bin\",field:Ue(t.field),as:i,signal:t.signal,...Br(s)?{extent:null}:{extent:s},...t.span?{span:{signal:`span(${t.span})`}}:{},...o};!s&&t.extentSignal&&(n.push({type:\"extent\",field:Ue(t.field),signal:t.extentSignal}),a.extent={signal:t.extentSignal}),n.push(a);for(const c of r)for(let l=0;l<2;l++)n.push({type:\"formula\",expr:E({field:i[l]},{expr:\"datum\"}),as:c[l]});return t.formula&&n.push({type:\"formula\",expr:t.formula,as:t.formulaAs}),n})}}function NS(e,t,n,i){const r=ae(i)?i.encoding[xt(t)]:void 0;if(Ce(n)&&ae(i)&&rf(n,r,i.markDef,i.config)){e.add(E(n,{})),e.add(E(n,{suffix:\"end\"}));const{mark:s,markDef:o,config:a}=i,c=Ht({fieldDef:n,markDef:o,config:a});zi(s)&&c!==.5&&ue(t)&&(e.add(E(n,{suffix:os})),e.add(E(n,{suffix:as}))),n.bin&&Qi(n,t)&&e.add(E(n,{binSuffix:\"range\"}))}else if(eu(t)){const s=Zl(t);e.add(i.getName(s))}else e.add(E(n));return Pn(n)&&mm(n.scale?.range)&&e.add(n.scale.range.field),e}function FS(e,t){for(const n of x(t)){const i=t[n];for(const r of x(i))n in e?e[n][r]=new Set([...e[n][r]??[],...i[r]]):e[n]={[r]:i[r]}}}class Je extends Y{clone(){return new Je(null,new Set(this.dimensions),z(this.measures))}constructor(t,n,i){super(t),this.dimensions=n,this.measures=i}get groupBy(){return this.dimensions}static makeFromEncoding(t,n){let i=!1;n.forEachFieldDef(o=>{o.aggregate&&(i=!0)});const r={},s=new Set;return!i||(n.forEachFieldDef((o,a)=>{const{aggregate:c,field:l}=o;if(c)if(c===\"count\")r[\"*\"]??(r[\"*\"]={}),r[\"*\"].count=new Set([E(o,{forAs:!0})]);else{if(At(c)||tn(c)){const u=At(c)?\"argmin\":\"argmax\",f=c[u];r[f]??(r[f]={}),r[f][u]=new Set([E({op:u,field:f},{forAs:!0})])}else r[l]??(r[l]={}),r[l][c]=new Set([E(o,{forAs:!0})]);Pt(a)&&n.scaleDomain(a)===\"unaggregated\"&&(r[l]??(r[l]={}),r[l].min=new Set([E({field:l,aggregate:\"min\"},{forAs:!0})]),r[l].max=new Set([E({field:l,aggregate:\"max\"},{forAs:!0})]))}else NS(s,a,o,n)}),s.size+x(r).length===0)?null:new Je(t,s,r)}static makeFromTransform(t,n){const i=new Set,r={};for(const s of n.aggregate){const{op:o,field:a,as:c}=s;o&&(o===\"count\"?(r[\"*\"]??(r[\"*\"]={}),r[\"*\"].count=new Set([c||E(s,{forAs:!0})])):(r[a]??(r[a]={}),r[a][o]=new Set([c||E(s,{forAs:!0})])))}for(const s of n.groupby??[])i.add(s);return i.size+x(r).length===0?null:new Je(t,i,r)}merge(t){return Hl(this.dimensions,t.dimensions)?(FS(this.measures,t.measures),!0):(Uh(\"different dimensions, cannot merge\"),!1)}addDimensions(t){t.forEach(this.dimensions.add,this.dimensions)}dependentFields(){return new Set([...this.dimensions,...x(this.measures)])}producedFields(){const t=new Set;for(const n of x(this.measures))for(const i of x(this.measures[n])){const r=this.measures[n][i];r.size===0?t.add(`${i}_${n}`):r.forEach(t.add,t)}return t}hash(){return`Aggregate ${W({dimensions:this.dimensions,measures:this.measures})}`}assemble(){const t=[],n=[],i=[];for(const s of x(this.measures))for(const o of x(this.measures[s]))for(const a of this.measures[s][o])i.push(a),t.push(o),n.push(s===\"*\"?null:Ue(s));return{type:\"aggregate\",groupby:[...this.dimensions].map(Ue),ops:t,fields:n,as:i}}}class bi extends Y{constructor(t,n,i,r){super(t),this.model=n,this.name=i,this.data=r;for(const s of je){const o=n.facet[s];if(o){const{bin:a,sort:c}=o;this[s]={name:n.getName(`${s}_domain`),fields:[E(o),...ee(a)?[E(o,{binSuffix:\"end\"})]:[]],...ut(c)?{sortField:c}:F(c)?{sortIndexField:li(o,s)}:{}}}}this.childModel=n.child}hash(){let t=\"Facet\";for(const n of je)this[n]&&(t+=` ${n.charAt(0)}:${W(this[n])}`);return t}get fields(){const t=[];for(const n of je)this[n]?.fields&&t.push(...this[n].fields);return t}dependentFields(){const t=new Set(this.fields);for(const n of je)this[n]&&(this[n].sortField&&t.add(this[n].sortField.field),this[n].sortIndexField&&t.add(this[n].sortIndexField));return t}producedFields(){return new Set}getSource(){return this.name}getChildIndependentFieldsWithStep(){const t={};for(const n of St){const i=this.childModel.component.scales[n];if(i&&!i.merged){const r=i.get(\"type\"),s=i.get(\"range\");if(ye(r)&&nn(s)){const o=ds(this.childModel,n),a=La(o);a?t[n]=a:S(Po(n))}}}return t}assembleRowColumnHeaderData(t,n,i){const r={row:\"y\",column:\"x\",facet:void 0}[t],s=[],o=[],a=[];r&&i&&i[r]&&(n?(s.push(`distinct_${i[r]}`),o.push(\"max\")):(s.push(i[r]),o.push(\"distinct\")),a.push(`distinct_${i[r]}`));const{sortField:c,sortIndexField:l}=this[t];if(c){const{op:u=Yr,field:f}=c;s.push(f),o.push(u),a.push(E(c,{forAs:!0}))}else l&&(s.push(l),o.push(\"max\"),a.push(l));return{name:this[t].name,source:n??this.data,transform:[{type:\"aggregate\",groupby:this[t].fields,...s.length?{fields:s,ops:o,as:a}:{}}]}}assembleFacetHeaderData(t){const{columns:n}=this.model.layout,{layoutHeaders:i}=this.model.component,r=[],s={};for(const c of Fa){for(const l of ka){const u=(i[c]&&i[c][l])??[];for(const f of u)if(f.axes?.length>0){s[c]=!0;break}}if(s[c]){const l=`length(data(\"${this.facet.name}\"))`,u=c===\"row\"?n?{signal:`ceil(${l} / ${n})`}:1:n?{signal:`min(${l}, ${n})`}:{signal:l};r.push({name:`${this.facet.name}_${c}`,transform:[{type:\"sequence\",start:0,stop:u}]})}}const{row:o,column:a}=s;return(o||a)&&r.unshift(this.assembleRowColumnHeaderData(\"facet\",null,t)),r}assemble(){const t=[];let n=null;const i=this.getChildIndependentFieldsWithStep(),{column:r,row:s,facet:o}=this;if(r&&s&&(i.x||i.y)){n=`cross_${this.column.name}_${this.row.name}`;const a=[].concat(i.x??[],i.y??[]),c=a.map(()=>\"distinct\");t.push({name:n,source:this.data,transform:[{type:\"aggregate\",groupby:this.fields,fields:a,ops:c}]})}for(const a of[Ft,Nt])this[a]&&t.push(this.assembleRowColumnHeaderData(a,n,i));if(o){const a=this.assembleFacetHeaderData(i);a&&t.push(...a)}return t}}function Zc(e){return e.startsWith(\"'\")&&e.endsWith(\"'\")||e.startsWith('\"')&&e.endsWith('\"')?e.slice(1,-1):e}function kS(e,t){const n=Co(e);if(t===\"number\")return`toNumber(${n})`;if(t===\"boolean\")return`toBoolean(${n})`;if(t===\"string\")return`toString(${n})`;if(t===\"date\")return`toDate(${n})`;if(t===\"flatten\")return n;if(t.startsWith(\"date:\")){const i=Zc(t.slice(5,t.length));return`timeParse(${n},'${i}')`}else if(t.startsWith(\"utc:\")){const i=Zc(t.slice(4,t.length));return`utcParse(${n},'${i}')`}else return S(Kg(t)),null}function TS(e){const t={};return gr(e.filter,n=>{if(Lu(n)){let i=null;jo(n)?i=Le(n.equal):Bo(n)?i=Le(n.lte):Uo(n)?i=Le(n.lt):Wo(n)?i=Le(n.gt):Go(n)?i=Le(n.gte):Ho(n)?i=n.range[0]:qo(n)&&(i=(n.oneOf??n.in)[0]),i&&(In(i)?t[n.field]=\"date\":ie(i)?t[n.field]=\"number\":R(i)&&(t[n.field]=\"string\")),n.timeUnit&&(t[n.field]=\"date\")}}),t}function AS(e){const t={};function n(i){si(i)?t[i.field]=\"date\":i.type===\"quantitative\"&&Fg(i.aggregate)?t[i.field]=\"number\":Qn(i.field)>1?i.field in t||(t[i.field]=\"flatten\"):Pn(i)&&ut(i.sort)&&Qn(i.sort.field)>1&&(i.sort.field in t||(t[i.sort.field]=\"flatten\"))}if((ae(e)||ze(e))&&e.forEachFieldDef((i,r)=>{if(Ce(i))n(i);else{const s=_n(r),o=e.fieldDef(s);n({...i,type:o.type})}}),ae(e)){const{mark:i,markDef:r,encoding:s}=e;if(rn(i)&&!e.encoding.order){const o=r.orient===\"horizontal\"?\"y\":\"x\",a=s[o];v(a)&&a.type===\"quantitative\"&&!(a.field in t)&&(t[a.field]=\"number\")}}return t}function OS(e){const t={};if(ae(e)&&e.component.selection)for(const n of x(e.component.selection)){const i=e.component.selection[n];for(const r of i.project.items)!r.channel&&Qn(r.field)>1&&(t[r.field]=\"flatten\")}return t}class $e extends Y{clone(){return new $e(null,z(this._parse))}constructor(t,n){super(t),this._parse=n}hash(){return`Parse ${W(this._parse)}`}static makeExplicit(t,n,i){let r={};const s=n.data;return!Bt(s)&&s?.format?.parse&&(r=s.format.parse),this.makeWithAncestors(t,r,{},i)}static makeWithAncestors(t,n,i,r){for(const a of x(i)){const c=r.getWithExplicit(a);c.value!==void 0&&(c.explicit||c.value===i[a]||c.value===\"derived\"||i[a]===\"flatten\"?delete i[a]:S(lc(a,i[a],c.value)))}for(const a of x(n)){const c=r.get(a);c!==void 0&&(c===n[a]?delete n[a]:S(lc(a,n[a],c)))}const s=new Dt(n,i);r.copyAll(s);const o={};for(const a of x(s.combine())){const c=s.get(a);c!==null&&(o[a]=c)}return x(o).length===0||r.parseNothing?null:new $e(t,o)}get parse(){return this._parse}merge(t){this._parse={...this._parse,...t.parse},t.remove()}assembleFormatParse(){const t={};for(const n of x(this._parse)){const i=this._parse[n];Qn(n)===1&&(t[n]=i)}return t}producedFields(){return new Set(x(this._parse))}dependentFields(){return new Set(x(this._parse))}assembleTransforms(t=!1){return x(this._parse).filter(n=>t?Qn(n)>1:!0).map(n=>{const i=kS(n,this._parse[n]);return i?{type:\"formula\",expr:i,as:No(n)}:null}).filter(n=>n!==null)}}class Yt extends Y{clone(){return new Yt(null)}constructor(t){super(t)}dependentFields(){return new Set}producedFields(){return new Set([Ze])}hash(){return\"Identifier\"}assemble(){return{type:\"identifier\",as:Ze}}}class tr extends Y{clone(){return new tr(null,this.params)}constructor(t,n){super(t),this.params=n}dependentFields(){return new Set}producedFields(){}hash(){return`Graticule ${W(this.params)}`}assemble(){return{type:\"graticule\",...this.params===!0?{}:this.params}}}class nr extends Y{clone(){return new nr(null,this.params)}constructor(t,n){super(t),this.params=n}dependentFields(){return new Set}producedFields(){return new Set([this.params.as??\"data\"])}hash(){return`Hash ${W(this.params)}`}assemble(){return{type:\"sequence\",...this.params}}}class Tn extends Y{constructor(t){super(null),t??(t={name:\"source\"});let n;if(Bt(t)||(n=t.format?{...ke(t.format,[\"parse\"])}:{}),Di(t))this._data={values:t.values};else if(oi(t)){if(this._data={url:t.url},!n.type){let i=/(?:\\.([^.]+))?$/.exec(t.url)[1];G([\"json\",\"csv\",\"tsv\",\"dsv\",\"topojson\"],i)||(i=\"json\"),n.type=i}}else Jf(t)?this._data={values:[{type:\"Sphere\"}]}:(Yf(t)||Bt(t))&&(this._data={});this._generator=Bt(t),t.name&&(this._name=t.name),n&&!K(n)&&(this._data.format=n)}dependentFields(){return new Set}producedFields(){}get data(){return this._data}hasName(){return!!this._name}get isGenerator(){return this._generator}get dataName(){return this._name}set dataName(t){this._name=t}set parent(t){throw new Error(\"Source nodes have to be roots.\")}remove(){throw new Error(\"Source nodes are roots and cannot be removed.\")}hash(){throw new Error(\"Cannot hash sources\")}assemble(){return{name:this._name,...this._data,transform:[]}}}var el=function(e,t,n,i,r){if(i===\"m\")throw new TypeError(\"Private method is not writable\");if(i===\"a\"&&!r)throw new TypeError(\"Private accessor was defined without a setter\");if(typeof t==\"function\"?e!==t||!r:!t.has(e))throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");return i===\"a\"?r.call(e,n):r?r.value=n:t.set(e,n),n},_S=function(e,t,n,i){if(n===\"a\"&&!i)throw new TypeError(\"Private accessor was defined without a getter\");if(typeof t==\"function\"?e!==t||!i:!t.has(e))throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");return n===\"m\"?i:n===\"a\"?i.call(e):i?i.value:t.get(e)},Ti;function _a(e){return e instanceof Tn||e instanceof tr||e instanceof nr}class Ra{constructor(){Ti.set(this,void 0),el(this,Ti,!1,\"f\")}setModified(){el(this,Ti,!0,\"f\")}get modifiedFlag(){return _S(this,Ti,\"f\")}}Ti=new WeakMap;class zn extends Ra{getNodeDepths(t,n,i){i.set(t,n);for(const r of t.children)this.getNodeDepths(r,n+1,i);return i}optimize(t){const i=[...this.getNodeDepths(t,0,new Map).entries()].sort((r,s)=>s[1]-r[1]);for(const r of i)this.run(r[0]);return this.modifiedFlag}}class Ia extends Ra{optimize(t){this.run(t);for(const n of t.children)this.optimize(n);return this.modifiedFlag}}class RS extends Ia{mergeNodes(t,n){const i=n.shift();for(const r of n)t.removeChild(r),r.parent=i,r.remove()}run(t){const n=t.children.map(r=>r.hash()),i={};for(let r=0;r1&&(this.setModified(),this.mergeNodes(t,i[r]))}}class IS extends Ia{constructor(t){super(),this.requiresSelectionId=t&&Na(t)}run(t){t instanceof Yt&&(this.requiresSelectionId&&(_a(t.parent)||t.parent instanceof Je||t.parent instanceof $e)||(this.setModified(),t.remove()))}}class LS extends Ra{optimize(t){return this.run(t,new Set),this.modifiedFlag}run(t,n){let i=new Set;t instanceof ft&&(i=t.producedFields(),$o(i,n)&&(this.setModified(),t.removeFormulas(n),t.producedFields.length===0&&t.remove()));for(const r of t.children)this.run(r,new Set([...n,...i]))}}class PS extends Ia{constructor(){super()}run(t){t instanceof we&&!t.isRequired()&&(this.setModified(),t.remove())}}class zS extends zn{run(t){if(!_a(t)&&!(t.numChildren()>1)){for(const n of t.children)if(n instanceof $e)if(t instanceof $e)this.setModified(),t.merge(n);else{if(wo(t.producedFields(),n.dependentFields()))continue;this.setModified(),n.swapWithParent()}}}}class DS extends zn{run(t){const n=[...t.children],i=t.children.filter(r=>r instanceof $e);if(t.numChildren()>1&&i.length>=1){const r={},s=new Set;for(const o of i){const a=o.parse;for(const c of x(a))c in r?r[c]!==a[c]&&s.add(c):r[c]=a[c]}for(const o of s)delete r[o];if(!K(r)){this.setModified();const o=new $e(t,r);for(const a of n){if(a instanceof $e)for(const c of x(r))delete a.parse[c];t.removeChild(a),a.parent=o,a instanceof $e&&x(a.parse).length===0&&a.remove()}}}}}class MS extends zn{run(t){t instanceof we||t.numChildren()>0||t instanceof bi||t instanceof Tn||(this.setModified(),t.remove())}}class jS extends zn{run(t){const n=t.children.filter(r=>r instanceof ft),i=n.pop();for(const r of n)this.setModified(),i.merge(r)}}class US extends zn{run(t){const n=t.children.filter(r=>r instanceof Je),i={};for(const r of n){const s=W(r.groupBy);s in i||(i[s]=[]),i[s].push(r)}for(const r of x(i)){const s=i[r];if(s.length>1){const o=s.pop();for(const a of s)o.merge(a)&&(t.removeChild(a),a.parent=o,a.remove(),this.setModified())}}}}class BS extends zn{constructor(t){super(),this.model=t}run(t){const n=!(_a(t)||t instanceof yi||t instanceof $e||t instanceof Yt),i=[],r=[];for(const s of t.children)s instanceof dt&&(n&&!wo(t.producedFields(),s.dependentFields())?i.push(s):r.push(s));if(i.length>0){const s=i.pop();for(const o of i)s.merge(o,this.model.renameSignal.bind(this.model));this.setModified(),t instanceof dt?t.merge(s,this.model.renameSignal.bind(this.model)):s.swapWithParent()}if(r.length>1){const s=r.pop();for(const o of r)s.merge(o,this.model.renameSignal.bind(this.model));this.setModified()}}}class WS extends zn{run(t){const n=[...t.children];if(!Sn(n,o=>o instanceof we)||t.numChildren()<=1)return;const r=[];let s;for(const o of n)if(o instanceof we){let a=o;for(;a.numChildren()===1;){const[c]=a.children;if(c instanceof we)a=c;else break}r.push(...a.children),s?(t.removeChild(o),o.parent=s.parent,s.parent.removeChild(s),s.parent=a,this.setModified()):s=a}else r.push(o);if(r.length){this.setModified();for(const o of r)o.parent.removeChild(o),o.parent=s}}}class Dn extends Y{clone(){return new Dn(null,z(this.transform))}constructor(t,n){super(t),this.transform=n}addDimensions(t){this.transform.groupby=lt(this.transform.groupby.concat(t),n=>n)}dependentFields(){const t=new Set;return this.transform.groupby&&this.transform.groupby.forEach(t.add,t),this.transform.joinaggregate.map(n=>n.field).filter(n=>n!==void 0).forEach(t.add,t),t}producedFields(){return new Set(this.transform.joinaggregate.map(this.getDefaultName))}getDefaultName(t){return t.as??E(t)}hash(){return`JoinAggregateTransform ${W(this.transform)}`}assemble(){const t=[],n=[],i=[];for(const s of this.transform.joinaggregate)n.push(s.op),i.push(this.getDefaultName(s)),t.push(s.field===void 0?null:s.field);const r=this.transform.groupby;return{type:\"joinaggregate\",as:i,ops:n,fields:t,...r!==void 0?{groupby:r}:{}}}}function GS(e){return e.stack.stackBy.reduce((t,n)=>{const i=n.fieldDef,r=E(i);return r&&t.push(r),t},[])}function HS(e){return F(e)&&e.every(t=>R(t))&&e.length>1}class Tt extends Y{clone(){return new Tt(null,z(this._stack))}constructor(t,n){super(t),this._stack=n}static makeFromTransform(t,n){const{stack:i,groupby:r,as:s,offset:o=\"zero\"}=n,a=[],c=[];if(n.sort!==void 0)for(const f of n.sort)a.push(f.field),c.push(le(f.order,\"ascending\"));const l={field:a,order:c};let u;return HS(s)?u=s:R(s)?u=[s,`${s}_end`]:u=[`${n.stack}_start`,`${n.stack}_end`],new Tt(t,{dimensionFieldDefs:[],stackField:i,groupby:r,offset:o,sort:l,facetby:[],as:u})}static makeFromEncoding(t,n){const i=n.stack,{encoding:r}=n;if(!i)return null;const{groupbyChannels:s,fieldChannel:o,offset:a,impute:c}=i,l=s.map(g=>{const p=r[g];return gt(p)}).filter(g=>!!g),u=GS(n),f=n.encoding.order;let d;if(F(f)||v(f))d=hu(f);else{const g=sf(f)?f.sort:o===\"y\"?\"descending\":\"ascending\";d=u.reduce((p,h)=>(p.field.includes(h)||(p.field.push(h),p.order.push(g)),p),{field:[],order:[]})}return new Tt(t,{dimensionFieldDefs:l,stackField:n.vgField(o),facetby:[],stackby:u,sort:d,offset:a,impute:c,as:[n.vgField(o,{suffix:\"start\",forAs:!0}),n.vgField(o,{suffix:\"end\",forAs:!0})]})}get stack(){return this._stack}addDimensions(t){this._stack.facetby.push(...t)}dependentFields(){const t=new Set;return t.add(this._stack.stackField),this.getGroupbyFields().forEach(t.add,t),this._stack.facetby.forEach(t.add,t),this._stack.sort.field.forEach(t.add,t),t}producedFields(){return new Set(this._stack.as)}hash(){return`Stack ${W(this._stack)}`}getGroupbyFields(){const{dimensionFieldDefs:t,impute:n,groupby:i}=this._stack;return t.length>0?t.map(r=>r.bin?n?[E(r,{binSuffix:\"mid\"})]:[E(r,{}),E(r,{binSuffix:\"end\"})]:[E(r)]).flat():i??[]}assemble(){const t=[],{facetby:n,dimensionFieldDefs:i,stackField:r,stackby:s,sort:o,offset:a,impute:c,as:l}=this._stack;if(c)for(const u of i){const{bandPosition:f=.5,bin:d}=u;if(d){const g=E(u,{expr:\"datum\"}),p=E(u,{expr:\"datum\",binSuffix:\"end\"});t.push({type:\"formula\",expr:`${f}*${g}+${1-f}*${p}`,as:E(u,{binSuffix:\"mid\",forAs:!0})})}t.push({type:\"impute\",field:r,groupby:[...s,...n],key:E(u,{binSuffix:\"mid\"}),method:\"value\",value:0})}return t.push({type:\"stack\",groupby:[...this.getGroupbyFields(),...n],field:r,sort:o,as:l,offset:a}),t}}class xi extends Y{clone(){return new xi(null,z(this.transform))}constructor(t,n){super(t),this.transform=n}addDimensions(t){this.transform.groupby=lt(this.transform.groupby.concat(t),n=>n)}dependentFields(){const t=new Set;return(this.transform.groupby??[]).forEach(t.add,t),(this.transform.sort??[]).forEach(n=>t.add(n.field)),this.transform.window.map(n=>n.field).filter(n=>n!==void 0).forEach(t.add,t),t}producedFields(){return new Set(this.transform.window.map(this.getDefaultName))}getDefaultName(t){return t.as??E(t)}hash(){return`WindowTransform ${W(this.transform)}`}assemble(){const t=[],n=[],i=[],r=[];for(const f of this.transform.window)n.push(f.op),i.push(this.getDefaultName(f)),r.push(f.param===void 0?null:f.param),t.push(f.field===void 0?null:f.field);const s=this.transform.frame,o=this.transform.groupby;if(s&&s[0]===null&&s[1]===null&&n.every(f=>Io(f)))return{type:\"joinaggregate\",as:i,ops:n,fields:t,...o!==void 0?{groupby:o}:{}};const a=[],c=[];if(this.transform.sort!==void 0)for(const f of this.transform.sort)a.push(f.field),c.push(f.order??\"ascending\");const l={field:a,order:c},u=this.transform.ignorePeers;return{type:\"window\",params:r,as:i,ops:n,fields:t,sort:l,...u!==void 0?{ignorePeers:u}:{},...o!==void 0?{groupby:o}:{},...s!==void 0?{frame:s}:{}}}}function qS(e){function t(n){if(!(n instanceof bi)){const i=n.clone();if(i instanceof we){const r=po+i.getSource();i.setSource(r),e.model.component.data.outputNodes[r]=i}else(i instanceof Je||i instanceof Tt||i instanceof xi||i instanceof Dn)&&i.addDimensions(e.fields);for(const r of n.children.flatMap(t))r.parent=i;return[i]}return n.children.flatMap(t)}return t}function fo(e){if(e instanceof bi)if(e.numChildren()===1&&!(e.children[0]instanceof we)){const t=e.children[0];(t instanceof Je||t instanceof Tt||t instanceof xi||t instanceof Dn)&&t.addDimensions(e.fields),t.swapWithParent(),fo(e)}else{const t=e.model.component.data.main;Gd(t);const n=qS(e),i=e.children.map(n).flat();for(const r of i)r.parent=t}else e.children.map(fo)}function Gd(e){if(e instanceof we&&e.type===Z.Main&&e.numChildren()===1){const t=e.children[0];t instanceof bi||(t.swapWithParent(),Gd(e))}}const po=\"scale_\",ar=5;function go(e){for(const t of e){for(const n of t.children)if(n.parent!==t)return!1;if(!go(t.children))return!1}return!0}function He(e,t){let n=!1;for(const i of t)n=e.optimize(i)||n;return n}function tl(e,t,n){let i=e.sources,r=!1;return r=He(new PS,i)||r,r=He(new IS(t),i)||r,i=i.filter(s=>s.numChildren()>0),r=He(new MS,i)||r,i=i.filter(s=>s.numChildren()>0),n||(r=He(new zS,i)||r,r=He(new BS(t),i)||r,r=He(new LS,i)||r,r=He(new DS,i)||r,r=He(new US,i)||r,r=He(new jS,i)||r,r=He(new RS,i)||r,r=He(new WS,i)||r),e.sources=i,r}function VS(e,t){go(e.sources);let n=0,i=0;for(let r=0;rt(n))}}function Hd(e){ae(e)?XS(e):YS(e)}function XS(e){const t=e.component.scales;for(const n of x(t)){const i=JS(e,n);if(t[n].setWithExplicit(\"domains\",i),ZS(e,n),e.component.data.isFaceted){let s=e;for(;!ze(s)&&s.parent;)s=s.parent;if(s.component.resolve.scale[n]===\"shared\")for(const a of i.value)Ct(a)&&(a.data=po+a.data.replace(po,\"\"))}}}function YS(e){for(const n of e.children)Hd(n);const t=e.component.scales;for(const n of x(t)){let i,r=null;for(const s of e.children){const o=s.component.scales[n];if(o){i===void 0?i=o.getWithExplicit(\"domains\"):i=qt(i,o.getWithExplicit(\"domains\"),\"domains\",\"scale\",ho);const a=o.get(\"selectionExtent\");r&&a&&r.param!==a.param&&S(qg),r=a}}t[n].setWithExplicit(\"domains\",i),r&&t[n].set(\"selectionExtent\",r,!0)}}function KS(e,t,n,i){if(e===\"unaggregated\"){const{valid:r,reason:s}=nl(t,n);if(!r){S(s);return}}else if(e===void 0&&i.useUnaggregatedDomain){const{valid:r}=nl(t,n);if(r)return\"unaggregated\"}return e}function JS(e,t){const n=e.getScaleComponent(t).get(\"type\"),{encoding:i}=e,r=KS(e.scaleDomain(t),e.typedFieldDef(t),n,e.config.scale);return r!==e.scaleDomain(t)&&(e.specifiedScales[t]={...e.specifiedScales[t],domain:r}),t===\"x\"&&fe(i.x2)?fe(i.x)?qt(Mt(n,r,e,\"x\"),Mt(n,r,e,\"x2\"),\"domain\",\"scale\",ho):Mt(n,r,e,\"x2\"):t===\"y\"&&fe(i.y2)?fe(i.y)?qt(Mt(n,r,e,\"y\"),Mt(n,r,e,\"y2\"),\"domain\",\"scale\",ho):Mt(n,r,e,\"y2\"):Mt(n,r,e,t)}function QS(e,t,n){return e.map(i=>({signal:`{data: ${es(i,{timeUnit:n,type:t})}}`}))}function Ls(e,t,n){const i=me(n)?.unit;return t===\"temporal\"||i?QS(e,t,i):[e]}function Mt(e,t,n,i){const{encoding:r,markDef:s,mark:o,config:a,stack:c}=n,l=fe(r[i]),{type:u}=l,f=l.timeUnit;if(hm(t)){const p=Mt(e,void 0,n,i),h=Ls(t.unionWith,u,f);return ct([...h,...p.value])}else{if(T(t))return ct([t]);if(t&&t!==\"unaggregated\"&&!Bu(t))return ct(Ls(t,u,f))}if(c&&i===c.fieldChannel){if(c.offset===\"normalize\")return Ie([[0,1]]);const p=n.requestDataName(Z.Main);return Ie([{data:p,field:n.vgField(i,{suffix:\"start\"})},{data:p,field:n.vgField(i,{suffix:\"end\"})}])}const d=Pt(i)&&v(l)?ev(n,i,e):void 0;if(vt(l)){const p=Ls([l.datum],u,f);return Ie(p)}const g=l;if(t===\"unaggregated\"){const p=n.requestDataName(Z.Main),{field:h}=l;return Ie([{data:p,field:E({field:h,aggregate:\"min\"})},{data:p,field:E({field:h,aggregate:\"max\"})}])}else if(ee(g.bin)){if(ye(e))return Ie(e===\"bin-ordinal\"?[]:[{data:Li(d)?n.requestDataName(Z.Main):n.requestDataName(Z.Raw),field:n.vgField(i,Qi(g,i)?{binSuffix:\"range\"}:{}),sort:d===!0||!H(d)?{field:n.vgField(i,{}),op:\"min\"}:d}]);{const{bin:p}=g;if(ee(p)){const h=Oa(n,g.field,p);return Ie([new ge(()=>{const m=n.getSignalName(h);return`[${m}.start, ${m}.stop]`})])}else return Ie([{data:n.requestDataName(Z.Main),field:n.vgField(i,{})}])}}else if(g.timeUnit&&G([\"time\",\"utc\"],e)){const p=r[xt(i)];if(rf(g,p,s,a)){const h=n.requestDataName(Z.Main),m=Ht({fieldDef:g,fieldDef2:p,markDef:s,config:a}),y=zi(o)&&m!==.5&&ue(i);return Ie([{data:h,field:n.vgField(i,y?{suffix:os}:{})},{data:h,field:n.vgField(i,{suffix:y?as:\"end\"})}])}}return Ie(d?[{data:Li(d)?n.requestDataName(Z.Main):n.requestDataName(Z.Raw),field:n.vgField(i),sort:d}]:[{data:n.requestDataName(Z.Main),field:n.vgField(i)}])}function Ps(e,t){const{op:n,field:i,order:r}=e;return{op:n??(t?\"sum\":Yr),...i?{field:Ue(i)}:{},...r?{order:r}:{}}}function ZS(e,t){const n=e.component.scales[t],i=e.specifiedScales[t].domain,r=e.fieldDef(t)?.bin,s=Bu(i)&&i,o=Rn(r)&&Br(r.extent)&&r.extent;(s||o)&&n.set(\"selectionExtent\",s??o,!0)}function ev(e,t,n){if(!ye(n))return;const i=e.fieldDef(t),r=i.sort;if(tf(r))return{op:\"min\",field:li(i,t),order:\"ascending\"};const{stack:s}=e,o=s?new Set([...s.groupbyFields,...s.stackBy.map(a=>a.fieldDef.field)]):void 0;if(ut(r)){const a=s&&!o.has(r.field);return Ps(r,a)}else if(ef(r)){const{encoding:a,order:c}=r,l=e.fieldDef(a),{aggregate:u,field:f}=l,d=s&&!o.has(f);if(At(u)||tn(u))return Ps({field:E(l),order:c},d);if(Io(u)||!u)return Ps({op:u,field:f,order:c},d)}else{if(r===\"descending\")return{op:\"min\",field:e.vgField(t),order:\"descending\"};if(G([\"ascending\",void 0],r))return!0}}function nl(e,t){const{aggregate:n,type:i}=e;return n?R(n)&&!Tg.has(n)?{valid:!1,reason:bh(n)}:i===\"quantitative\"&&t===\"log\"?{valid:!1,reason:xh(e)}:{valid:!0}:{valid:!1,reason:yh(e)}}function ho(e,t,n,i){return e.explicit&&t.explicit&&S(wh(n,i,e.value,t.value)),{explicit:e.explicit,value:[...e.value,...t.value]}}function tv(e){const t=lt(e.map(o=>{if(Ct(o)){const{sort:a,...c}=o;return c}return o}),W),n=lt(e.map(o=>{if(Ct(o)){const a=o.sort;return a!==void 0&&!Li(a)&&(\"op\"in a&&a.op===\"count\"&&delete a.field,a.order===\"ascending\"&&delete a.order),a}}).filter(o=>o!==void 0),W);if(t.length===0)return;if(t.length===1){const o=e[0];if(Ct(o)&&n.length>0){let a=n[0];if(n.length>1){S(fc);const c=n.filter(l=>H(l)&&\"op\"in l&&l.op!==\"min\");n.every(l=>H(l)&&\"op\"in l)&&c.length===1?a=c[0]:a=!0}else if(H(a)&&\"field\"in a){const c=a.field;o.field===c&&(a=a.order?{order:a.order}:!0)}return{...o,sort:a}}return o}const i=lt(n.map(o=>Li(o)||!(\"op\"in o)||R(o.op)&&o.op in Cg?o:(S(Nh(o)),!0)),W);let r;i.length===1?r=i[0]:i.length>1&&(S(fc),r=!0);const s=lt(e.map(o=>Ct(o)?o.data:null),o=>o);return s.length===1&&s[0]!==null?{data:s[0],fields:t.map(a=>a.field),...r?{sort:r}:{}}:{fields:t,...r?{sort:r}:{}}}function La(e){if(Ct(e)&&R(e.field))return e.field;if(Ag(e)){let t;for(const n of e.fields)if(Ct(n)&&R(n.field)){if(!t)t=n.field;else if(t!==n.field)return S(Fh),t}return S(kh),t}else if(Og(e)){S(Th);const t=e.fields[0];return R(t)?t:void 0}}function ds(e,t){const i=e.component.scales[t].get(\"domains\").map(r=>(Ct(r)&&(r.data=e.lookupDataSource(r.data)),r));return tv(i)}function qd(e){return Si(e)||Pa(e)?e.children.reduce((t,n)=>t.concat(qd(n)),il(e)):il(e)}function il(e){return x(e.component.scales).reduce((t,n)=>{const i=e.component.scales[n];if(i.merged)return t;const r=i.combine(),{name:s,type:o,selectionExtent:a,domains:c,range:l,reverse:u,...f}=r,d=nv(r.range,s,n,e),g=ds(e,n),p=a?Kb(e,a,i,g):null;return t.push({name:s,type:o,...g?{domain:g}:{},...p?{domainRaw:p}:{},range:d,...u!==void 0?{reverse:u}:{},...f}),t},[])}function nv(e,t,n,i){if(ue(n)){if(nn(e))return{step:{signal:`${t}_step`}}}else if(H(e)&&Ct(e))return{...e,data:i.lookupDataSource(e.data)};return e}class Vd extends Dt{constructor(t,n){super({},{name:t}),this.merged=!1,this.setWithExplicit(\"type\",n)}domainDefinitelyIncludesZero(){return this.get(\"zero\")!==!1?!0:Sn(this.get(\"domains\"),t=>F(t)&&t.length===2&&ie(t[0])&&t[0]<=0&&ie(t[1])&&t[1]>=0)}}const iv=[\"range\",\"scheme\"];function rv(e){const t=e.component.scales;for(const n of Ur){const i=t[n];if(!i)continue;const r=sv(n,e);i.setWithExplicit(\"range\",r)}}function rl(e,t){const n=e.fieldDef(t);if(n?.bin){const{bin:i,field:r}=n,s=_e(t),o=e.getName(s);if(H(i)&&i.binned&&i.step!==void 0)return new ge(()=>{const a=e.scaleName(t),c=`(domain(\"${a}\")[1] - domain(\"${a}\")[0]) / ${i.step}`;return`${e.getSignalName(o)} / (${c})`});if(ee(i)){const a=Oa(e,r,i);return new ge(()=>{const c=e.getSignalName(a),l=`(${c}.stop - ${c}.start) / ${c}.step`;return`${e.getSignalName(o)} / (${l})`})}}}function sv(e,t){const n=t.specifiedScales[e],{size:i}=t,s=t.getScaleComponent(e).get(\"type\");for(const f of iv)if(n[f]!==void 0){const d=Qs(s,f),g=Wu(e,f);if(!d)S(Eu(s,f,e));else if(g)S(g);else switch(f){case\"range\":{const p=n.range;if(F(p)){if(ue(e))return ct(p.map(h=>{if(h===\"width\"||h===\"height\"){const m=t.getName(h),y=t.getSignalName.bind(t);return ge.fromName(y,m)}return h}))}else if(H(p))return ct({data:t.requestDataName(Z.Main),field:p.field,sort:{op:\"min\",field:t.vgField(e)}});return ct(p)}case\"scheme\":return ct(ov(n[f]))}}const o=e===se||e===\"xOffset\"?\"width\":\"height\",a=i[o];if(ht(a)){if(ue(e))if(ye(s)){const f=Yd(a,t,e);if(f)return ct({step:f})}else S($u(o));else if(qi(e)){const f=e===Kt?\"x\":\"y\";if(t.getScaleComponent(f).get(\"type\")===\"band\"){const p=Kd(a,s);if(p)return ct(p)}}}const{rangeMin:c,rangeMax:l}=n,u=av(e,t);return(c!==void 0||l!==void 0)&&Qs(s,\"rangeMin\")&&F(u)&&u.length===2?ct([c??u[0],l??u[1]]):Ie(u)}function ov(e){return gm(e)?{scheme:e.name,...ke(e,[\"name\"])}:{scheme:e}}function Xd(e,t,n,{center:i}={}){const r=_e(e),s=t.getName(r),o=t.getSignalName.bind(t);return e===be&&De(n)?i?[ge.fromName(a=>`${o(a)}/2`,s),ge.fromName(a=>`-${o(a)}/2`,s)]:[ge.fromName(o,s),0]:i?[ge.fromName(a=>`-${o(a)}/2`,s),ge.fromName(a=>`${o(a)}/2`,s)]:[0,ge.fromName(o,s)]}function av(e,t){const{size:n,config:i,mark:r,encoding:s}=t,{type:o}=fe(s[e]),c=t.getScaleComponent(e).get(\"type\"),{domain:l,domainMid:u}=t.specifiedScales[e];switch(e){case se:case be:{if(G([\"point\",\"band\"],c)){const f=Jd(e,n,i.view);if(ht(f))return{step:Yd(f,t,e)}}return Xd(e,t,c)}case Kt:case gi:return cv(e,t,c);case It:{const f=t.component.scales[e].get(\"zero\"),d=Qd(r,f,i),g=fv(r,n,t,i);return ni(c)?uv(d,g,lv(c,i,l,e)):[d,g]}case We:return[0,Math.PI*2];case On:return[0,360];case tt:return[0,new ge(()=>{const f=t.getSignalName(ze(t.parent)?\"child_width\":\"width\"),d=t.getSignalName(ze(t.parent)?\"child_height\":\"height\");return`min(${f},${d})/2`})];case Zt:return[i.scale.minStrokeWidth,i.scale.maxStrokeWidth];case en:return[[1,0],[4,2],[2,1],[1,1],[1,2,4,2]];case Oe:return\"symbol\";case Ae:case yt:case bt:return c===\"ordinal\"?o===\"nominal\"?\"category\":\"ordinal\":u!==void 0?\"diverging\":r===\"rect\"||r===\"geoshape\"?\"heatmap\":\"ramp\";case Lt:case Jt:case Qt:return[i.scale.minOpacity,i.scale.maxOpacity]}}function Yd(e,t,n){const{encoding:i}=t,r=t.getScaleComponent(n),s=Ao(n),o=i[s];if(Lf({step:e,offsetIsDiscrete:D(o)&&zu(o.type)})===\"offset\"&&mf(i,s)){const c=t.getScaleComponent(s);let u=`domain('${t.scaleName(s)}').length`;if(c.get(\"type\")===\"band\"){const d=c.get(\"paddingInner\")??c.get(\"padding\")??0,g=c.get(\"paddingOuter\")??c.get(\"padding\")??0;u=`bandspace(${u}, ${d}, ${g})`}const f=r.get(\"paddingInner\")??r.get(\"padding\");return{signal:`${e.step} * ${u} / (1-${Lg(f)})`}}else return e.step}function Kd(e,t){if(Lf({step:e,offsetIsDiscrete:ye(t)})===\"offset\")return{step:e.step}}function cv(e,t,n){const i=e===Kt?\"x\":\"y\",r=t.getScaleComponent(i);if(!r)return Xd(i,t,n,{center:!0});const s=r.get(\"type\"),o=t.scaleName(i),{markDef:a,config:c}=t;if(s===\"band\"){const l=Jd(i,t.size,t.config.view);if(ht(l)){const u=Kd(l,n);if(u)return u}return[0,{signal:`bandwidth('${o}')`}]}else{const l=t.encoding[i];if(v(l)&&l.timeUnit){const u=Ru(l.timeUnit,p=>`scale('${o}', ${p})`),f=t.config.scale.bandWithNestedOffsetPaddingInner,d=Ht({fieldDef:l,markDef:a,config:c})-.5,g=d!==0?` + ${d}`:\"\";if(f){const p=T(f)?`${f.signal}/2`+g:`${f/2+d}`,h=T(f)?`(1 - ${f.signal}/2)`+g:`${1-f/2+d}`;return[{signal:`${p} * (${u})`},{signal:`${h} * (${u})`}]}return[0,{signal:u}]}return Wl(`Cannot use ${e} scale if ${i} scale is not discrete.`)}}function Jd(e,t,n){const i=e===se?\"width\":\"height\",r=t[i];return r||Nr(n,i)}function lv(e,t,n,i){switch(e){case\"quantile\":return t.scale.quantileCount;case\"quantize\":return t.scale.quantizeCount;case\"threshold\":return n!==void 0&&F(n)?n.length+1:(S(Dh(i)),3)}}function uv(e,t,n){const i=()=>{const r=Xe(t),s=Xe(e),o=`(${r} - ${s}) / (${n} - 1)`;return`sequence(${s}, ${r} + ${o}, ${o})`};return T(t)?new ge(i):{signal:i()}}function Qd(e,t,n){if(t)return T(t)?{signal:`${t.signal} ? 0 : ${Qd(e,!1,n)}`}:0;switch(e){case\"bar\":case\"tick\":return n.scale.minBandSize;case\"line\":case\"trail\":case\"rule\":return n.scale.minStrokeWidth;case\"text\":return n.scale.minFontSize;case\"point\":case\"square\":case\"circle\":return n.scale.minSize}throw new Error(Wr(\"size\",e))}const sl=.95;function fv(e,t,n,i){const r={x:rl(n,\"x\"),y:rl(n,\"y\")};switch(e){case\"bar\":case\"tick\":{if(i.scale.maxBandSize!==void 0)return i.scale.maxBandSize;const s=ol(t,r,i.view);return ie(s)?s-1:new ge(()=>`${s.signal} - 1`)}case\"line\":case\"trail\":case\"rule\":return i.scale.maxStrokeWidth;case\"text\":return i.scale.maxFontSize;case\"point\":case\"square\":case\"circle\":{if(i.scale.maxSize)return i.scale.maxSize;const s=ol(t,r,i.view);return ie(s)?Math.pow(sl*s,2):new ge(()=>`pow(${sl} * ${s.signal}, 2)`)}}throw new Error(Wr(\"size\",e))}function ol(e,t,n){const i=ht(e.width)?e.width.step:Cr(n,\"width\"),r=ht(e.height)?e.height.step:Cr(n,\"height\");return t.x||t.y?new ge(()=>`min(${[t.x?t.x.signal:i,t.y?t.y.signal:r].join(\", \")})`):Math.min(i,r)}function Zd(e,t){ae(e)?dv(e,t):tp(e,t)}function dv(e,t){const n=e.component.scales,{config:i,encoding:r,markDef:s,specifiedScales:o}=e;for(const a of x(n)){const c=o[a],l=n[a],u=e.getScaleComponent(a),f=fe(r[a]),d=c[t],g=u.get(\"type\"),p=u.get(\"padding\"),h=u.get(\"paddingInner\"),m=Qs(g,t),y=Wu(a,t);if(d!==void 0&&(m?y&&S(y):S(Eu(g,t,a))),m&&y===void 0)if(d!==void 0){const b=f.timeUnit,C=f.type;switch(t){case\"domainMax\":case\"domainMin\":In(c[t])||C===\"temporal\"||b?l.set(t,{signal:es(c[t],{type:C,timeUnit:b})},!0):l.set(t,c[t],!0);break;default:l.copyKeyFromObject(t,c)}}else{const b=t in al?al[t]({model:e,channel:a,fieldOrDatumDef:f,scaleType:g,scalePadding:p,scalePaddingInner:h,domain:c.domain,domainMin:c.domainMin,domainMax:c.domainMax,markDef:s,config:i,hasNestedOffsetScale:yf(r,a),hasSecondaryRangeChannel:!!r[xt(a)]}):i.scale[t];b!==void 0&&l.set(t,b,!1)}}}const al={bins:({model:e,fieldOrDatumDef:t})=>v(t)?pv(e,t):void 0,interpolate:({channel:e,fieldOrDatumDef:t})=>gv(e,t.type),nice:({scaleType:e,channel:t,domain:n,domainMin:i,domainMax:r,fieldOrDatumDef:s})=>hv(e,t,n,i,r,s),padding:({channel:e,scaleType:t,fieldOrDatumDef:n,markDef:i,config:r})=>mv(e,t,r.scale,n,i,r.bar),paddingInner:({scalePadding:e,channel:t,markDef:n,scaleType:i,config:r,hasNestedOffsetScale:s})=>yv(e,t,n.type,i,r.scale,s),paddingOuter:({scalePadding:e,channel:t,scaleType:n,scalePaddingInner:i,config:r,hasNestedOffsetScale:s})=>bv(e,t,n,i,r.scale,s),reverse:({fieldOrDatumDef:e,scaleType:t,channel:n,config:i})=>{const r=v(e)?e.sort:void 0;return xv(t,r,n,i.scale)},zero:({channel:e,fieldOrDatumDef:t,domain:n,markDef:i,scaleType:r,config:s,hasSecondaryRangeChannel:o})=>Sv(e,t,n,i,r,s.scale,o)};function ep(e){ae(e)?rv(e):tp(e,\"range\")}function tp(e,t){const n=e.component.scales;for(const i of e.children)t===\"range\"?ep(i):Zd(i,t);for(const i of x(n)){let r;for(const s of e.children){const o=s.component.scales[i];if(o){const a=o.getWithExplicit(t);r=qt(r,a,t,\"scale\",Xf((c,l)=>{switch(t){case\"range\":return c.step&&l.step?c.step-l.step:0}return 0}))}}n[i].setWithExplicit(t,r)}}function pv(e,t){const n=t.bin;if(ee(n)){const i=Oa(e,t.field,n);return new ge(()=>e.getSignalName(i))}else if(xe(n)&&Rn(n)&&n.step!==void 0)return{step:n.step}}function gv(e,t){if(G([Ae,yt,bt],e)&&t!==\"nominal\")return\"hcl\"}function hv(e,t,n,i,r,s){if(!(gt(s)?.bin||F(n)||r!=null||i!=null||G([Te.TIME,Te.UTC],e)))return ue(t)?!0:void 0}function mv(e,t,n,i,r,s){if(ue(e)){if(Ye(t)){if(n.continuousPadding!==void 0)return n.continuousPadding;const{type:o,orient:a}=r;if(o===\"bar\"&&!(v(i)&&(i.bin||i.timeUnit))&&(a===\"vertical\"&&e===\"x\"||a===\"horizontal\"&&e===\"y\"))return s.continuousBandSize}if(t===Te.POINT)return n.pointPadding}}function yv(e,t,n,i,r,s=!1){if(e===void 0){if(ue(t)){const{bandPaddingInner:o,barBandPaddingInner:a,rectBandPaddingInner:c,bandWithNestedOffsetPaddingInner:l}=r;return s?l:le(o,n===\"bar\"?a:c)}else if(qi(t)&&i===Te.BAND)return r.offsetBandPaddingInner}}function bv(e,t,n,i,r,s=!1){if(e===void 0){if(ue(t)){const{bandPaddingOuter:o,bandWithNestedOffsetPaddingOuter:a}=r;if(s)return a;if(n===Te.BAND)return le(o,T(i)?{signal:`${i.signal}/2`}:i/2)}else if(qi(t)){if(n===Te.POINT)return .5;if(n===Te.BAND)return r.offsetBandPaddingOuter}}}function xv(e,t,n,i){if(n===\"x\"&&i.xReverse!==void 0)return De(e)&&t===\"descending\"?T(i.xReverse)?{signal:`!${i.xReverse.signal}`}:!i.xReverse:i.xReverse;if(De(e)&&t===\"descending\")return!0}function Sv(e,t,n,i,r,s,o){if(!!n&&n!==\"unaggregated\"&&De(r)){if(F(n)){const c=n[0],l=n[n.length-1];if(ie(c)&&c<=0&&ie(l)&&l>=0)return!0}return!1}if(e===\"size\"&&t.type===\"quantitative\"&&!ni(r))return!0;if(!(v(t)&&t.bin)&&G([...St,...yg],e)){const{orient:c,type:l}=i;return G([\"bar\",\"area\",\"line\",\"trail\"],l)&&(c===\"horizontal\"&&e===\"y\"||c===\"vertical\"&&e===\"x\")?!1:G([\"bar\",\"area\"],l)&&!o?!0:s?.zero}return!1}function vv(e,t,n,i,r=!1){const s=Ev(t,n,i,r),{type:o}=e;return Pt(t)?o!==void 0?vm(t,o)?v(n)&&!Sm(o,n.type)?(S(Eh(o,s)),s):o:(S(vh(t,o,s)),s):s:null}function Ev(e,t,n,i){switch(t.type){case\"nominal\":case\"ordinal\":{if(qn(e)||Fs(e)===\"discrete\")return e===\"shape\"&&t.type===\"ordinal\"&&S(ks(e,\"ordinal\")),\"ordinal\";if(ue(e)||qi(e)){if(G([\"rect\",\"bar\",\"image\",\"rule\"],n.type)||i)return\"band\"}else if(n.type===\"arc\"&&e in Ro)return\"band\";const r=n[_e(e)];return Cn(r)||ri(t)&&t.axis?.tickBand?\"band\":\"point\"}case\"temporal\":return qn(e)?\"time\":Fs(e)===\"discrete\"?(S(ks(e,\"temporal\")),\"ordinal\"):v(t)&&t.timeUnit&&me(t.timeUnit).utc?\"utc\":\"time\";case\"quantitative\":return qn(e)?v(t)&&ee(t.bin)?\"bin-ordinal\":\"linear\":Fs(e)===\"discrete\"?(S(ks(e,\"quantitative\")),\"ordinal\"):\"linear\";case\"geojson\":return}throw new Error(Su(t.type))}function $v(e,{ignoreRange:t}={}){np(e),Hd(e);for(const n of xm)Zd(e,n);t||ep(e)}function np(e){ae(e)?e.component.scales=wv(e):e.component.scales=Nv(e)}function wv(e){const{encoding:t,mark:n,markDef:i}=e,r={};for(const s of Ur){const o=fe(t[s]);if(o&&n===qu&&s===Oe&&o.type===hi)continue;let a=o&&o.scale;if(o&&a!==null&&a!==!1){a??(a={});const c=yf(t,s),l=vv(a,s,o,i,c);r[s]=new Vd(e.scaleName(`${s}`,!0),{value:l,explicit:a.type===l})}}return r}const Cv=Xf((e,t)=>pc(e)-pc(t));function Nv(e){var t;const n=e.component.scales={},i={},r=e.component.resolve;for(const s of e.children){np(s);for(const o of x(s.component.scales))if((t=r.scale)[o]??(t[o]=_d(o,e)),r.scale[o]===\"shared\"){const a=i[o],c=s.component.scales[o].getWithExplicit(\"type\");a?lm(a.value,c.value)?i[o]=qt(a,c,\"type\",\"scale\",Cv):(r.scale[o]=\"independent\",delete i[o]):i[o]=c}}for(const s of x(i)){const o=e.scaleName(s,!0),a=i[s];n[s]=new Vd(o,a);for(const c of e.children){const l=c.component.scales[s];l&&(c.renameScale(l.get(\"name\"),o),l.merged=!0)}}return n}class zs{constructor(){this.nameMap={}}rename(t,n){this.nameMap[t]=n}has(t){return this.nameMap[t]!==void 0}get(t){for(;this.nameMap[t]&&t!==this.nameMap[t];)t=this.nameMap[t];return t}}function ae(e){return e?.type===\"unit\"}function ze(e){return e?.type===\"facet\"}function Pa(e){return e?.type===\"concat\"}function Si(e){return e?.type===\"layer\"}class za{constructor(t,n,i,r,s,o,a){this.type=n,this.parent=i,this.config=s,this.correctDataNames=c=>(c.from?.data&&(c.from.data=this.lookupDataSource(c.from.data)),c.from?.facet?.data&&(c.from.facet.data=this.lookupDataSource(c.from.facet.data)),c),this.parent=i,this.config=s,this.view=Fe(a),this.name=t.name??r,this.title=jt(t.title)?{text:t.title}:t.title?Fe(t.title):void 0,this.scaleNameMap=i?i.scaleNameMap:new zs,this.projectionNameMap=i?i.projectionNameMap:new zs,this.signalNameMap=i?i.signalNameMap:new zs,this.data=t.data,this.description=t.description,this.transforms=Rb(t.transform??[]),this.layout=n===\"layer\"||n===\"unit\"?{}:zy(t,n,s),this.component={data:{sources:i?i.component.data.sources:[],outputNodes:i?i.component.data.outputNodes:{},outputNodeRefCounts:i?i.component.data.outputNodeRefCounts:{},isFaceted:Kr(t)||i?.component.data.isFaceted&&t.data===void 0},layoutSize:new Dt,layoutHeaders:{row:{},column:{},facet:{}},mark:null,resolve:{scale:{},axis:{},legend:{},...o?z(o):{}},selection:null,scales:null,projection:null,axes:{},legends:{}}}get width(){return this.getSizeSignalRef(\"width\")}get height(){return this.getSizeSignalRef(\"height\")}parse(){this.parseScale(),this.parseLayoutSize(),this.renameTopLevelLayoutSizeSignal(),this.parseSelections(),this.parseProjection(),this.parseData(),this.parseAxesAndHeaders(),this.parseLegends(),this.parseMarkGroup()}parseScale(){$v(this)}parseProjection(){Bd(this)}renameTopLevelLayoutSizeSignal(){this.getName(\"width\")!==\"width\"&&this.renameSignal(this.getName(\"width\"),\"width\"),this.getName(\"height\")!==\"height\"&&this.renameSignal(this.getName(\"height\"),\"height\")}parseLegends(){zd(this)}assembleEncodeFromView(t){const{style:n,...i}=t,r={};for(const s of x(i)){const o=i[s];o!==void 0&&(r[s]=ne(o))}return r}assembleGroupEncodeEntry(t){let n={};return this.view&&(n=this.assembleEncodeFromView(this.view)),!t&&(this.description&&(n.description=ne(this.description)),this.type===\"unit\"||this.type===\"layer\")?{width:this.getSizeSignalRef(\"width\"),height:this.getSizeSignalRef(\"height\"),...n}:K(n)?void 0:n}assembleLayout(){if(!this.layout)return;const{spacing:t,...n}=this.layout,{component:i,config:r}=this,s=Vx(i.layoutHeaders,r);return{padding:t,...this.assembleDefaultLayout(),...n,...s?{titleBand:s}:{}}}assembleDefaultLayout(){return{}}assembleHeaderMarks(){const{layoutHeaders:t}=this.component;let n=[];for(const i of je)t[i].title&&n.push(Ux(this,i));for(const i of Fa)n=n.concat(Bx(this,i));return n}assembleAxes(){return kx(this.component.axes,this.config)}assembleLegends(){return Md(this)}assembleProjections(){return mS(this)}assembleTitle(){const{encoding:t,...n}=this.title??{},i={...fu(this.config.title).nonMarkTitleProperties,...n,...t?{encode:{update:t}}:{}};if(i.text)return G([\"unit\",\"layer\"],this.type)?G([\"middle\",void 0],i.anchor)&&(i.frame??(i.frame=\"group\")):i.anchor??(i.anchor=\"start\"),K(i)?void 0:i}assembleGroup(t=[]){const n={};t=t.concat(this.assembleSignals()),t.length>0&&(n.signals=t);const i=this.assembleLayout();i&&(n.layout=i),n.marks=[].concat(this.assembleHeaderMarks(),this.assembleMarks());const r=!this.parent||ze(this.parent)?qd(this):[];r.length>0&&(n.scales=r);const s=this.assembleAxes();s.length>0&&(n.axes=s);const o=this.assembleLegends();return o.length>0&&(n.legends=o),n}getName(t){return re((this.name?`${this.name}_`:\"\")+t)}getDataName(t){return this.getName(Z[t].toLowerCase())}requestDataName(t){const n=this.getDataName(t),i=this.component.data.outputNodeRefCounts;return i[n]=(i[n]||0)+1,n}getSizeSignalRef(t){if(ze(this.parent)){const n=Ad(t),i=jr(n),r=this.component.scales[i];if(r&&!r.merged){const s=r.get(\"type\"),o=r.get(\"range\");if(ye(s)&&nn(o)){const a=r.get(\"name\"),c=ds(this,i),l=La(c);if(l){const u=E({aggregate:\"distinct\",field:l},{expr:\"datum\"});return{signal:Td(a,r,u)}}else return S(Po(i)),null}}}return{signal:this.signalNameMap.get(this.getName(t))}}lookupDataSource(t){const n=this.component.data.outputNodes[t];return n?n.getSource():t}getSignalName(t){return this.signalNameMap.get(t)}renameSignal(t,n){this.signalNameMap.rename(t,n)}renameScale(t,n){this.scaleNameMap.rename(t,n)}renameProjection(t,n){this.projectionNameMap.rename(t,n)}scaleName(t,n){if(n)return this.getName(t);if(nu(t)&&Pt(t)&&this.component.scales[t]||this.scaleNameMap.has(this.getName(t)))return this.scaleNameMap.get(this.getName(t))}projectionName(t){if(t)return this.getName(\"projection\");if(this.component.projection&&!this.component.projection.merged||this.projectionNameMap.has(this.getName(\"projection\")))return this.projectionNameMap.get(this.getName(\"projection\"))}getScaleComponent(t){if(!this.component.scales)throw new Error(\"getScaleComponent cannot be called before parseScale(). Make sure you have called parseScale or use parseUnitModelWithScale().\");const n=this.component.scales[t];return n&&!n.merged?n:this.parent?this.parent.getScaleComponent(t):void 0}getSelectionComponent(t,n){let i=this.component.selection[t];if(!i&&this.parent&&(i=this.parent.getSelectionComponent(t,n)),!i)throw new Error(jg(n));return i}hasAxisOrientSignalRef(){return this.component.axes.x?.some(t=>t.hasOrientSignalRef())||this.component.axes.y?.some(t=>t.hasOrientSignalRef())}}class ip extends za{vgField(t,n={}){const i=this.fieldDef(t);if(i)return E(i,n)}reduceFieldDef(t,n){return dy(this.getMapping(),(i,r,s)=>{const o=gt(r);return o?t(i,o,s):i},n)}forEachFieldDef(t,n){la(this.getMapping(),(i,r)=>{const s=gt(i);s&&t(s,r)},n)}}class ps extends Y{clone(){return new ps(null,z(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=z(n);const i=this.transform.as??[void 0,void 0];this.transform.as=[i[0]??\"value\",i[1]??\"density\"]}dependentFields(){return new Set([this.transform.density,...this.transform.groupby??[]])}producedFields(){return new Set(this.transform.as)}hash(){return`DensityTransform ${W(this.transform)}`}assemble(){const{density:t,...n}=this.transform,i={type:\"kde\",field:t,...n};return this.transform.groupby&&(i.resolve=\"shared\"),i}}class gs extends Y{clone(){return new gs(null,z(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=z(n)}dependentFields(){return new Set([this.transform.extent])}producedFields(){return new Set([])}hash(){return`ExtentTransform ${W(this.transform)}`}assemble(){const{extent:t,param:n}=this.transform;return{type:\"extent\",field:t,signal:n}}}class Mi extends Y{clone(){return new Mi(null,{...this.filter})}constructor(t,n){super(t),this.filter=n}static make(t,n){const{config:i,mark:r,markDef:s}=n;if(X(\"invalid\",s,i)!==\"filter\")return null;const a=n.reduceFieldDef((c,l,u)=>{const f=Pt(u)&&n.getScaleComponent(u);if(f){const d=f.get(\"type\");De(d)&&l.aggregate!==\"count\"&&!rn(r)&&(c[l.field]=l)}return c},{});return x(a).length?new Mi(t,a):null}dependentFields(){return new Set(x(this.filter))}producedFields(){return new Set}hash(){return`FilterInvalid ${W(this.filter)}`}assemble(){const t=x(this.filter).reduce((n,i)=>{const r=this.filter[i],s=E(r,{expr:\"datum\"});return r!==null&&(r.type===\"temporal\"?n.push(`(isDate(${s}) || (isValid(${s}) && isFinite(+${s})))`):r.type===\"quantitative\"&&(n.push(`isValid(${s})`),n.push(`isFinite(+${s})`))),n},[]);return t.length>0?{type:\"filter\",expr:t.join(\" && \")}:null}}class hs extends Y{clone(){return new hs(this.parent,z(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=z(n);const{flatten:i,as:r=[]}=this.transform;this.transform.as=i.map((s,o)=>r[o]??s)}dependentFields(){return new Set(this.transform.flatten)}producedFields(){return new Set(this.transform.as)}hash(){return`FlattenTransform ${W(this.transform)}`}assemble(){const{flatten:t,as:n}=this.transform;return{type:\"flatten\",fields:t,as:n}}}class ms extends Y{clone(){return new ms(null,z(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=z(n);const i=this.transform.as??[void 0,void 0];this.transform.as=[i[0]??\"key\",i[1]??\"value\"]}dependentFields(){return new Set(this.transform.fold)}producedFields(){return new Set(this.transform.as)}hash(){return`FoldTransform ${W(this.transform)}`}assemble(){const{fold:t,as:n}=this.transform;return{type:\"fold\",fields:t,as:n}}}class Yn extends Y{clone(){return new Yn(null,z(this.fields),this.geojson,this.signal)}static parseAll(t,n){if(n.component.projection&&!n.component.projection.isFit)return t;let i=0;for(const r of[[it,nt],[Be,rt]]){const s=r.map(o=>{const a=fe(n.encoding[o]);return v(a)?a.field:vt(a)?{expr:`${a.datum}`}:Qe(a)?{expr:`${a.value}`}:void 0});(s[0]||s[1])&&(t=new Yn(t,s,null,n.getName(`geojson_${i++}`)))}if(n.channelHasField(Oe)){const r=n.typedFieldDef(Oe);r.type===hi&&(t=new Yn(t,null,r.field,n.getName(`geojson_${i++}`)))}return t}constructor(t,n,i,r){super(t),this.fields=n,this.geojson=i,this.signal=r}dependentFields(){const t=(this.fields??[]).filter(R);return new Set([...this.geojson?[this.geojson]:[],...t])}producedFields(){return new Set}hash(){return`GeoJSON ${this.geojson} ${this.signal} ${W(this.fields)}`}assemble(){return[...this.geojson?[{type:\"filter\",expr:`isValid(datum[\"${this.geojson}\"])`}]:[],{type:\"geojson\",...this.fields?{fields:this.fields}:{},...this.geojson?{geojson:this.geojson}:{},signal:this.signal}]}}class ji extends Y{clone(){return new ji(null,this.projection,z(this.fields),z(this.as))}constructor(t,n,i,r){super(t),this.projection=n,this.fields=i,this.as=r}static parseAll(t,n){if(!n.projectionName())return t;for(const i of[[it,nt],[Be,rt]]){const r=i.map(o=>{const a=fe(n.encoding[o]);return v(a)?a.field:vt(a)?{expr:`${a.datum}`}:Qe(a)?{expr:`${a.value}`}:void 0}),s=i[0]===Be?\"2\":\"\";(r[0]||r[1])&&(t=new ji(t,n.projectionName(),r,[n.getName(`x${s}`),n.getName(`y${s}`)]))}return t}dependentFields(){return new Set(this.fields.filter(R))}producedFields(){return new Set(this.as)}hash(){return`Geopoint ${this.projection} ${W(this.fields)} ${W(this.as)}`}assemble(){return{type:\"geopoint\",projection:this.projection,fields:this.fields,as:this.as}}}class xn extends Y{clone(){return new xn(null,z(this.transform))}constructor(t,n){super(t),this.transform=n}dependentFields(){return new Set([this.transform.impute,this.transform.key,...this.transform.groupby??[]])}producedFields(){return new Set([this.transform.impute])}processSequence(t){const{start:n=0,stop:i,step:r}=t;return{signal:`sequence(${[n,i,...r?[r]:[]].join(\",\")})`}}static makeFromTransform(t,n){return new xn(t,n)}static makeFromEncoding(t,n){const i=n.encoding,r=i.x,s=i.y;if(v(r)&&v(s)){const o=r.impute?r:s.impute?s:void 0;if(o===void 0)return;const a=r.impute?s:s.impute?r:void 0,{method:c,value:l,frame:u,keyvals:f}=o.impute,d=xf(n.mark,i);return new xn(t,{impute:o.field,key:a.field,...c?{method:c}:{},...l!==void 0?{value:l}:{},...u?{frame:u}:{},...f!==void 0?{keyvals:f}:{},...d.length?{groupby:d}:{}})}return null}hash(){return`Impute ${W(this.transform)}`}assemble(){const{impute:t,key:n,keyvals:i,method:r,groupby:s,value:o,frame:a=[null,null]}=this.transform,c={type:\"impute\",field:t,key:n,...i?{keyvals:gb(i)?this.processSequence(i):i}:{},method:\"value\",...s?{groupby:s}:{},value:!r||r===\"value\"?o:null};if(r&&r!==\"value\"){const l={type:\"window\",as:[`imputed_${t}_value`],ops:[r],fields:[t],frame:a,ignorePeers:!1,...s?{groupby:s}:{}},u={type:\"formula\",expr:`datum.${t} === null ? datum.imputed_${t}_value : datum.${t}`,as:t};return[c,l,u]}else return[c]}}class ys extends Y{clone(){return new ys(null,z(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=z(n);const i=this.transform.as??[void 0,void 0];this.transform.as=[i[0]??n.on,i[1]??n.loess]}dependentFields(){return new Set([this.transform.loess,this.transform.on,...this.transform.groupby??[]])}producedFields(){return new Set(this.transform.as)}hash(){return`LoessTransform ${W(this.transform)}`}assemble(){const{loess:t,on:n,...i}=this.transform;return{type:\"loess\",x:n,y:t,...i}}}class Ui extends Y{clone(){return new Ui(null,z(this.transform),this.secondary)}constructor(t,n,i){super(t),this.transform=n,this.secondary=i}static make(t,n,i,r){const s=n.component.data.sources,{from:o}=i;let a=null;if(hb(o)){let c=op(o.data,s);c||(c=new Tn(o.data),s.push(c));const l=n.getName(`lookup_${r}`);a=new we(c,l,Z.Lookup,n.component.data.outputNodeRefCounts),n.component.data.outputNodes[l]=a}else if(mb(o)){const c=o.param;i={as:c,...i};let l;try{l=n.getSelectionComponent(re(c),c)}catch{throw new Error(Gg(c))}if(a=l.materialized,!a)throw new Error(Hg(c))}return new Ui(t,i,a.getSource())}dependentFields(){return new Set([this.transform.lookup])}producedFields(){return new Set(this.transform.as?ce(this.transform.as):this.transform.from.fields)}hash(){return`Lookup ${W({transform:this.transform,secondary:this.secondary})}`}assemble(){let t;if(this.transform.from.fields)t={values:this.transform.from.fields,...this.transform.as?{as:ce(this.transform.as)}:{}};else{let n=this.transform.as;R(n)||(S(Zg),n=\"_lookup\"),t={as:[n]}}return{type:\"lookup\",from:this.secondary,key:this.transform.from.key,fields:[this.transform.lookup],...t,...this.transform.default?{default:this.transform.default}:{}}}}class bs extends Y{clone(){return new bs(null,z(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=z(n);const i=this.transform.as??[void 0,void 0];this.transform.as=[i[0]??\"prob\",i[1]??\"value\"]}dependentFields(){return new Set([this.transform.quantile,...this.transform.groupby??[]])}producedFields(){return new Set(this.transform.as)}hash(){return`QuantileTransform ${W(this.transform)}`}assemble(){const{quantile:t,...n}=this.transform;return{type:\"quantile\",field:t,...n}}}class xs extends Y{clone(){return new xs(null,z(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=z(n);const i=this.transform.as??[void 0,void 0];this.transform.as=[i[0]??n.on,i[1]??n.regression]}dependentFields(){return new Set([this.transform.regression,this.transform.on,...this.transform.groupby??[]])}producedFields(){return new Set(this.transform.as)}hash(){return`RegressionTransform ${W(this.transform)}`}assemble(){const{regression:t,on:n,...i}=this.transform;return{type:\"regression\",x:n,y:t,...i}}}class Ss extends Y{clone(){return new Ss(null,z(this.transform))}constructor(t,n){super(t),this.transform=n}addDimensions(t){this.transform.groupby=lt((this.transform.groupby??[]).concat(t),n=>n)}producedFields(){}dependentFields(){return new Set([this.transform.pivot,this.transform.value,...this.transform.groupby??[]])}hash(){return`PivotTransform ${W(this.transform)}`}assemble(){const{pivot:t,value:n,groupby:i,limit:r,op:s}=this.transform;return{type:\"pivot\",field:t,value:n,...r!==void 0?{limit:r}:{},...s!==void 0?{op:s}:{},...i!==void 0?{groupby:i}:{}}}}class vs extends Y{clone(){return new vs(null,z(this.transform))}constructor(t,n){super(t),this.transform=n}dependentFields(){return new Set}producedFields(){return new Set}hash(){return`SampleTransform ${W(this.transform)}`}assemble(){return{type:\"sample\",size:this.transform.sample}}}function rp(e){let t=0;function n(i,r){if(i instanceof Tn&&!i.isGenerator&&!oi(i.data)&&(e.push(r),r={name:null,source:r.name,transform:[]}),i instanceof $e&&(i.parent instanceof Tn&&!r.source?(r.format={...r.format,parse:i.assembleFormatParse()},r.transform.push(...i.assembleTransforms(!0))):r.transform.push(...i.assembleTransforms())),i instanceof bi){r.name||(r.name=`data_${t++}`),!r.source||r.transform.length>0?(e.push(r),i.data=r.name):i.data=r.source,e.push(...i.assemble());return}switch((i instanceof tr||i instanceof nr||i instanceof Mi||i instanceof yi||i instanceof ci||i instanceof ji||i instanceof Je||i instanceof Ui||i instanceof xi||i instanceof Dn||i instanceof ms||i instanceof hs||i instanceof ps||i instanceof ys||i instanceof bs||i instanceof xs||i instanceof Yt||i instanceof vs||i instanceof Ss||i instanceof gs)&&r.transform.push(i.assemble()),(i instanceof dt||i instanceof ft||i instanceof xn||i instanceof Tt||i instanceof Yn)&&r.transform.push(...i.assemble()),i instanceof we&&(r.source&&r.transform.length===0?i.setSource(r.source):i.parent instanceof we?i.setSource(r.name):(r.name||(r.name=`data_${t++}`),i.setSource(r.name),i.numChildren()===1&&(e.push(r),r={name:null,source:r.name,transform:[]}))),i.numChildren()){case 0:i instanceof we&&(!r.source||r.transform.length>0)&&e.push(r);break;case 1:n(i.children[0],r);break;default:{r.name||(r.name=`data_${t++}`);let s=r.name;!r.source||r.transform.length>0?e.push(r):s=r.source;for(const o of i.children)n(o,{name:null,source:s,transform:[]});break}}}return n}function Fv(e){const t=[],n=rp(t);for(const i of e.children)n(i,{source:e.name,name:null,transform:[]});return t}function kv(e,t){const n=[],i=rp(n);let r=0;for(const o of e.sources){o.hasName()||(o.dataName=`source_${r++}`);const a=o.assemble();i(o,a)}for(const o of n)o.transform.length===0&&delete o.transform;let s=0;for(const[o,a]of n.entries())(a.transform??[]).length===0&&!a.source&&n.splice(s++,0,n.splice(o,1)[0]);for(const o of n)for(const a of o.transform??[])a.type===\"lookup\"&&(a.from=e.outputNodes[a.from].getSource());for(const o of n)o.name in t&&(o.values=t[o.name]);return n}function Tv(e){return e===\"top\"||e===\"left\"||T(e)?\"header\":\"footer\"}function Av(e){for(const t of je)Ov(e,t);cl(e,\"x\"),cl(e,\"y\")}function Ov(e,t){const{facet:n,config:i,child:r,component:s}=e;if(e.channelHasField(t)){const o=n[t],a=ui(\"title\",null,i,t);let c=Vn(o,i,{allowDisabling:!0,includeDefault:a===void 0||!!a});r.component.layoutHeaders[t].title&&(c=F(c)?c.join(\", \"):c,c+=` / ${r.component.layoutHeaders[t].title}`,r.component.layoutHeaders[t].title=null);const l=ui(\"labelOrient\",o.header,i,t),u=o.header!==null?le(o.header?.labels,i.header.labels,!0):!1,f=G([\"bottom\",\"right\"],l)?\"footer\":\"header\";s.layoutHeaders[t]={title:o.header!==null?c:null,facetFieldDef:o,[f]:t===\"facet\"?[]:[sp(e,t,u)]}}}function sp(e,t,n){const i=t===\"row\"?\"height\":\"width\";return{labels:n,sizeSignal:e.child.component.layoutSize.get(i)?e.child.getSizeSignalRef(i):void 0,axes:[]}}function cl(e,t){const{child:n}=e;if(n.component.axes[t]){const{layoutHeaders:i,resolve:r}=e.component;if(r.axis[t]=Aa(r,t),r.axis[t]===\"shared\"){const s=t===\"x\"?\"column\":\"row\",o=i[s];for(const a of n.component.axes[t]){const c=Tv(a.get(\"orient\"));o[c]??(o[c]=[sp(e,s,!1)]);const l=ki(a,\"main\",e.config,{header:!0});l&&o[c][0].axes.push(l),a.mainExtracted=!0}}}}function _v(e){Da(e),Ar(e,\"width\"),Ar(e,\"height\")}function Rv(e){Da(e);const t=e.layout.columns===1?\"width\":\"childWidth\",n=e.layout.columns===void 0?\"height\":\"childHeight\";Ar(e,t),Ar(e,n)}function Da(e){for(const t of e.children)t.parseLayoutSize()}function Ar(e,t){const n=Ad(t),i=jr(n),r=e.component.resolve,s=e.component.layoutSize;let o;for(const a of e.children){const c=a.component.layoutSize.getWithExplicit(n),l=r.scale[i]??_d(i,e);if(l===\"independent\"&&c.value===\"step\"){o=void 0;break}if(o){if(l===\"independent\"&&o.value!==c.value){o=void 0;break}o=qt(o,c,n,\"\")}else o=c}if(o){for(const a of e.children)e.renameSignal(a.getName(n),e.getName(t)),a.component.layoutSize.set(n,\"merged\",!1);s.setWithExplicit(t,o)}else s.setWithExplicit(t,{explicit:!1,value:void 0})}function Iv(e){const{size:t,component:n}=e;for(const i of St){const r=_e(i);if(t[r]){const s=t[r];n.layoutSize.set(r,ht(s)?\"step\":s,!0)}else{const s=Lv(e,r);n.layoutSize.set(r,s,!1)}}}function Lv(e,t){const n=t===\"width\"?\"x\":\"y\",i=e.config,r=e.getScaleComponent(n);if(r){const s=r.get(\"type\"),o=r.get(\"range\");if(ye(s)){const a=Nr(i.view,t);return nn(o)||ht(a)?\"step\":a}else return to(i.view,t)}else{if(e.hasProjection||e.mark===\"arc\")return to(i.view,t);{const s=Nr(i.view,t);return ht(s)?s.step:s}}}function mo(e,t,n){return E(t,{suffix:`by_${E(e)}`,...n})}class Ri extends ip{constructor(t,n,i,r){super(t,\"facet\",n,i,r,t.resolve),this.child=Wa(t.spec,this,this.getName(\"child\"),void 0,r),this.children=[this.child],this.facet=this.initFacet(t.facet)}initFacet(t){if(!Ki(t))return{facet:this.initFacetFieldDef(t,\"facet\")};const n=x(t),i={};for(const r of n){if(![Nt,Ft].includes(r)){S(Wr(r,\"facet\"));break}const s=t[r];if(s.field===void 0){S(Ks(s,r));break}i[r]=this.initFacetFieldDef(s,r)}return i}initFacetFieldDef(t,n){const i=aa(t,n);return i.header?i.header=Fe(i.header):i.header===null&&(i.header=null),i}channelHasField(t){return!!this.facet[t]}fieldDef(t){return this.facet[t]}parseData(){this.component.data=Es(this),this.child.parseData()}parseLayoutSize(){Da(this)}parseSelections(){this.child.parseSelections(),this.component.selection=this.child.component.selection}parseMarkGroup(){this.child.parseMarkGroup()}parseAxesAndHeaders(){this.child.parseAxesAndHeaders(),Av(this)}assembleSelectionTopLevelSignals(t){return this.child.assembleSelectionTopLevelSignals(t)}assembleSignals(){return this.child.assembleSignals(),[]}assembleSelectionData(t){return this.child.assembleSelectionData(t)}getHeaderLayoutMixins(){const t={};for(const n of je)for(const i of ka){const r=this.component.layoutHeaders[n],s=r[i],{facetFieldDef:o}=r;if(o){const a=ui(\"titleOrient\",o.header,this.config,n);if([\"right\",\"bottom\"].includes(a)){const c=us(n,a);t.titleAnchor??(t.titleAnchor={}),t.titleAnchor[c]=\"end\"}}if(s?.[0]){const a=n===\"row\"?\"height\":\"width\",c=i===\"header\"?\"headerBand\":\"footerBand\";n!==\"facet\"&&!this.child.component.layoutSize.get(a)&&(t[c]??(t[c]={}),t[c][n]=.5),r.title&&(t.offset??(t.offset={}),t.offset[n===\"row\"?\"rowTitle\":\"columnTitle\"]=10)}}return t}assembleDefaultLayout(){const{column:t,row:n}=this.facet,i=t?this.columnDistinctSignal():n?1:void 0;let r=\"all\";return(!n&&this.component.resolve.scale.x===\"independent\"||!t&&this.component.resolve.scale.y===\"independent\")&&(r=\"none\"),{...this.getHeaderLayoutMixins(),...i?{columns:i}:{},bounds:\"full\",align:r}}assembleLayoutSignals(){return this.child.assembleLayoutSignals()}columnDistinctSignal(){if(!(this.parent&&this.parent instanceof Ri))return{signal:`length(data('${this.getName(\"column_domain\")}'))`}}assembleGroupStyle(){}assembleGroup(t){return this.parent&&this.parent instanceof Ri?{...this.channelHasField(\"column\")?{encode:{update:{columns:{field:E(this.facet.column,{prefix:\"distinct\"})}}}}:{},...super.assembleGroup(t)}:super.assembleGroup(t)}getCardinalityAggregateForChild(){const t=[],n=[],i=[];if(this.child instanceof Ri){if(this.child.channelHasField(\"column\")){const r=E(this.child.facet.column);t.push(r),n.push(\"distinct\"),i.push(`distinct_${r}`)}}else for(const r of St){const s=this.child.component.scales[r];if(s&&!s.merged){const o=s.get(\"type\"),a=s.get(\"range\");if(ye(o)&&nn(a)){const c=ds(this.child,r),l=La(c);l?(t.push(l),n.push(\"distinct\"),i.push(`distinct_${l}`)):S(Po(r))}}}return{fields:t,ops:n,as:i}}assembleFacet(){const{name:t,data:n}=this.component.data.facetRoot,{row:i,column:r}=this.facet,{fields:s,ops:o,as:a}=this.getCardinalityAggregateForChild(),c=[];for(const u of je){const f=this.facet[u];if(f){c.push(E(f));const{bin:d,sort:g}=f;if(ee(d)&&c.push(E(f,{binSuffix:\"end\"})),ut(g)){const{field:p,op:h=Yr}=g,m=mo(f,g);i&&r?(s.push(m),o.push(\"max\"),a.push(m)):(s.push(p),o.push(h),a.push(m))}else if(F(g)){const p=li(f,u);s.push(p),o.push(\"max\"),a.push(p)}}}const l=!!i&&!!r;return{name:t,data:n,groupby:c,...l||s.length>0?{aggregate:{...l?{cross:l}:{},...s.length?{fields:s,ops:o,as:a}:{}}}:{}}}facetSortFields(t){const{facet:n}=this,i=n[t];return i?ut(i.sort)?[mo(i,i.sort,{expr:\"datum\"})]:F(i.sort)?[li(i,t,{expr:\"datum\"})]:[E(i,{expr:\"datum\"})]:[]}facetSortOrder(t){const{facet:n}=this,i=n[t];if(i){const{sort:r}=i;return[(ut(r)?r.order:!F(r)&&r)||\"ascending\"]}return[]}assembleLabelTitle(){const{facet:t,config:n}=this;if(t.facet)return lo(t.facet,\"facet\",n);const i={row:[\"top\",\"bottom\"],column:[\"left\",\"right\"]};for(const r of Fa)if(t[r]){const s=ui(\"labelOrient\",t[r]?.header,n,r);if(i[r].includes(s))return lo(t[r],r,n)}}assembleMarks(){const{child:t}=this,n=this.component.data.facetRoot,i=Fv(n),r=t.assembleGroupEncodeEntry(!1),s=this.assembleLabelTitle()||t.assembleTitle(),o=t.assembleGroupStyle();return[{name:this.getName(\"cell\"),type:\"group\",...s?{title:s}:{},...o?{style:o}:{},from:{facet:this.assembleFacet()},sort:{field:je.map(c=>this.facetSortFields(c)).flat(),order:je.map(c=>this.facetSortOrder(c)).flat()},...i.length>0?{data:i}:{},...r?{encode:{update:r}}:{},...t.assembleGroup(qb(this,[]))}]}getMapping(){return this.facet}}function Pv(e,t){const{row:n,column:i}=t;if(n&&i){let r=null;for(const s of[n,i])if(ut(s.sort)){const{field:o,op:a=Yr}=s.sort;e=r=new Dn(e,{joinaggregate:[{op:a,field:o,as:mo(s,s.sort,{forAs:!0})}],groupby:[E(s)]})}return r}return null}function op(e,t){for(const n of t){const i=n.data;if(e.name&&n.hasName()&&e.name!==n.dataName)continue;const r=e.format?.mesh,s=i.format?.feature;if(r&&s)continue;const o=e.format?.feature;if((o||s)&&o!==s)continue;const a=i.format?.mesh;if(!((r||a)&&r!==a)){if(Di(e)&&Di(i)){if(Pe(e.values,i.values))return n}else if(oi(e)&&oi(i)){if(e.url===i.url)return n}else if(Yf(e)&&e.name===n.dataName)return n}}return null}function zv(e,t){if(e.data||!e.parent){if(e.data===null){const i=new Tn({values:[]});return t.push(i),i}const n=op(e.data,t);if(n)return Bt(e.data)||(n.data.format=Gl({},e.data.format,n.data.format)),!n.hasName()&&e.data.name&&(n.dataName=e.data.name),n;{const i=new Tn(e.data);return t.push(i),i}}else return e.parent.component.data.facetRoot?e.parent.component.data.facetRoot:e.parent.component.data.main}function Dv(e,t,n){let i=0;for(const r of t.transforms){let s,o;if(Nb(r))o=e=new ci(e,r),s=\"derived\";else if(Sa(r)){const a=TS(r);o=e=$e.makeWithAncestors(e,{},a,n)??e,e=new yi(e,t,r.filter)}else if(Gf(r))o=e=dt.makeFromTransform(e,r,t),s=\"number\";else if(kb(r))s=\"date\",n.getWithExplicit(r.field).value===void 0&&(e=new $e(e,{[r.field]:s}),n.set(r.field,s,!1)),o=e=ft.makeFromTransform(e,r);else if(Tb(r))o=e=Je.makeFromTransform(e,r),s=\"number\",Na(t)&&(e=new Yt(e));else if(Wf(r))o=e=Ui.make(e,t,r,i++),s=\"derived\";else if($b(r))o=e=new xi(e,r),s=\"number\";else if(wb(r))o=e=new Dn(e,r),s=\"number\";else if(Ab(r))o=e=Tt.makeFromTransform(e,r),s=\"derived\";else if(Ob(r))o=e=new ms(e,r),s=\"derived\";else if(_b(r))o=e=new gs(e,r),s=\"derived\";else if(Cb(r))o=e=new hs(e,r),s=\"derived\";else if(yb(r))o=e=new Ss(e,r),s=\"derived\";else if(Eb(r))e=new vs(e,r);else if(Fb(r))o=e=xn.makeFromTransform(e,r),s=\"derived\";else if(bb(r))o=e=new ps(e,r),s=\"derived\";else if(xb(r))o=e=new bs(e,r),s=\"derived\";else if(Sb(r))o=e=new xs(e,r),s=\"derived\";else if(vb(r))o=e=new ys(e,r),s=\"derived\";else{S(Qg(r));continue}if(o&&s!==void 0)for(const a of o.producedFields()??[])n.set(a,s,!1)}return e}function Es(e){let t=zv(e,e.component.data.sources);const{outputNodes:n,outputNodeRefCounts:i}=e.component.data,r=e.data,o=!(r&&(Bt(r)||oi(r)||Di(r)))&&e.parent?e.parent.component.data.ancestorParse.clone():new Gb;Bt(r)?(Kf(r)?t=new nr(t,r.sequence):va(r)&&(t=new tr(t,r.graticule)),o.parseNothing=!0):r?.format?.parse===null&&(o.parseNothing=!0),t=$e.makeExplicit(t,e,o)??t,t=new Yt(t);const a=e.parent&&Si(e.parent);(ae(e)||ze(e))&&a&&(t=dt.makeFromEncoding(t,e)??t),e.transforms.length>0&&(t=Dv(t,e,o));const c=OS(e),l=AS(e);t=$e.makeWithAncestors(t,{},{...c,...l},o)??t,ae(e)&&(t=Yn.parseAll(t,e),t=ji.parseAll(t,e)),(ae(e)||ze(e))&&(a||(t=dt.makeFromEncoding(t,e)??t),t=ft.makeFromEncoding(t,e)??t,t=ci.parseAllForSortIndex(t,e));const u=e.getDataName(Z.Raw),f=new we(t,u,Z.Raw,i);if(n[u]=f,t=f,ae(e)){const h=Je.makeFromEncoding(t,e);h&&(t=h,Na(e)&&(t=new Yt(t))),t=xn.makeFromEncoding(t,e)??t,t=Tt.makeFromEncoding(t,e)??t}ae(e)&&(t=Mi.make(t,e)??t);const d=e.getDataName(Z.Main),g=new we(t,d,Z.Main,i);n[d]=g,t=g,ae(e)&&Nx(e,g);let p=null;if(ze(e)){const h=e.getName(\"facet\");t=Pv(t,e.facet)??t,p=new bi(t,e,h,g.getSource()),n[h]=p}return{...e.component.data,outputNodes:n,outputNodeRefCounts:i,raw:f,main:g,facetRoot:p,ancestorParse:o}}class Mv extends za{constructor(t,n,i,r){super(t,\"concat\",n,i,r,t.resolve),(t.resolve?.axis?.x===\"shared\"||t.resolve?.axis?.y===\"shared\")&&S(Yg),this.children=this.getChildren(t).map((s,o)=>Wa(s,this,this.getName(`concat_${o}`),void 0,r))}parseData(){this.component.data=Es(this);for(const t of this.children)t.parseData()}parseSelections(){this.component.selection={};for(const t of this.children){t.parseSelections();for(const n of x(t.component.selection))this.component.selection[n]=t.component.selection[n]}}parseMarkGroup(){for(const t of this.children)t.parseMarkGroup()}parseAxesAndHeaders(){for(const t of this.children)t.parseAxesAndHeaders()}getChildren(t){return is(t)?t.vconcat:ba(t)?t.hconcat:t.concat}parseLayoutSize(){Rv(this)}parseAxisGroup(){return null}assembleSelectionTopLevelSignals(t){return this.children.reduce((n,i)=>i.assembleSelectionTopLevelSignals(n),t)}assembleSignals(){return this.children.forEach(t=>t.assembleSignals()),[]}assembleLayoutSignals(){const t=Ta(this);for(const n of this.children)t.push(...n.assembleLayoutSignals());return t}assembleSelectionData(t){return this.children.reduce((n,i)=>i.assembleSelectionData(n),t)}assembleMarks(){return this.children.map(t=>{const n=t.assembleTitle(),i=t.assembleGroupStyle(),r=t.assembleGroupEncodeEntry(!1);return{type:\"group\",name:t.getName(\"group\"),...n?{title:n}:{},...i?{style:i}:{},...r?{encode:{update:r}}:{},...t.assembleGroup()}})}assembleGroupStyle(){}assembleDefaultLayout(){const t=this.layout.columns;return{...t!=null?{columns:t}:{},bounds:\"full\",align:\"each\"}}}function jv(e){return e===!1||e===null}const Uv={disable:1,gridScale:1,scale:1,...gf,labelExpr:1,encode:1},ap=x(Uv);class Ma extends Dt{constructor(t={},n={},i=!1){super(),this.explicit=t,this.implicit=n,this.mainExtracted=i}clone(){return new Ma(z(this.explicit),z(this.implicit),this.mainExtracted)}hasAxisPart(t){return t===\"axis\"?!0:t===\"grid\"||t===\"title\"?!!this.get(t):!jv(this.get(t))}hasOrientSignalRef(){return T(this.explicit.orient)}}function Bv(e,t,n){const{encoding:i,config:r}=e,s=fe(i[t])??fe(i[xt(t)]),o=e.axis(t)||{},{format:a,formatType:c}=o;if(Nn(c))return{text:Ke({fieldOrDatumDef:s,field:\"datum.value\",format:a,formatType:c,config:r}),...n};if(a===void 0&&c===void 0&&r.customFormatTypes){if(ii(s)===\"quantitative\"){if(ri(s)&&s.stack===\"normalize\"&&r.normalizedNumberFormatType)return{text:Ke({fieldOrDatumDef:s,field:\"datum.value\",format:r.normalizedNumberFormat,formatType:r.normalizedNumberFormatType,config:r}),...n};if(r.numberFormatType)return{text:Ke({fieldOrDatumDef:s,field:\"datum.value\",format:r.numberFormat,formatType:r.numberFormatType,config:r}),...n}}if(ii(s)===\"temporal\"&&r.timeFormatType&&v(s)&&!s.timeUnit)return{text:Ke({fieldOrDatumDef:s,field:\"datum.value\",format:r.timeFormat,formatType:r.timeFormatType,config:r}),...n}}return n}function Wv(e){return St.reduce((t,n)=>(e.component.scales[n]&&(t[n]=[Kv(n,e)]),t),{})}const Gv={bottom:\"top\",top:\"bottom\",left:\"right\",right:\"left\"};function Hv(e){const{axes:t,resolve:n}=e.component,i={top:0,bottom:0,right:0,left:0};for(const r of e.children){r.parseAxesAndHeaders();for(const s of x(r.component.axes))n.axis[s]=Aa(e.component.resolve,s),n.axis[s]===\"shared\"&&(t[s]=qv(t[s],r.component.axes[s]),t[s]||(n.axis[s]=\"independent\",delete t[s]))}for(const r of St){for(const s of e.children)if(s.component.axes[r]){if(n.axis[r]===\"independent\"){t[r]=(t[r]??[]).concat(s.component.axes[r]);for(const o of s.component.axes[r]){const{value:a,explicit:c}=o.getWithExplicit(\"orient\");if(!T(a)){if(i[a]>0&&!c){const l=Gv[a];i[a]>i[l]&&o.set(\"orient\",l,!1)}i[a]++}}}delete s.component.axes[r]}if(n.axis[r]===\"independent\"&&t[r]&&t[r].length>1)for(const[s,o]of(t[r]||[]).entries())s>0&&o.get(\"grid\")&&!o.explicit.grid&&(o.implicit.grid=!1)}}function qv(e,t){if(e){if(e.length!==t.length)return;const n=e.length;for(let i=0;in.clone());return e}function Vv(e,t){for(const n of ap){const i=qt(e.getWithExplicit(n),t.getWithExplicit(n),n,\"axis\",(r,s)=>{switch(n){case\"title\":return bu(r,s);case\"gridScale\":return{explicit:r.explicit,value:le(r.value,s.value)}}return ss(r,s,n,\"axis\")});e.setWithExplicit(n,i)}return e}function Xv(e,t,n,i,r){if(t===\"disable\")return n!==void 0;switch(n=n||{},t){case\"titleAngle\":case\"labelAngle\":return e===(T(n.labelAngle)?n.labelAngle:Pi(n.labelAngle));case\"values\":return!!n.values;case\"encode\":return!!n.encoding||!!n.labelAngle;case\"title\":if(e===Cd(i,r))return!0}return e===n[t]}const Yv=new Set([\"grid\",\"translate\",\"format\",\"formatType\",\"orient\",\"labelExpr\",\"tickCount\",\"position\",\"tickMinStep\"]);function Kv(e,t){let n=t.axis(e);const i=new Ma,r=fe(t.encoding[e]),{mark:s,config:o}=t,a=n?.orient||o[e===\"x\"?\"axisX\":\"axisY\"]?.orient||o.axis?.orient||Px(e),c=t.getScaleComponent(e).get(\"type\"),l=Tx(e,c,a,t.config),u=n!==void 0?!n:ao(\"disable\",o.style,n?.style,l).configValue;if(i.set(\"disable\",u,n!==void 0),u)return i;n=n||{};const f=Rx(r,n,e,o.style,l),d=Qu(n.formatType,r,c),g=Ju(r,r.type,n.format,n.formatType,o,!0),p={fieldOrDatumDef:r,axis:n,channel:e,model:t,scaleType:c,orient:a,labelAngle:f,format:g,formatType:d,mark:s,config:o};for(const y of ap){const b=y in Vc?Vc[y](p):Sc(y)?n[y]:void 0,C=b!==void 0,k=Xv(b,y,n,t,e);if(C&&k)i.set(y,b,k);else{const{configValue:N=void 0,configFrom:_=void 0}=Sc(y)&&y!==\"values\"?ao(y,o.style,n.style,l):{},L=N!==void 0;C&&!L?i.set(y,b,k):(_!==\"vgAxisConfig\"||Yv.has(y)&&L||Zi(N)||T(N))&&i.set(y,N,!1)}}const h=n.encoding??{},m=pf.reduce((y,b)=>{if(!i.hasAxisPart(b))return y;const C=Od(h[b]??{},t),k=b===\"labels\"?Bv(t,e,C):C;return k!==void 0&&!K(k)&&(y[b]={update:k}),y},{});return K(m)||i.set(\"encode\",m,!!n.encoding||n.labelAngle!==void 0),i}function Jv({encoding:e,size:t}){for(const n of St){const i=_e(n);ht(t[i])&&Ut(e[n])&&(delete t[i],S($u(i)))}return t}const Qv={vgMark:\"arc\",encodeEntry:e=>({...Ge(e,{align:\"ignore\",baseline:\"ignore\",color:\"include\",size:\"ignore\",orient:\"ignore\",theta:\"ignore\"}),...Ee(\"x\",e,{defaultPos:\"mid\"}),...Ee(\"y\",e,{defaultPos:\"mid\"}),...Vt(e,\"radius\"),...Vt(e,\"theta\")})},Zv={vgMark:\"area\",encodeEntry:e=>({...Ge(e,{align:\"ignore\",baseline:\"ignore\",color:\"include\",orient:\"include\",size:\"ignore\",theta:\"ignore\"}),...Fr(\"x\",e,{defaultPos:\"zeroOrMin\",defaultPos2:\"zeroOrMin\",range:e.markDef.orient===\"horizontal\"}),...Fr(\"y\",e,{defaultPos:\"zeroOrMin\",defaultPos2:\"zeroOrMin\",range:e.markDef.orient===\"vertical\"}),...Ca(e)})},eE={vgMark:\"rect\",encodeEntry:e=>({...Ge(e,{align:\"ignore\",baseline:\"ignore\",color:\"include\",orient:\"ignore\",size:\"ignore\",theta:\"ignore\"}),...Vt(e,\"x\"),...Vt(e,\"y\")})},tE={vgMark:\"shape\",encodeEntry:e=>({...Ge(e,{align:\"ignore\",baseline:\"ignore\",color:\"include\",size:\"ignore\",orient:\"ignore\",theta:\"ignore\"})}),postEncodingTransform:e=>{const{encoding:t}=e,n=t.shape;return[{type:\"geoshape\",projection:e.projectionName(),...n&&v(n)&&n.type===hi?{field:E(n,{expr:\"datum\"})}:{}}]}},nE={vgMark:\"image\",encodeEntry:e=>({...Ge(e,{align:\"ignore\",baseline:\"ignore\",color:\"ignore\",orient:\"ignore\",size:\"ignore\",theta:\"ignore\"}),...Vt(e,\"x\"),...Vt(e,\"y\"),...$a(e,\"url\")})},iE={vgMark:\"line\",encodeEntry:e=>({...Ge(e,{align:\"ignore\",baseline:\"ignore\",color:\"include\",size:\"ignore\",orient:\"ignore\",theta:\"ignore\"}),...Ee(\"x\",e,{defaultPos:\"mid\"}),...Ee(\"y\",e,{defaultPos:\"mid\"}),...he(\"size\",e,{vgChannel:\"strokeWidth\"}),...Ca(e)})},rE={vgMark:\"trail\",encodeEntry:e=>({...Ge(e,{align:\"ignore\",baseline:\"ignore\",color:\"include\",size:\"include\",orient:\"ignore\",theta:\"ignore\"}),...Ee(\"x\",e,{defaultPos:\"mid\"}),...Ee(\"y\",e,{defaultPos:\"mid\"}),...he(\"size\",e),...Ca(e)})};function ja(e,t){const{config:n}=e;return{...Ge(e,{align:\"ignore\",baseline:\"ignore\",color:\"include\",size:\"include\",orient:\"ignore\",theta:\"ignore\"}),...Ee(\"x\",e,{defaultPos:\"mid\"}),...Ee(\"y\",e,{defaultPos:\"mid\"}),...he(\"size\",e),...he(\"angle\",e),...sE(e,n,t)}}function sE(e,t,n){return n?{shape:{value:n}}:he(\"shape\",e)}const oE={vgMark:\"symbol\",encodeEntry:e=>ja(e)},aE={vgMark:\"symbol\",encodeEntry:e=>ja(e,\"circle\")},cE={vgMark:\"symbol\",encodeEntry:e=>ja(e,\"square\")},lE={vgMark:\"rect\",encodeEntry:e=>({...Ge(e,{align:\"ignore\",baseline:\"ignore\",color:\"include\",orient:\"ignore\",size:\"ignore\",theta:\"ignore\"}),...Vt(e,\"x\"),...Vt(e,\"y\")})},uE={vgMark:\"rule\",encodeEntry:e=>{const{markDef:t}=e,n=t.orient;return!e.encoding.x&&!e.encoding.y&&!e.encoding.latitude&&!e.encoding.longitude?{}:{...Ge(e,{align:\"ignore\",baseline:\"ignore\",color:\"include\",orient:\"ignore\",size:\"ignore\",theta:\"ignore\"}),...Fr(\"x\",e,{defaultPos:n===\"horizontal\"?\"zeroOrMax\":\"mid\",defaultPos2:\"zeroOrMin\",range:n!==\"vertical\"}),...Fr(\"y\",e,{defaultPos:n===\"vertical\"?\"zeroOrMax\":\"mid\",defaultPos2:\"zeroOrMin\",range:n!==\"horizontal\"}),...he(\"size\",e,{vgChannel:\"strokeWidth\"})}}},fE={vgMark:\"text\",encodeEntry:e=>{const{config:t,encoding:n}=e;return{...Ge(e,{align:\"include\",baseline:\"include\",color:\"include\",size:\"ignore\",orient:\"ignore\",theta:\"include\"}),...Ee(\"x\",e,{defaultPos:\"mid\"}),...Ee(\"y\",e,{defaultPos:\"mid\"}),...$a(e),...he(\"size\",e,{vgChannel:\"fontSize\"}),...he(\"angle\",e),...Wc(\"align\",dE(e.markDef,n,t)),...Wc(\"baseline\",pE(e.markDef,n,t)),...Ee(\"radius\",e,{defaultPos:null}),...Ee(\"theta\",e,{defaultPos:null})}}};function dE(e,t,n){if(X(\"align\",e,n)===void 0)return\"center\"}function pE(e,t,n){if(X(\"baseline\",e,n)===void 0)return\"middle\"}const gE={vgMark:\"rect\",encodeEntry:e=>{const{config:t,markDef:n}=e,i=n.orient,r=i===\"horizontal\"?\"width\":\"height\",s=i===\"horizontal\"?\"height\":\"width\";return{...Ge(e,{align:\"ignore\",baseline:\"ignore\",color:\"include\",orient:\"ignore\",size:\"ignore\",theta:\"ignore\"}),...Ee(\"x\",e,{defaultPos:\"mid\",vgChannel:\"xc\"}),...Ee(\"y\",e,{defaultPos:\"mid\",vgChannel:\"yc\"}),...he(\"size\",e,{defaultValue:hE(e),vgChannel:r}),[s]:ne(X(\"thickness\",n,t))}}};function hE(e){const{config:t,markDef:n}=e,{orient:i}=n,r=i===\"horizontal\"?\"width\":\"height\",s=e.getScaleComponent(i===\"horizontal\"?\"x\":\"y\"),o=X(\"size\",n,t,{vgChannel:r})??t.tick.bandSize;if(o!==void 0)return o;{const a=s?s.get(\"range\"):void 0;return a&&nn(a)&&ie(a.step)?a.step*3/4:Cr(t.view,r)*3/4}}const cr={arc:Qv,area:Zv,bar:eE,circle:aE,geoshape:tE,image:nE,line:iE,point:oE,rect:lE,rule:uE,square:cE,text:fE,tick:gE,trail:rE};function mE(e){if(G([Vr,Hr,wm],e.mark)){const t=xf(e.mark,e.encoding);if(t.length>0)return yE(e,t)}else if(e.mark===qr){const t=Ys.some(n=>X(n,e.markDef,e.config));if(e.stack&&!e.fieldDef(\"size\")&&t)return bE(e)}return Ua(e)}const ll=\"faceted_path_\";function yE(e,t){return[{name:e.getName(\"pathgroup\"),type:\"group\",from:{facet:{name:ll+e.requestDataName(Z.Main),data:e.requestDataName(Z.Main),groupby:t}},encode:{update:{width:{field:{group:\"width\"}},height:{field:{group:\"height\"}}}},marks:Ua(e,{fromPrefix:ll})}]}const ul=\"stack_group_\";function bE(e){const[t]=Ua(e,{fromPrefix:ul}),n=e.scaleName(e.stack.fieldChannel),i=(l={})=>e.vgField(e.stack.fieldChannel,l),r=(l,u)=>{const f=[i({prefix:\"min\",suffix:\"start\",expr:u}),i({prefix:\"max\",suffix:\"start\",expr:u}),i({prefix:\"min\",suffix:\"end\",expr:u}),i({prefix:\"max\",suffix:\"end\",expr:u})];return`${l}(${f.map(d=>`scale('${n}',${d})`).join(\",\")})`};let s,o;e.stack.fieldChannel===\"x\"?(s={...Jn(t.encode.update,[\"y\",\"yc\",\"y2\",\"height\",...Ys]),x:{signal:r(\"min\",\"datum\")},x2:{signal:r(\"max\",\"datum\")},clip:{value:!0}},o={x:{field:{group:\"x\"},mult:-1},height:{field:{group:\"height\"}}},t.encode.update={...ke(t.encode.update,[\"y\",\"yc\",\"y2\"]),height:{field:{group:\"height\"}}}):(s={...Jn(t.encode.update,[\"x\",\"xc\",\"x2\",\"width\"]),y:{signal:r(\"min\",\"datum\")},y2:{signal:r(\"max\",\"datum\")},clip:{value:!0}},o={y:{field:{group:\"y\"},mult:-1},width:{field:{group:\"width\"}}},t.encode.update={...ke(t.encode.update,[\"x\",\"xc\",\"x2\"]),width:{field:{group:\"width\"}}});for(const l of Ys){const u=Ot(l,e.markDef,e.config);t.encode.update[l]?(s[l]=t.encode.update[l],delete t.encode.update[l]):u&&(s[l]=ne(u)),u&&(t.encode.update[l]={value:0})}const a=[];if(e.stack.groupbyChannels?.length>0)for(const l of e.stack.groupbyChannels){const u=e.fieldDef(l),f=E(u);f&&a.push(f),(u?.bin||u?.timeUnit)&&a.push(E(u,{binSuffix:\"end\"}))}return s=[\"stroke\",\"strokeWidth\",\"strokeJoin\",\"strokeCap\",\"strokeDash\",\"strokeDashOffset\",\"strokeMiterLimit\",\"strokeOpacity\"].reduce((l,u)=>{if(t.encode.update[u])return{...l,[u]:t.encode.update[u]};{const f=Ot(u,e.markDef,e.config);return f!==void 0?{...l,[u]:ne(f)}:l}},s),s.stroke&&(s.strokeForeground={value:!0},s.strokeOffset={value:0}),[{type:\"group\",from:{facet:{data:e.requestDataName(Z.Main),name:ul+e.requestDataName(Z.Main),groupby:a,aggregate:{fields:[i({suffix:\"start\"}),i({suffix:\"start\"}),i({suffix:\"end\"}),i({suffix:\"end\"})],ops:[\"min\",\"max\",\"min\",\"max\"]}}},encode:{update:s},marks:[{type:\"group\",encode:{update:o},marks:[t]}]}]}function xE(e){const{encoding:t,stack:n,mark:i,markDef:r,config:s}=e,o=t.order;if(!(!F(o)&&Qe(o)&&Vs(o.value)||!o&&Vs(X(\"order\",r,s)))){if((F(o)||v(o))&&!n)return hu(o,{expr:\"datum\"});if(rn(i)){const a=r.orient===\"horizontal\"?\"y\":\"x\",c=t[a];if(v(c)){const l=c.sort;if(F(l))return{field:E(c,{prefix:a,suffix:\"sort_index\",expr:\"datum\"})};if(ut(l))return{field:E({aggregate:ca(e.encoding)?l.op:void 0,field:l.field},{expr:\"datum\"})};if(ef(l)){const u=e.fieldDef(l.encoding);return{field:E(u,{expr:\"datum\"}),order:l.order}}else return l===null?void 0:{field:E(c,{binSuffix:e.stack?.impute?\"mid\":void 0,expr:\"datum\"})}}return}}}function Ua(e,t={fromPrefix:\"\"}){const{mark:n,markDef:i,encoding:r,config:s}=e,o=le(i.clip,SE(e),vE(e)),a=pu(i),c=r.key,l=xE(e),u=EE(e),f=X(\"aria\",i,s),d=cr[n].postEncodingTransform?cr[n].postEncodingTransform(e):null;return[{name:e.getName(\"marks\"),type:cr[n].vgMark,...o?{clip:o}:{},...a?{style:a}:{},...c?{key:c.field}:{},...l?{sort:l}:{},...u||{},...f===!1?{aria:f}:{},from:{data:t.fromPrefix+e.requestDataName(Z.Main)},encode:{update:cr[n].encodeEntry(e)},...d?{transform:d}:{}}]}function SE(e){const t=e.getScaleComponent(\"x\"),n=e.getScaleComponent(\"y\");return t?.get(\"selectionExtent\")||n?.get(\"selectionExtent\")?!0:void 0}function vE(e){const t=e.component.projection;return t&&!t.isFit?!0:void 0}function EE(e){if(!e.component.selection)return null;const t=x(e.component.selection).length;let n=t,i=e.parent;for(;i&&n===0;)n=x(i.component.selection).length,i=i.parent;return n?{interactive:t>0||e.mark===\"geoshape\"||!!e.encoding.tooltip||!!e.markDef.tooltip}:null}class cp extends ip{constructor(t,n,i,r={},s){super(t,\"unit\",n,i,s,void 0,Ec(t)?t.view:void 0),this.specifiedScales={},this.specifiedAxes={},this.specifiedLegends={},this.specifiedProjection={},this.selection=[],this.children=[];const o=pt(t.mark)?{...t.mark}:{type:t.mark},a=o.type;o.filled===void 0&&(o.filled=ob(o,s,{graticule:t.data&&va(t.data)}));const c=this.encoding=uy(t.encoding||{},a,o.filled,s);this.markDef=jf(o,c,s),this.size=Jv({encoding:c,size:Ec(t)?{...r,...t.width?{width:t.width}:{},...t.height?{height:t.height}:{}}:r}),this.stack=Mf(this.markDef,c),this.specifiedScales=this.initScales(a,c),this.specifiedAxes=this.initAxes(c),this.specifiedLegends=this.initLegends(c),this.specifiedProjection=t.projection,this.selection=(t.params??[]).filter(l=>ma(l))}get hasProjection(){const{encoding:t}=this,n=this.mark===qu,i=t&&cg.some(r=>D(t[r]));return n||i}scaleDomain(t){const n=this.specifiedScales[t];return n?n.domain:void 0}axis(t){return this.specifiedAxes[t]}legend(t){return this.specifiedLegends[t]}initScales(t,n){return Ur.reduce((i,r)=>{const s=fe(n[r]);return s&&(i[r]=this.initScale(s.scale??{})),i},{})}initScale(t){const{domain:n,range:i}=t,r=Fe(t);return F(n)&&(r.domain=n.map(Le)),F(i)&&(r.range=i.map(Le)),r}initAxes(t){return St.reduce((n,i)=>{const r=t[i];if(D(r)||i===se&&D(t.x2)||i===be&&D(t.y2)){const s=D(r)?r.axis:void 0;n[i]=s&&this.initAxis({...s})}return n},{})}initAxis(t){const n=x(t),i={};for(const r of n){const s=t[r];i[r]=Zi(s)?du(s):Le(s)}return i}initLegends(t){return bg.reduce((n,i)=>{const r=fe(t[i]);if(r&&Sg(i)){const s=r.legend;n[i]=s&&Fe(s)}return n},{})}parseData(){this.component.data=Es(this)}parseLayoutSize(){Iv(this)}parseSelections(){this.component.selection=Cx(this,this.selection)}parseMarkGroup(){this.component.mark=mE(this)}parseAxesAndHeaders(){this.component.axes=Wv(this)}assembleSelectionTopLevelSignals(t){return Vb(this,t)}assembleSignals(){return[...Ed(this),...Hb(this,[])]}assembleSelectionData(t){return Xb(this,t)}assembleLayout(){return null}assembleLayoutSignals(){return Ta(this)}assembleMarks(){let t=this.component.mark??[];return(!this.parent||!Si(this.parent))&&(t=Zf(this,t)),t.map(this.correctDataNames)}assembleGroupStyle(){const{style:t}=this.view||{};return t!==void 0?t:this.encoding.x||this.encoding.y?\"cell\":\"view\"}getMapping(){return this.encoding}get mark(){return this.markDef.type}channelHasField(t){return yn(this.encoding,t)}fieldDef(t){const n=this.encoding[t];return gt(n)}typedFieldDef(t){const n=this.fieldDef(t);return Ce(n)?n:null}}class Ba extends za{constructor(t,n,i,r,s){super(t,\"layer\",n,i,s,t.resolve,t.view);const o={...r,...t.width?{width:t.width}:{},...t.height?{height:t.height}:{}};this.children=t.layer.map((a,c)=>{if(rs(a))return new Ba(a,this,this.getName(`layer_${c}`),o,s);if(zt(a))return new cp(a,this,this.getName(`layer_${c}`),o,s);throw new Error(Lo(a))})}parseData(){this.component.data=Es(this);for(const t of this.children)t.parseData()}parseLayoutSize(){_v(this)}parseSelections(){this.component.selection={};for(const t of this.children){t.parseSelections();for(const n of x(t.component.selection))this.component.selection[n]=t.component.selection[n]}}parseMarkGroup(){for(const t of this.children)t.parseMarkGroup()}parseAxesAndHeaders(){Hv(this)}assembleSelectionTopLevelSignals(t){return this.children.reduce((n,i)=>i.assembleSelectionTopLevelSignals(n),t)}assembleSignals(){return this.children.reduce((t,n)=>t.concat(n.assembleSignals()),Ed(this))}assembleLayoutSignals(){return this.children.reduce((t,n)=>t.concat(n.assembleLayoutSignals()),Ta(this))}assembleSelectionData(t){return this.children.reduce((n,i)=>i.assembleSelectionData(n),t)}assembleGroupStyle(){const t=new Set;for(const i of this.children)for(const r of ce(i.assembleGroupStyle()))t.add(r);const n=Array.from(t);return n.length>1?n:n.length===1?n[0]:void 0}assembleTitle(){let t=super.assembleTitle();if(t)return t;for(const n of this.children)if(t=n.assembleTitle(),t)return t}assembleLayout(){return null}assembleMarks(){return Yb(this,this.children.flatMap(t=>t.assembleMarks()))}assembleLegends(){return this.children.reduce((t,n)=>t.concat(n.assembleLegends()),Md(this))}}function Wa(e,t,n,i,r){if(Kr(e))return new Ri(e,t,n,r);if(rs(e))return new Ba(e,t,n,i,r);if(zt(e))return new cp(e,t,n,i,r);if(Iy(e))return new Mv(e,t,n,r);throw new Error(Lo(e))}function $E(e,t={}){t.logger&&Mh(t.logger),t.fieldTitle&&uf(t.fieldTitle);try{const n=Df(Rr(t.config,e.config)),i=Vf(e,n),r=Wa(i,null,\"\",void 0,n);return r.parse(),VS(r.component.data,r),{spec:CE(r,wE(e,i.autosize,n,r),e.datasets,e.usermeta),normalized:i}}finally{t.logger&&jh(),t.fieldTitle&&ty()}}function wE(e,t,n,i){const r=i.component.layoutSize.get(\"width\"),s=i.component.layoutSize.get(\"height\");if(t===void 0?(t={type:\"pad\"},i.hasAxisOrientSignalRef()&&(t.resize=!0)):R(t)&&(t={type:t}),r&&s&&Ub(t.type)){if(r===\"step\"&&s===\"step\")S(oc()),t.type=\"pad\";else if(r===\"step\"||s===\"step\"){const o=r===\"step\"?\"width\":\"height\";S(oc(jr(o)));const a=o===\"width\"?\"height\":\"width\";t.type=Bb(a)}}return{...x(t).length===1&&t.type?t.type===\"pad\"?{}:{autosize:t.type}:{autosize:t},...Ic(n,!1),...Ic(e,!0)}}function CE(e,t,n={},i){const r=e.config?Xy(e.config):void 0,s=[].concat(e.assembleSelectionData([]),kv(e.component.data,n)),o=e.assembleProjections(),a=e.assembleTitle(),c=e.assembleGroupStyle(),l=e.assembleGroupEncodeEntry(!0);let u=e.assembleLayoutSignals();u=u.filter(g=>(g.name===\"width\"||g.name===\"height\")&&g.value!==void 0?(t[g.name]=+g.value,!1):!0);const{params:f,...d}=t;return{$schema:\"https://vega.github.io/schema/vega/v5.json\",...e.description?{description:e.description}:{},...d,...a?{title:a}:{},...c?{style:c}:{},...l?{encode:{update:l}}:{},data:s,...o.length>0?{projections:o}:{},...e.assembleGroup([...u,...e.assembleSelectionTopLevelSignals([]),...If(f)]),...r?{config:r}:{},...i?{usermeta:i}:{}}}const NE=ng.version,FE=Object.freeze(Object.defineProperty({__proto__:null,accessPathDepth:Qn,accessPathWithDatum:Co,compile:$E,contains:G,deepEqual:Pe,deleteNestedProperty:hr,duplicate:z,entries:Wt,every:Eo,fieldIntersection:wo,flatAccessWithDatum:ql,getFirstDefined:le,hasIntersection:$o,hash:W,internalField:Yl,isBoolean:Li,isEmpty:K,isEqual:rg,isInternalField:Kl,isNullOrFalse:Vs,isNumeric:Ir,keys:x,logicalExpr:Oi,mergeDeep:Gl,never:Wl,normalize:Vf,normalizeAngle:Pi,omit:ke,pick:Jn,prefixGenerator:Xs,removePathFromField:No,replaceAll:vn,replacePathInField:Ue,resetIdCounter:og,setEqual:Hl,some:Sn,stringify:J,titleCase:Wi,unique:lt,uniqueId:Xl,vals:Se,varName:re,version:NE},Symbol.toStringTag,{value:\"Module\"}));function lp(e){const[t,n]=/schema\\/([\\w-]+)\\/([\\w\\.\\-]+)\\.json$/g.exec(e).slice(1,3);return{library:t,version:n}}var kE=\"vega-themes\",TE=\"2.14.0\",AE=\"Themes for stylized Vega and Vega-Lite visualizations.\",OE=[\"vega\",\"vega-lite\",\"themes\",\"style\"],_E=\"BSD-3-Clause\",RE={name:\"UW Interactive Data Lab\",url:\"https://idl.cs.washington.edu\"},IE=[{name:\"Emily Gu\",url:\"https://github.com/emilygu\"},{name:\"Arvind Satyanarayan\",url:\"http://arvindsatya.com\"},{name:\"Jeffrey Heer\",url:\"https://idl.cs.washington.edu\"},{name:\"Dominik Moritz\",url:\"https://www.domoritz.de\"}],LE=\"build/vega-themes.js\",PE=\"build/vega-themes.module.js\",zE=\"build/vega-themes.min.js\",DE=\"build/vega-themes.min.js\",ME=\"build/vega-themes.module.d.ts\",jE={type:\"git\",url:\"https://github.com/vega/vega-themes.git\"},UE=[\"src\",\"build\"],BE={prebuild:\"yarn clean\",build:\"rollup -c\",clean:\"rimraf build && rimraf examples/build\",\"copy:data\":\"rsync -r node_modules/vega-datasets/data/* examples/data\",\"copy:build\":\"rsync -r build/* examples/build\",\"deploy:gh\":\"yarn build && mkdir -p examples/build && rsync -r build/* examples/build && gh-pages -d examples\",preversion:\"yarn lint\",serve:\"browser-sync start -s -f build examples --serveStatic examples\",start:\"yarn build && concurrently --kill-others -n Server,Rollup 'yarn serve' 'rollup -c -w'\",format:\"eslint . --fix\",lint:\"eslint .\",release:\"release-it\"},WE={\"@babel/core\":\"^7.22.9\",\"@babel/plugin-proposal-async-generator-functions\":\"^7.20.7\",\"@babel/plugin-proposal-json-strings\":\"^7.18.6\",\"@babel/plugin-proposal-object-rest-spread\":\"^7.20.7\",\"@babel/plugin-proposal-optional-catch-binding\":\"^7.18.6\",\"@babel/plugin-transform-runtime\":\"^7.22.9\",\"@babel/preset-env\":\"^7.22.9\",\"@babel/preset-typescript\":\"^7.22.5\",\"@release-it/conventional-changelog\":\"^7.0.0\",\"@rollup/plugin-json\":\"^6.0.0\",\"@rollup/plugin-node-resolve\":\"^15.1.0\",\"@rollup/plugin-terser\":\"^0.4.3\",\"@typescript-eslint/eslint-plugin\":\"^6.0.0\",\"@typescript-eslint/parser\":\"^6.0.0\",\"browser-sync\":\"^2.29.3\",concurrently:\"^8.2.0\",eslint:\"^8.45.0\",\"eslint-config-prettier\":\"^8.8.0\",\"eslint-plugin-prettier\":\"^5.0.0\",\"gh-pages\":\"^5.0.0\",prettier:\"^3.0.0\",\"release-it\":\"^16.1.0\",rollup:\"^3.26.2\",\"rollup-plugin-bundle-size\":\"^1.0.3\",\"rollup-plugin-ts\":\"^3.2.0\",typescript:\"^5.1.6\",vega:\"^5.25.0\",\"vega-lite\":\"^5.9.3\"},GE={vega:\"*\",\"vega-lite\":\"*\"},HE={},qE={name:kE,version:TE,description:AE,keywords:OE,license:_E,author:RE,contributors:IE,main:LE,module:PE,unpkg:zE,jsdelivr:DE,types:ME,repository:jE,files:UE,scripts:BE,devDependencies:WE,peerDependencies:GE,dependencies:HE};const Un=\"#fff\",fl=\"#888\",VE={background:\"#333\",view:{stroke:fl},title:{color:Un,subtitleColor:Un},style:{\"guide-label\":{fill:Un},\"guide-title\":{fill:Un}},axis:{domainColor:Un,gridColor:fl,tickColor:Un}},an=\"#4572a7\",XE={background:\"#fff\",arc:{fill:an},area:{fill:an},line:{stroke:an,strokeWidth:2},path:{stroke:an},rect:{fill:an},shape:{stroke:an},symbol:{fill:an,strokeWidth:1.5,size:50},axis:{bandPosition:.5,grid:!0,gridColor:\"#000000\",gridOpacity:1,gridWidth:.5,labelPadding:10,tickSize:5,tickWidth:.5},axisBand:{grid:!1,tickExtra:!0},legend:{labelBaseline:\"middle\",labelFontSize:11,symbolSize:50,symbolType:\"square\"},range:{category:[\"#4572a7\",\"#aa4643\",\"#8aa453\",\"#71598e\",\"#4598ae\",\"#d98445\",\"#94aace\",\"#d09393\",\"#b9cc98\",\"#a99cbc\"]}},cn=\"#30a2da\",Ds=\"#cbcbcb\",YE=\"#999\",KE=\"#333\",dl=\"#f0f0f0\",pl=\"#333\",JE={arc:{fill:cn},area:{fill:cn},axis:{domainColor:Ds,grid:!0,gridColor:Ds,gridWidth:1,labelColor:YE,labelFontSize:10,titleColor:KE,tickColor:Ds,tickSize:10,titleFontSize:14,titlePadding:10,labelPadding:4},axisBand:{grid:!1},background:dl,group:{fill:dl},legend:{labelColor:pl,labelFontSize:11,padding:1,symbolSize:30,symbolType:\"square\",titleColor:pl,titleFontSize:14,titlePadding:10},line:{stroke:cn,strokeWidth:2},path:{stroke:cn,strokeWidth:.5},rect:{fill:cn},range:{category:[\"#30a2da\",\"#fc4f30\",\"#e5ae38\",\"#6d904f\",\"#8b8b8b\",\"#b96db8\",\"#ff9e27\",\"#56cc60\",\"#52d2ca\",\"#52689e\",\"#545454\",\"#9fe4f8\"],diverging:[\"#cc0020\",\"#e77866\",\"#f6e7e1\",\"#d6e8ed\",\"#91bfd9\",\"#1d78b5\"],heatmap:[\"#d6e8ed\",\"#cee0e5\",\"#91bfd9\",\"#549cc6\",\"#1d78b5\"]},point:{filled:!0,shape:\"circle\"},shape:{stroke:cn},bar:{binSpacing:2,fill:cn,stroke:null},title:{anchor:\"start\",fontSize:24,fontWeight:600,offset:20}},ln=\"#000\",QE={group:{fill:\"#e5e5e5\"},arc:{fill:ln},area:{fill:ln},line:{stroke:ln},path:{stroke:ln},rect:{fill:ln},shape:{stroke:ln},symbol:{fill:ln,size:40},axis:{domain:!1,grid:!0,gridColor:\"#FFFFFF\",gridOpacity:1,labelColor:\"#7F7F7F\",labelPadding:4,tickColor:\"#7F7F7F\",tickSize:5.67,titleFontSize:16,titleFontWeight:\"normal\"},legend:{labelBaseline:\"middle\",labelFontSize:11,symbolSize:40},range:{category:[\"#000000\",\"#7F7F7F\",\"#1A1A1A\",\"#999999\",\"#333333\",\"#B0B0B0\",\"#4D4D4D\",\"#C9C9C9\",\"#666666\",\"#DCDCDC\"]}},ZE=22,e$=\"normal\",gl=\"Benton Gothic, sans-serif\",hl=11.5,t$=\"normal\",un=\"#82c6df\",Ms=\"Benton Gothic Bold, sans-serif\",ml=\"normal\",yl=13,$i={\"category-6\":[\"#ec8431\",\"#829eb1\",\"#c89d29\",\"#3580b1\",\"#adc839\",\"#ab7fb4\"],\"fire-7\":[\"#fbf2c7\",\"#f9e39c\",\"#f8d36e\",\"#f4bb6a\",\"#e68a4f\",\"#d15a40\",\"#ab4232\"],\"fireandice-6\":[\"#e68a4f\",\"#f4bb6a\",\"#f9e39c\",\"#dadfe2\",\"#a6b7c6\",\"#849eae\"],\"ice-7\":[\"#edefee\",\"#dadfe2\",\"#c4ccd2\",\"#a6b7c6\",\"#849eae\",\"#607785\",\"#47525d\"]},n$={background:\"#ffffff\",title:{anchor:\"start\",color:\"#000000\",font:Ms,fontSize:ZE,fontWeight:e$},arc:{fill:un},area:{fill:un},line:{stroke:un,strokeWidth:2},path:{stroke:un},rect:{fill:un},shape:{stroke:un},symbol:{fill:un,size:30},axis:{labelFont:gl,labelFontSize:hl,labelFontWeight:t$,titleFont:Ms,titleFontSize:yl,titleFontWeight:ml},axisX:{labelAngle:0,labelPadding:4,tickSize:3},axisY:{labelBaseline:\"middle\",maxExtent:45,minExtent:45,tickSize:2,titleAlign:\"left\",titleAngle:0,titleX:-45,titleY:-11},legend:{labelFont:gl,labelFontSize:hl,symbolType:\"square\",titleFont:Ms,titleFontSize:yl,titleFontWeight:ml},range:{category:$i[\"category-6\"],diverging:$i[\"fireandice-6\"],heatmap:$i[\"fire-7\"],ordinal:$i[\"fire-7\"],ramp:$i[\"fire-7\"]}},fn=\"#ab5787\",lr=\"#979797\",i$={background:\"#f9f9f9\",arc:{fill:fn},area:{fill:fn},line:{stroke:fn},path:{stroke:fn},rect:{fill:fn},shape:{stroke:fn},symbol:{fill:fn,size:30},axis:{domainColor:lr,domainWidth:.5,gridWidth:.2,labelColor:lr,tickColor:lr,tickWidth:.2,titleColor:lr},axisBand:{grid:!1},axisX:{grid:!0,tickSize:10},axisY:{domain:!1,grid:!0,tickSize:0},legend:{labelFontSize:11,padding:1,symbolSize:30,symbolType:\"square\"},range:{category:[\"#ab5787\",\"#51b2e5\",\"#703c5c\",\"#168dd9\",\"#d190b6\",\"#00609f\",\"#d365ba\",\"#154866\",\"#666666\",\"#c4c4c4\"]}},dn=\"#3e5c69\",r$={background:\"#fff\",arc:{fill:dn},area:{fill:dn},line:{stroke:dn},path:{stroke:dn},rect:{fill:dn},shape:{stroke:dn},symbol:{fill:dn},axis:{domainWidth:.5,grid:!0,labelPadding:2,tickSize:5,tickWidth:.5,titleFontWeight:\"normal\"},axisBand:{grid:!1},axisX:{gridWidth:.2},axisY:{gridDash:[3],gridWidth:.4},legend:{labelFontSize:11,padding:1,symbolType:\"square\"},range:{category:[\"#3e5c69\",\"#6793a6\",\"#182429\",\"#0570b0\",\"#3690c0\",\"#74a9cf\",\"#a6bddb\",\"#e2ddf2\"]}},Me=\"#1696d2\",bl=\"#000000\",s$=\"#FFFFFF\",ur=\"Lato\",js=\"Lato\",o$=\"Lato\",a$=\"#DEDDDD\",c$=18,wi={\"main-colors\":[\"#1696d2\",\"#d2d2d2\",\"#000000\",\"#fdbf11\",\"#ec008b\",\"#55b748\",\"#5c5859\",\"#db2b27\"],\"shades-blue\":[\"#CFE8F3\",\"#A2D4EC\",\"#73BFE2\",\"#46ABDB\",\"#1696D2\",\"#12719E\",\"#0A4C6A\",\"#062635\"],\"shades-gray\":[\"#F5F5F5\",\"#ECECEC\",\"#E3E3E3\",\"#DCDBDB\",\"#D2D2D2\",\"#9D9D9D\",\"#696969\",\"#353535\"],\"shades-yellow\":[\"#FFF2CF\",\"#FCE39E\",\"#FDD870\",\"#FCCB41\",\"#FDBF11\",\"#E88E2D\",\"#CA5800\",\"#843215\"],\"shades-magenta\":[\"#F5CBDF\",\"#EB99C2\",\"#E46AA7\",\"#E54096\",\"#EC008B\",\"#AF1F6B\",\"#761548\",\"#351123\"],\"shades-green\":[\"#DCEDD9\",\"#BCDEB4\",\"#98CF90\",\"#78C26D\",\"#55B748\",\"#408941\",\"#2C5C2D\",\"#1A2E19\"],\"shades-black\":[\"#D5D5D4\",\"#ADABAC\",\"#848081\",\"#5C5859\",\"#332D2F\",\"#262223\",\"#1A1717\",\"#0E0C0D\"],\"shades-red\":[\"#F8D5D4\",\"#F1AAA9\",\"#E9807D\",\"#E25552\",\"#DB2B27\",\"#A4201D\",\"#6E1614\",\"#370B0A\"],\"one-group\":[\"#1696d2\",\"#000000\"],\"two-groups-cat-1\":[\"#1696d2\",\"#000000\"],\"two-groups-cat-2\":[\"#1696d2\",\"#fdbf11\"],\"two-groups-cat-3\":[\"#1696d2\",\"#db2b27\"],\"two-groups-seq\":[\"#a2d4ec\",\"#1696d2\"],\"three-groups-cat\":[\"#1696d2\",\"#fdbf11\",\"#000000\"],\"three-groups-seq\":[\"#a2d4ec\",\"#1696d2\",\"#0a4c6a\"],\"four-groups-cat-1\":[\"#000000\",\"#d2d2d2\",\"#fdbf11\",\"#1696d2\"],\"four-groups-cat-2\":[\"#1696d2\",\"#ec0008b\",\"#fdbf11\",\"#5c5859\"],\"four-groups-seq\":[\"#cfe8f3\",\"#73bf42\",\"#1696d2\",\"#0a4c6a\"],\"five-groups-cat-1\":[\"#1696d2\",\"#fdbf11\",\"#d2d2d2\",\"#ec008b\",\"#000000\"],\"five-groups-cat-2\":[\"#1696d2\",\"#0a4c6a\",\"#d2d2d2\",\"#fdbf11\",\"#332d2f\"],\"five-groups-seq\":[\"#cfe8f3\",\"#73bf42\",\"#1696d2\",\"#0a4c6a\",\"#000000\"],\"six-groups-cat-1\":[\"#1696d2\",\"#ec008b\",\"#fdbf11\",\"#000000\",\"#d2d2d2\",\"#55b748\"],\"six-groups-cat-2\":[\"#1696d2\",\"#d2d2d2\",\"#ec008b\",\"#fdbf11\",\"#332d2f\",\"#0a4c6a\"],\"six-groups-seq\":[\"#cfe8f3\",\"#a2d4ec\",\"#73bfe2\",\"#46abdb\",\"#1696d2\",\"#12719e\"],\"diverging-colors\":[\"#ca5800\",\"#fdbf11\",\"#fdd870\",\"#fff2cf\",\"#cfe8f3\",\"#73bfe2\",\"#1696d2\",\"#0a4c6a\"]},l$={background:s$,title:{anchor:\"start\",fontSize:c$,font:ur},axisX:{domain:!0,domainColor:bl,domainWidth:1,grid:!1,labelFontSize:12,labelFont:js,labelAngle:0,tickColor:bl,tickSize:5,titleFontSize:12,titlePadding:10,titleFont:ur},axisY:{domain:!1,domainWidth:1,grid:!0,gridColor:a$,gridWidth:1,labelFontSize:12,labelFont:js,labelPadding:8,ticks:!1,titleFontSize:12,titlePadding:10,titleFont:ur,titleAngle:0,titleY:-10,titleX:18},legend:{labelFontSize:12,labelFont:js,symbolSize:100,titleFontSize:12,titlePadding:10,titleFont:ur,orient:\"right\",offset:10},view:{stroke:\"transparent\"},range:{category:wi[\"six-groups-cat-1\"],diverging:wi[\"diverging-colors\"],heatmap:wi[\"diverging-colors\"],ordinal:wi[\"six-groups-seq\"],ramp:wi[\"shades-blue\"]},area:{fill:Me},rect:{fill:Me},line:{color:Me,stroke:Me,strokeWidth:5},trail:{color:Me,stroke:Me,strokeWidth:0,size:1},path:{stroke:Me,strokeWidth:.5},point:{filled:!0},text:{font:o$,color:Me,fontSize:11,align:\"center\",fontWeight:400,size:11},style:{bar:{fill:Me,stroke:null}},arc:{fill:Me},shape:{stroke:Me},symbol:{fill:Me,size:30}},pn=\"#3366CC\",xl=\"#ccc\",fr=\"Arial, sans-serif\",u$={arc:{fill:pn},area:{fill:pn},path:{stroke:pn},rect:{fill:pn},shape:{stroke:pn},symbol:{stroke:pn},circle:{fill:pn},background:\"#fff\",padding:{top:10,right:10,bottom:10,left:10},style:{\"guide-label\":{font:fr,fontSize:12},\"guide-title\":{font:fr,fontSize:12},\"group-title\":{font:fr,fontSize:12}},title:{font:fr,fontSize:14,fontWeight:\"bold\",dy:-3,anchor:\"start\"},axis:{gridColor:xl,tickColor:xl,domain:!1,grid:!0},range:{category:[\"#4285F4\",\"#DB4437\",\"#F4B400\",\"#0F9D58\",\"#AB47BC\",\"#00ACC1\",\"#FF7043\",\"#9E9D24\",\"#5C6BC0\",\"#F06292\",\"#00796B\",\"#C2185B\"],heatmap:[\"#c6dafc\",\"#5e97f6\",\"#2a56c6\"]}},Ga=e=>e*(1/3+1),Sl=Ga(9),vl=Ga(10),El=Ga(12),Ci=\"Segoe UI\",$l=\"wf_standard-font, helvetica, arial, sans-serif\",wl=\"#252423\",Ni=\"#605E5C\",Cl=\"transparent\",f$=\"#C8C6C4\",qe=\"#118DFF\",d$=\"#12239E\",p$=\"#E66C37\",g$=\"#6B007B\",h$=\"#E044A7\",m$=\"#744EC2\",y$=\"#D9B300\",b$=\"#D64550\",up=qe,fp=\"#DEEFFF\",Nl=[fp,up],x$=[fp,\"#c7e4ff\",\"#b0d9ff\",\"#9aceff\",\"#83c3ff\",\"#6cb9ff\",\"#55aeff\",\"#3fa3ff\",\"#2898ff\",up],S$={view:{stroke:Cl},background:Cl,font:Ci,header:{titleFont:$l,titleFontSize:El,titleColor:wl,labelFont:Ci,labelFontSize:vl,labelColor:Ni},axis:{ticks:!1,grid:!1,domain:!1,labelColor:Ni,labelFontSize:Sl,titleFont:$l,titleColor:wl,titleFontSize:El,titleFontWeight:\"normal\"},axisQuantitative:{tickCount:3,grid:!0,gridColor:f$,gridDash:[1,5],labelFlush:!1},axisBand:{tickExtra:!0},axisX:{labelPadding:5},axisY:{labelPadding:10},bar:{fill:qe},line:{stroke:qe,strokeWidth:3,strokeCap:\"round\",strokeJoin:\"round\"},text:{font:Ci,fontSize:Sl,fill:Ni},arc:{fill:qe},area:{fill:qe,line:!0,opacity:.6},path:{stroke:qe},rect:{fill:qe},point:{fill:qe,filled:!0,size:75},shape:{stroke:qe},symbol:{fill:qe,strokeWidth:1.5,size:50},legend:{titleFont:Ci,titleFontWeight:\"bold\",titleColor:Ni,labelFont:Ci,labelFontSize:vl,labelColor:Ni,symbolType:\"circle\",symbolSize:75},range:{category:[qe,d$,p$,g$,h$,m$,y$,b$],diverging:Nl,heatmap:Nl,ordinal:x$}},Us='IBM Plex Sans,system-ui,-apple-system,BlinkMacSystemFont,\".sfnstext-regular\",sans-serif',Fl=400,v$=[\"#8a3ffc\",\"#33b1ff\",\"#007d79\",\"#ff7eb6\",\"#fa4d56\",\"#fff1f1\",\"#6fdc8c\",\"#4589ff\",\"#d12771\",\"#d2a106\",\"#08bdba\",\"#bae6ff\",\"#ba4e00\",\"#d4bbff\"],E$=[\"#6929c4\",\"#1192e8\",\"#005d5d\",\"#9f1853\",\"#fa4d56\",\"#570408\",\"#198038\",\"#002d9c\",\"#ee538b\",\"#b28600\",\"#009d9a\",\"#012749\",\"#8a3800\",\"#a56eff\"];function $s({type:e,background:t}){const n=e===\"dark\"?\"#161616\":\"#ffffff\",i=e===\"dark\"?\"#f4f4f4\":\"#161616\",r=e===\"dark\"?v$:E$,s=e===\"dark\"?\"#d4bbff\":\"#6929c4\";return{background:t,arc:{fill:s},area:{fill:s},path:{stroke:s},rect:{fill:s},shape:{stroke:s},symbol:{stroke:s},circle:{fill:s},view:{fill:n,stroke:n},group:{fill:n},title:{color:i,anchor:\"start\",dy:-15,fontSize:16,font:Us,fontWeight:600},axis:{labelColor:i,labelFontSize:12,grid:!0,gridColor:\"#525252\",titleColor:i,labelAngle:0},style:{\"guide-label\":{font:Us,fill:i,fontWeight:Fl},\"guide-title\":{font:Us,fill:i,fontWeight:Fl}},range:{category:r,diverging:[\"#750e13\",\"#a2191f\",\"#da1e28\",\"#fa4d56\",\"#ff8389\",\"#ffb3b8\",\"#ffd7d9\",\"#fff1f1\",\"#e5f6ff\",\"#bae6ff\",\"#82cfff\",\"#33b1ff\",\"#1192e8\",\"#0072c3\",\"#00539a\",\"#003a6d\"],heatmap:[\"#f6f2ff\",\"#e8daff\",\"#d4bbff\",\"#be95ff\",\"#a56eff\",\"#8a3ffc\",\"#6929c4\",\"#491d8b\",\"#31135e\",\"#1c0f30\"]}}}const $$=$s({type:\"light\",background:\"#ffffff\"}),w$=$s({type:\"light\",background:\"#f4f4f4\"}),C$=$s({type:\"dark\",background:\"#262626\"}),N$=$s({type:\"dark\",background:\"#161616\"}),F$=qE.version,k$=Object.freeze(Object.defineProperty({__proto__:null,carbong10:w$,carbong100:N$,carbong90:C$,carbonwhite:$$,dark:VE,excel:XE,fivethirtyeight:JE,ggplot2:QE,googlecharts:u$,latimes:n$,powerbi:S$,quartz:i$,urbaninstitute:l$,version:F$,vox:r$},Symbol.toStringTag,{value:\"Module\"}));function T$(e,t,n,i){if(F(e))return`[${e.map(r=>t(R(r)?r:kl(r,n))).join(\", \")}]`;if(H(e)){let r=\"\";const{title:s,image:o,...a}=e;s&&(r+=`

${t(s)}

`),o&&(r+=``);const c=Object.keys(a);if(c.length>0){r+=\"\";for(const l of c){let u=a[l];u!==void 0&&(H(u)&&(u=kl(u,n)),r+=``)}r+=\"
${t(l)}${t(u)}
\"}return r||\"{}\"}return t(e)}function A$(e){const t=[];return function(n,i){if(typeof i!=\"object\"||i===null)return i;const r=t.indexOf(this)+1;return t.length=r,t.length>e?\"[Object]\":t.indexOf(i)>=0?\"[Circular]\":(t.push(i),i)}}function kl(e,t){return JSON.stringify(e,A$(t))}var O$=`#vg-tooltip-element {\n visibility: hidden;\n padding: 8px;\n position: fixed;\n z-index: 1000;\n font-family: sans-serif;\n font-size: 11px;\n border-radius: 3px;\n box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);\n /* The default theme is the light theme. */\n background-color: rgba(255, 255, 255, 0.95);\n border: 1px solid #d9d9d9;\n color: black;\n}\n#vg-tooltip-element.visible {\n visibility: visible;\n}\n#vg-tooltip-element h2 {\n margin-top: 0;\n margin-bottom: 10px;\n font-size: 13px;\n}\n#vg-tooltip-element table {\n border-spacing: 0;\n}\n#vg-tooltip-element table tr {\n border: none;\n}\n#vg-tooltip-element table tr td {\n overflow: hidden;\n text-overflow: ellipsis;\n padding-top: 2px;\n padding-bottom: 2px;\n}\n#vg-tooltip-element table tr td.key {\n color: #808080;\n max-width: 150px;\n text-align: right;\n padding-right: 4px;\n}\n#vg-tooltip-element table tr td.value {\n display: block;\n max-width: 300px;\n max-height: 7em;\n text-align: left;\n}\n#vg-tooltip-element.dark-theme {\n background-color: rgba(32, 32, 32, 0.9);\n border: 1px solid #f5f5f5;\n color: white;\n}\n#vg-tooltip-element.dark-theme td.key {\n color: #bfbfbf;\n}\n`;const dp=\"vg-tooltip-element\",_$={offsetX:10,offsetY:10,id:dp,styleId:\"vega-tooltip-style\",theme:\"light\",disableDefaultStyle:!1,sanitize:R$,maxDepth:2,formatTooltip:T$,baseURL:\"\"};function R$(e){return String(e).replace(/&/g,\"&\").replace(/window.innerWidth&&(r=+e.clientX-n-t.width);let s=e.clientY+i;return s+t.height>window.innerHeight&&(s=+e.clientY-i-t.height),{x:r,y:s}}class P${constructor(t){this.options={..._$,...t};const n=this.options.id;if(this.el=null,this.call=this.tooltipHandler.bind(this),!this.options.disableDefaultStyle&&!document.getElementById(this.options.styleId)){const i=document.createElement(\"style\");i.setAttribute(\"id\",this.options.styleId),i.innerHTML=I$(n);const r=document.head;r.childNodes.length>0?r.insertBefore(i,r.childNodes[0]):r.appendChild(i)}}tooltipHandler(t,n,i,r){if(this.el=document.getElementById(this.options.id),this.el||(this.el=document.createElement(\"div\"),this.el.setAttribute(\"id\",this.options.id),this.el.classList.add(\"vg-tooltip\"),(document.fullscreenElement??document.body).appendChild(this.el)),r==null||r===\"\"){this.el.classList.remove(\"visible\",`${this.options.theme}-theme`);return}this.el.innerHTML=this.options.formatTooltip(r,this.options.sanitize,this.options.maxDepth,this.options.baseURL),this.el.classList.add(\"visible\",`${this.options.theme}-theme`);const{x:s,y:o}=L$(n,this.el.getBoundingClientRect(),this.options.offsetX,this.options.offsetY);this.el.style.top=`${o}px`,this.el.style.left=`${s}px`}}function z$(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,\"default\")?e.default:e}var Bs,Tl;function D$(){return Tl||(Tl=1,Bs=function(e){e.prototype[Symbol.iterator]=function*(){for(let t=this.head;t;t=t.next)yield t.value}}),Bs}var M$=q;q.Node=An;q.create=q;function q(e){var t=this;if(t instanceof q||(t=new q),t.tail=null,t.head=null,t.length=0,e&&typeof e.forEach==\"function\")e.forEach(function(r){t.push(r)});else if(arguments.length>0)for(var n=0,i=arguments.length;n1)n=t;else if(this.head)i=this.head.next,n=this.head.value;else throw new TypeError(\"Reduce of empty list with no initial value\");for(var r=0;i!==null;r++)n=e(n,i.value,r),i=i.next;return n};q.prototype.reduceReverse=function(e,t){var n,i=this.tail;if(arguments.length>1)n=t;else if(this.tail)i=this.tail.prev,n=this.tail.value;else throw new TypeError(\"Reduce of empty list with no initial value\");for(var r=this.length-1;i!==null;r--)n=e(n,i.value,r),i=i.prev;return n};q.prototype.toArray=function(){for(var e=new Array(this.length),t=0,n=this.head;n!==null;t++)e[t]=n.value,n=n.next;return e};q.prototype.toArrayReverse=function(){for(var e=new Array(this.length),t=0,n=this.tail;n!==null;t++)e[t]=n.value,n=n.prev;return e};q.prototype.slice=function(e,t){t=t||this.length,t<0&&(t+=this.length),e=e||0,e<0&&(e+=this.length);var n=new q;if(tthis.length&&(t=this.length);for(var i=0,r=this.head;r!==null&&ithis.length&&(t=this.length);for(var i=this.length,r=this.tail;r!==null&&i>t;i--)r=r.prev;for(;r!==null&&i>e;i--,r=r.prev)n.push(r.value);return n};q.prototype.splice=function(e,t,...n){e>this.length&&(e=this.length-1),e<0&&(e=this.length+e);for(var i=0,r=this.head;r!==null&&i1;class G${constructor(t){if(typeof t==\"number\"&&(t={max:t}),t||(t={}),t.max&&(typeof t.max!=\"number\"||t.max<0))throw new TypeError(\"max must be a non-negative number\");this[gn]=t.max||1/0;const n=t.length||Ws;if(this[Bn]=typeof n!=\"function\"?Ws:n,this[Ii]=t.stale||!1,t.maxAge&&typeof t.maxAge!=\"number\")throw new TypeError(\"maxAge must be a number\");this[hn]=t.maxAge||0,this[$t]=t.dispose,this[Al]=t.noDisposeOnSet||!1,this[pp]=t.updateAgeOnGet||!1,this.reset()}set max(t){if(typeof t!=\"number\"||t<0)throw new TypeError(\"max must be a non-negative number\");this[gn]=t||1/0,Fi(this)}get max(){return this[gn]}set allowStale(t){this[Ii]=!!t}get allowStale(){return this[Ii]}set maxAge(t){if(typeof t!=\"number\")throw new TypeError(\"maxAge must be a non-negative number\");this[hn]=t,Fi(this)}get maxAge(){return this[hn]}set lengthCalculator(t){typeof t!=\"function\"&&(t=Ws),t!==this[Bn]&&(this[Bn]=t,this[wt]=0,this[pe].forEach(n=>{n.length=this[Bn](n.value,n.key),this[wt]+=n.length})),Fi(this)}get lengthCalculator(){return this[Bn]}get length(){return this[wt]}get itemCount(){return this[pe].length}rforEach(t,n){n=n||this;for(let i=this[pe].tail;i!==null;){const r=i.prev;Ol(this,t,i,n),i=r}}forEach(t,n){n=n||this;for(let i=this[pe].head;i!==null;){const r=i.next;Ol(this,t,i,n),i=r}}keys(){return this[pe].toArray().map(t=>t.key)}values(){return this[pe].toArray().map(t=>t.value)}reset(){this[$t]&&this[pe]&&this[pe].length&&this[pe].forEach(t=>this[$t](t.key,t.value)),this[Ve]=new Map,this[pe]=new W$,this[wt]=0}dump(){return this[pe].map(t=>Or(this,t)?!1:{k:t.key,v:t.value,e:t.now+(t.maxAge||0)}).toArray().filter(t=>t)}dumpLru(){return this[pe]}set(t,n,i){if(i=i||this[hn],i&&typeof i!=\"number\")throw new TypeError(\"maxAge must be a number\");const r=i?Date.now():0,s=this[Bn](n,t);if(this[Ve].has(t)){if(s>this[gn])return Kn(this,this[Ve].get(t)),!1;const c=this[Ve].get(t).value;return this[$t]&&(this[Al]||this[$t](t,c.value)),c.now=r,c.maxAge=i,c.value=n,this[wt]+=s-c.length,c.length=s,this.get(t),Fi(this),!0}const o=new H$(t,n,s,r,i);return o.length>this[gn]?(this[$t]&&this[$t](t,n),!1):(this[wt]+=o.length,this[pe].unshift(o),this[Ve].set(t,this[pe].head),Fi(this),!0)}has(t){if(!this[Ve].has(t))return!1;const n=this[Ve].get(t).value;return!Or(this,n)}get(t){return Gs(this,t,!0)}peek(t){return Gs(this,t,!1)}pop(){const t=this[pe].tail;return t?(Kn(this,t),t.value):null}del(t){Kn(this,this[Ve].get(t))}load(t){this.reset();const n=Date.now();for(let i=t.length-1;i>=0;i--){const r=t[i],s=r.e||0;if(s===0)this.set(r.k,r.v);else{const o=s-n;o>0&&this.set(r.k,r.v,o)}}}prune(){this[Ve].forEach((t,n)=>Gs(this,n,!1))}}const Gs=(e,t,n)=>{const i=e[Ve].get(t);if(i){const r=i.value;if(Or(e,r)){if(Kn(e,i),!e[Ii])return}else n&&(e[pp]&&(i.value.now=Date.now()),e[pe].unshiftNode(i));return r.value}},Or=(e,t)=>{if(!t||!t.maxAge&&!e[hn])return!1;const n=Date.now()-t.now;return t.maxAge?n>t.maxAge:e[hn]&&n>e[hn]},Fi=e=>{if(e[wt]>e[gn])for(let t=e[pe].tail;e[wt]>e[gn]&&t!==null;){const n=t.prev;Kn(e,t),t=n}},Kn=(e,t)=>{if(t){const n=t.value;e[$t]&&e[$t](n.key,n.value),e[wt]-=n.length,e[Ve].delete(n.key),e[pe].removeNode(t)}};class H${constructor(t,n,i,r,s){this.key=t,this.value=n,this.length=i,this.now=r,this.maxAge=s||0}}const Ol=(e,t,n,i)=>{let r=n.value;Or(e,r)&&(Kn(e,n),e[Ii]||(r=void 0)),r&&t.call(i,r.value,r.key,e)};var q$=G$;const V$=Object.freeze({loose:!0}),X$=Object.freeze({}),Y$=e=>e?typeof e!=\"object\"?V$:e:X$;var Ha=Y$,yo={exports:{}};const K$=\"2.0.0\",gp=256,J$=Number.MAX_SAFE_INTEGER||9007199254740991,Q$=16,Z$=gp-6,e1=[\"major\",\"premajor\",\"minor\",\"preminor\",\"patch\",\"prepatch\",\"prerelease\"];var qa={MAX_LENGTH:gp,MAX_SAFE_COMPONENT_LENGTH:Q$,MAX_SAFE_BUILD_LENGTH:Z$,MAX_SAFE_INTEGER:J$,RELEASE_TYPES:e1,SEMVER_SPEC_VERSION:K$,FLAG_INCLUDE_PRERELEASE:1,FLAG_LOOSE:2};const t1=typeof process==\"object\"&&process.env&&process.env.NODE_DEBUG&&/\\bsemver\\b/i.test(process.env.NODE_DEBUG)?(...e)=>console.error(\"SEMVER\",...e):()=>{};var ws=t1;(function(e,t){const{MAX_SAFE_COMPONENT_LENGTH:n,MAX_SAFE_BUILD_LENGTH:i,MAX_LENGTH:r}=qa,s=ws;t=e.exports={};const o=t.re=[],a=t.safeRe=[],c=t.src=[],l=t.t={};let u=0;const f=\"[a-zA-Z0-9-]\",d=[[\"\\\\s\",1],[\"\\\\d\",r],[f,i]],g=h=>{for(const[m,y]of d)h=h.split(`${m}*`).join(`${m}{0,${y}}`).split(`${m}+`).join(`${m}{1,${y}}`);return h},p=(h,m,y)=>{const b=g(m),C=u++;s(h,C,m),l[h]=C,c[C]=m,o[C]=new RegExp(m,y?\"g\":void 0),a[C]=new RegExp(b,y?\"g\":void 0)};p(\"NUMERICIDENTIFIER\",\"0|[1-9]\\\\d*\"),p(\"NUMERICIDENTIFIERLOOSE\",\"\\\\d+\"),p(\"NONNUMERICIDENTIFIER\",`\\\\d*[a-zA-Z-]${f}*`),p(\"MAINVERSION\",`(${c[l.NUMERICIDENTIFIER]})\\\\.(${c[l.NUMERICIDENTIFIER]})\\\\.(${c[l.NUMERICIDENTIFIER]})`),p(\"MAINVERSIONLOOSE\",`(${c[l.NUMERICIDENTIFIERLOOSE]})\\\\.(${c[l.NUMERICIDENTIFIERLOOSE]})\\\\.(${c[l.NUMERICIDENTIFIERLOOSE]})`),p(\"PRERELEASEIDENTIFIER\",`(?:${c[l.NUMERICIDENTIFIER]}|${c[l.NONNUMERICIDENTIFIER]})`),p(\"PRERELEASEIDENTIFIERLOOSE\",`(?:${c[l.NUMERICIDENTIFIERLOOSE]}|${c[l.NONNUMERICIDENTIFIER]})`),p(\"PRERELEASE\",`(?:-(${c[l.PRERELEASEIDENTIFIER]}(?:\\\\.${c[l.PRERELEASEIDENTIFIER]})*))`),p(\"PRERELEASELOOSE\",`(?:-?(${c[l.PRERELEASEIDENTIFIERLOOSE]}(?:\\\\.${c[l.PRERELEASEIDENTIFIERLOOSE]})*))`),p(\"BUILDIDENTIFIER\",`${f}+`),p(\"BUILD\",`(?:\\\\+(${c[l.BUILDIDENTIFIER]}(?:\\\\.${c[l.BUILDIDENTIFIER]})*))`),p(\"FULLPLAIN\",`v?${c[l.MAINVERSION]}${c[l.PRERELEASE]}?${c[l.BUILD]}?`),p(\"FULL\",`^${c[l.FULLPLAIN]}$`),p(\"LOOSEPLAIN\",`[v=\\\\s]*${c[l.MAINVERSIONLOOSE]}${c[l.PRERELEASELOOSE]}?${c[l.BUILD]}?`),p(\"LOOSE\",`^${c[l.LOOSEPLAIN]}$`),p(\"GTLT\",\"((?:<|>)?=?)\"),p(\"XRANGEIDENTIFIERLOOSE\",`${c[l.NUMERICIDENTIFIERLOOSE]}|x|X|\\\\*`),p(\"XRANGEIDENTIFIER\",`${c[l.NUMERICIDENTIFIER]}|x|X|\\\\*`),p(\"XRANGEPLAIN\",`[v=\\\\s]*(${c[l.XRANGEIDENTIFIER]})(?:\\\\.(${c[l.XRANGEIDENTIFIER]})(?:\\\\.(${c[l.XRANGEIDENTIFIER]})(?:${c[l.PRERELEASE]})?${c[l.BUILD]}?)?)?`),p(\"XRANGEPLAINLOOSE\",`[v=\\\\s]*(${c[l.XRANGEIDENTIFIERLOOSE]})(?:\\\\.(${c[l.XRANGEIDENTIFIERLOOSE]})(?:\\\\.(${c[l.XRANGEIDENTIFIERLOOSE]})(?:${c[l.PRERELEASELOOSE]})?${c[l.BUILD]}?)?)?`),p(\"XRANGE\",`^${c[l.GTLT]}\\\\s*${c[l.XRANGEPLAIN]}$`),p(\"XRANGELOOSE\",`^${c[l.GTLT]}\\\\s*${c[l.XRANGEPLAINLOOSE]}$`),p(\"COERCEPLAIN\",`(^|[^\\\\d])(\\\\d{1,${n}})(?:\\\\.(\\\\d{1,${n}}))?(?:\\\\.(\\\\d{1,${n}}))?`),p(\"COERCE\",`${c[l.COERCEPLAIN]}(?:$|[^\\\\d])`),p(\"COERCEFULL\",c[l.COERCEPLAIN]+`(?:${c[l.PRERELEASE]})?(?:${c[l.BUILD]})?(?:$|[^\\\\d])`),p(\"COERCERTL\",c[l.COERCE],!0),p(\"COERCERTLFULL\",c[l.COERCEFULL],!0),p(\"LONETILDE\",\"(?:~>?)\"),p(\"TILDETRIM\",`(\\\\s*)${c[l.LONETILDE]}\\\\s+`,!0),t.tildeTrimReplace=\"$1~\",p(\"TILDE\",`^${c[l.LONETILDE]}${c[l.XRANGEPLAIN]}$`),p(\"TILDELOOSE\",`^${c[l.LONETILDE]}${c[l.XRANGEPLAINLOOSE]}$`),p(\"LONECARET\",\"(?:\\\\^)\"),p(\"CARETTRIM\",`(\\\\s*)${c[l.LONECARET]}\\\\s+`,!0),t.caretTrimReplace=\"$1^\",p(\"CARET\",`^${c[l.LONECARET]}${c[l.XRANGEPLAIN]}$`),p(\"CARETLOOSE\",`^${c[l.LONECARET]}${c[l.XRANGEPLAINLOOSE]}$`),p(\"COMPARATORLOOSE\",`^${c[l.GTLT]}\\\\s*(${c[l.LOOSEPLAIN]})$|^$`),p(\"COMPARATOR\",`^${c[l.GTLT]}\\\\s*(${c[l.FULLPLAIN]})$|^$`),p(\"COMPARATORTRIM\",`(\\\\s*)${c[l.GTLT]}\\\\s*(${c[l.LOOSEPLAIN]}|${c[l.XRANGEPLAIN]})`,!0),t.comparatorTrimReplace=\"$1$2$3\",p(\"HYPHENRANGE\",`^\\\\s*(${c[l.XRANGEPLAIN]})\\\\s+-\\\\s+(${c[l.XRANGEPLAIN]})\\\\s*$`),p(\"HYPHENRANGELOOSE\",`^\\\\s*(${c[l.XRANGEPLAINLOOSE]})\\\\s+-\\\\s+(${c[l.XRANGEPLAINLOOSE]})\\\\s*$`),p(\"STAR\",\"(<|>)?=?\\\\s*\\\\*\"),p(\"GTE0\",\"^\\\\s*>=\\\\s*0\\\\.0\\\\.0\\\\s*$\"),p(\"GTE0PRE\",\"^\\\\s*>=\\\\s*0\\\\.0\\\\.0-0\\\\s*$\")})(yo,yo.exports);var Va=yo.exports;const _l=/^[0-9]+$/,hp=(e,t)=>{const n=_l.test(e),i=_l.test(t);return n&&i&&(e=+e,t=+t),e===t?0:n&&!i?-1:i&&!n?1:ehp(t,e);var i1={compareIdentifiers:hp,rcompareIdentifiers:n1};const dr=ws,{MAX_LENGTH:Rl,MAX_SAFE_INTEGER:pr}=qa,{safeRe:Il,t:Ll}=Va,r1=Ha,{compareIdentifiers:Wn}=i1;let s1=class ot{constructor(t,n){if(n=r1(n),t instanceof ot){if(t.loose===!!n.loose&&t.includePrerelease===!!n.includePrerelease)return t;t=t.version}else if(typeof t!=\"string\")throw new TypeError(`Invalid version. Must be a string. Got type \"${typeof t}\".`);if(t.length>Rl)throw new TypeError(`version is longer than ${Rl} characters`);dr(\"SemVer\",t,n),this.options=n,this.loose=!!n.loose,this.includePrerelease=!!n.includePrerelease;const i=t.trim().match(n.loose?Il[Ll.LOOSE]:Il[Ll.FULL]);if(!i)throw new TypeError(`Invalid Version: ${t}`);if(this.raw=t,this.major=+i[1],this.minor=+i[2],this.patch=+i[3],this.major>pr||this.major<0)throw new TypeError(\"Invalid major version\");if(this.minor>pr||this.minor<0)throw new TypeError(\"Invalid minor version\");if(this.patch>pr||this.patch<0)throw new TypeError(\"Invalid patch version\");i[4]?this.prerelease=i[4].split(\".\").map(r=>{if(/^[0-9]+$/.test(r)){const s=+r;if(s>=0&&s=0;)typeof this.prerelease[s]==\"number\"&&(this.prerelease[s]++,s=-2);if(s===-1){if(n===this.prerelease.join(\".\")&&i===!1)throw new Error(\"invalid increment argument: identifier already exists\");this.prerelease.push(r)}}if(n){let s=[n,r];i===!1&&(s=[n]),Wn(this.prerelease[0],n)===0?isNaN(this.prerelease[1])&&(this.prerelease=s):this.prerelease=s}break}default:throw new Error(`invalid increment argument: ${t}`)}return this.raw=this.format(),this.build.length&&(this.raw+=`+${this.build.join(\".\")}`),this}};var Xa=s1;const Pl=Xa,o1=(e,t,n)=>new Pl(e,n).compare(new Pl(t,n));var vi=o1;const a1=vi,c1=(e,t,n)=>a1(e,t,n)===0;var l1=c1;const u1=vi,f1=(e,t,n)=>u1(e,t,n)!==0;var d1=f1;const p1=vi,g1=(e,t,n)=>p1(e,t,n)>0;var h1=g1;const m1=vi,y1=(e,t,n)=>m1(e,t,n)>=0;var b1=y1;const x1=vi,S1=(e,t,n)=>x1(e,t,n)<0;var v1=S1;const E1=vi,$1=(e,t,n)=>E1(e,t,n)<=0;var w1=$1;const C1=l1,N1=d1,F1=h1,k1=b1,T1=v1,A1=w1,O1=(e,t,n,i)=>{switch(t){case\"===\":return typeof e==\"object\"&&(e=e.version),typeof n==\"object\"&&(n=n.version),e===n;case\"!==\":return typeof e==\"object\"&&(e=e.version),typeof n==\"object\"&&(n=n.version),e!==n;case\"\":case\"=\":case\"==\":return C1(e,n,i);case\"!=\":return N1(e,n,i);case\">\":return F1(e,n,i);case\">=\":return k1(e,n,i);case\"<\":return T1(e,n,i);case\"<=\":return A1(e,n,i);default:throw new TypeError(`Invalid operator: ${t}`)}};var _1=O1,Hs,zl;function R1(){if(zl)return Hs;zl=1;const e=Symbol(\"SemVer ANY\");class t{static get ANY(){return e}constructor(u,f){if(f=n(f),u instanceof t){if(u.loose===!!f.loose)return u;u=u.value}u=u.trim().split(/\\s+/).join(\" \"),o(\"comparator\",u,f),this.options=f,this.loose=!!f.loose,this.parse(u),this.semver===e?this.value=\"\":this.value=this.operator+this.semver.version,o(\"comp\",this)}parse(u){const f=this.options.loose?i[r.COMPARATORLOOSE]:i[r.COMPARATOR],d=u.match(f);if(!d)throw new TypeError(`Invalid comparator: ${u}`);this.operator=d[1]!==void 0?d[1]:\"\",this.operator===\"=\"&&(this.operator=\"\"),d[2]?this.semver=new a(d[2],this.options.loose):this.semver=e}toString(){return this.value}test(u){if(o(\"Comparator.test\",u,this.options.loose),this.semver===e||u===e)return!0;if(typeof u==\"string\")try{u=new a(u,this.options)}catch{return!1}return s(u,this.operator,this.semver,this.options)}intersects(u,f){if(!(u instanceof t))throw new TypeError(\"a Comparator is required\");return this.operator===\"\"?this.value===\"\"?!0:new c(u.value,f).test(this.value):u.operator===\"\"?u.value===\"\"?!0:new c(this.value,f).test(u.semver):(f=n(f),f.includePrerelease&&(this.value===\"<0.0.0-0\"||u.value===\"<0.0.0-0\")||!f.includePrerelease&&(this.value.startsWith(\"<0.0.0\")||u.value.startsWith(\"<0.0.0\"))?!1:!!(this.operator.startsWith(\">\")&&u.operator.startsWith(\">\")||this.operator.startsWith(\"<\")&&u.operator.startsWith(\"<\")||this.semver.version===u.semver.version&&this.operator.includes(\"=\")&&u.operator.includes(\"=\")||s(this.semver,\"<\",u.semver,f)&&this.operator.startsWith(\">\")&&u.operator.startsWith(\"<\")||s(this.semver,\">\",u.semver,f)&&this.operator.startsWith(\"<\")&&u.operator.startsWith(\">\")))}}Hs=t;const n=Ha,{safeRe:i,t:r}=Va,s=_1,o=ws,a=Xa,c=mp();return Hs}var qs,Dl;function mp(){if(Dl)return qs;Dl=1;class e{constructor($,I){if(I=i(I),$ instanceof e)return $.loose===!!I.loose&&$.includePrerelease===!!I.includePrerelease?$:new e($.raw,I);if($ instanceof r)return this.raw=$.value,this.set=[[$]],this.format(),this;if(this.options=I,this.loose=!!I.loose,this.includePrerelease=!!I.includePrerelease,this.raw=$.trim().split(/\\s+/).join(\" \"),this.set=this.raw.split(\"||\").map(O=>this.parseRange(O.trim())).filter(O=>O.length),!this.set.length)throw new TypeError(`Invalid SemVer Range: ${this.raw}`);if(this.set.length>1){const O=this.set[0];if(this.set=this.set.filter(P=>!p(P[0])),this.set.length===0)this.set=[O];else if(this.set.length>1){for(const P of this.set)if(P.length===1&&h(P[0])){this.set=[P];break}}}this.format()}format(){return this.range=this.set.map($=>$.join(\" \").trim()).join(\"||\").trim(),this.range}toString(){return this.range}parseRange($){const O=((this.options.includePrerelease&&d)|(this.options.loose&&g))+\":\"+$,P=n.get(O);if(P)return P;const A=this.options.loose,M=A?a[c.HYPHENRANGELOOSE]:a[c.HYPHENRANGE];$=$.replace(M,Re(this.options.includePrerelease)),s(\"hyphen replace\",$),$=$.replace(a[c.COMPARATORTRIM],l),s(\"comparator trim\",$),$=$.replace(a[c.TILDETRIM],u),s(\"tilde trim\",$),$=$.replace(a[c.CARETTRIM],f),s(\"caret trim\",$);let V=$.split(\" \").map(te=>y(te,this.options)).join(\" \").split(/\\s+/).map(te=>de(te,this.options));A&&(V=V.filter(te=>(s(\"loose invalid filter\",te,this.options),!!te.match(a[c.COMPARATORLOOSE])))),s(\"range list\",V);const j=new Map,Q=V.map(te=>new r(te,this.options));for(const te of Q){if(p(te))return[te];j.set(te.value,te)}j.size>1&&j.has(\"\")&&j.delete(\"\");const ve=[...j.values()];return n.set(O,ve),ve}intersects($,I){if(!($ instanceof e))throw new TypeError(\"a Range is required\");return this.set.some(O=>m(O,I)&&$.set.some(P=>m(P,I)&&O.every(A=>P.every(M=>A.intersects(M,I)))))}test($){if(!$)return!1;if(typeof $==\"string\")try{$=new o($,this.options)}catch{return!1}for(let I=0;Iw.value===\"<0.0.0-0\",h=w=>w.value===\"\",m=(w,$)=>{let I=!0;const O=w.slice();let P=O.pop();for(;I&&O.length;)I=O.every(A=>P.intersects(A,$)),P=O.pop();return I},y=(w,$)=>(s(\"comp\",w,$),w=N(w,$),s(\"caret\",w),w=C(w,$),s(\"tildes\",w),w=L(w,$),s(\"xrange\",w),w=oe(w,$),s(\"stars\",w),w),b=w=>!w||w.toLowerCase()===\"x\"||w===\"*\",C=(w,$)=>w.trim().split(/\\s+/).map(I=>k(I,$)).join(\" \"),k=(w,$)=>{const I=$.loose?a[c.TILDELOOSE]:a[c.TILDE];return w.replace(I,(O,P,A,M,V)=>{s(\"tilde\",w,O,P,A,M,V);let j;return b(P)?j=\"\":b(A)?j=`>=${P}.0.0 <${+P+1}.0.0-0`:b(M)?j=`>=${P}.${A}.0 <${P}.${+A+1}.0-0`:V?(s(\"replaceTilde pr\",V),j=`>=${P}.${A}.${M}-${V} <${P}.${+A+1}.0-0`):j=`>=${P}.${A}.${M} <${P}.${+A+1}.0-0`,s(\"tilde return\",j),j})},N=(w,$)=>w.trim().split(/\\s+/).map(I=>_(I,$)).join(\" \"),_=(w,$)=>{s(\"caret\",w,$);const I=$.loose?a[c.CARETLOOSE]:a[c.CARET],O=$.includePrerelease?\"-0\":\"\";return w.replace(I,(P,A,M,V,j)=>{s(\"caret\",w,P,A,M,V,j);let Q;return b(A)?Q=\"\":b(M)?Q=`>=${A}.0.0${O} <${+A+1}.0.0-0`:b(V)?A===\"0\"?Q=`>=${A}.${M}.0${O} <${A}.${+M+1}.0-0`:Q=`>=${A}.${M}.0${O} <${+A+1}.0.0-0`:j?(s(\"replaceCaret pr\",j),A===\"0\"?M===\"0\"?Q=`>=${A}.${M}.${V}-${j} <${A}.${M}.${+V+1}-0`:Q=`>=${A}.${M}.${V}-${j} <${A}.${+M+1}.0-0`:Q=`>=${A}.${M}.${V}-${j} <${+A+1}.0.0-0`):(s(\"no pr\"),A===\"0\"?M===\"0\"?Q=`>=${A}.${M}.${V}${O} <${A}.${M}.${+V+1}-0`:Q=`>=${A}.${M}.${V}${O} <${A}.${+M+1}.0-0`:Q=`>=${A}.${M}.${V} <${+A+1}.0.0-0`),s(\"caret return\",Q),Q})},L=(w,$)=>(s(\"replaceXRanges\",w,$),w.split(/\\s+/).map(I=>U(I,$)).join(\" \")),U=(w,$)=>{w=w.trim();const I=$.loose?a[c.XRANGELOOSE]:a[c.XRANGE];return w.replace(I,(O,P,A,M,V,j)=>{s(\"xRange\",w,O,P,A,M,V,j);const Q=b(A),ve=Q||b(M),te=ve||b(V),on=te;return P===\"=\"&&on&&(P=\"\"),j=$.includePrerelease?\"-0\":\"\",Q?P===\">\"||P===\"<\"?O=\"<0.0.0-0\":O=\"*\":P&&on?(ve&&(M=0),V=0,P===\">\"?(P=\">=\",ve?(A=+A+1,M=0,V=0):(M=+M+1,V=0)):P===\"<=\"&&(P=\"<\",ve?A=+A+1:M=+M+1),P===\"<\"&&(j=\"-0\"),O=`${P+A}.${M}.${V}${j}`):ve?O=`>=${A}.0.0${j} <${+A+1}.0.0-0`:te&&(O=`>=${A}.${M}.0${j} <${A}.${+M+1}.0-0`),s(\"xRange return\",O),O})},oe=(w,$)=>(s(\"replaceStars\",w,$),w.trim().replace(a[c.STAR],\"\")),de=(w,$)=>(s(\"replaceGTE0\",w,$),w.trim().replace(a[$.includePrerelease?c.GTE0PRE:c.GTE0],\"\")),Re=w=>($,I,O,P,A,M,V,j,Q,ve,te,on,Cs)=>(b(O)?I=\"\":b(P)?I=`>=${O}.0.0${w?\"-0\":\"\"}`:b(A)?I=`>=${O}.${P}.0${w?\"-0\":\"\"}`:M?I=`>=${I}`:I=`>=${I}${w?\"-0\":\"\"}`,b(Q)?j=\"\":b(ve)?j=`<${+Q+1}.0.0-0`:b(te)?j=`<${Q}.${+ve+1}.0-0`:on?j=`<=${Q}.${ve}.${te}-${on}`:w?j=`<${Q}.${ve}.${+te+1}-0`:j=`<=${j}`,`${I} ${j}`.trim()),sn=(w,$,I)=>{for(let O=0;O0){const P=w[O].semver;if(P.major===$.major&&P.minor===$.minor&&P.patch===$.patch)return!0}return!1}return!0};return qs}const I1=mp(),L1=(e,t,n)=>{try{t=new I1(t,n)}catch{return!1}return t.test(e)};var P1=L1,yp=z$(P1);function z1(e,t,n){const i=e.open(t),r=1e4,s=250,{origin:o}=new URL(t);let a=~~(r/s);function c(u){u.source===i&&(a=0,e.removeEventListener(\"message\",c,!1))}e.addEventListener(\"message\",c,!1);function l(){a<=0||(i.postMessage(n,o),setTimeout(l,s),a-=1)}setTimeout(l,s)}var D1=`.vega-embed {\n position: relative;\n display: inline-block;\n box-sizing: border-box;\n}\n.vega-embed.has-actions {\n padding-right: 38px;\n}\n.vega-embed details:not([open]) > :not(summary) {\n display: none !important;\n}\n.vega-embed summary {\n list-style: none;\n position: absolute;\n top: 0;\n right: 0;\n padding: 6px;\n z-index: 1000;\n background: white;\n box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);\n color: #1b1e23;\n border: 1px solid #aaa;\n border-radius: 999px;\n opacity: 0.2;\n transition: opacity 0.4s ease-in;\n cursor: pointer;\n line-height: 0px;\n}\n.vega-embed summary::-webkit-details-marker {\n display: none;\n}\n.vega-embed summary:active {\n box-shadow: #aaa 0px 0px 0px 1px inset;\n}\n.vega-embed summary svg {\n width: 14px;\n height: 14px;\n}\n.vega-embed details[open] summary {\n opacity: 0.7;\n}\n.vega-embed:hover summary, .vega-embed:focus-within summary {\n opacity: 1 !important;\n transition: opacity 0.2s ease;\n}\n.vega-embed .vega-actions {\n position: absolute;\n z-index: 1001;\n top: 35px;\n right: -9px;\n display: flex;\n flex-direction: column;\n padding-bottom: 8px;\n padding-top: 8px;\n border-radius: 4px;\n box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2);\n border: 1px solid #d9d9d9;\n background: white;\n animation-duration: 0.15s;\n animation-name: scale-in;\n animation-timing-function: cubic-bezier(0.2, 0, 0.13, 1.5);\n text-align: left;\n}\n.vega-embed .vega-actions a {\n padding: 8px 16px;\n font-family: sans-serif;\n font-size: 14px;\n font-weight: 600;\n white-space: nowrap;\n color: #434a56;\n text-decoration: none;\n}\n.vega-embed .vega-actions a:hover, .vega-embed .vega-actions a:focus {\n background-color: #f7f7f9;\n color: black;\n}\n.vega-embed .vega-actions::before, .vega-embed .vega-actions::after {\n content: \"\";\n display: inline-block;\n position: absolute;\n}\n.vega-embed .vega-actions::before {\n left: auto;\n right: 14px;\n top: -16px;\n border: 8px solid rgba(0, 0, 0, 0);\n border-bottom-color: #d9d9d9;\n}\n.vega-embed .vega-actions::after {\n left: auto;\n right: 15px;\n top: -14px;\n border: 7px solid rgba(0, 0, 0, 0);\n border-bottom-color: #fff;\n}\n.vega-embed .chart-wrapper.fit-x {\n width: 100%;\n}\n.vega-embed .chart-wrapper.fit-y {\n height: 100%;\n}\n\n.vega-embed-wrapper {\n max-width: 100%;\n overflow: auto;\n padding-right: 14px;\n}\n\n@keyframes scale-in {\n from {\n opacity: 0;\n transform: scale(0.6);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n`;function bp(e,...t){for(const n of t)M1(e,n);return e}function M1(e,t){for(const n of Object.keys(t))bo(e,n,t[n],!0)}const at=Ap;let Bi=FE;const Ml=typeof window<\"u\"?window:void 0;Bi===void 0&&Ml?.vl?.compile&&(Bi=Ml.vl);const j1={export:{svg:!0,png:!0},source:!0,compiled:!0,editor:!0},U1={CLICK_TO_VIEW_ACTIONS:\"Click to view actions\",COMPILED_ACTION:\"View Compiled Vega\",EDITOR_ACTION:\"Open in Vega Editor\",PNG_ACTION:\"Save as PNG\",SOURCE_ACTION:\"View Source\",SVG_ACTION:\"Save as SVG\"},Ai={vega:\"Vega\",\"vega-lite\":\"Vega-Lite\"},_r={vega:at.version,\"vega-lite\":Bi?Bi.version:\"not available\"},B1={vega:e=>e,\"vega-lite\":(e,t)=>Bi.compile(e,{config:t}).spec},W1=`\n\n \n \n \n`,G1=\"chart-wrapper\";function H1(e){return typeof e==\"function\"}function jl(e,t,n,i){const r=`${t}
`,s=`
${n}`,o=window.open(\"\");o.document.write(r+e+s),o.document.title=`${Ai[i]} JSON Source`}function q1(e,t){if(e.$schema){const n=lp(e.$schema);t&&t!==n.library&&console.warn(`The given visualization spec is written in ${Ai[n.library]}, but mode argument sets ${Ai[t]??t}.`);const i=n.library;return yp(_r[i],`^${n.version.slice(1)}`)||console.warn(`The input spec uses ${Ai[i]} ${n.version}, but the current version of ${Ai[i]} is v${_r[i]}.`),i}return\"mark\"in e||\"encoding\"in e||\"layer\"in e||\"hconcat\"in e||\"vconcat\"in e||\"facet\"in e||\"repeat\"in e?\"vega-lite\":\"marks\"in e||\"signals\"in e||\"scales\"in e||\"axes\"in e?\"vega\":t??\"vega\"}function xp(e){return!!(e&&\"load\"in e)}function Ul(e){return xp(e)?e:at.loader(e)}function V1(e){const t=e.usermeta?.embedOptions??{};return R(t.defaultStyle)&&(t.defaultStyle=!1),t}async function Iw(e,t,n={}){let i,r;R(t)?(r=Ul(n.loader),i=JSON.parse(await r.load(t))):i=t;const s=V1(i),o=s.loader;(!r||o)&&(r=Ul(n.loader??o));const a=await Bl(s,r),c=await Bl(n,r),l={...bp(c,a),config:Rr(c.config??{},a.config??{})};return await Y1(e,i,l,r)}async function Bl(e,t){const n=R(e.config)?JSON.parse(await t.load(e.config)):e.config??{},i=R(e.patch)?JSON.parse(await t.load(e.patch)):e.patch;return{...e,...i?{patch:i}:{},...n?{config:n}:{}}}function X1(e){const t=e.getRootNode?e.getRootNode():document;return t instanceof ShadowRoot?{root:t,rootContainer:t}:{root:document,rootContainer:document.head??document.body}}async function Y1(e,t,n={},i){const r=n.theme?Rr(k$[n.theme],n.config??{}):n.config,s=di(n.actions)?n.actions:bp({},j1,n.actions??{}),o={...U1,...n.i18n},a=n.renderer??\"canvas\",c=n.logLevel??at.Warn,l=n.downloadFileName??\"visualization\",u=typeof e==\"string\"?document.querySelector(e):e;if(!u)throw new Error(`${e} does not exist`);if(n.defaultStyle!==!1){const N=\"vega-embed-style\",{root:_,rootContainer:L}=X1(u);if(!_.getElementById(N)){const U=document.createElement(\"style\");U.id=N,U.innerHTML=n.defaultStyle===void 0||n.defaultStyle===!0?D1.toString():n.defaultStyle,L.appendChild(U)}}const f=q1(t,n.mode);let d=B1[f](t,r);if(f===\"vega-lite\"&&d.$schema){const N=lp(d.$schema);yp(_r.vega,`^${N.version.slice(1)}`)||console.warn(`The compiled spec uses Vega ${N.version}, but current version is v${_r.vega}.`)}u.classList.add(\"vega-embed\"),s&&u.classList.add(\"has-actions\"),u.innerHTML=\"\";let g=u;if(s){const N=document.createElement(\"div\");N.classList.add(G1),u.appendChild(N),g=N}const p=n.patch;if(p&&(d=p instanceof Function?p(d):kp(d,p,!0,!1).newDocument),n.formatLocale&&at.formatLocale(n.formatLocale),n.timeFormatLocale&&at.timeFormatLocale(n.timeFormatLocale),n.expressionFunctions)for(const N in n.expressionFunctions){const _=n.expressionFunctions[N];\"fn\"in _?at.expressionFunction(N,_.fn,_.visitor):_ instanceof Function&&at.expressionFunction(N,_)}const{ast:h}=n,m=at.parse(d,f===\"vega-lite\"?{}:r,{ast:h}),y=new(n.viewClass||at.View)(m,{loader:i,logLevel:c,renderer:a,...h?{expr:at.expressionInterpreter??n.expr??Tp}:{}});if(y.addSignalListener(\"autosize\",(N,_)=>{const{type:L}=_;L==\"fit-x\"?(g.classList.add(\"fit-x\"),g.classList.remove(\"fit-y\")):L==\"fit-y\"?(g.classList.remove(\"fit-x\"),g.classList.add(\"fit-y\")):L==\"fit\"?g.classList.add(\"fit-x\",\"fit-y\"):g.classList.remove(\"fit-x\",\"fit-y\")}),n.tooltip!==!1){const{loader:N,tooltip:_}=n,L=N&&!xp(N)?N?.baseURL:void 0,U=H1(_)?_:new P$({baseURL:L,..._===!0?{}:_}).call;y.tooltip(U)}let{hover:b}=n;if(b===void 0&&(b=f===\"vega\"),b){const{hoverSet:N,updateSet:_}=typeof b==\"boolean\"?{}:b;y.hover(N,_)}n&&(n.width!=null&&y.width(n.width),n.height!=null&&y.height(n.height),n.padding!=null&&y.padding(n.padding)),await y.initialize(g,n.bind).runAsync();let C;if(s!==!1){let N=u;if(n.defaultStyle!==!1||n.forceActionsMenu){const L=document.createElement(\"details\");L.title=o.CLICK_TO_VIEW_ACTIONS,u.append(L),N=L;const U=document.createElement(\"summary\");U.innerHTML=W1,L.append(U),C=oe=>{L.contains(oe.target)||L.removeAttribute(\"open\")},document.addEventListener(\"click\",C)}const _=document.createElement(\"div\");if(N.append(_),_.classList.add(\"vega-actions\"),s===!0||s.export!==!1){for(const L of[\"svg\",\"png\"])if(s===!0||s.export===!0||s.export[L]){const U=o[`${L.toUpperCase()}_ACTION`],oe=document.createElement(\"a\"),de=H(n.scaleFactor)?n.scaleFactor[L]:n.scaleFactor;oe.text=U,oe.href=\"#\",oe.target=\"_blank\",oe.download=`${l}.${L}`,oe.addEventListener(\"mousedown\",async function(Re){Re.preventDefault();const sn=await y.toImageURL(L,de);this.href=sn}),_.append(oe)}}if(s===!0||s.source!==!1){const L=document.createElement(\"a\");L.text=o.SOURCE_ACTION,L.href=\"#\",L.addEventListener(\"click\",function(U){jl(Ns(t),n.sourceHeader??\"\",n.sourceFooter??\"\",f),U.preventDefault()}),_.append(L)}if(f===\"vega-lite\"&&(s===!0||s.compiled!==!1)){const L=document.createElement(\"a\");L.text=o.COMPILED_ACTION,L.href=\"#\",L.addEventListener(\"click\",function(U){jl(Ns(d),n.sourceHeader??\"\",n.sourceFooter??\"\",\"vega\"),U.preventDefault()}),_.append(L)}if(s===!0||s.editor!==!1){const L=n.editorUrl??\"https://vega.github.io/editor/\",U=document.createElement(\"a\");U.text=o.EDITOR_ACTION,U.href=\"#\",U.addEventListener(\"click\",function(oe){z1(window,L,{config:r,mode:f,renderer:a,spec:Ns(t)}),oe.preventDefault()}),_.append(U)}}function k(){C&&document.removeEventListener(\"click\",C),y.finalize()}return{view:y,spec:t,vgSpec:d,finalize:k,embedOptions:n}}export{j1 as DEFAULT_ACTIONS,Iw as default,q1 as guessMode,at as vega,Bi as vegaLite};\n//# sourceMappingURL=vega-embed.module.js.map\n"],"names":["Op","Gn","ie","R","bo","fi","B","di","H","F","ce","$p","wp","Cp","Rr","Np","pi","U","Fp","Ap","kp","Tp"],"mappings":"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C,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAA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AAK,CAAC,CAAC,GAAG,MAAM,CAAC,OAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,M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CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,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AAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,C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AC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CA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C,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAA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CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAC,CAAC,IAAI,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,IAAI,SAAS,CAAC,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAA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CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,KAAK,CAAC,OAAO,OAAO,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,OAAO,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,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,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAA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,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAM,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,CAAC,OAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAC/lzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAACJ,IAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAM,MAAC,EAAE,CAACe,GAAM,IAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,OAAO,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAM,MAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAA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"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/vega-interpreter.module-D8ONVnUK.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/vega-interpreter.module-D8ONVnUK.js new file mode 100644 index 0000000000000000000000000000000000000000..b31b5df53aa7ef4c5f928990d559806bc8eb0548 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/vega-interpreter.module-D8ONVnUK.js @@ -0,0 +1,29 @@ +import { l } from './dispatch-DGVRt-1i.js'; + +var Ny={},Eh={},_h=34,vu=10,Ch=13;function Sb(t){return new Function("d","return {"+t.map(function(e,n){return JSON.stringify(e)+": d["+n+'] || ""'}).join(",")+"}")}function P5(t,e){var n=Sb(t);return function(r,i){return e(n(r),i,t)}}function Ly(t){var e=Object.create(null),n=[];return t.forEach(function(r){for(var i in r)i in e||n.push(e[i]=i);}),n}function Te(t,e){var n=t+"",r=n.length;return r9999?"+"+Te(t,6):Te(t,4)}function I5(t){var e=t.getUTCHours(),n=t.getUTCMinutes(),r=t.getUTCSeconds(),i=t.getUTCMilliseconds();return isNaN(t)?"Invalid Date":z5(t.getUTCFullYear())+"-"+Te(t.getUTCMonth()+1,2)+"-"+Te(t.getUTCDate(),2)+(i?"T"+Te(e,2)+":"+Te(n,2)+":"+Te(r,2)+"."+Te(i,3)+"Z":r?"T"+Te(e,2)+":"+Te(n,2)+":"+Te(r,2)+"Z":n||e?"T"+Te(e,2)+":"+Te(n,2)+"Z":"")}function U5(t){var e=new RegExp('["'+t+` +\r]`),n=t.charCodeAt(0);function r(c,h){var d,g,p=i(c,function(m,y){if(d)return d(m,y-1);g=m,d=h?P5(m,h):Sb(m);});return p.columns=g||[],p}function i(c,h){var d=[],g=c.length,p=0,m=0,y,x=g<=0,v=!1;c.charCodeAt(g-1)===vu&&--g,c.charCodeAt(g-1)===Ch&&--g;function b(){if(x)return Eh;if(v)return v=!1,Ny;var E,A=p,_;if(c.charCodeAt(A)===_h){for(;p++=g?x=!0:(_=c.charCodeAt(p++))===vu?v=!0:_===Ch&&(v=!0,c.charCodeAt(p)===vu&&++p),c.slice(A+1,E-1).replace(/""/g,'"')}for(;pe?1:t>=e?0:NaN}function q5(t,e){return t==null||e==null?NaN:et?1:e>=t?0:NaN}function Za(t){let e,n,r;t.length!==2?(e=wr,n=(o,s)=>wr(t(o),s),r=(o,s)=>t(o)-s):(e=t===wr||t===q5?t:j5,n=t,r=t);function i(o,s,l=0,f=o.length){if(l>>1;n(o[c],s)<0?l=c+1:f=c;}while(l>>1;n(o[c],s)<=0?l=c+1:f=c;}while(ll&&r(o[c-1],s)>-r(o[c],s)?c-1:c}return {left:i,center:u,right:a}}function j5(){return 0}function Bb(t){return t===null?NaN:+t}function*W5(t,e){if(e===void 0)for(let n of t)n!=null&&(n=+n)>=n&&(yield n);else {let n=-1;for(let r of t)(r=e(r,++n,t))!=null&&(r=+r)>=r&&(yield r);}}const Tb=Za(wr),ti=Tb.right,Y5=Tb.left;Za(Bb).center;function H5(t,e){let n=0,r,i=0,a=0;if(e===void 0)for(let u of t)u!=null&&(u=+u)>=u&&(r=u-i,i+=r/++n,a+=r*(u-i));else {let u=-1;for(let o of t)(o=e(o,++u,t))!=null&&(o=+o)>=o&&(r=o-i,i+=r/++n,a+=r*(o-i));}if(n>1)return a/(n-1)}function G5(t,e){const n=H5(t,e);return n&&Math.sqrt(n)}class De{constructor(){this._partials=new Float64Array(32),this._n=0;}add(e){const n=this._partials;let r=0;for(let i=0;i0){for(u=e[--n];n>0&&(r=u,i=e[--n],u=r+i,a=i-(u-r),!a););n>0&&(a<0&&e[n-1]<0||a>0&&e[n-1]>0)&&(i=a*2,r=u+i,i==r-u&&(u=r));}return u}}class Py extends Map{constructor(e,n=Nb){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:n}}),e!=null)for(const[r,i]of e)this.set(r,i);}get(e){return super.get(B0(this,e))}has(e){return super.has(B0(this,e))}set(e,n){return super.set(Rb(this,e),n)}delete(e){return super.delete(Ob(this,e))}}class $l extends Set{constructor(e,n=Nb){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:n}}),e!=null)for(const r of e)this.add(r);}has(e){return super.has(B0(this,e))}add(e){return super.add(Rb(this,e))}delete(e){return super.delete(Ob(this,e))}}function B0({_intern:t,_key:e},n){const r=e(n);return t.has(r)?t.get(r):n}function Rb({_intern:t,_key:e},n){const r=e(n);return t.has(r)?t.get(r):(t.set(r,n),n)}function Ob({_intern:t,_key:e},n){const r=e(n);return t.has(r)&&(n=t.get(r),t.delete(r)),n}function Nb(t){return t!==null&&typeof t=="object"?t.valueOf():t}function X5(t,e){return Array.from(e,n=>t[n])}function V5(t=wr){if(t===wr)return Lb;if(typeof t!="function")throw new TypeError("compare is not a function");return (e,n)=>{const r=t(e,n);return r||r===0?r:(t(n,n)===0)-(t(e,e)===0)}}function Lb(t,e){return (t==null||!(t>=t))-(e==null||!(e>=e))||(te?1:0)}const K5=Math.sqrt(50),Q5=Math.sqrt(10),Z5=Math.sqrt(2);function Sl(t,e,n){const r=(e-t)/Math.max(0,n),i=Math.floor(Math.log10(r)),a=r/Math.pow(10,i),u=a>=K5?10:a>=Q5?5:a>=Z5?2:1;let o,s,l;return i<0?(l=Math.pow(10,-i)/u,o=Math.round(t*l),s=Math.round(e*l),o/le&&--s,l=-l):(l=Math.pow(10,i)*u,o=Math.round(t/l),s=Math.round(e/l),o*le&&--s),s0))return [];if(t===e)return [t];const r=e=i))return [];const o=a-i+1,s=new Array(o);if(r)if(u<0)for(let l=0;l=r)&&(n=r);else {let r=-1;for(let i of t)(i=e(i,++r,t))!=null&&(n=i)&&(n=i);}return n}function O0(t,e){let n;if(e===void 0)for(const r of t)r!=null&&(n>r||n===void 0&&r>=r)&&(n=r);else {let r=-1;for(let i of t)(i=e(i,++r,t))!=null&&(n>i||n===void 0&&i>=i)&&(n=i);}return n}function Pb(t,e,n=0,r=1/0,i){if(e=Math.floor(e),n=Math.floor(Math.max(0,n)),r=Math.floor(Math.min(t.length-1,r)),!(n<=e&&e<=r))return t;for(i=i===void 0?Lb:V5(i);r>n;){if(r-n>600){const s=r-n+1,l=e-n+1,f=Math.log(s),c=.5*Math.exp(2*f/3),h=.5*Math.sqrt(f*c*(s-c)/s)*(l-s/2<0?-1:1),d=Math.max(n,Math.floor(e-l*c/s+h)),g=Math.min(r,Math.floor(e+(s-l)*c/s+h));Pb(t,e,d,g,i);}const a=t[e];let u=n,o=r;for(bu(t,n,e),i(t[r],a)>0&&bu(t,n,r);u0;)--o;}i(t[n],a)===0?bu(t,n,o):(++o,bu(t,o,r)),o<=e&&(n=o+1),e<=o&&(r=o-1);}return t}function bu(t,e,n){const r=t[e];t[e]=t[n],t[n]=r;}function N0(t,e,n){if(t=Float64Array.from(W5(t,n)),!(!(r=t.length)||isNaN(e=+e))){if(e<=0||r<2)return O0(t);if(e>=1)return Ri(t);var r,i=(r-1)*e,a=Math.floor(i),u=Ri(Pb(t,a).subarray(0,a+1)),o=O0(t.subarray(a+1));return u+(o-u)*(i-a)}}function zb(t,e,n=Bb){if(!(!(r=t.length)||isNaN(e=+e))){if(e<=0||r<2)return +n(t[0],0,t);if(e>=1)return +n(t[r-1],r-1,t);var r,i=(r-1)*e,a=Math.floor(i),u=+n(t[a],a,t),o=+n(t[a+1],a+1,t);return u+(o-u)*(i-a)}}function J5(t,e){let n=0,r=0;if(e===void 0)for(let i of t)i!=null&&(i=+i)>=i&&(++n,r+=i);else {let i=-1;for(let a of t)(a=e(a,++i,t))!=null&&(a=+a)>=a&&(++n,r+=a);}if(n)return r/n}function Ib(t,e){return N0(t,.5,e)}function*tF(t){for(const e of t)yield*e;}function Ub(t){return Array.from(tF(t))}function Ie(t,e,n){t=+t,e=+e,n=(i=arguments.length)<2?(e=t,t=0,1):i<3?1:+n;for(var r=-1,i=Math.max(0,Math.ceil((e-t)/n))|0,a=new Array(i);++r>8&15|e>>4&240,e>>4&15|e&240,(e&15)<<4|e&15,1):n===8?Ss(e>>24&255,e>>16&255,e>>8&255,(e&255)/255):n===4?Ss(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|e&240,((e&15)<<4|e&15)/255):null):(e=aF.exec(t))?new qt(e[1],e[2],e[3],1):(e=uF.exec(t))?new qt(e[1]*255/100,e[2]*255/100,e[3]*255/100,1):(e=oF.exec(t))?Ss(e[1],e[2],e[3],e[4]):(e=sF.exec(t))?Ss(e[1]*255/100,e[2]*255/100,e[3]*255/100,e[4]):(e=lF.exec(t))?Yy(e[1],e[2]/100,e[3]/100,1):(e=fF.exec(t))?Yy(e[1],e[2]/100,e[3]/100,e[4]):zy.hasOwnProperty(t)?qy(zy[t]):t==="transparent"?new qt(NaN,NaN,NaN,0):null}function qy(t){return new qt(t>>16&255,t>>8&255,t&255,1)}function Ss(t,e,n,r){return r<=0&&(t=e=n=NaN),new qt(t,e,n,r)}function E1(t){return t instanceof fi||(t=bo(t)),t?(t=t.rgb(),new qt(t.r,t.g,t.b,t.opacity)):new qt}function Vn(t,e,n,r){return arguments.length===1?E1(t):new qt(t,e,n,r??1)}function qt(t,e,n,r){this.r=+t,this.g=+e,this.b=+n,this.opacity=+r;}Ja(qt,Vn,Vo(fi,{brighter(t){return t=t==null?Sa:Math.pow(Sa,t),new qt(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=t==null?Ii:Math.pow(Ii,t),new qt(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new qt(Oi(this.r),Oi(this.g),Oi(this.b),Bl(this.opacity))},displayable(){return -.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:jy,formatHex:jy,formatHex8:dF,formatRgb:Wy,toString:Wy}));function jy(){return `#${ki(this.r)}${ki(this.g)}${ki(this.b)}`}function dF(){return `#${ki(this.r)}${ki(this.g)}${ki(this.b)}${ki((isNaN(this.opacity)?1:this.opacity)*255)}`}function Wy(){const t=Bl(this.opacity);return `${t===1?"rgb(":"rgba("}${Oi(this.r)}, ${Oi(this.g)}, ${Oi(this.b)}${t===1?")":`, ${t})`}`}function Bl(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function Oi(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function ki(t){return t=Oi(t),(t<16?"0":"")+t.toString(16)}function Yy(t,e,n,r){return r<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=NaN),new _n(t,e,n,r)}function jb(t){if(t instanceof _n)return new _n(t.h,t.s,t.l,t.opacity);if(t instanceof fi||(t=bo(t)),!t)return new _n;if(t instanceof _n)return t;t=t.rgb();var e=t.r/255,n=t.g/255,r=t.b/255,i=Math.min(e,n,r),a=Math.max(e,n,r),u=NaN,o=a-i,s=(a+i)/2;return o?(e===a?u=(n-r)/o+(n0&&s<1?0:u,new _n(u,o,s,t.opacity)}function Ao(t,e,n,r){return arguments.length===1?jb(t):new _n(t,e,n,r??1)}function _n(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r;}Ja(_n,Ao,Vo(fi,{brighter(t){return t=t==null?Sa:Math.pow(Sa,t),new _n(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=t==null?Ii:Math.pow(Ii,t),new _n(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+(this.h<0)*360,e=isNaN(t)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*e,i=2*n-r;return new qt(Dh(t>=240?t-240:t+120,i,r),Dh(t,i,r),Dh(t<120?t+240:t-120,i,r),this.opacity)},clamp(){return new _n(Hy(this.h),Bs(this.s),Bs(this.l),Bl(this.opacity))},displayable(){return (0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=Bl(this.opacity);return `${t===1?"hsl(":"hsla("}${Hy(this.h)}, ${Bs(this.s)*100}%, ${Bs(this.l)*100}%${t===1?")":`, ${t})`}`}}));function Hy(t){return t=(t||0)%360,t<0?t+360:t}function Bs(t){return Math.max(0,Math.min(1,t||0))}function Dh(t,e,n){return (t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t)/60:e)*255}const Wb=Math.PI/180,Yb=180/Math.PI,Tl=18,Hb=.96422,Gb=1,Xb=.82521,Vb=4/29,Fa=6/29,Kb=3*Fa*Fa,gF=Fa*Fa*Fa;function Qb(t){if(t instanceof Gn)return new Gn(t.l,t.a,t.b,t.opacity);if(t instanceof yr)return Zb(t);t instanceof qt||(t=E1(t));var e=$h(t.r),n=$h(t.g),r=$h(t.b),i=Fh((.2225045*e+.7168786*n+.0606169*r)/Gb),a,u;return e===n&&n===r?a=u=i:(a=Fh((.4360747*e+.3850649*n+.1430804*r)/Hb),u=Fh((.0139322*e+.0971045*n+.7141733*r)/Xb)),new Gn(116*i-16,500*(a-i),200*(i-u),t.opacity)}function wo(t,e,n,r){return arguments.length===1?Qb(t):new Gn(t,e,n,r??1)}function Gn(t,e,n,r){this.l=+t,this.a=+e,this.b=+n,this.opacity=+r;}Ja(Gn,wo,Vo(fi,{brighter(t){return new Gn(this.l+Tl*(t??1),this.a,this.b,this.opacity)},darker(t){return new Gn(this.l-Tl*(t??1),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,n=isNaN(this.b)?t:t-this.b/200;return e=Hb*Mh(e),t=Gb*Mh(t),n=Xb*Mh(n),new qt(kh(3.1338561*e-1.6168667*t-.4906146*n),kh(-.9787684*e+1.9161415*t+.033454*n),kh(.0719453*e-.2289914*t+1.4052427*n),this.opacity)}}));function Fh(t){return t>gF?Math.pow(t,1/3):t/Kb+Vb}function Mh(t){return t>Fa?t*t*t:Kb*(t-Vb)}function kh(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function $h(t){return (t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function pF(t){if(t instanceof yr)return new yr(t.h,t.c,t.l,t.opacity);if(t instanceof Gn||(t=Qb(t)),t.a===0&&t.b===0)return new yr(NaN,0=1?(n=1,e-1):Math.floor(n*e),i=t[r],a=t[r+1],u=r>0?t[r-1]:2*i-a,o=r()=>t;function rA(t,e){return function(n){return t+n*e}}function yF(t,e,n){return t=Math.pow(t,n),e=Math.pow(e,n)-t,n=1/n,function(r){return Math.pow(t+r*e,n)}}function Gf(t,e){var n=e-t;return n?rA(t,n>180||n<-180?n-360*Math.round(n/360):n):Hf(isNaN(t)?e:t)}function xF(t){return (t=+t)==1?jt:function(e,n){return n-e?yF(e,n,t):Hf(isNaN(e)?n:e)}}function jt(t,e){var n=e-t;return n?rA(t,n):Hf(isNaN(t)?e:t)}const P0=function t(e){var n=xF(e);function r(i,a){var u=n((i=Vn(i)).r,(a=Vn(a)).r),o=n(i.g,a.g),s=n(i.b,a.b),l=jt(i.opacity,a.opacity);return function(f){return i.r=u(f),i.g=o(f),i.b=s(f),i.opacity=l(f),i+""}}return r.gamma=t,r}(1);function iA(t){return function(e){var n=e.length,r=new Array(n),i=new Array(n),a=new Array(n),u,o;for(u=0;un&&(a=e.slice(n,a),o[u]?o[u]+=a:o[++u]=a),(r=r[0])===(i=i[0])?o[u]?o[u]+=i:o[++u]=i:(o[++u]=null,s.push({i:u,x:wn(r,i)})),n=Sh.lastIndex;return n180?f+=360:f-l>180&&(l+=360),h.push({i:c.push(i(c)+"rotate(",null,r)-2,x:wn(l,f)})):f&&c.push(i(c)+"rotate("+f+r);}function o(l,f,c,h){l!==f?h.push({i:c.push(i(c)+"skewX(",null,r)-2,x:wn(l,f)}):f&&c.push(i(c)+"skewX("+f+r);}function s(l,f,c,h,d,g){if(l!==c||f!==h){var p=d.push(i(d)+"scale(",null,",",null,")");g.push({i:p-4,x:wn(l,c)},{i:p-2,x:wn(f,h)});}else (c!==1||h!==1)&&d.push(i(d)+"scale("+c+","+h+")");}return function(l,f){var c=[],h=[];return l=t(l),f=t(f),a(l.translateX,l.translateY,f.translateX,f.translateY,c,h),u(l.rotate,f.rotate,c,h),o(l.skewX,f.skewX,c,h),s(l.scaleX,l.scaleY,f.scaleX,f.scaleY,c,h),l=f=null,function(d){for(var g=-1,p=h.length,m;++g=0&&t._call.call(void 0,e),t=t._next;--Ba;}function Zy(){Ui=(Ol=Co.now())+Xf,Ba=zu=0;try{WF();}finally{Ba=0,HF(),Ui=0;}}function YF(){var t=Co.now(),e=t-Ol;e>pA&&(Xf-=e,Ol=t);}function HF(){for(var t,e=Rl,n,r=1/0;e;)e._call?(r>e._time&&(r=e._time),t=e,e=e._next):(n=e._next,e._next=null,e=t?t._next=n:Rl=n);Iu=t,U0(r);}function U0(t){if(!Ba){zu&&(zu=clearTimeout(zu));var e=t-Ui;e>24?(t<1/0&&(zu=setTimeout(Zy,t-Co.now()-Xf)),Au&&(Au=clearInterval(Au))):(Au||(Ol=Co.now(),Au=setInterval(YF,pA)),Ba=1,mA(Zy));}}function GF(t,e,n){var r=new Nl,i=e;return e==null?(r.restart(t,e,n),r):(r._restart=r.restart,r.restart=function(a,u,o){u=+u,o=o==null?M1():+o,r._restart(function s(l){l+=i,r._restart(s,i+=u,o),a(l);},u,o);},r.restart(t,e,n),r)}const q0=Math.PI,j0=2*q0,Ai=1e-6,XF=j0-Ai;function xA(t){this._+=t[0];for(let e=1,n=t.length;e=0))throw new Error(`invalid digits: ${t}`);if(e>15)return xA;const n=10**e;return function(r){this._+=r[0];for(let i=1,a=r.length;iAi)if(!(Math.abs(c*s-l*f)>Ai)||!a)this._append`L${this._x1=e},${this._y1=n}`;else {let d=r-u,g=i-o,p=s*s+l*l,m=d*d+g*g,y=Math.sqrt(p),x=Math.sqrt(h),v=a*Math.tan((q0-Math.acos((p+h-m)/(2*y*x)))/2),b=v/x,w=v/y;Math.abs(b-1)>Ai&&this._append`L${e+b*f},${n+b*c}`,this._append`A${a},${a},0,0,${+(c*d>f*g)},${this._x1=e+w*s},${this._y1=n+w*l}`;}}arc(e,n,r,i,a,u){if(e=+e,n=+n,r=+r,u=!!u,r<0)throw new Error(`negative radius: ${r}`);let o=r*Math.cos(i),s=r*Math.sin(i),l=e+o,f=n+s,c=1^u,h=u?i-a:a-i;this._x1===null?this._append`M${l},${f}`:(Math.abs(this._x1-l)>Ai||Math.abs(this._y1-f)>Ai)&&this._append`L${l},${f}`,r&&(h<0&&(h=h%j0+j0),h>XF?this._append`A${r},${r},0,1,${c},${e-o},${n-s}A${r},${r},0,1,${c},${this._x1=l},${this._y1=f}`:h>Ai&&this._append`A${r},${r},0,${+(h>=q0)},${c},${this._x1=e+r*Math.cos(a)},${this._y1=n+r*Math.sin(a)}`);}rect(e,n,r,i){this._append`M${this._x0=this._x1=+e},${this._y0=this._y1=+n}h${r=+r}v${+i}h${-r}Z`;}toString(){return this._}};function Vf(){return new k1}Vf.prototype=k1.prototype;const Er=11102230246251565e-32,ne=134217729,KF=(3+8*Er)*Er;function Bh(t,e,n,r,i){let a,u,o,s,l=e[0],f=r[0],c=0,h=0;f>l==f>-l?(a=l,l=e[++c]):(a=f,f=r[++h]);let d=0;if(cl==f>-l?(u=l+a,o=a-(u-l),l=e[++c]):(u=f+a,o=a-(u-f),f=r[++h]),a=u,o!==0&&(i[d++]=o);cl==f>-l?(u=a+l,s=u-a,o=a-(u-s)+(l-s),l=e[++c]):(u=a+f,s=u-a,o=a-(u-s)+(f-s),f=r[++h]),a=u,o!==0&&(i[d++]=o);for(;c=N||-k>=N||(c=t-C,o=t-(C+c)+(c-i),c=n-F,l=n-(F+c)+(c-i),c=e-D,s=e-(D+c)+(c-a),c=r-R,f=r-(R+c)+(c-a),o===0&&s===0&&l===0&&f===0)||(N=tM*u+KF*Math.abs(k),k+=C*f+R*o-(D*l+F*s),k>=N||-k>=N))return k;b=o*R,h=ne*o,d=h-(h-o),g=o-d,h=ne*R,p=h-(h-R),m=R-p,w=g*m-(b-d*p-g*p-d*m),E=s*F,h=ne*s,d=h-(h-s),g=s-d,h=ne*F,p=h-(h-F),m=F-p,A=g*m-(E-d*p-g*p-d*m),y=w-A,c=w-y,ye[0]=w-(y+c)+(c-A),x=b+y,c=x-b,v=b-(x-c)+(y-c),y=v-E,c=v-y,ye[1]=v-(y+c)+(c-E),_=x+y,c=_-x,ye[2]=x-(_-c)+(y-c),ye[3]=_;const M=Bh(4,la,4,ye,Jy);b=C*f,h=ne*C,d=h-(h-C),g=C-d,h=ne*f,p=h-(h-f),m=f-p,w=g*m-(b-d*p-g*p-d*m),E=D*l,h=ne*D,d=h-(h-D),g=D-d,h=ne*l,p=h-(h-l),m=l-p,A=g*m-(E-d*p-g*p-d*m),y=w-A,c=w-y,ye[0]=w-(y+c)+(c-A),x=b+y,c=x-b,v=b-(x-c)+(y-c),y=v-E,c=v-y,ye[1]=v-(y+c)+(c-E),_=x+y,c=_-x,ye[2]=x-(_-c)+(y-c),ye[3]=_;const O=Bh(M,Jy,4,ye,t2);b=o*f,h=ne*o,d=h-(h-o),g=o-d,h=ne*f,p=h-(h-f),m=f-p,w=g*m-(b-d*p-g*p-d*m),E=s*l,h=ne*s,d=h-(h-s),g=s-d,h=ne*l,p=h-(h-l),m=l-p,A=g*m-(E-d*p-g*p-d*m),y=w-A,c=w-y,ye[0]=w-(y+c)+(c-A),x=b+y,c=x-b,v=b-(x-c)+(y-c),y=v-E,c=v-y,ye[1]=v-(y+c)+(c-E),_=x+y,c=_-x,ye[2]=x-(_-c)+(y-c),ye[3]=_;const z=Bh(O,t2,4,ye,e2);return e2[z-1]}function Rs(t,e,n,r,i,a){const u=(e-a)*(n-i),o=(t-i)*(r-a),s=u-o,l=Math.abs(u+o);return Math.abs(s)>=ZF*l?s:-eM(t,e,n,r,i,a,l)}const n2=Math.pow(2,-52),Os=new Uint32Array(512);class Ll{static from(e,n=uM,r=oM){const i=e.length,a=new Float64Array(i*2);for(let u=0;u>1;if(n>0&&typeof e[0]!="number")throw new Error("Expected coords to contain numbers.");this.coords=e;const r=Math.max(2*n-5,0);this._triangles=new Uint32Array(r*3),this._halfedges=new Int32Array(r*3),this._hashSize=Math.ceil(Math.sqrt(n)),this._hullPrev=new Uint32Array(n),this._hullNext=new Uint32Array(n),this._hullTri=new Uint32Array(n),this._hullHash=new Int32Array(this._hashSize),this._ids=new Uint32Array(n),this._dists=new Float64Array(n),this.update();}update(){const{coords:e,_hullPrev:n,_hullNext:r,_hullTri:i,_hullHash:a}=this,u=e.length>>1;let o=1/0,s=1/0,l=-1/0,f=-1/0;for(let C=0;Cl&&(l=F),D>f&&(f=D),this._ids[C]=C;}const c=(o+l)/2,h=(s+f)/2;let d,g,p;for(let C=0,F=1/0;C0&&(g=C,F=D);}let x=e[2*g],v=e[2*g+1],b=1/0;for(let C=0;CR&&(C[F++]=k,R=N);}this.hull=C.subarray(0,F),this.triangles=new Uint32Array(0),this.halfedges=new Uint32Array(0);return}if(Rs(m,y,x,v,w,E)<0){const C=g,F=x,D=v;g=p,x=w,v=E,p=C,w=F,E=D;}const A=aM(m,y,x,v,w,E);this._cx=A.x,this._cy=A.y;for(let C=0;C0&&Math.abs(k-F)<=n2&&Math.abs(N-D)<=n2||(F=k,D=N,R===d||R===g||R===p))continue;let M=0;for(let bt=0,It=this._hashKey(k,N);bt=0;)if(O=z,O===M){O=-1;break}if(O===-1)continue;let G=this._addTriangle(O,R,r[O],-1,-1,i[O]);i[R]=this._legalize(G+2),i[O]=G,_++;let W=r[O];for(;z=r[W],Rs(k,N,e[2*W],e[2*W+1],e[2*z],e[2*z+1])<0;)G=this._addTriangle(W,R,z,i[R],-1,i[W]),i[R]=this._legalize(G+2),r[W]=W,_--,W=z;if(O===M)for(;z=n[O],Rs(k,N,e[2*z],e[2*z+1],e[2*O],e[2*O+1])<0;)G=this._addTriangle(z,R,O,-1,i[O],i[z]),this._legalize(G+2),i[z]=G,r[O]=O,_--,O=z;this._hullStart=n[R]=O,r[O]=n[W]=R,r[R]=W,a[this._hashKey(k,N)]=R,a[this._hashKey(e[2*O],e[2*O+1])]=O;}this.hull=new Uint32Array(_);for(let C=0,F=this._hullStart;C<_;C++)this.hull[C]=F,F=r[F];this.triangles=this._triangles.subarray(0,this.trianglesLen),this.halfedges=this._halfedges.subarray(0,this.trianglesLen);}_hashKey(e,n){return Math.floor(nM(e-this._cx,n-this._cy)*this._hashSize)%this._hashSize}_legalize(e){const{_triangles:n,_halfedges:r,coords:i}=this;let a=0,u=0;for(;;){const o=r[e],s=e-e%3;if(u=s+(e+2)%3,o===-1){if(a===0)break;e=Os[--a];continue}const l=o-o%3,f=s+(e+1)%3,c=l+(o+2)%3,h=n[u],d=n[e],g=n[f],p=n[c];if(rM(i[2*h],i[2*h+1],i[2*d],i[2*d+1],i[2*g],i[2*g+1],i[2*p],i[2*p+1])){n[e]=p,n[o]=h;const y=r[c];if(y===-1){let v=this._hullStart;do{if(this._hullTri[v]===c){this._hullTri[v]=e;break}v=this._hullPrev[v];}while(v!==this._hullStart)}this._link(e,y),this._link(o,r[u]),this._link(u,c);const x=l+(o+1)%3;a0?3-n:1+n)/4}function Th(t,e,n,r){const i=t-n,a=e-r;return i*i+a*a}function rM(t,e,n,r,i,a,u,o){const s=t-u,l=e-o,f=n-u,c=r-o,h=i-u,d=a-o,g=s*s+l*l,p=f*f+c*c,m=h*h+d*d;return s*(c*m-p*d)-l*(f*m-p*h)+g*(f*d-c*h)<0}function iM(t,e,n,r,i,a){const u=n-t,o=r-e,s=i-t,l=a-e,f=u*u+o*o,c=s*s+l*l,h=.5/(u*l-o*s),d=(l*f-o*c)*h,g=(u*c-s*f)*h;return d*d+g*g}function aM(t,e,n,r,i,a){const u=n-t,o=r-e,s=i-t,l=a-e,f=u*u+o*o,c=s*s+l*l,h=.5/(u*l-o*s),d=t+(l*f-o*c)*h,g=e+(u*c-s*f)*h;return {x:d,y:g}}function ba(t,e,n,r){if(r-n<=20)for(let i=n+1;i<=r;i++){const a=t[i],u=e[a];let o=i-1;for(;o>=n&&e[t[o]]>u;)t[o+1]=t[o--];t[o+1]=a;}else {const i=n+r>>1;let a=n+1,u=r;wu(t,i,a),e[t[n]]>e[t[r]]&&wu(t,n,r),e[t[a]]>e[t[r]]&&wu(t,a,r),e[t[n]]>e[t[a]]&&wu(t,n,a);const o=t[a],s=e[o];for(;;){do a++;while(e[t[a]]s);if(u=u-n?(ba(t,e,a,r),ba(t,e,n,u-1)):(ba(t,e,n,u-1),ba(t,e,a,r));}}function wu(t,e,n){const r=t[e];t[e]=t[n],t[n]=r;}function uM(t){return t[0]}function oM(t){return t[1]}const r2=1e-6;class $i{constructor(){this._x0=this._y0=this._x1=this._y1=null,this._="";}moveTo(e,n){this._+=`M${this._x0=this._x1=+e},${this._y0=this._y1=+n}`;}closePath(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._+="Z");}lineTo(e,n){this._+=`L${this._x1=+e},${this._y1=+n}`;}arc(e,n,r){e=+e,n=+n,r=+r;const i=e+r,a=n;if(r<0)throw new Error("negative radius");this._x1===null?this._+=`M${i},${a}`:(Math.abs(this._x1-i)>r2||Math.abs(this._y1-a)>r2)&&(this._+="L"+i+","+a),r&&(this._+=`A${r},${r},0,1,1,${e-r},${n}A${r},${r},0,1,1,${this._x1=i},${this._y1=a}`);}rect(e,n,r,i){this._+=`M${this._x0=this._x1=+e},${this._y0=this._y1=+n}h${+r}v${+i}h${-r}Z`;}value(){return this._||null}}class W0{constructor(){this._=[];}moveTo(e,n){this._.push([e,n]);}closePath(){this._.push(this._[0].slice());}lineTo(e,n){this._.push([e,n]);}value(){return this._.length?this._:null}}let sM=class{constructor(e,[n,r,i,a]=[0,0,960,500]){if(!((i=+i)>=(n=+n))||!((a=+a)>=(r=+r)))throw new Error("invalid bounds");this.delaunay=e,this._circumcenters=new Float64Array(e.points.length*2),this.vectors=new Float64Array(e.points.length*2),this.xmax=i,this.xmin=n,this.ymax=a,this.ymin=r,this._init();}update(){return this.delaunay.update(),this._init(),this}_init(){const{delaunay:{points:e,hull:n,triangles:r},vectors:i}=this;let a,u;const o=this.circumcenters=this._circumcenters.subarray(0,r.length/3*2);for(let p=0,m=0,y=r.length,x,v;p1;)a-=2;for(let u=2;u0){if(n>=this.ymax)return null;(u=(this.ymax-n)/i)0){if(e>=this.xmax)return null;(u=(this.xmax-e)/r)this.xmax?2:0)|(nthis.ymax?8:0)}_simplify(e){if(e&&e.length>4){for(let n=0;n1e-10)return !1}return !0}function dM(t,e,n){return [t+Math.sin(t+e)*n,e+Math.cos(t-e)*n]}class $1{static from(e,n=fM,r=cM,i){return new $1("length"in e?gM(e,n,r,i):Float64Array.from(pM(e,n,r,i)))}constructor(e){this._delaunator=new Ll(e),this.inedges=new Int32Array(e.length/2),this._hullIndex=new Int32Array(e.length/2),this.points=this._delaunator.coords,this._init();}update(){return this._delaunator.update(),this._init(),this}_init(){const e=this._delaunator,n=this.points;if(e.hull&&e.hull.length>2&&hM(e)){this.collinear=Int32Array.from({length:n.length/2},(h,d)=>d).sort((h,d)=>n[2*h]-n[2*d]||n[2*h+1]-n[2*d+1]);const s=this.collinear[0],l=this.collinear[this.collinear.length-1],f=[n[2*s],n[2*s+1],n[2*l],n[2*l+1]],c=1e-8*Math.hypot(f[3]-f[1],f[2]-f[0]);for(let h=0,d=n.length/2;h0&&(this.triangles=new Int32Array(3).fill(-1),this.halfedges=new Int32Array(3).fill(-1),this.triangles[0]=i[0],u[i[0]]=1,i.length===2&&(u[i[1]]=0,this.triangles[1]=i[1],this.triangles[2]=i[1]));}voronoi(e){return new sM(this,e)}*neighbors(e){const{inedges:n,hull:r,_hullIndex:i,halfedges:a,triangles:u,collinear:o}=this;if(o){const c=o.indexOf(e);c>0&&(yield o[c-1]),c=0&&a!==r&&a!==i;)r=a;return a}_step(e,n,r){const{inedges:i,hull:a,_hullIndex:u,halfedges:o,triangles:s,points:l}=this;if(i[e]===-1||!l.length)return (e+1)%(l.length>>1);let f=e,c=fa(n-l[e*2],2)+fa(r-l[e*2+1],2);const h=i[e];let d=h;do{let g=s[d];const p=fa(n-l[g*2],2)+fa(r-l[g*2+1],2);if(p=(c=(o+l)/2))?o=c:l=c,(m=n>=(h=(s+f)/2))?s=h:f=h,i=a,!(a=a[y=m<<1|p]))return i[y]=u,t;if(d=+t._x.call(null,a.data),g=+t._y.call(null,a.data),e===d&&n===g)return u.next=a,i?i[y]=u:t._root=u,t;do i=i?i[y]=new Array(4):t._root=new Array(4),(p=e>=(c=(o+l)/2))?o=c:l=c,(m=n>=(h=(s+f)/2))?s=h:f=h;while((y=m<<1|p)===(x=(g>=h)<<1|d>=c));return i[x]=a,i[y]=u,t}function xM(t){var e,n,r=t.length,i,a,u=new Array(r),o=new Array(r),s=1/0,l=1/0,f=-1/0,c=-1/0;for(n=0;nf&&(f=i),ac&&(c=a));if(s>f||l>c)return this;for(this.cover(s,l).cover(f,c),n=0;nt||t>=i||r>e||e>=a;)switch(l=(ef||(o=g.y0)>c||(s=g.x1)=y)<<1|t>=m)&&(g=h[h.length-1],h[h.length-1]=h[h.length-1-p],h[h.length-1-p]=g);}else {var x=t-+this._x.call(null,d.data),v=e-+this._y.call(null,d.data),b=x*x+v*v;if(b=(h=(u+s)/2))?u=h:s=h,(p=c>=(d=(o+l)/2))?o=d:l=d,e=n,!(n=n[m=p<<1|g]))return this;if(!n.length)break;(e[m+1&3]||e[m+2&3]||e[m+3&3])&&(r=e,y=m);}for(;n.data!==t;)if(i=n,!(n=n.next))return this;return (a=n.next)&&delete n.next,i?(a?i.next=a:delete i.next,this):e?(a?e[m]=a:delete e[m],(n=e[0]||e[1]||e[2]||e[3])&&n===(e[3]||e[2]||e[1]||e[0])&&!n.length&&(r?r[y]=n:this._root=n),this):(this._root=a,this)}function _M(t){for(var e=0,n=t.length;eh.index){var D=d-_.x-_.vx,R=g-_.y-_.vy,k=D*D+R*R;kd+F||Eg+F||Al.r&&(l.r=l[f].r);}function s(){if(e){var l,f=e.length,c;for(n=new Array(f),l=0;l[e(w,E,u),w])),b;for(m=0,o=new Array(y);m(t=(PM*t+zM)%u2)/u2}function UM(t){return t.x}function qM(t){return t.y}var jM=10,WM=Math.PI*(3-Math.sqrt(5));function YM(t){var e,n=1,r=.001,i=1-Math.pow(r,1/300),a=0,u=.6,o=new Map,s=yA(c),l$1=l("tick","end"),f=IM();t==null&&(t=[]);function c(){h(),l$1.call("tick",e),n1?(m==null?o.delete(p):o.set(p,g(m)),e):o.get(p)},find:function(p,m,y){var x=0,v=t.length,b,w,E,A,_;for(y==null?y=1/0:y*=y,x=0;x1?(l$1.on(p,m),e):l$1.on(p)}}}function HM(){var t,e,n,r,i=Ce(-30),a,u=1,o=1/0,s=.81;function l(d){var g,p=t.length,m=S1(t,UM,qM).visitAfter(c);for(r=d,g=0;g=o)return;(d.data!==e||d.next)&&(y===0&&(y=Ur(n),b+=y*y),x===0&&(x=Ur(n),b+=x*x),b=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)}function Pl(t,e){if((n=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var n,r=t.slice(0,n);return [r.length>1?r[0]+r.slice(2):r,+t.slice(n+1)]}function Ta(t){return t=Pl(Math.abs(t)),t?t[1]:NaN}function KM(t,e){return function(n,r){for(var i=n.length,a=[],u=0,o=t[0],s=0;i>0&&o>0&&(s+o+1>r&&(o=Math.max(1,r-s)),a.push(n.substring(i-=o,i+o)),!((s+=o+1)>r));)o=t[u=(u+1)%t.length];return a.reverse().join(e)}}function QM(t){return function(e){return e.replace(/[0-9]/g,function(n){return t[+n]})}}var ZM=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function qi(t){if(!(e=ZM.exec(t)))throw new Error("invalid format: "+t);var e;return new T1({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}qi.prototype=T1.prototype;function T1(t){this.fill=t.fill===void 0?" ":t.fill+"",this.align=t.align===void 0?">":t.align+"",this.sign=t.sign===void 0?"-":t.sign+"",this.symbol=t.symbol===void 0?"":t.symbol+"",this.zero=!!t.zero,this.width=t.width===void 0?void 0:+t.width,this.comma=!!t.comma,this.precision=t.precision===void 0?void 0:+t.precision,this.trim=!!t.trim,this.type=t.type===void 0?"":t.type+"";}T1.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function JM(t){t:for(var e=t.length,n=1,r=-1,i;n0&&(r=0);break}return r>0?t.slice(0,r)+t.slice(i+1):t}var bA;function t6(t,e){var n=Pl(t,e);if(!n)return t+"";var r=n[0],i=n[1],a=i-(bA=Math.max(-8,Math.min(8,Math.floor(i/3)))*3)+1,u=r.length;return a===u?r:a>u?r+new Array(a-u+1).join("0"):a>0?r.slice(0,a)+"."+r.slice(a):"0."+new Array(1-a).join("0")+Pl(t,Math.max(0,e+a-1))[0]}function o2(t,e){var n=Pl(t,e);if(!n)return t+"";var r=n[0],i=n[1];return i<0?"0."+new Array(-i).join("0")+r:r.length>i+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")}const s2={"%":(t,e)=>(t*100).toFixed(e),b:t=>Math.round(t).toString(2),c:t=>t+"",d:VM,e:(t,e)=>t.toExponential(e),f:(t,e)=>t.toFixed(e),g:(t,e)=>t.toPrecision(e),o:t=>Math.round(t).toString(8),p:(t,e)=>o2(t*100,e),r:o2,s:t6,X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function l2(t){return t}var f2=Array.prototype.map,c2=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function AA(t){var e=t.grouping===void 0||t.thousands===void 0?l2:KM(f2.call(t.grouping,Number),t.thousands+""),n=t.currency===void 0?"":t.currency[0]+"",r=t.currency===void 0?"":t.currency[1]+"",i=t.decimal===void 0?".":t.decimal+"",a=t.numerals===void 0?l2:QM(f2.call(t.numerals,String)),u=t.percent===void 0?"%":t.percent+"",o=t.minus===void 0?"−":t.minus+"",s=t.nan===void 0?"NaN":t.nan+"";function l(c){c=qi(c);var h=c.fill,d=c.align,g=c.sign,p=c.symbol,m=c.zero,y=c.width,x=c.comma,v=c.precision,b=c.trim,w=c.type;w==="n"?(x=!0,w="g"):s2[w]||(v===void 0&&(v=12),b=!0,w="g"),(m||h==="0"&&d==="=")&&(m=!0,h="0",d="=");var E=p==="$"?n:p==="#"&&/[boxX]/.test(w)?"0"+w.toLowerCase():"",A=p==="$"?r:/[%p]/.test(w)?u:"",_=s2[w],C=/[defgprs%]/.test(w);v=v===void 0?6:/[gprs]/.test(w)?Math.max(1,Math.min(21,v)):Math.max(0,Math.min(20,v));function F(D){var R=E,k=A,N,M,O;if(w==="c")k=_(D)+k,D="";else {D=+D;var z=D<0||1/D<0;if(D=isNaN(D)?s:_(Math.abs(D),v),b&&(D=JM(D)),z&&+D==0&&g!=="+"&&(z=!1),R=(z?g==="("?g:o:g==="-"||g==="("?"":g)+R,k=(w==="s"?c2[8+bA/3]:"")+k+(z&&g==="("?")":""),C){for(N=-1,M=D.length;++NO||O>57){k=(O===46?i+D.slice(N+1):D.slice(N))+k,D=D.slice(0,N);break}}}x&&!m&&(D=e(D,1/0));var G=R.length+D.length+k.length,W=G>1)+R+D+k+W.slice(G);break;default:D=W+R+D+k;break}return a(D)}return F.toString=function(){return c+""},F}function f(c,h){var d=l((c=qi(c),c.type="f",c)),g=Math.max(-8,Math.min(8,Math.floor(Ta(h)/3)))*3,p=Math.pow(10,-g),m=c2[8+g/3];return function(y){return d(p*y)+m}}return {format:l,formatPrefix:f}}var Ns,Kf,R1;e6({thousands:",",grouping:[3],currency:["$",""]});function e6(t){return Ns=AA(t),Kf=Ns.format,R1=Ns.formatPrefix,Ns}function wA(t){return Math.max(0,-Ta(Math.abs(t)))}function EA(t,e){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(Ta(e)/3)))*3-Ta(Math.abs(t)))}function _A(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,Ta(e)-Ta(t))+1}var Z=1e-6,zl=1e-12,at=Math.PI,kt=at/2,Il=at/4,Me=at*2,Bt=180/at,it=at/180,st=Math.abs,tu=Math.atan,mn=Math.atan2,J=Math.cos,Ls=Math.ceil,CA=Math.exp,Y0=Math.hypot,Ul=Math.log,Rh=Math.pow,Q=Math.sin,cn=Math.sign||function(t){return t>0?1:t<0?-1:0},ke=Math.sqrt,O1=Math.tan;function DA(t){return t>1?0:t<-1?at:Math.acos(t)}function je(t){return t>1?kt:t<-1?-kt:Math.asin(t)}function Vt(){}function ql(t,e){t&&d2.hasOwnProperty(t.type)&&d2[t.type](t,e);}var h2={Feature:function(t,e){ql(t.geometry,e);},FeatureCollection:function(t,e){for(var n=t.features,r=-1,i=n.length;++r=0?1:-1,i=r*n,a=J(e),u=Q(e),o=V0*u,s=X0*a+o*J(i),l=o*r*Q(i);jl.add(mn(l,s)),G0=t,X0=a,V0=u;}function $A(t){return Wl=new De,pr(t,Kn),Wl*2}function Yl(t){return [mn(t[1],t[0]),je(t[2])]}function ji(t){var e=t[0],n=t[1],r=J(n);return [r*J(e),r*Q(e),Q(n)]}function Ps(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function Ra(t,e){return [t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function Oh(t,e){t[0]+=e[0],t[1]+=e[1],t[2]+=e[2];}function zs(t,e){return [t[0]*e,t[1]*e,t[2]*e]}function Hl(t){var e=ke(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=e,t[1]/=e,t[2]/=e;}var Dt,Ne,Ft,Ze,wi,SA,BA,Ma,uo,Nr,Dr,hr={point:K0,lineStart:p2,lineEnd:m2,polygonStart:function(){hr.point=RA,hr.lineStart=a6,hr.lineEnd=u6,uo=new De,Kn.polygonStart();},polygonEnd:function(){Kn.polygonEnd(),hr.point=K0,hr.lineStart=p2,hr.lineEnd=m2,jl<0?(Dt=-(Ft=180),Ne=-(Ze=90)):uo>Z?Ze=90:uo<-Z&&(Ne=-90),Dr[0]=Dt,Dr[1]=Ft;},sphere:function(){Dt=-(Ft=180),Ne=-(Ze=90);}};function K0(t,e){Nr.push(Dr=[Dt=t,Ft=t]),eZe&&(Ze=e);}function TA(t,e){var n=ji([t*it,e*it]);if(Ma){var r=Ra(Ma,n),i=[r[1],-r[0],0],a=Ra(i,r);Hl(a),a=Yl(a);var u=t-wi,o=u>0?1:-1,s=a[0]*Bt*o,l,f=st(u)>180;f^(o*wiZe&&(Ze=l)):(s=(s+360)%360-180,f^(o*wiZe&&(Ze=e))),f?tQe(Dt,Ft)&&(Ft=t):Qe(t,Ft)>Qe(Dt,Ft)&&(Dt=t):Ft>=Dt?(tFt&&(Ft=t)):t>wi?Qe(Dt,t)>Qe(Dt,Ft)&&(Ft=t):Qe(t,Ft)>Qe(Dt,Ft)&&(Dt=t);}else Nr.push(Dr=[Dt=t,Ft=t]);eZe&&(Ze=e),Ma=n,wi=t;}function p2(){hr.point=TA;}function m2(){Dr[0]=Dt,Dr[1]=Ft,hr.point=K0,Ma=null;}function RA(t,e){if(Ma){var n=t-wi;uo.add(st(n)>180?n+(n>0?360:-360):n);}else SA=t,BA=e;Kn.point(t,e),TA(t,e);}function a6(){Kn.lineStart();}function u6(){RA(SA,BA),Kn.lineEnd(),st(uo)>Z&&(Dt=-(Ft=180)),Dr[0]=Dt,Dr[1]=Ft,Ma=null;}function Qe(t,e){return (e-=t)<0?e+360:e}function o6(t,e){return t[0]-e[0]}function y2(t,e){return t[0]<=t[1]?t[0]<=e&&e<=t[1]:eQe(r[0],r[1])&&(r[1]=i[1]),Qe(i[0],r[1])>Qe(r[0],r[1])&&(r[0]=i[0])):a.push(r=i);for(u=-1/0,n=a.length-1,e=0,r=a[n];e<=n;r=i,++e)i=a[e],(o=Qe(r[1],i[0]))>u&&(u=o,Dt=i[0],Ft=r[1]);}return Nr=Dr=null,Dt===1/0||Ne===1/0?[[NaN,NaN],[NaN,NaN]]:[[Dt,Ne],[Ft,Ze]]}var Uu,Gl,Xl,Vl,Kl,Ql,Zl,Jl,Q0,Z0,J0,NA,LA,Ae,we,Ee,Fn={sphere:Vt,point:N1,lineStart:x2,lineEnd:v2,polygonStart:function(){Fn.lineStart=f6,Fn.lineEnd=c6;},polygonEnd:function(){Fn.lineStart=x2,Fn.lineEnd=v2;}};function N1(t,e){t*=it,e*=it;var n=J(e);Zo(n*J(t),n*Q(t),Q(e));}function Zo(t,e,n){++Uu,Xl+=(t-Xl)/Uu,Vl+=(e-Vl)/Uu,Kl+=(n-Kl)/Uu;}function x2(){Fn.point=s6;}function s6(t,e){t*=it,e*=it;var n=J(e);Ae=n*J(t),we=n*Q(t),Ee=Q(e),Fn.point=l6,Zo(Ae,we,Ee);}function l6(t,e){t*=it,e*=it;var n=J(e),r=n*J(t),i=n*Q(t),a=Q(e),u=mn(ke((u=we*a-Ee*i)*u+(u=Ee*r-Ae*a)*u+(u=Ae*i-we*r)*u),Ae*r+we*i+Ee*a);Gl+=u,Ql+=u*(Ae+(Ae=r)),Zl+=u*(we+(we=i)),Jl+=u*(Ee+(Ee=a)),Zo(Ae,we,Ee);}function v2(){Fn.point=N1;}function f6(){Fn.point=h6;}function c6(){PA(NA,LA),Fn.point=N1;}function h6(t,e){NA=t,LA=e,t*=it,e*=it,Fn.point=PA;var n=J(e);Ae=n*J(t),we=n*Q(t),Ee=Q(e),Zo(Ae,we,Ee);}function PA(t,e){t*=it,e*=it;var n=J(e),r=n*J(t),i=n*Q(t),a=Q(e),u=we*a-Ee*i,o=Ee*r-Ae*a,s=Ae*i-we*r,l=Y0(u,o,s),f=je(l),c=l&&-f/l;Q0.add(c*u),Z0.add(c*o),J0.add(c*s),Gl+=f,Ql+=f*(Ae+(Ae=r)),Zl+=f*(we+(we=i)),Jl+=f*(Ee+(Ee=a)),Zo(Ae,we,Ee);}function zA(t){Uu=Gl=Xl=Vl=Kl=Ql=Zl=Jl=0,Q0=new De,Z0=new De,J0=new De,pr(t,Fn);var e=+Q0,n=+Z0,r=+J0,i=Y0(e,n,r);return iat&&(t-=Math.round(t/Me)*Me),[t,e]}ed.invert=ed;function IA(t,e,n){return (t%=Me)?e||n?td(A2(t),w2(e,n)):A2(t):e||n?w2(e,n):ed}function b2(t){return function(e,n){return e+=t,st(e)>at&&(e-=Math.round(e/Me)*Me),[e,n]}}function A2(t){var e=b2(t);return e.invert=b2(-t),e}function w2(t,e){var n=J(t),r=Q(t),i=J(e),a=Q(e);function u(o,s){var l=J(s),f=J(o)*l,c=Q(o)*l,h=Q(s),d=h*n+f*r;return [mn(c*i-d*a,f*n-h*r),je(d*i+c*a)]}return u.invert=function(o,s){var l=J(s),f=J(o)*l,c=Q(o)*l,h=Q(s),d=h*i-c*a;return [mn(c*i+h*a,f*n+d*r),je(d*n-f*r)]},u}function d6(t){t=IA(t[0]*it,t[1]*it,t.length>2?t[2]*it:0);function e(n){return n=t(n[0]*it,n[1]*it),n[0]*=Bt,n[1]*=Bt,n}return e.invert=function(n){return n=t.invert(n[0]*it,n[1]*it),n[0]*=Bt,n[1]*=Bt,n},e}function g6(t,e,n,r,i,a){if(n){var u=J(e),o=Q(e),s=r*n;i==null?(i=e+r*Me,a=e-s/2):(i=E2(u,i),a=E2(u,a),(r>0?ia)&&(i+=r*Me));for(var l,f=i;r>0?f>a:f1&&t.push(t.pop().concat(t.shift()));},result:function(){var n=t;return t=[],e=null,n}}}function ol(t,e){return st(t[0]-e[0])=0;--o)i.point((c=f[o])[0],c[1]);else r(h.x,h.p.x,-1,i);h=h.p;}h=h.o,f=h.z,d=!d;}while(!h.v);i.lineEnd();}}}function _2(t){if(e=t.length){for(var e,n=0,r=t[0],i;++n=0?1:-1,F=C*_,D=F>at,R=m*E;if(s.add(mn(R*C*Q(F),y*A+R*J(F))),u+=D?_+C*Me:_,D^g>=n^b>=n){var k=Ra(ji(d),ji(v));Hl(k);var N=Ra(a,k);Hl(N);var M=(D^_>=0?-1:1)*je(N[2]);(r>M||r===M&&(k[0]||k[1]))&&(o+=D^_>=0?1:-1);}}return (u<-Z||u0){for(s||(i.polygonStart(),s=!0),i.lineStart(),E=0;E<_;++E)i.point((F=C[E])[0],F[1]);i.lineEnd();}return}A>1&&b&2&&w.push(w.pop().concat(w.shift())),f.push(w.filter(m6));}}return h}}function m6(t){return t.length>1}function y6(t,e){return ((t=t.x)[0]<0?t[1]-kt-Z:kt-t[1])-((e=e.x)[0]<0?e[1]-kt-Z:kt-e[1])}const C2=jA(function(){return !0},x6,b6,[-at,-kt]);function x6(t){var e=NaN,n=NaN,r=NaN,i;return {lineStart:function(){t.lineStart(),i=1;},point:function(a,u){var o=a>0?at:-at,s=st(a-e);st(s-at)0?kt:-kt),t.point(r,n),t.lineEnd(),t.lineStart(),t.point(o,n),t.point(a,n),i=0):r!==o&&s>=at&&(st(e-r)Z?tu((Q(e)*(a=J(r))*Q(n)-Q(r)*(i=J(e))*Q(t))/(i*a*u)):(e+r)/2}function b6(t,e,n,r){var i;if(t==null)i=n*kt,r.point(-at,i),r.point(0,i),r.point(at,i),r.point(at,0),r.point(at,-i),r.point(0,-i),r.point(-at,-i),r.point(-at,0),r.point(-at,i);else if(st(t[0]-e[0])>Z){var a=t[0]0,i=st(e)>Z;function a(f,c,h,d){g6(d,t,n,h,f,c);}function u(f,c){return J(f)*J(c)>e}function o(f){var c,h,d,g,p;return {lineStart:function(){g=d=!1,p=1;},point:function(m,y){var x=[m,y],v,b=u(m,y),w=r?b?0:l(m,y):b?l(m+(m<0?at:-at),y):0;if(!c&&(g=d=b)&&f.lineStart(),b!==d&&(v=s(c,x),(!v||ol(c,v)||ol(x,v))&&(x[2]=1)),b!==d)p=0,b?(f.lineStart(),v=s(x,c),f.point(v[0],v[1])):(v=s(c,x),f.point(v[0],v[1],2),f.lineEnd()),c=v;else if(i&&c&&r^b){var E;!(w&h)&&(E=s(x,c,!0))&&(p=0,r?(f.lineStart(),f.point(E[0][0],E[0][1]),f.point(E[1][0],E[1][1]),f.lineEnd()):(f.point(E[1][0],E[1][1]),f.lineEnd(),f.lineStart(),f.point(E[0][0],E[0][1],3)));}b&&(!c||!ol(c,x))&&f.point(x[0],x[1]),c=x,d=b,h=w;},lineEnd:function(){d&&f.lineEnd(),c=null;},clean:function(){return p|(g&&d)<<1}}}function s(f,c,h){var d=ji(f),g=ji(c),p=[1,0,0],m=Ra(d,g),y=Ps(m,m),x=m[0],v=y-x*x;if(!v)return !h&&f;var b=e*y/v,w=-e*x/v,E=Ra(p,m),A=zs(p,b),_=zs(m,w);Oh(A,_);var C=E,F=Ps(A,C),D=Ps(C,C),R=F*F-D*(Ps(A,A)-1);if(!(R<0)){var k=ke(R),N=zs(C,(-F-k)/D);if(Oh(N,A),N=Yl(N),!h)return N;var M=f[0],O=c[0],z=f[1],G=c[1],W;O0^N[1]<(st(N[0]-M)at^(M<=N[0]&&N[0]<=O)){var me=zs(C,(-F+k)/D);return Oh(me,A),[N,Yl(me)]}}}function l(f,c){var h=r?t:at-t,d=0;return f<-h?d|=1:f>h&&(d|=2),c<-h?d|=4:c>h&&(d|=8),d}return jA(u,o,a,r?[0,-t]:[-at,t-at])}function w6(t,e,n,r,i,a){var u=t[0],o=t[1],s=e[0],l=e[1],f=0,c=1,h=s-u,d=l-o,g;if(g=n-u,!(!h&&g>0)){if(g/=h,h<0){if(g0){if(g>c)return;g>f&&(f=g);}if(g=i-u,!(!h&&g<0)){if(g/=h,h<0){if(g>c)return;g>f&&(f=g);}else if(h>0){if(g0)){if(g/=d,d<0){if(g0){if(g>c)return;g>f&&(f=g);}if(g=a-o,!(!d&&g<0)){if(g/=d,d<0){if(g>c)return;g>f&&(f=g);}else if(d>0){if(g0&&(t[0]=u+f*h,t[1]=o+f*d),c<1&&(e[0]=u+c*h,e[1]=o+c*d),!0}}}}}var qu=1e9,Us=-qu;function WA(t,e,n,r){function i(l,f){return t<=l&&l<=n&&e<=f&&f<=r}function a(l,f,c,h){var d=0,g=0;if(l==null||(d=u(l,c))!==(g=u(f,c))||s(l,f)<0^c>0)do h.point(d===0||d===3?t:n,d>1?r:e);while((d=(d+c+4)%4)!==g);else h.point(f[0],f[1]);}function u(l,f){return st(l[0]-t)0?0:3:st(l[0]-n)0?2:1:st(l[1]-e)0?1:0:f>0?3:2}function o(l,f){return s(l.x,f.x)}function s(l,f){var c=u(l,1),h=u(f,1);return c!==h?c-h:c===0?f[1]-l[1]:c===1?l[0]-f[0]:c===2?l[1]-f[1]:f[0]-l[0]}return function(l){var f=l,c=UA(),h,d,g,p,m,y,x,v,b,w,E,A={point:_,lineStart:R,lineEnd:k,polygonStart:F,polygonEnd:D};function _(M,O){i(M,O)&&f.point(M,O);}function C(){for(var M=0,O=0,z=d.length;Or&&(Pn-Se)*(r-me)>(Ut-me)*(t-Se)&&++M:Ut<=r&&(Pn-Se)*(r-me)<(Ut-me)*(t-Se)&&--M;return M}function F(){f=c,h=[],d=[],E=!0;}function D(){var M=C(),O=E&&M,z=(h=Ub(h)).length;(O||z)&&(l.polygonStart(),O&&(l.lineStart(),a(null,null,1,l),l.lineEnd()),z&&qA(h,o,M,a,l),l.polygonEnd()),f=l,h=d=g=null;}function R(){A.point=N,d&&d.push(g=[]),w=!0,b=!1,x=v=NaN;}function k(){h&&(N(p,m),y&&b&&c.rejoin(),h.push(c.result())),A.point=_,b&&f.lineEnd();}function N(M,O){var z=i(M,O);if(d&&g.push([M,O]),w)p=M,m=O,y=z,w=!1,z&&(f.lineStart(),f.point(M,O));else if(z&&b)f.point(M,O);else {var G=[x=Math.max(Us,Math.min(qu,x)),v=Math.max(Us,Math.min(qu,v))],W=[M=Math.max(Us,Math.min(qu,M)),O=Math.max(Us,Math.min(qu,O))];w6(G,W,t,e,n,r)?(b||(f.lineStart(),f.point(G[0],G[1])),f.point(W[0],W[1]),z||f.lineEnd(),E=!1):z&&(f.lineStart(),f.point(M,O),E=!1);}x=M,v=O,b=z;}return A}}function D2(t,e,n){var r=Ie(t,e-Z,n).concat(e);return function(i){return r.map(function(a){return [i,a]})}}function F2(t,e,n){var r=Ie(t,e-Z,n).concat(e);return function(i){return r.map(function(a){return [a,i]})}}function E6(){var t,e,n,r,i,a,u,o,s=10,l=s,f=90,c=360,h,d,g,p,m=2.5;function y(){return {type:"MultiLineString",coordinates:x()}}function x(){return Ie(Ls(r/f)*f,n,f).map(g).concat(Ie(Ls(o/c)*c,u,c).map(p)).concat(Ie(Ls(e/s)*s,t,s).filter(function(v){return st(v%f)>Z}).map(h)).concat(Ie(Ls(a/l)*l,i,l).filter(function(v){return st(v%c)>Z}).map(d))}return y.lines=function(){return x().map(function(v){return {type:"LineString",coordinates:v}})},y.outline=function(){return {type:"Polygon",coordinates:[g(r).concat(p(u).slice(1),g(n).reverse().slice(1),p(o).reverse().slice(1))]}},y.extent=function(v){return arguments.length?y.extentMajor(v).extentMinor(v):y.extentMinor()},y.extentMajor=function(v){return arguments.length?(r=+v[0][0],n=+v[1][0],o=+v[0][1],u=+v[1][1],r>n&&(v=r,r=n,n=v),o>u&&(v=o,o=u,u=v),y.precision(m)):[[r,o],[n,u]]},y.extentMinor=function(v){return arguments.length?(e=+v[0][0],t=+v[1][0],a=+v[0][1],i=+v[1][1],e>t&&(v=e,e=t,t=v),a>i&&(v=a,a=i,i=v),y.precision(m)):[[e,a],[t,i]]},y.step=function(v){return arguments.length?y.stepMajor(v).stepMinor(v):y.stepMinor()},y.stepMajor=function(v){return arguments.length?(f=+v[0],c=+v[1],y):[f,c]},y.stepMinor=function(v){return arguments.length?(s=+v[0],l=+v[1],y):[s,l]},y.precision=function(v){return arguments.length?(m=+v,h=D2(a,i,90),d=F2(e,t,m),g=D2(o,u,90),p=F2(r,n,m),y):m},y.extentMajor([[-180,-90+Z],[180,90-Z]]).extentMinor([[-180,-80-Z],[180,80+Z]])}const Do=t=>t;var Lh=new De,nd=new De,YA,HA,rd,id,mr={point:Vt,lineStart:Vt,lineEnd:Vt,polygonStart:function(){mr.lineStart=_6,mr.lineEnd=D6;},polygonEnd:function(){mr.lineStart=mr.lineEnd=mr.point=Vt,Lh.add(st(nd)),nd=new De;},result:function(){var t=Lh/2;return Lh=new De,t}};function _6(){mr.point=C6;}function C6(t,e){mr.point=GA,YA=rd=t,HA=id=e;}function GA(t,e){nd.add(id*t-rd*e),rd=t,id=e;}function D6(){GA(YA,HA);}var Oa=1/0,tf=Oa,Fo=-Oa,ef=Fo,nf={point:F6,lineStart:Vt,lineEnd:Vt,polygonStart:Vt,polygonEnd:Vt,result:function(){var t=[[Oa,tf],[Fo,ef]];return Fo=ef=-(tf=Oa=1/0),t}};function F6(t,e){tFo&&(Fo=t),eef&&(ef=e);}var ad=0,ud=0,ju=0,rf=0,af=0,Aa=0,od=0,sd=0,Wu=0,XA,VA,jn,Wn,fn={point:Wi,lineStart:M2,lineEnd:k2,polygonStart:function(){fn.lineStart=$6,fn.lineEnd=S6;},polygonEnd:function(){fn.point=Wi,fn.lineStart=M2,fn.lineEnd=k2;},result:function(){var t=Wu?[od/Wu,sd/Wu]:Aa?[rf/Aa,af/Aa]:ju?[ad/ju,ud/ju]:[NaN,NaN];return ad=ud=ju=rf=af=Aa=od=sd=Wu=0,t}};function Wi(t,e){ad+=t,ud+=e,++ju;}function M2(){fn.point=M6;}function M6(t,e){fn.point=k6,Wi(jn=t,Wn=e);}function k6(t,e){var n=t-jn,r=e-Wn,i=ke(n*n+r*r);rf+=i*(jn+t)/2,af+=i*(Wn+e)/2,Aa+=i,Wi(jn=t,Wn=e);}function k2(){fn.point=Wi;}function $6(){fn.point=B6;}function S6(){KA(XA,VA);}function B6(t,e){fn.point=KA,Wi(XA=jn=t,VA=Wn=e);}function KA(t,e){var n=t-jn,r=e-Wn,i=ke(n*n+r*r);rf+=i*(jn+t)/2,af+=i*(Wn+e)/2,Aa+=i,i=Wn*t-jn*e,od+=i*(jn+t),sd+=i*(Wn+e),Wu+=i*3,Wi(jn=t,Wn=e);}function QA(t){this._context=t;}QA.prototype={_radius:4.5,pointRadius:function(t){return this._radius=t,this},polygonStart:function(){this._line=0;},polygonEnd:function(){this._line=NaN;},lineStart:function(){this._point=0;},lineEnd:function(){this._line===0&&this._context.closePath(),this._point=NaN;},point:function(t,e){switch(this._point){case 0:{this._context.moveTo(t,e),this._point=1;break}case 1:{this._context.lineTo(t,e);break}default:{this._context.moveTo(t+this._radius,e),this._context.arc(t,e,this._radius,0,Me);break}}},result:Vt};var ld=new De,Ph,ZA,JA,Yu,Hu,Mo={point:Vt,lineStart:function(){Mo.point=T6;},lineEnd:function(){Ph&&tw(ZA,JA),Mo.point=Vt;},polygonStart:function(){Ph=!0;},polygonEnd:function(){Ph=null;},result:function(){var t=+ld;return ld=new De,t}};function T6(t,e){Mo.point=tw,ZA=Yu=t,JA=Hu=e;}function tw(t,e){Yu-=t,Hu-=e,ld.add(ke(Yu*Yu+Hu*Hu)),Yu=t,Hu=e;}let $2,uf,S2,B2;class T2{constructor(e){this._append=e==null?ew:R6(e),this._radius=4.5,this._="";}pointRadius(e){return this._radius=+e,this}polygonStart(){this._line=0;}polygonEnd(){this._line=NaN;}lineStart(){this._point=0;}lineEnd(){this._line===0&&(this._+="Z"),this._point=NaN;}point(e,n){switch(this._point){case 0:{this._append`M${e},${n}`,this._point=1;break}case 1:{this._append`L${e},${n}`;break}default:{if(this._append`M${e},${n}`,this._radius!==S2||this._append!==uf){const r=this._radius,i=this._;this._="",this._append`m0,${r}a${r},${r} 0 1,1 0,${-2*r}a${r},${r} 0 1,1 0,${2*r}z`,S2=r,uf=this._append,B2=this._,this._=i;}this._+=B2;break}}}result(){const e=this._;return this._="",e.length?e:null}}function ew(t){let e=1;this._+=t[0];for(const n=t.length;e=0))throw new RangeError(`invalid digits: ${t}`);if(e>15)return ew;if(e!==$2){const n=10**e;$2=e,uf=function(i){let a=1;this._+=i[0];for(const u=i.length;a=0))throw new RangeError(`invalid digits: ${o}`);n=s;}return e===null&&(a=new T2(n)),u},u.projection(t).digits(n).context(e)}function Qf(t){return function(e){var n=new fd;for(var r in t)n[r]=t[r];return n.stream=e,n}}function fd(){}fd.prototype={constructor:fd,point:function(t,e){this.stream.point(t,e);},sphere:function(){this.stream.sphere();},lineStart:function(){this.stream.lineStart();},lineEnd:function(){this.stream.lineEnd();},polygonStart:function(){this.stream.polygonStart();},polygonEnd:function(){this.stream.polygonEnd();}};function L1(t,e,n){var r=t.clipExtent&&t.clipExtent();return t.scale(150).translate([0,0]),r!=null&&t.clipExtent(null),pr(n,t.stream(nf)),e(nf.result()),r!=null&&t.clipExtent(r),t}function Zf(t,e,n){return L1(t,function(r){var i=e[1][0]-e[0][0],a=e[1][1]-e[0][1],u=Math.min(i/(r[1][0]-r[0][0]),a/(r[1][1]-r[0][1])),o=+e[0][0]+(i-u*(r[1][0]+r[0][0]))/2,s=+e[0][1]+(a-u*(r[1][1]+r[0][1]))/2;t.scale(150*u).translate([o,s]);},n)}function P1(t,e,n){return Zf(t,[[0,0],e],n)}function z1(t,e,n){return L1(t,function(r){var i=+e,a=i/(r[1][0]-r[0][0]),u=(i-a*(r[1][0]+r[0][0]))/2,o=-a*r[0][1];t.scale(150*a).translate([u,o]);},n)}function I1(t,e,n){return L1(t,function(r){var i=+e,a=i/(r[1][1]-r[0][1]),u=-a*r[0][0],o=(i-a*(r[1][1]+r[0][1]))/2;t.scale(150*a).translate([u,o]);},n)}var R2=16,O6=J(30*it);function O2(t,e){return +e?L6(t,e):N6(t)}function N6(t){return Qf({point:function(e,n){e=t(e,n),this.stream.point(e[0],e[1]);}})}function L6(t,e){function n(r,i,a,u,o,s,l,f,c,h,d,g,p,m){var y=l-r,x=f-i,v=y*y+x*x;if(v>4*e&&p--){var b=u+h,w=o+d,E=s+g,A=ke(b*b+w*w+E*E),_=je(E/=A),C=st(st(E)-1)e||st((y*k+x*N)/v-.5)>.3||u*h+o*d+s*g2?M[2]%360*it:0,k()):[o*Bt,s*Bt,l*Bt]},D.angle=function(M){return arguments.length?(c=M%360*it,k()):c*Bt},D.reflectX=function(M){return arguments.length?(h=M?-1:1,k()):h<0},D.reflectY=function(M){return arguments.length?(d=M?-1:1,k()):d<0},D.precision=function(M){return arguments.length?(E=O2(A,w=M*M),N()):ke(w)},D.fitExtent=function(M,O){return Zf(D,M,O)},D.fitSize=function(M,O){return P1(D,M,O)},D.fitWidth=function(M,O){return z1(D,M,O)},D.fitHeight=function(M,O){return I1(D,M,O)};function k(){var M=N2(n,0,0,h,d,c).apply(null,e(a,u)),O=N2(n,r-M[0],i-M[1],h,d,c);return f=IA(o,s,l),A=td(e,O),_=td(f,A),E=O2(A,w),N()}function N(){return C=F=null,D}return function(){return e=t.apply(this,arguments),D.invert=e.invert&&R,k()}}function U1(t){var e=0,n=at/3,r=rw(t),i=r(e,n);return i.parallels=function(a){return arguments.length?r(e=a[0]*it,n=a[1]*it):[e*Bt,n*Bt]},i}function U6(t){var e=J(t);function n(r,i){return [r*e,Q(i)/e]}return n.invert=function(r,i){return [r/e,je(i*e)]},n}function q6(t,e){var n=Q(t),r=(n+Q(e))/2;if(st(r)=.12&&m<.234&&p>=-.425&&p<-.214?i:m>=.166&&m<.234&&p>=-.214&&p<-.115?u:n).invert(h)},f.stream=function(h){return t&&e===h?t:t=j6([n.stream(e=h),i.stream(h),u.stream(h)])},f.precision=function(h){return arguments.length?(n.precision(h),i.precision(h),u.precision(h),c()):n.precision()},f.scale=function(h){return arguments.length?(n.scale(h),i.scale(h*.35),u.scale(h),f.translate(n.translate())):n.scale()},f.translate=function(h){if(!arguments.length)return n.translate();var d=n.scale(),g=+h[0],p=+h[1];return r=n.translate(h).clipExtent([[g-.455*d,p-.238*d],[g+.455*d,p+.238*d]]).stream(l),a=i.translate([g-.307*d,p+.201*d]).clipExtent([[g-.425*d+Z,p+.12*d+Z],[g-.214*d-Z,p+.234*d-Z]]).stream(l),o=u.translate([g-.205*d,p+.212*d]).clipExtent([[g-.214*d+Z,p+.166*d+Z],[g-.115*d-Z,p+.234*d-Z]]).stream(l),c()},f.fitExtent=function(h,d){return Zf(f,h,d)},f.fitSize=function(h,d){return P1(f,h,d)},f.fitWidth=function(h,d){return z1(f,h,d)},f.fitHeight=function(h,d){return I1(f,h,d)};function c(){return t=e=null,f}return f.scale(1070)}function aw(t){return function(e,n){var r=J(e),i=J(n),a=t(r*i);return a===1/0?[2,0]:[a*i*Q(e),a*Q(n)]}}function Jo(t){return function(e,n){var r=ke(e*e+n*n),i=t(r),a=Q(i),u=J(i);return [mn(e*a,r*u),je(r&&n*a/r)]}}var uw=aw(function(t){return ke(2/(1+t))});uw.invert=Jo(function(t){return 2*je(t/2)});function Y6(){return er(uw).scale(124.75).clipAngle(180-.001)}var ow=aw(function(t){return (t=DA(t))&&t/Q(t)});ow.invert=Jo(function(t){return t});function H6(){return er(ow).scale(79.4188).clipAngle(180-.001)}function Jf(t,e){return [t,Ul(O1((kt+e)/2))]}Jf.invert=function(t,e){return [t,2*tu(CA(e))-kt]};function G6(){return sw(Jf).scale(961/Me)}function sw(t){var e=er(t),n=e.center,r=e.scale,i=e.translate,a=e.clipExtent,u=null,o,s,l;e.scale=function(c){return arguments.length?(r(c),f()):r()},e.translate=function(c){return arguments.length?(i(c),f()):i()},e.center=function(c){return arguments.length?(n(c),f()):n()},e.clipExtent=function(c){return arguments.length?(c==null?u=o=s=l=null:(u=+c[0][0],o=+c[0][1],s=+c[1][0],l=+c[1][1]),f()):u==null?null:[[u,o],[s,l]]};function f(){var c=at*r(),h=e(d6(e.rotate()).invert([0,0]));return a(u==null?[[h[0]-c,h[1]-c],[h[0]+c,h[1]+c]]:t===Jf?[[Math.max(h[0]-c,u),o],[Math.min(h[0]+c,s),l]]:[[u,Math.max(h[1]-c,o)],[s,Math.min(h[1]+c,l)]])}return f()}function qs(t){return O1((kt+t)/2)}function X6(t,e){var n=J(t),r=t===e?Q(t):Ul(n/J(e))/Ul(qs(e)/qs(t)),i=n*Rh(qs(t),r)/r;if(!r)return Jf;function a(u,o){i>0?o<-kt+Z&&(o=-kt+Z):o>kt-Z&&(o=kt-Z);var s=i/Rh(qs(o),r);return [s*Q(r*u),i-s*J(r*u)]}return a.invert=function(u,o){var s=i-o,l=cn(r)*ke(u*u+s*s),f=mn(u,st(s))*cn(s);return s*r<0&&(f-=at*cn(u)*cn(s)),[f/r,2*tu(Rh(i/l,1/r))-kt]},a}function V6(){return U1(X6).scale(109.5).parallels([30,30])}function sf(t,e){return [t,e]}sf.invert=sf;function K6(){return er(sf).scale(152.63)}function Q6(t,e){var n=J(t),r=t===e?Q(t):(n-J(e))/(e-t),i=n/r+t;if(st(r)Z&&--r>0);return [t/(.8707+(a=n*n)*(-.131979+a*(-.013791+a*a*a*(.003971-.001529*a)))),n]};function rk(){return er(cw).scale(175.295)}function hw(t,e){return [J(e)*Q(t),Q(e)]}hw.invert=Jo(je);function ik(){return er(hw).scale(249.5).clipAngle(90+Z)}function dw(t,e){var n=J(e),r=1+J(t)*n;return [n*Q(t)/r,Q(e)/r]}dw.invert=Jo(function(t){return 2*tu(t)});function ak(){return er(dw).scale(250).clipAngle(142)}function gw(t,e){return [Ul(O1((kt+e)/2)),-t]}gw.invert=function(t,e){return [-e,2*tu(CA(t))-kt]};function uk(){var t=sw(gw),e=t.center,n=t.rotate;return t.center=function(r){return arguments.length?e([-r[1],r[0]]):(r=e(),[r[1],-r[0]])},t.rotate=function(r){return arguments.length?n([r[0],r[1],r.length>2?r[2]+90:90]):(r=n(),[r[0],r[1],r[2]-90])},n([0,0,90]).scale(159.155)}function ok(t,e){return t.parent===e.parent?1:2}function sk(t){return t.reduce(lk,0)/t.length}function lk(t,e){return t+e.x}function fk(t){return 1+t.reduce(ck,0)}function ck(t,e){return Math.max(t,e.y)}function hk(t){for(var e;e=t.children;)t=e[0];return t}function dk(t){for(var e;e=t.children;)t=e[e.length-1];return t}function gk(){var t=ok,e=1,n=1,r=!1;function i(a){var u,o=0;a.eachAfter(function(h){var d=h.children;d?(h.x=sk(d),h.y=fk(d)):(h.x=u?o+=t(h,u):0,h.y=0,u=h);});var s=hk(a),l=dk(a),f=s.x-t(s,l)/2,c=l.x+t(l,s)/2;return a.eachAfter(r?function(h){h.x=(h.x-a.x)*e,h.y=(a.y-h.y)*n;}:function(h){h.x=(h.x-f)/(c-f)*e,h.y=(1-(a.y?h.y/a.y:1))*n;})}return i.separation=function(a){return arguments.length?(t=a,i):t},i.size=function(a){return arguments.length?(r=!1,e=+a[0],n=+a[1],i):r?null:[e,n]},i.nodeSize=function(a){return arguments.length?(r=!0,e=+a[0],n=+a[1],i):r?[e,n]:null},i}function pk(t){var e=0,n=t.children,r=n&&n.length;if(!r)e=1;else for(;--r>=0;)e+=n[r].value;t.value=e;}function mk(){return this.eachAfter(pk)}function yk(t,e){let n=-1;for(const r of this)t.call(e,r,++n,this);return this}function xk(t,e){for(var n=this,r=[n],i,a,u=-1;n=r.pop();)if(t.call(e,n,++u,this),i=n.children)for(a=i.length-1;a>=0;--a)r.push(i[a]);return this}function vk(t,e){for(var n=this,r=[n],i=[],a,u,o,s=-1;n=r.pop();)if(i.push(n),a=n.children)for(u=0,o=a.length;u=0;)n+=r[i].value;e.value=n;})}function wk(t){return this.eachBefore(function(e){e.children&&e.children.sort(t);})}function Ek(t){for(var e=this,n=_k(e,t),r=[e];e!==n;)e=e.parent,r.push(e);for(var i=r.length;t!==n;)r.splice(i,0,t),t=t.parent;return r}function _k(t,e){if(t===e)return t;var n=t.ancestors(),r=e.ancestors(),i=null;for(t=n.pop(),e=r.pop();t===e;)i=t,t=n.pop(),e=r.pop();return i}function Ck(){for(var t=this,e=[t];t=t.parent;)e.push(t);return e}function Dk(){return Array.from(this)}function Fk(){var t=[];return this.eachBefore(function(e){e.children||t.push(e);}),t}function Mk(){var t=this,e=[];return t.each(function(n){n!==t&&e.push({source:n.parent,target:n});}),e}function*kk(){var t=this,e,n=[t],r,i,a;do for(e=n.reverse(),n=[];t=e.pop();)if(yield t,r=t.children)for(i=0,a=r.length;i=0;--o)i.push(a=u[o]=new Na(u[o])),a.parent=r,a.depth=r.depth+1;return n.eachBefore(pw)}function $k(){return q1(this).eachBefore(Tk)}function Sk(t){return t.children}function Bk(t){return Array.isArray(t)?t[1]:null}function Tk(t){t.data.value!==void 0&&(t.value=t.data.value),t.data=t.data.data;}function pw(t){var e=0;do t.height=e;while((t=t.parent)&&t.height<++e)}function Na(t){this.data=t,this.depth=this.height=0,this.parent=null;}Na.prototype=q1.prototype={constructor:Na,count:mk,each:yk,eachAfter:vk,eachBefore:xk,find:bk,sum:Ak,sort:wk,path:Ek,ancestors:Ck,descendants:Dk,leaves:Fk,links:Mk,copy:$k,[Symbol.iterator]:kk};function sl(t){return t==null?null:mw(t)}function mw(t){if(typeof t!="function")throw new Error;return t}function _i(){return 0}function xa(t){return function(){return t}}const Rk=1664525,Ok=1013904223,L2=4294967296;function Nk(){let t=1;return ()=>(t=(Rk*t+Ok)%L2)/L2}function Lk(t){return typeof t=="object"&&"length"in t?t:Array.from(t)}function Pk(t,e){let n=t.length,r,i;for(;n;)i=e()*n--|0,r=t[n],t[n]=t[i],t[i]=r;return t}function zk(t,e){for(var n=0,r=(t=Pk(Array.from(t),e)).length,i=[],a,u;n0&&n*n>r*r+i*i}function zh(t,e){for(var n=0;n1e-6?(D+Math.sqrt(D*D-4*F*R))/(2*F):R/D);return {x:r+E+A*k,y:i+_+C*k,r:k}}function P2(t,e,n){var r=t.x-e.x,i,a,u=t.y-e.y,o,s,l=r*r+u*u;l?(a=e.r+n.r,a*=a,s=t.r+n.r,s*=s,a>s?(i=(l+s-a)/(2*l),o=Math.sqrt(Math.max(0,s/l-i*i)),n.x=t.x-i*r-o*u,n.y=t.y-i*u+o*r):(i=(l+a-s)/(2*l),o=Math.sqrt(Math.max(0,a/l-i*i)),n.x=e.x+i*r-o*u,n.y=e.y+i*u+o*r)):(n.x=e.x+n.r,n.y=e.y);}function z2(t,e){var n=t.r+e.r-1e-6,r=e.x-t.x,i=e.y-t.y;return n>0&&n*n>r*r+i*i}function I2(t){var e=t._,n=t.next._,r=e.r+n.r,i=(e.x*n.r+n.x*e.r)/r,a=(e.y*n.r+n.y*e.r)/r;return i*i+a*a}function Ws(t){this._=t,this.next=null,this.previous=null;}function jk(t,e){if(!(a=(t=Lk(t)).length))return 0;var n,r,i,a,u,o,s,l,f,c,h;if(n=t[0],n.x=0,n.y=0,!(a>1))return n.r;if(r=t[1],n.x=-r.r,r.x=n.r,r.y=0,!(a>2))return n.r+r.r;P2(r,n,i=t[2]),n=new Ws(n),r=new Ws(r),i=new Ws(i),n.next=i.previous=r,r.next=n.previous=i,i.next=r.previous=n;t:for(s=3;sKk(n(b,w,i))),x=y.map(Y2),v=new Set(y).add("");for(const b of x)v.has(b)||(v.add(b),y.push(b),x.push(Y2(b)),a.push(Uh));u=(b,w)=>y[w],o=(b,w)=>x[w];}for(f=0,s=a.length;f=0&&(d=a[y],d.data===Uh);--y)d.data=null;}if(c.parent=Gk,c.eachBefore(function(y){y.depth=y.parent.depth+1,--s;}).eachBefore(pw),c.parent=null,s>0)throw new Error("cycle");return c}return r.id=function(i){return arguments.length?(t=sl(i),r):t},r.parentId=function(i){return arguments.length?(e=sl(i),r):e},r.path=function(i){return arguments.length?(n=sl(i),r):n},r}function Kk(t){t=`${t}`;let e=t.length;return cd(t,e-1)&&!cd(t,e-2)&&(t=t.slice(0,-1)),t[0]==="/"?t:`/${t}`}function Y2(t){let e=t.length;if(e<2)return "";for(;--e>1&&!cd(t,e););return t.slice(0,e)}function cd(t,e){if(t[e]==="/"){let n=0;for(;e>0&&t[--e]==="\\";)++n;if(!(n&1))return !0}return !1}function Qk(t,e){return t.parent===e.parent?1:2}function qh(t){var e=t.children;return e?e[0]:t.t}function jh(t){var e=t.children;return e?e[e.length-1]:t.t}function Zk(t,e,n){var r=n/(e.i-t.i);e.c-=r,e.s+=n,t.c+=r,e.z+=n,e.m+=n;}function Jk(t){for(var e=0,n=0,r=t.children,i=r.length,a;--i>=0;)a=r[i],a.z+=e,a.m+=e,e+=a.s+(n+=a.c);}function t8(t,e,n){return t.a.parent===e.parent?t.a:n}function ll(t,e){this._=t,this.parent=null,this.children=null,this.A=null,this.a=this,this.z=0,this.m=0,this.c=0,this.s=0,this.t=null,this.i=e;}ll.prototype=Object.create(Na.prototype);function e8(t){for(var e=new ll(t,0),n,r=[e],i,a,u,o;n=r.pop();)if(a=n._.children)for(n.children=new Array(o=a.length),u=o-1;u>=0;--u)r.push(i=n.children[u]=new ll(a[u],u)),i.parent=n;return (e.parent=new ll(null,0)).children=[e],e}function n8(){var t=Qk,e=1,n=1,r=null;function i(l){var f=e8(l);if(f.eachAfter(a),f.parent.m=-f.z,f.eachBefore(u),r)l.eachBefore(s);else {var c=l,h=l,d=l;l.eachBefore(function(x){x.xh.x&&(h=x),x.depth>d.depth&&(d=x);});var g=c===h?1:t(c,h)/2,p=g-c.x,m=e/(h.x+g+p),y=n/(d.depth||1);l.eachBefore(function(x){x.x=(x.x+p)*m,x.y=x.depth*y;});}return l}function a(l){var f=l.children,c=l.parent.children,h=l.i?c[l.i-1]:null;if(f){Jk(l);var d=(f[0].z+f[f.length-1].z)/2;h?(l.z=h.z+t(l._,h._),l.m=l.z-d):l.z=d;}else h&&(l.z=h.z+t(l._,h._));l.parent.A=o(l,h,l.parent.A||c[0]);}function u(l){l._.x=l.z+l.parent.m,l.m+=l.parent.m;}function o(l,f,c){if(f){for(var h=l,d=l,g=f,p=h.parent.children[0],m=h.m,y=d.m,x=g.m,v=p.m,b;g=jh(g),h=qh(h),g&&h;)p=qh(p),d=jh(d),d.a=l,b=g.z+x-h.z-m+t(g._,h._),b>0&&(Zk(t8(g,l,c),l,b),m+=b,y+=b),x+=g.m,m+=h.m,v+=p.m,y+=d.m;g&&!jh(d)&&(d.t=g,d.m+=x-y),h&&!qh(p)&&(p.t=h,p.m+=m-v,c=l);}return c}function s(l){l.x*=e,l.y=l.depth*n;}return i.separation=function(l){return arguments.length?(t=l,i):t},i.size=function(l){return arguments.length?(r=!1,e=+l[0],n=+l[1],i):r?null:[e,n]},i.nodeSize=function(l){return arguments.length?(r=!0,e=+l[0],n=+l[1],i):r?[e,n]:null},i}function tc(t,e,n,r,i){for(var a=t.children,u,o=-1,s=a.length,l=t.value&&(i-n)/t.value;++ox&&(x=l),E=m*m*w,v=Math.max(x/E,E/y),v>b){m-=l;break}b=v;}u.push(s={value:m,dice:d1?r:1)},n}(bw);function r8(){var t=ww,e=!1,n=1,r=1,i=[0],a=_i,u=_i,o=_i,s=_i,l=_i;function f(h){return h.x0=h.y0=0,h.x1=n,h.y1=r,h.eachBefore(c),i=[0],e&&h.eachBefore(vw),h}function c(h){var d=i[h.depth],g=h.x0+d,p=h.y0+d,m=h.x1-d,y=h.y1-d;m=h-1){var x=a[c];x.x0=g,x.y0=p,x.x1=m,x.y1=y;return}for(var v=l[c],b=d/2+v,w=c+1,E=h-1;w>>1;l[A]y-p){var F=d?(g*C+m*_)/d:m;f(c,w,_,g,p,F,y),f(w,h,C,F,p,m,y);}else {var D=d?(p*C+y*_)/d:y;f(c,w,_,g,p,m,D),f(w,h,C,g,D,m,y);}}}function a8(t,e,n,r,i){(t.depth&1?tc:ts)(t,e,n,r,i);}const u8=function t(e){function n(r,i,a,u,o){if((s=r._squarify)&&s.ratio===e)for(var s,l,f,c,h=-1,d,g=s.length,p=r.value;++h1?r:1)},n}(bw);function nr(t,e){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(e).domain(t);break}return this}function hi(t,e){switch(arguments.length){case 0:break;case 1:{typeof t=="function"?this.interpolator(t):this.range(t);break}default:{this.domain(t),typeof e=="function"?this.interpolator(e):this.range(e);break}}return this}const hd=Symbol("implicit");function j1(){var t=new Py,e=[],n=[],r=hd;function i(a){let u=t.get(a);if(u===void 0){if(r!==hd)return r;t.set(a,u=e.push(a)-1);}return n[u%n.length]}return i.domain=function(a){if(!arguments.length)return e.slice();e=[],t=new Py;for(const u of a)t.has(u)||t.set(u,e.push(u)-1);return i},i.range=function(a){return arguments.length?(n=Array.from(a),i):n.slice()},i.unknown=function(a){return arguments.length?(r=a,i):r},i.copy=function(){return j1(e,n).unknown(r)},nr.apply(i,arguments),i}function o8(t){return function(){return t}}function dd(t){return +t}var H2=[0,1];function Ue(t){return t}function gd(t,e){return (e-=t=+t)?function(n){return (n-t)/e}:o8(isNaN(e)?NaN:.5)}function s8(t,e){var n;return t>e&&(n=t,t=e,e=n),function(r){return Math.max(t,Math.min(e,r))}}function l8(t,e,n){var r=t[0],i=t[1],a=e[0],u=e[1];return i2?f8:l8,s=l=null,c}function c(h){return h==null||isNaN(h=+h)?a:(s||(s=o(t.map(r),e,n)))(r(u(h)))}return c.invert=function(h){return u(i((l||(l=o(e,t.map(r),wn)))(h)))},c.domain=function(h){return arguments.length?(t=Array.from(h,dd),f()):t.slice()},c.range=function(h){return arguments.length?(e=Array.from(h),f()):e.slice()},c.rangeRound=function(h){return e=Array.from(h),n=Ko,f()},c.clamp=function(h){return arguments.length?(u=h?!0:Ue,f()):u!==Ue},c.interpolate=function(h){return arguments.length?(n=h,f()):n},c.unknown=function(h){return arguments.length?(a=h,c):a},function(h,d){return r=h,i=d,f()}}function Ew(){return ec()(Ue,Ue)}function _w(t,e,n,r){var i=ei(t,e,n),a;switch(r=qi(r??",f"),r.type){case"s":{var u=Math.max(Math.abs(t),Math.abs(e));return r.precision==null&&!isNaN(a=EA(i,u))&&(r.precision=a),R1(r,u)}case"":case"e":case"g":case"p":case"r":{r.precision==null&&!isNaN(a=_A(i,Math.max(Math.abs(t),Math.abs(e))))&&(r.precision=a-(r.type==="e"));break}case"f":case"%":{r.precision==null&&!isNaN(a=wA(i))&&(r.precision=a-(r.type==="%")*2);break}}return Kf(r)}function Ji(t){var e=t.domain;return t.ticks=function(n){var r=e();return T0(r[0],r[r.length-1],n??10)},t.tickFormat=function(n,r){var i=e();return _w(i[0],i[i.length-1],n??10,r)},t.nice=function(n){n==null&&(n=10);var r=e(),i=0,a=r.length-1,u=r[i],o=r[a],s,l,f=10;for(o0;){if(l=R0(u,o,n),l===s)return r[i]=u,r[a]=o,e(r);if(l>0)u=Math.floor(u/l)*l,o=Math.ceil(o/l)*l;else if(l<0)u=Math.ceil(u*l)/l,o=Math.floor(o*l)/l;else break;s=l;}return t},t}function Cw(){var t=Ew();return t.copy=function(){return es(t,Cw())},nr.apply(t,arguments),Ji(t)}function Dw(t){var e;function n(r){return r==null||isNaN(r=+r)?e:r}return n.invert=n,n.domain=n.range=function(r){return arguments.length?(t=Array.from(r,dd),n):t.slice()},n.unknown=function(r){return arguments.length?(e=r,n):e},n.copy=function(){return Dw(t).unknown(e)},t=arguments.length?Array.from(t,dd):[0,1],Ji(n)}function Fw(t,e){t=t.slice();var n=0,r=t.length-1,i=t[n],a=t[r],u;return aMath.pow(t,e)}function p8(t){return t===Math.E?Math.log:t===10&&Math.log10||t===2&&Math.log2||(t=Math.log(t),e=>Math.log(e)/t)}function V2(t){return (e,n)=>-t(-e,n)}function W1(t){const e=t(G2,X2),n=e.domain;let r=10,i,a;function u(){return i=p8(r),a=g8(r),n()[0]<0?(i=V2(i),a=V2(a),t(c8,h8)):t(G2,X2),e}return e.base=function(o){return arguments.length?(r=+o,u()):r},e.domain=function(o){return arguments.length?(n(o),u()):n()},e.ticks=o=>{const s=n();let l=s[0],f=s[s.length-1];const c=f0){for(;h<=d;++h)for(g=1;gf)break;y.push(p);}}else for(;h<=d;++h)for(g=r-1;g>=1;--g)if(p=h>0?g/a(-h):g*a(h),!(pf)break;y.push(p);}y.length*2{if(o==null&&(o=10),s==null&&(s=r===10?"s":","),typeof s!="function"&&(!(r%1)&&(s=qi(s)).precision==null&&(s.trim=!0),s=Kf(s)),o===1/0)return s;const l=Math.max(1,r*o/e.ticks().length);return f=>{let c=f/a(Math.round(i(f)));return c*rn(Fw(n(),{floor:o=>a(Math.floor(i(o))),ceil:o=>a(Math.ceil(i(o)))})),e}function Mw(){const t=W1(ec()).domain([1,10]);return t.copy=()=>es(t,Mw()).base(t.base()),nr.apply(t,arguments),t}function K2(t){return function(e){return Math.sign(e)*Math.log1p(Math.abs(e/t))}}function Q2(t){return function(e){return Math.sign(e)*Math.expm1(Math.abs(e))*t}}function Y1(t){var e=1,n=t(K2(e),Q2(e));return n.constant=function(r){return arguments.length?t(K2(e=+r),Q2(e)):e},Ji(n)}function kw(){var t=Y1(ec());return t.copy=function(){return es(t,kw()).constant(t.constant())},nr.apply(t,arguments)}function Z2(t){return function(e){return e<0?-Math.pow(-e,t):Math.pow(e,t)}}function m8(t){return t<0?-Math.sqrt(-t):Math.sqrt(t)}function y8(t){return t<0?-t*t:t*t}function H1(t){var e=t(Ue,Ue),n=1;function r(){return n===1?t(Ue,Ue):n===.5?t(m8,y8):t(Z2(n),Z2(1/n))}return e.exponent=function(i){return arguments.length?(n=+i,r()):n},Ji(e)}function G1(){var t=H1(ec());return t.copy=function(){return es(t,G1()).exponent(t.exponent())},nr.apply(t,arguments),t}function x8(){return G1.apply(null,arguments).exponent(.5)}function $w(){var t=[],e=[],n=[],r;function i(){var u=0,o=Math.max(1,e.length);for(n=new Array(o-1);++u0?n[o-1]:t[0],o=n?[r[n-1],e]:[r[l-1],r[l]]},u.unknown=function(s){return arguments.length&&(a=s),u},u.thresholds=function(){return r.slice()},u.copy=function(){return Sw().domain([t,e]).range(i).unknown(a)},nr.apply(Ji(u),arguments)}function Bw(){var t=[.5],e=[0,1],n,r=1;function i(a){return a!=null&&a<=a?e[ti(t,a,0,r)]:n}return i.domain=function(a){return arguments.length?(t=Array.from(a),r=Math.min(t.length,e.length-1),i):t.slice()},i.range=function(a){return arguments.length?(e=Array.from(a),r=Math.min(t.length,e.length-1),i):e.slice()},i.invertExtent=function(a){var u=e.indexOf(a);return [t[u-1],t[u]]},i.unknown=function(a){return arguments.length?(n=a,i):n},i.copy=function(){return Bw().domain(t).range(e).unknown(n)},nr.apply(i,arguments)}const Wh=new Date,Yh=new Date;function Pt(t,e,n,r){function i(a){return t(a=arguments.length===0?new Date:new Date(+a)),a}return i.floor=a=>(t(a=new Date(+a)),a),i.ceil=a=>(t(a=new Date(a-1)),e(a,1),t(a),a),i.round=a=>{const u=i(a),o=i.ceil(a);return a-u(e(a=new Date(+a),u==null?1:Math.floor(u)),a),i.range=(a,u,o)=>{const s=[];if(a=i.ceil(a),o=o==null?1:Math.floor(o),!(a0))return s;let l;do s.push(l=new Date(+a)),e(a,o),t(a);while(lPt(u=>{if(u>=u)for(;t(u),!a(u);)u.setTime(u-1);},(u,o)=>{if(u>=u)if(o<0)for(;++o<=0;)for(;e(u,-1),!a(u););else for(;--o>=0;)for(;e(u,1),!a(u););}),n&&(i.count=(a,u)=>(Wh.setTime(+a),Yh.setTime(+u),t(Wh),t(Yh),Math.floor(n(Wh,Yh))),i.every=a=>(a=Math.floor(a),!isFinite(a)||!(a>0)?null:a>1?i.filter(r?u=>r(u)%a===0:u=>i.count(0,u)%a===0):i)),i}const La=Pt(()=>{},(t,e)=>{t.setTime(+t+e);},(t,e)=>e-t);La.every=t=>(t=Math.floor(t),!isFinite(t)||!(t>0)?null:t>1?Pt(e=>{e.setTime(Math.floor(e/t)*t);},(e,n)=>{e.setTime(+e+n*t);},(e,n)=>(n-e)/t):La);La.range;const xr=1e3,hn=xr*60,vr=hn*60,Fr=vr*24,X1=Fr*7,J2=Fr*30,Hh=Fr*365,br=Pt(t=>{t.setTime(t-t.getMilliseconds());},(t,e)=>{t.setTime(+t+e*xr);},(t,e)=>(e-t)/xr,t=>t.getUTCSeconds());br.range;const nc=Pt(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*xr);},(t,e)=>{t.setTime(+t+e*hn);},(t,e)=>(e-t)/hn,t=>t.getMinutes());nc.range;const rc=Pt(t=>{t.setUTCSeconds(0,0);},(t,e)=>{t.setTime(+t+e*hn);},(t,e)=>(e-t)/hn,t=>t.getUTCMinutes());rc.range;const ic=Pt(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*xr-t.getMinutes()*hn);},(t,e)=>{t.setTime(+t+e*vr);},(t,e)=>(e-t)/vr,t=>t.getHours());ic.range;const ac=Pt(t=>{t.setUTCMinutes(0,0,0);},(t,e)=>{t.setTime(+t+e*vr);},(t,e)=>(e-t)/vr,t=>t.getUTCHours());ac.range;const _r=Pt(t=>t.setHours(0,0,0,0),(t,e)=>t.setDate(t.getDate()+e),(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*hn)/Fr,t=>t.getDate()-1);_r.range;const Kr=Pt(t=>{t.setUTCHours(0,0,0,0);},(t,e)=>{t.setUTCDate(t.getUTCDate()+e);},(t,e)=>(e-t)/Fr,t=>t.getUTCDate()-1);Kr.range;const Tw=Pt(t=>{t.setUTCHours(0,0,0,0);},(t,e)=>{t.setUTCDate(t.getUTCDate()+e);},(t,e)=>(e-t)/Fr,t=>Math.floor(t/Fr));Tw.range;function ta(t){return Pt(e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0);},(e,n)=>{e.setDate(e.getDate()+n*7);},(e,n)=>(n-e-(n.getTimezoneOffset()-e.getTimezoneOffset())*hn)/X1)}const eu=ta(0),ff=ta(1),v8=ta(2),b8=ta(3),Pa=ta(4),A8=ta(5),w8=ta(6);eu.range;ff.range;v8.range;b8.range;Pa.range;A8.range;w8.range;function ea(t){return Pt(e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0);},(e,n)=>{e.setUTCDate(e.getUTCDate()+n*7);},(e,n)=>(n-e)/X1)}const nu=ea(0),cf=ea(1),E8=ea(2),_8=ea(3),za=ea(4),C8=ea(5),D8=ea(6);nu.range;cf.range;E8.range;_8.range;za.range;C8.range;D8.range;const ko=Pt(t=>{t.setDate(1),t.setHours(0,0,0,0);},(t,e)=>{t.setMonth(t.getMonth()+e);},(t,e)=>e.getMonth()-t.getMonth()+(e.getFullYear()-t.getFullYear())*12,t=>t.getMonth());ko.range;const $o=Pt(t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0);},(t,e)=>{t.setUTCMonth(t.getUTCMonth()+e);},(t,e)=>e.getUTCMonth()-t.getUTCMonth()+(e.getUTCFullYear()-t.getUTCFullYear())*12,t=>t.getUTCMonth());$o.range;const Qn=Pt(t=>{t.setMonth(0,1),t.setHours(0,0,0,0);},(t,e)=>{t.setFullYear(t.getFullYear()+e);},(t,e)=>e.getFullYear()-t.getFullYear(),t=>t.getFullYear());Qn.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:Pt(e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0);},(e,n)=>{e.setFullYear(e.getFullYear()+n*t);});Qn.range;const Zn=Pt(t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0);},(t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e);},(t,e)=>e.getUTCFullYear()-t.getUTCFullYear(),t=>t.getUTCFullYear());Zn.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:Pt(e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0);},(e,n)=>{e.setUTCFullYear(e.getUTCFullYear()+n*t);});Zn.range;function Rw(t,e,n,r,i,a){const u=[[br,1,xr],[br,5,5*xr],[br,15,15*xr],[br,30,30*xr],[a,1,hn],[a,5,5*hn],[a,15,15*hn],[a,30,30*hn],[i,1,vr],[i,3,3*vr],[i,6,6*vr],[i,12,12*vr],[r,1,Fr],[r,2,2*Fr],[n,1,X1],[e,1,J2],[e,3,3*J2],[t,1,Hh]];function o(l,f,c){const h=fm).right(u,h);if(d===u.length)return t.every(ei(l/Hh,f/Hh,c));if(d===0)return La.every(Math.max(ei(l,f,c),1));const[g,p]=u[h/u[d-1][2]53)return null;"w"in P||(P.w=1),"Z"in P?(wt=Xh(Eu(P.y,0,1)),Ve=wt.getUTCDay(),wt=Ve>4||Ve===0?cf.ceil(wt):cf(wt),wt=Kr.offset(wt,(P.V-1)*7),P.y=wt.getUTCFullYear(),P.m=wt.getUTCMonth(),P.d=wt.getUTCDate()+(P.w+6)%7):(wt=Gh(Eu(P.y,0,1)),Ve=wt.getDay(),wt=Ve>4||Ve===0?ff.ceil(wt):ff(wt),wt=_r.offset(wt,(P.V-1)*7),P.y=wt.getFullYear(),P.m=wt.getMonth(),P.d=wt.getDate()+(P.w+6)%7);}else ("W"in P||"U"in P)&&("w"in P||(P.w="u"in P?P.u%7:"W"in P?1:0),Ve="Z"in P?Xh(Eu(P.y,0,1)).getUTCDay():Gh(Eu(P.y,0,1)).getDay(),P.m=0,P.d="W"in P?(P.w+6)%7+P.W*7-(Ve+5)%7:P.w+P.U*7-(Ve+6)%7);return "Z"in P?(P.H+=P.Z/100|0,P.M+=P.Z%100,Xh(P)):Gh(P)}}function _(I,rt,ot,P){for(var Be=0,wt=rt.length,Ve=ot.length,Ke,mi;Be=Ve)return -1;if(Ke=rt.charCodeAt(Be++),Ke===37){if(Ke=rt.charAt(Be++),mi=w[Ke in tx?rt.charAt(Be++):Ke],!mi||(P=mi(I,ot,P))<0)return -1}else if(Ke!=ot.charCodeAt(P++))return -1}return P}function C(I,rt,ot){var P=l.exec(rt.slice(ot));return P?(I.p=f.get(P[0].toLowerCase()),ot+P[0].length):-1}function F(I,rt,ot){var P=d.exec(rt.slice(ot));return P?(I.w=g.get(P[0].toLowerCase()),ot+P[0].length):-1}function D(I,rt,ot){var P=c.exec(rt.slice(ot));return P?(I.w=h.get(P[0].toLowerCase()),ot+P[0].length):-1}function R(I,rt,ot){var P=y.exec(rt.slice(ot));return P?(I.m=x.get(P[0].toLowerCase()),ot+P[0].length):-1}function k(I,rt,ot){var P=p.exec(rt.slice(ot));return P?(I.m=m.get(P[0].toLowerCase()),ot+P[0].length):-1}function N(I,rt,ot){return _(I,e,rt,ot)}function M(I,rt,ot){return _(I,n,rt,ot)}function O(I,rt,ot){return _(I,r,rt,ot)}function z(I){return u[I.getDay()]}function G(I){return a[I.getDay()]}function W(I){return s[I.getMonth()]}function bt(I){return o[I.getMonth()]}function It(I){return i[+(I.getHours()>=12)]}function Se(I){return 1+~~(I.getMonth()/3)}function me(I){return u[I.getUTCDay()]}function Pn(I){return a[I.getUTCDay()]}function Ut(I){return s[I.getUTCMonth()]}function mu(I){return o[I.getUTCMonth()]}function yu(I){return i[+(I.getUTCHours()>=12)]}function xu(I){return 1+~~(I.getUTCMonth()/3)}return {format:function(I){var rt=E(I+="",v);return rt.toString=function(){return I},rt},parse:function(I){var rt=A(I+="",!1);return rt.toString=function(){return I},rt},utcFormat:function(I){var rt=E(I+="",b);return rt.toString=function(){return I},rt},utcParse:function(I){var rt=A(I+="",!0);return rt.toString=function(){return I},rt}}}var tx={"-":"",_:" ",0:"0"},Xt=/^\s*\d+/,S8=/^%/,B8=/[\\^$*+?|[\]().{}]/g;function dt(t,e,n){var r=t<0?"-":"",i=(r?-t:t)+"",a=i.length;return r+(a[e.toLowerCase(),n]))}function R8(t,e,n){var r=Xt.exec(e.slice(n,n+1));return r?(t.w=+r[0],n+r[0].length):-1}function O8(t,e,n){var r=Xt.exec(e.slice(n,n+1));return r?(t.u=+r[0],n+r[0].length):-1}function N8(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.U=+r[0],n+r[0].length):-1}function L8(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.V=+r[0],n+r[0].length):-1}function P8(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.W=+r[0],n+r[0].length):-1}function ex(t,e,n){var r=Xt.exec(e.slice(n,n+4));return r?(t.y=+r[0],n+r[0].length):-1}function nx(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),n+r[0].length):-1}function z8(t,e,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(n,n+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),n+r[0].length):-1}function I8(t,e,n){var r=Xt.exec(e.slice(n,n+1));return r?(t.q=r[0]*3-3,n+r[0].length):-1}function U8(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function rx(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function q8(t,e,n){var r=Xt.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function ix(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function j8(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function W8(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function Y8(t,e,n){var r=Xt.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function H8(t,e,n){var r=Xt.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function G8(t,e,n){var r=S8.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function X8(t,e,n){var r=Xt.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function V8(t,e,n){var r=Xt.exec(e.slice(n));return r?(t.s=+r[0],n+r[0].length):-1}function ax(t,e){return dt(t.getDate(),e,2)}function K8(t,e){return dt(t.getHours(),e,2)}function Q8(t,e){return dt(t.getHours()%12||12,e,2)}function Z8(t,e){return dt(1+_r.count(Qn(t),t),e,3)}function Nw(t,e){return dt(t.getMilliseconds(),e,3)}function J8(t,e){return Nw(t,e)+"000"}function t9(t,e){return dt(t.getMonth()+1,e,2)}function e9(t,e){return dt(t.getMinutes(),e,2)}function n9(t,e){return dt(t.getSeconds(),e,2)}function r9(t){var e=t.getDay();return e===0?7:e}function i9(t,e){return dt(eu.count(Qn(t)-1,t),e,2)}function Lw(t){var e=t.getDay();return e>=4||e===0?Pa(t):Pa.ceil(t)}function a9(t,e){return t=Lw(t),dt(Pa.count(Qn(t),t)+(Qn(t).getDay()===4),e,2)}function u9(t){return t.getDay()}function o9(t,e){return dt(ff.count(Qn(t)-1,t),e,2)}function s9(t,e){return dt(t.getFullYear()%100,e,2)}function l9(t,e){return t=Lw(t),dt(t.getFullYear()%100,e,2)}function f9(t,e){return dt(t.getFullYear()%1e4,e,4)}function c9(t,e){var n=t.getDay();return t=n>=4||n===0?Pa(t):Pa.ceil(t),dt(t.getFullYear()%1e4,e,4)}function h9(t){var e=t.getTimezoneOffset();return (e>0?"-":(e*=-1,"+"))+dt(e/60|0,"0",2)+dt(e%60,"0",2)}function ux(t,e){return dt(t.getUTCDate(),e,2)}function d9(t,e){return dt(t.getUTCHours(),e,2)}function g9(t,e){return dt(t.getUTCHours()%12||12,e,2)}function p9(t,e){return dt(1+Kr.count(Zn(t),t),e,3)}function Pw(t,e){return dt(t.getUTCMilliseconds(),e,3)}function m9(t,e){return Pw(t,e)+"000"}function y9(t,e){return dt(t.getUTCMonth()+1,e,2)}function x9(t,e){return dt(t.getUTCMinutes(),e,2)}function v9(t,e){return dt(t.getUTCSeconds(),e,2)}function b9(t){var e=t.getUTCDay();return e===0?7:e}function A9(t,e){return dt(nu.count(Zn(t)-1,t),e,2)}function zw(t){var e=t.getUTCDay();return e>=4||e===0?za(t):za.ceil(t)}function w9(t,e){return t=zw(t),dt(za.count(Zn(t),t)+(Zn(t).getUTCDay()===4),e,2)}function E9(t){return t.getUTCDay()}function _9(t,e){return dt(cf.count(Zn(t)-1,t),e,2)}function C9(t,e){return dt(t.getUTCFullYear()%100,e,2)}function D9(t,e){return t=zw(t),dt(t.getUTCFullYear()%100,e,2)}function F9(t,e){return dt(t.getUTCFullYear()%1e4,e,4)}function M9(t,e){var n=t.getUTCDay();return t=n>=4||n===0?za(t):za.ceil(t),dt(t.getUTCFullYear()%1e4,e,4)}function k9(){return "+0000"}function ox(){return "%"}function sx(t){return +t}function lx(t){return Math.floor(+t/1e3)}var ca,V1,Iw,K1,Uw;$9({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});function $9(t){return ca=Ow(t),V1=ca.format,Iw=ca.parse,K1=ca.utcFormat,Uw=ca.utcParse,ca}function S9(t){return new Date(t)}function B9(t){return t instanceof Date?+t:+new Date(+t)}function Q1(t,e,n,r,i,a,u,o,s,l){var f=Ew(),c=f.invert,h=f.domain,d=l(".%L"),g=l(":%S"),p=l("%I:%M"),m=l("%I %p"),y=l("%a %d"),x=l("%b %d"),v=l("%B"),b=l("%Y");function w(E){return (s(E)1?0:t<-1?Ia:Math.acos(t)}function cx(t){return t>=1?hf:t<=-1?-hf:Math.asin(t)}function sc(t){let e=3;return t.digits=function(n){if(!arguments.length)return e;if(n==null)e=null;else {const r=Math.floor(n);if(!(r>=0))throw new RangeError(`invalid digits: ${n}`);e=r;}return t},()=>new k1(e)}function z9(t){return t.innerRadius}function I9(t){return t.outerRadius}function U9(t){return t.startAngle}function q9(t){return t.endAngle}function j9(t){return t&&t.padAngle}function W9(t,e,n,r,i,a,u,o){var s=n-t,l=r-e,f=u-i,c=o-a,h=c*s-f*l;if(!(h*hN*N+M*M&&(_=F,C=D),{cx:_,cy:C,x01:-f,y01:-c,x11:_*(i/w-1),y11:C*(i/w-1)}}function Y9(){var t=z9,e=I9,n=pt(0),r=null,i=U9,a=q9,u=j9,o=null,s=sc(l);function l(){var f,c,h=+t.apply(this,arguments),d=+e.apply(this,arguments),g=i.apply(this,arguments)-hf,p=a.apply(this,arguments)-hf,m=fx(p-g),y=p>g;if(o||(o=f=s()),die))o.moveTo(0,0);else if(m>Gw-ie)o.moveTo(d*yi(g),d*zn(g)),o.arc(0,0,d,g,p,!y),h>ie&&(o.moveTo(h*yi(p),h*zn(p)),o.arc(0,0,h,p,g,y));else {var x=g,v=p,b=g,w=p,E=m,A=m,_=u.apply(this,arguments)/2,C=_>ie&&(r?+r.apply(this,arguments):Si(h*h+d*d)),F=Vh(fx(d-h)/2,+n.apply(this,arguments)),D=F,R=F,k,N;if(C>ie){var M=cx(C/h*zn(_)),O=cx(C/d*zn(_));(E-=M*2)>ie?(M*=y?1:-1,b+=M,w-=M):(E=0,b=w=(g+p)/2),(A-=O*2)>ie?(O*=y?1:-1,x+=O,v-=O):(A=0,x=v=(g+p)/2);}var z=d*yi(x),G=d*zn(x),W=h*yi(w),bt=h*zn(w);if(F>ie){var It=d*yi(v),Se=d*zn(v),me=h*yi(b),Pn=h*zn(b),Ut;if(mie?R>ie?(k=Ys(me,Pn,z,G,d,R,y),N=Ys(It,Se,W,bt,d,R,y),o.moveTo(k.cx+k.x01,k.cy+k.y01),Rie)||!(E>ie)?o.lineTo(W,bt):D>ie?(k=Ys(W,bt,It,Se,h,-D,y),N=Ys(z,G,me,Pn,h,-D,y),o.lineTo(k.cx+k.x01,k.cy+k.y01),D=d;--g)o.point(v[g],b[g]);o.lineEnd(),o.areaEnd();}y&&(v[h]=+t(m,h,c),b[h]=+e(m,h,c),o.point(r?+r(m,h,c):v[h],n?+n(m,h,c):b[h]));}if(x)return o=null,x+""||null}function f(){return Zw().defined(i).curve(u).context(a)}return l.x=function(c){return arguments.length?(t=typeof c=="function"?c:pt(+c),r=null,l):t},l.x0=function(c){return arguments.length?(t=typeof c=="function"?c:pt(+c),l):t},l.x1=function(c){return arguments.length?(r=c==null?null:typeof c=="function"?c:pt(+c),l):r},l.y=function(c){return arguments.length?(e=typeof c=="function"?c:pt(+c),n=null,l):e},l.y0=function(c){return arguments.length?(e=typeof c=="function"?c:pt(+c),l):e},l.y1=function(c){return arguments.length?(n=c==null?null:typeof c=="function"?c:pt(+c),l):n},l.lineX0=l.lineY0=function(){return f().x(t).y(e)},l.lineY1=function(){return f().x(t).y(n)},l.lineX1=function(){return f().x(r).y(e)},l.defined=function(c){return arguments.length?(i=typeof c=="function"?c:pt(!!c),l):i},l.curve=function(c){return arguments.length?(u=c,a!=null&&(o=u(a)),l):u},l.context=function(c){return arguments.length?(c==null?a=o=null:o=u(a=c),l):a},l}const H9={draw(t,e){const n=Si(e/Ia);t.moveTo(n,0),t.arc(0,0,n,0,Gw);}};function G9(t,e){let n=null,r=sc(i);t=typeof t=="function"?t:pt(t||H9),e=typeof e=="function"?e:pt(e===void 0?64:+e);function i(){let a;if(n||(n=a=r()),t.apply(this,arguments).draw(n,+e.apply(this,arguments)),a)return n=null,a+""||null}return i.type=function(a){return arguments.length?(t=typeof a=="function"?a:pt(a),i):t},i.size=function(a){return arguments.length?(e=typeof a=="function"?a:pt(+a),i):e},i.context=function(a){return arguments.length?(n=a??null,i):n},i}function ni(){}function df(t,e,n){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+n)/6);}function lc(t){this._context=t;}lc.prototype={areaStart:function(){this._line=0;},areaEnd:function(){this._line=NaN;},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0;},lineEnd:function(){switch(this._point){case 3:df(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line;},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:df(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e;}};function X9(t){return new lc(t)}function t3(t){this._context=t;}t3.prototype={areaStart:ni,areaEnd:ni,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0;},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x2,this._y2),this._context.closePath();break}case 2:{this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break}case 3:{this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4);break}}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:df(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e;}};function V9(t){return new t3(t)}function e3(t){this._context=t;}e3.prototype={areaStart:function(){this._line=0;},areaEnd:function(){this._line=NaN;},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0;},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line;},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var n=(this._x0+4*this._x1+t)/6,r=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(n,r):this._context.moveTo(n,r);break;case 3:this._point=4;default:df(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e;}};function K9(t){return new e3(t)}function n3(t,e){this._basis=new lc(t),this._beta=e;}n3.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart();},lineEnd:function(){var t=this._x,e=this._y,n=t.length-1;if(n>0)for(var r=t[0],i=e[0],a=t[n]-r,u=e[n]-i,o=-1,s;++o<=n;)s=o/n,this._basis.point(this._beta*t[o]+(1-this._beta)*(r+s*a),this._beta*e[o]+(1-this._beta)*(i+s*u));this._x=this._y=null,this._basis.lineEnd();},point:function(t,e){this._x.push(+t),this._y.push(+e);}};const Q9=function t(e){function n(r){return e===1?new lc(r):new n3(r,e)}return n.beta=function(r){return t(+r)},n}(.85);function gf(t,e,n){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-n),t._x2,t._y2);}function ng(t,e){this._context=t,this._k=(1-e)/6;}ng.prototype={areaStart:function(){this._line=0;},areaEnd:function(){this._line=NaN;},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0;},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:gf(this,this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line;},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:gf(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e;}};const Z9=function t(e){function n(r){return new ng(r,e)}return n.tension=function(r){return t(+r)},n}(0);function rg(t,e){this._context=t,this._k=(1-e)/6;}rg.prototype={areaStart:ni,areaEnd:ni,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0;},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:gf(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e;}};const J9=function t(e){function n(r){return new rg(r,e)}return n.tension=function(r){return t(+r)},n}(0);function ig(t,e){this._context=t,this._k=(1-e)/6;}ig.prototype={areaStart:function(){this._line=0;},areaEnd:function(){this._line=NaN;},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0;},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line;},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:gf(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e;}};const t4=function t(e){function n(r){return new ig(r,e)}return n.tension=function(r){return t(+r)},n}(0);function ag(t,e,n){var r=t._x1,i=t._y1,a=t._x2,u=t._y2;if(t._l01_a>ie){var o=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,s=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*o-t._x0*t._l12_2a+t._x2*t._l01_2a)/s,i=(i*o-t._y0*t._l12_2a+t._y2*t._l01_2a)/s;}if(t._l23_a>ie){var l=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,f=3*t._l23_a*(t._l23_a+t._l12_a);a=(a*l+t._x1*t._l23_2a-e*t._l12_2a)/f,u=(u*l+t._y1*t._l23_2a-n*t._l12_2a)/f;}t._context.bezierCurveTo(r,i,a,u,t._x2,t._y2);}function r3(t,e){this._context=t,this._alpha=e;}r3.prototype={areaStart:function(){this._line=0;},areaEnd:function(){this._line=NaN;},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0;},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line;},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha));}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:ag(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e;}};const e4=function t(e){function n(r){return e?new r3(r,e):new ng(r,0)}return n.alpha=function(r){return t(+r)},n}(.5);function i3(t,e){this._context=t,this._alpha=e;}i3.prototype={areaStart:ni,areaEnd:ni,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0;},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha));}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:ag(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e;}};const n4=function t(e){function n(r){return e?new i3(r,e):new rg(r,0)}return n.alpha=function(r){return t(+r)},n}(.5);function a3(t,e){this._context=t,this._alpha=e;}a3.prototype={areaStart:function(){this._line=0;},areaEnd:function(){this._line=NaN;},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0;},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line;},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha));}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:ag(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e;}};const r4=function t(e){function n(r){return e?new a3(r,e):new ig(r,0)}return n.alpha=function(r){return t(+r)},n}(.5);function u3(t){this._context=t;}u3.prototype={areaStart:ni,areaEnd:ni,lineStart:function(){this._point=0;},lineEnd:function(){this._point&&this._context.closePath();},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e));}};function i4(t){return new u3(t)}function hx(t){return t<0?-1:1}function dx(t,e,n){var r=t._x1-t._x0,i=e-t._x1,a=(t._y1-t._y0)/(r||i<0&&-0),u=(n-t._y1)/(i||r<0&&-0),o=(a*i+u*r)/(r+i);return (hx(a)+hx(u))*Math.min(Math.abs(a),Math.abs(u),.5*Math.abs(o))||0}function gx(t,e){var n=t._x1-t._x0;return n?(3*(t._y1-t._y0)/n-e)/2:e}function Kh(t,e,n){var r=t._x0,i=t._y0,a=t._x1,u=t._y1,o=(a-r)/3;t._context.bezierCurveTo(r+o,i+o*e,a-o,u-o*n,a,u);}function pf(t){this._context=t;}pf.prototype={areaStart:function(){this._line=0;},areaEnd:function(){this._line=NaN;},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0;},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:Kh(this,this._t0,gx(this,this._t0));break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line;},point:function(t,e){var n=NaN;if(t=+t,e=+e,!(t===this._x1&&e===this._y1)){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,Kh(this,gx(this,n=dx(this,t,e)),n);break;default:Kh(this,this._t0,n=dx(this,t,e));break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e,this._t0=n;}}};function o3(t){this._context=new s3(t);}(o3.prototype=Object.create(pf.prototype)).point=function(t,e){pf.prototype.point.call(this,e,t);};function s3(t){this._context=t;}s3.prototype={moveTo:function(t,e){this._context.moveTo(e,t);},closePath:function(){this._context.closePath();},lineTo:function(t,e){this._context.lineTo(e,t);},bezierCurveTo:function(t,e,n,r,i,a){this._context.bezierCurveTo(e,t,r,n,a,i);}};function a4(t){return new pf(t)}function u4(t){return new o3(t)}function l3(t){this._context=t;}l3.prototype={areaStart:function(){this._line=0;},areaEnd:function(){this._line=NaN;},lineStart:function(){this._x=[],this._y=[];},lineEnd:function(){var t=this._x,e=this._y,n=t.length;if(n)if(this._line?this._context.lineTo(t[0],e[0]):this._context.moveTo(t[0],e[0]),n===2)this._context.lineTo(t[1],e[1]);else for(var r=px(t),i=px(e),a=0,u=1;u=0;--e)i[e]=(u[e]-i[e+1])/a[e];for(a[n-1]=(t[n]+i[n-1])/2,e=0;e=0&&(this._t=1-this._t,this._line=1-this._line);},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:{if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else {var n=this._x*(1-this._t)+t*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,e);}break}}this._x=t,this._y=e;}};function s4(t){return new fc(t,.5)}function l4(t){return new fc(t,0)}function f4(t){return new fc(t,1)}/*! + * https://github.com/Starcounter-Jack/JSON-Patch + * (c) 2017-2022 Joachim Wester + * MIT licensed + */var c4=function(){var t=function(e,n){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(r,i){r.__proto__=i;}||function(r,i){for(var a in i)i.hasOwnProperty(a)&&(r[a]=i[a]);},t(e,n)};return function(e,n){t(e,n);function r(){this.constructor=e;}e.prototype=n===null?Object.create(n):(r.prototype=n.prototype,new r);}}(),h4=Object.prototype.hasOwnProperty;function pd(t,e){return h4.call(t,e)}function md(t){if(Array.isArray(t)){for(var e=new Array(t.length),n=0;n=48&&r<=57){e++;continue}return !1}return !0}function Ei(t){return t.indexOf("/")===-1&&t.indexOf("~")===-1?t:t.replace(/~/g,"~0").replace(/\//g,"~1")}function f3(t){return t.replace(/~1/g,"/").replace(/~0/g,"~")}function xd(t){if(t===void 0)return !0;if(t){if(Array.isArray(t)){for(var e=0,n=t.length;e0&&s[f-1]=="constructor"))throw new TypeError("JSON-Patch: modifying `__proto__` or `constructor/prototype` prop is banned for security reasons, if this was on purpose, please set `banPrototypeModifications` flag false and pass it to this function. More info in fast-json-patch README");if(n&&h===void 0&&(l[d]===void 0?h=s.slice(0,f).join("/"):f==c-1&&(h=e.path),h!==void 0&&g(e,0,t,h)),f++,Array.isArray(l)){if(d==="-")d=l.length;else {if(n&&!yd(d))throw new Mt("Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index","OPERATION_PATH_ILLEGAL_ARRAY_INDEX",a,e,t);yd(d)&&(d=~~d);}if(f>=c){if(n&&e.op==="add"&&d>l.length)throw new Mt("The specified index MUST NOT be greater than the number of elements in the array","OPERATION_VALUE_OUT_OF_BOUNDS",a,e,t);var u=g4[e.op].call(e,l,d,t);if(u.test===!1)throw new Mt("Test operation failed","TEST_OPERATION_FAILED",a,e,t);return u}}else if(f>=c){var u=wa[e.op].call(e,l,d,t);if(u.test===!1)throw new Mt("Test operation failed","TEST_OPERATION_FAILED",a,e,t);return u}if(l=l[d],n&&f0)throw new Mt('Operation `path` property must start with "/"',"OPERATION_PATH_INVALID",e,t,n);if((t.op==="move"||t.op==="copy")&&typeof t.from!="string")throw new Mt("Operation `from` property is not present (applicable in `move` and `copy` operations)","OPERATION_FROM_REQUIRED",e,t,n);if((t.op==="add"||t.op==="replace"||t.op==="test")&&t.value===void 0)throw new Mt("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_REQUIRED",e,t,n);if((t.op==="add"||t.op==="replace"||t.op==="test")&&xd(t.value))throw new Mt("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED",e,t,n);if(n){if(t.op=="add"){var i=t.path.split("/").length,a=r.split("/").length;if(i!==a+1&&i!==a)throw new Mt("Cannot perform an `add` operation at the desired path","OPERATION_PATH_CANNOT_ADD",e,t,n)}else if(t.op==="replace"||t.op==="remove"||t.op==="_get"){if(t.path!==r)throw new Mt("Cannot perform the operation at a path that does not exist","OPERATION_PATH_UNRESOLVABLE",e,t,n)}else if(t.op==="move"||t.op==="copy"){var u={op:"_get",path:t.from,value:void 0},o=h3([u],n);if(o&&o.name==="OPERATION_PATH_UNRESOLVABLE")throw new Mt("Cannot perform the operation from a path that does not exist","OPERATION_FROM_UNRESOLVABLE",e,t,n)}}}else throw new Mt("Operation `op` property is not one of operations defined in RFC-6902","OPERATION_OP_INVALID",e,t,n)}function h3(t,e,n){try{if(!Array.isArray(t))throw new Mt("Patch sequence must be an array","SEQUENCE_NOT_AN_ARRAY");if(e)ug(Je(e),Je(t),n||!0);else {n=n||yf;for(var r=0;r0&&(t.patches=[],t.callback&&t.callback(r)),r}function sg(t,e,n,r,i){if(e!==t){typeof e.toJSON=="function"&&(e=e.toJSON());for(var a=md(e),u=md(t),o=!1,s=u.length-1;s>=0;s--){var l=u[s],f=t[l];if(pd(e,l)&&!(e[l]===void 0&&f!==void 0&&Array.isArray(e)===!1)){var c=e[l];typeof f=="object"&&f!=null&&typeof c=="object"&&c!=null&&Array.isArray(f)===Array.isArray(c)?sg(f,c,n,r+"/"+Ei(l),i):f!==c&&(i&&n.push({op:"test",path:r+"/"+Ei(l),value:Je(f)}),n.push({op:"replace",path:r+"/"+Ei(l),value:Je(c)}));}else Array.isArray(t)===Array.isArray(e)?(i&&n.push({op:"test",path:r+"/"+Ei(l),value:Je(f)}),n.push({op:"remove",path:r+"/"+Ei(l)}),o=!0):(i&&n.push({op:"test",path:r,value:t}),n.push({op:"replace",path:r,value:e}));}if(!(!o&&a.length==u.length))for(var s=0;sfunction(e){return e[t]},F4=t=>{const e=t.length;return function(n){for(let r=0;ru?l():u=o+1:s==="["?(o>u&&l(),i=u=o+1):s==="]"&&(i||$("Access path missing open bracket: "+t),i>0&&l(),i=0,u=o+1);}return i&&$("Access path missing closing bracket: "+t),r&&$("Access path missing closing quote: "+t),o>u&&(o++,l()),e}function en(t,e,n){const r=cc(t);return t=r.length===1?r[0]:t,Ge((n&&n.get||d3)(r),[t],e||t)}const ns=en("id"),ge=Ge(t=>t,[],"identity"),Ir=Ge(()=>0,[],"zero"),ru=Ge(()=>1,[],"one"),We=Ge(()=>!0,[],"true"),Rr=Ge(()=>!1,[],"false");function M4(t,e,n){const r=[e].concat([].slice.call(n));console[t].apply(console,r);}const g3=0,lg=1,p3=2,m3=3,y3=4;function x3(t,e){let n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:M4,r=t||g3;return {level(i){return arguments.length?(r=+i,this):r},error(){return r>=lg&&n(e||"error","ERROR",arguments),this},warn(){return r>=p3&&n(e||"warn","WARN",arguments),this},info(){return r>=m3&&n(e||"log","INFO",arguments),this},debug(){return r>=y3&&n(e||"log","DEBUG",arguments),this}}}var U=Array.isArray;function et(t){return t===Object(t)}const yx=t=>t!=="__proto__";function v3(){for(var t=arguments.length,e=new Array(t),n=0;n{for(const a in i)if(a==="signals")r.signals=k4(r.signals,i.signals);else {const u=a==="legend"?{layout:1}:a==="style"?!0:null;fg(r,a,i[a],u);}return r},{})}function fg(t,e,n,r){if(!yx(e))return;let i,a;if(et(n)&&!U(n)){a=et(t[e])?t[e]:t[e]={};for(i in n)r&&(r===!0||r[i])?fg(a,i,n[i]):yx(i)&&(a[i]=n[i]);}else t[e]=n;}function k4(t,e){if(t==null)return e;const n={},r=[];function i(a){n[a.name]||(n[a.name]=1,r.push(a));}return e.forEach(i),t.forEach(i),r}function ut(t){return t[t.length-1]}function Kt(t){return t==null||t===""?null:+t}const b3=t=>e=>t*Math.exp(e),A3=t=>e=>Math.log(t*e),w3=t=>e=>Math.sign(e)*Math.log1p(Math.abs(e/t)),E3=t=>e=>Math.sign(e)*Math.expm1(Math.abs(e))*t,xf=t=>e=>e<0?-Math.pow(-e,t):Math.pow(e,t);function hc(t,e,n,r){const i=n(t[0]),a=n(ut(t)),u=(a-i)*e;return [r(i-u),r(a-u)]}function cg(t,e){return hc(t,e,Kt,ge)}function hg(t,e){var n=Math.sign(t[0]);return hc(t,e,A3(n),b3(n))}function dg(t,e,n){return hc(t,e,xf(n),xf(1/n))}function gg(t,e,n){return hc(t,e,w3(n),E3(n))}function dc(t,e,n,r,i){const a=r(t[0]),u=r(ut(t)),o=e!=null?r(e):(a+u)/2;return [i(o+(a-o)*n),i(o+(u-o)*n)]}function gc(t,e,n){return dc(t,e,n,Kt,ge)}function pc(t,e,n){const r=Math.sign(t[0]);return dc(t,e,n,A3(r),b3(r))}function Bo(t,e,n,r){return dc(t,e,n,xf(r),xf(1/r))}function mc(t,e,n,r){return dc(t,e,n,w3(r),E3(r))}function pg(t){return 1+~~(new Date(t).getMonth()/3)}function mg(t){return 1+~~(new Date(t).getUTCMonth()/3)}function H(t){return t!=null?U(t)?t:[t]:[]}function yg(t,e,n){let r=t[0],i=t[1],a;return i=n-e?[e,n]:[r=Math.min(Math.max(r,e),n-a),r+a]}function tt(t){return typeof t=="function"}const $4="descending";function xg(t,e,n){n=n||{},e=H(e)||[];const r=[],i=[],a={},u=n.comparator||S4;return H(t).forEach((o,s)=>{o!=null&&(r.push(e[s]===$4?-1:1),i.push(o=tt(o)?o:en(o,null,n)),(se(o)||[]).forEach(l=>a[l]=1));}),i.length===0?null:Ge(u(i,r),Object.keys(a))}const yc=(t,e)=>(te||e==null)&&t!=null?1:(e=e instanceof Date?+e:e,(t=t instanceof Date?+t:t)!==t&&e===e?-1:e!==e&&t===t?1:0),S4=(t,e)=>t.length===1?B4(t[0],e[0]):T4(t,e,t.length),B4=(t,e)=>function(n,r){return yc(t(n),t(r))*e},T4=(t,e,n)=>(e.push(0),function(r,i){let a,u=0,o=-1;for(;u===0&&++ot}function vg(t,e){let n;return r=>{n&&clearTimeout(n),n=setTimeout(()=>(e(r),n=null),t);}}function nt(t){for(let e,n,r=1,i=arguments.length;ru&&(u=i));}else {for(i=e(t[n]);nu&&(u=i));}return [a,u]}function _3(t,e){const n=t.length;let r=-1,i,a,u,o,s;if(e==null){for(;++r=a){i=u=a;break}if(r===n)return [-1,-1];for(o=s=r;++ra&&(i=a,o=r),u=a){i=u=a;break}if(r===n)return [-1,-1];for(o=s=r;++ra&&(i=a,o=r),u{i.set(a,t[a]);}),i}function bg(t,e,n,r,i,a){if(!n&&n!==0)return a;const u=+n;let o=t[0],s=ut(t),l;sa&&(u=i,i=a,a=u),n=n===void 0||n,r=r===void 0||r,(n?i<=t:io.replace(/\\(.)/g,"$1")):H(t));const r=t&&t.length,i=n&&n.get||d3,a=o=>i(e?[o]:cc(o));let u;if(!r)u=function(){return ""};else if(r===1){const o=a(t[0]);u=function(s){return ""+o(s)};}else {const o=t.map(a);u=function(s){let l=""+o[0](s),f=0;for(;++f{e={},n={},r=0;},a=(u,o)=>(++r>t&&(n=e,e={},r=1),e[u]=o);return i(),{clear:i,has:u=>X(e,u)||X(n,u),get:u=>X(e,u)?e[u]:X(n,u)?a(u,n[u]):void 0,set:(u,o)=>X(e,u)?e[u]=o:a(u,o)}}function F3(t,e,n,r){const i=e.length,a=n.length;if(!a)return e;if(!i)return n;const u=r||new e.constructor(i+a);let o=0,s=0,l=0;for(;o0?n[s++]:e[o++];for(;o=0;)n+=t;return n}function Cg(t,e,n,r){const i=n||" ",a=t+"",u=e-a.length;return u<=0?a:r==="left"?Xu(i,u)+a:r==="center"?Xu(i,~~(u/2))+a+Xu(i,Math.ceil(u/2)):a+Xu(i,u)}function au(t){return t&&ut(t)-t[0]||0}function Y(t){return U(t)?"["+t.map(Y)+"]":et(t)||xt(t)?JSON.stringify(t).replace("\u2028","\\u2028").replace("\u2029","\\u2029"):t}function xc(t){return t==null||t===""?null:!t||t==="false"||t==="0"?!1:!!t}const N4=t=>Mr(t)||Cr(t)?t:Date.parse(t);function vc(t,e){return e=e||N4,t==null||t===""?null:e(t)}function bc(t){return t==null||t===""?null:t+""}function nn(t){const e={},n=t.length;for(let r=0;r1)r=W4(t,e,n);else for(i=0,r=new Array(a=t.arcs.length);i(t[e]=1+n,t),{});function Mg(t){const e=H(t).slice(),n={};return e.length||$("Missing time unit."),e.forEach(i=>{X(Qh,i)?n[i]=1:$(`Invalid time unit: ${i}.`);}),(n[Nt]||n[oe]?1:0)+(n[Ye]||n[le]||n[He]?1:0)+(n[Jn]?1:0)>1&&$(`Incompatible time units: ${t}`),e.sort((i,a)=>Qh[i]-Qh[a]),e}const Y4={[Jt]:"%Y ",[Ye]:"Q%q ",[le]:"%b ",[He]:"%d ",[Nt]:"W%U ",[oe]:"%a ",[Jn]:"%j ",[rn]:"%H:00",[an]:"00:%M",[yn]:":%S",[Bn]:".%L",[`${Jt}-${le}`]:"%Y-%m ",[`${Jt}-${le}-${He}`]:"%Y-%m-%d ",[`${rn}-${an}`]:"%H:%M"};function kg(t,e){const n=nt({},Y4,e),r=Mg(t),i=r.length;let a="",u=0,o,s;for(u=0;uu;--o)if(s=r.slice(u,o).join("-"),n[s]!=null){a+=n[s],u=o;break}return a.trim()}const Ci=new Date;function $g(t){return Ci.setFullYear(t),Ci.setMonth(0),Ci.setDate(1),Ci.setHours(0,0,0,0),Ci}function Sg(t){return k3(new Date(t))}function Bg(t){return bd(new Date(t))}function k3(t){return _r.count($g(t.getFullYear())-1,t)}function bd(t){return eu.count($g(t.getFullYear())-1,t)}function Ad(t){return $g(t).getDay()}function H4(t,e,n,r,i,a,u){if(0<=t&&t<100){const o=new Date(-1,e,n,r,i,a,u);return o.setFullYear(t),o}return new Date(t,e,n,r,i,a,u)}function Tg(t){return $3(new Date(t))}function Rg(t){return wd(new Date(t))}function $3(t){const e=Date.UTC(t.getUTCFullYear(),0,1);return Kr.count(e-1,t)}function wd(t){const e=Date.UTC(t.getUTCFullYear(),0,1);return nu.count(e-1,t)}function Ed(t){return Ci.setTime(Date.UTC(t,0,1)),Ci.getUTCDay()}function G4(t,e,n,r,i,a,u){if(0<=t&&t<100){const o=new Date(Date.UTC(-1,e,n,r,i,a,u));return o.setUTCFullYear(n.y),o}return new Date(Date.UTC(t,e,n,r,i,a,u))}function S3(t,e,n,r,i){const a=e||1,u=ut(t),o=(y,x,v)=>(v=v||y,X4(n[v],r[v],y===u&&a,x)),s=new Date,l=nn(t),f=l[Jt]?o(Jt):pe(2012),c=l[le]?o(le):l[Ye]?o(Ye):Ir,h=l[Nt]&&l[oe]?o(oe,1,Nt+oe):l[Nt]?o(Nt,1):l[oe]?o(oe,1):l[He]?o(He,1):l[Jn]?o(Jn,1):ru,d=l[rn]?o(rn):Ir,g=l[an]?o(an):Ir,p=l[yn]?o(yn):Ir,m=l[Bn]?o(Bn):Ir;return function(y){s.setTime(+y);const x=f(s);return i(x,c(s),h(s,x),d(s),g(s),p(s),m(s))}}function X4(t,e,n,r){const i=n<=1?t:r?(a,u)=>r+n*Math.floor((t(a,u)-r)/n):(a,u)=>n*Math.floor(t(a,u)/n);return e?(a,u)=>e(i(a,u),u):i}function Ua(t,e,n){return e+t*7-(n+6)%7}const V4={[Jt]:t=>t.getFullYear(),[Ye]:t=>Math.floor(t.getMonth()/3),[le]:t=>t.getMonth(),[He]:t=>t.getDate(),[rn]:t=>t.getHours(),[an]:t=>t.getMinutes(),[yn]:t=>t.getSeconds(),[Bn]:t=>t.getMilliseconds(),[Jn]:t=>k3(t),[Nt]:t=>bd(t),[Nt+oe]:(t,e)=>Ua(bd(t),t.getDay(),Ad(e)),[oe]:(t,e)=>Ua(1,t.getDay(),Ad(e))},K4={[Ye]:t=>3*t,[Nt]:(t,e)=>Ua(t,0,Ad(e))};function B3(t,e){return S3(t,e||1,V4,K4,H4)}const Q4={[Jt]:t=>t.getUTCFullYear(),[Ye]:t=>Math.floor(t.getUTCMonth()/3),[le]:t=>t.getUTCMonth(),[He]:t=>t.getUTCDate(),[rn]:t=>t.getUTCHours(),[an]:t=>t.getUTCMinutes(),[yn]:t=>t.getUTCSeconds(),[Bn]:t=>t.getUTCMilliseconds(),[Jn]:t=>$3(t),[Nt]:t=>wd(t),[oe]:(t,e)=>Ua(1,t.getUTCDay(),Ed(e)),[Nt+oe]:(t,e)=>Ua(wd(t),t.getUTCDay(),Ed(e))},Z4={[Ye]:t=>3*t,[Nt]:(t,e)=>Ua(t,0,Ed(e))};function T3(t,e){return S3(t,e||1,Q4,Z4,G4)}const J4={[Jt]:Qn,[Ye]:ko.every(3),[le]:ko,[Nt]:eu,[He]:_r,[oe]:_r,[Jn]:_r,[rn]:ic,[an]:nc,[yn]:br,[Bn]:La},t7={[Jt]:Zn,[Ye]:$o.every(3),[le]:$o,[Nt]:nu,[He]:Kr,[oe]:Kr,[Jn]:Kr,[rn]:ac,[an]:rc,[yn]:br,[Bn]:La};function uu(t){return J4[t]}function ou(t){return t7[t]}function R3(t,e,n){return t?t.offset(e,n):void 0}function Og(t,e,n){return R3(uu(t),e,n)}function Ng(t,e,n){return R3(ou(t),e,n)}function O3(t,e,n,r){return t?t.range(e,n,r):void 0}function Lg(t,e,n,r){return O3(uu(t),e,n,r)}function Pg(t,e,n,r){return O3(ou(t),e,n,r)}const Vu=1e3,Ku=Vu*60,Qu=Ku*60,Ac=Qu*24,e7=Ac*7,vx=Ac*30,_d=Ac*365,N3=[Jt,le,He,rn,an,yn,Bn],Zu=N3.slice(0,-1),Ju=Zu.slice(0,-1),to=Ju.slice(0,-1),n7=to.slice(0,-1),r7=[Jt,Nt],bx=[Jt,le],L3=[Jt],Du=[[Zu,1,Vu],[Zu,5,5*Vu],[Zu,15,15*Vu],[Zu,30,30*Vu],[Ju,1,Ku],[Ju,5,5*Ku],[Ju,15,15*Ku],[Ju,30,30*Ku],[to,1,Qu],[to,3,3*Qu],[to,6,6*Qu],[to,12,12*Qu],[n7,1,Ac],[r7,1,e7],[bx,1,vx],[bx,3,3*vx],[L3,1,_d]];function P3(t){const e=t.extent,n=t.maxbins||40,r=Math.abs(au(e))/n;let i=Za(o=>o[2]).right(Du,r),a,u;return i===Du.length?(a=L3,u=ei(e[0]/_d,e[1]/_d,n)):i?(i=Du[r/Du[i-1][2]e[n]||(e[n]=t(n))}function i7(t,e){return n=>{const r=t(n),i=r.indexOf(e);if(i<0)return r;let a=a7(r,i);const u=ai;)if(r[a]!=="0"){++a;break}return r.slice(0,a)+u}}function a7(t,e){let n=t.lastIndexOf("e"),r;if(n>0)return n;for(n=t.length;--n>e;)if(r=t.charCodeAt(n),r>=48&&r<=57)return n+1}function z3(t){const e=eo(t.format),n=t.formatPrefix;return {format:e,formatPrefix:n,formatFloat(r){const i=qi(r||",");if(i.precision==null){switch(i.precision=12,i.type){case"%":i.precision-=2;break;case"e":i.precision-=1;break}return i7(e(i),e(".1f")(1)[1])}else return e(i)},formatSpan(r,i,a,u){u=qi(u??",f");const o=ei(r,i,a),s=Math.max(Math.abs(r),Math.abs(i));let l;if(u.precision==null)switch(u.type){case"s":return isNaN(l=EA(o,s))||(u.precision=l),n(u,s);case"":case"e":case"g":case"p":case"r":{isNaN(l=_A(o,s))||(u.precision=l-(u.type==="e"));break}case"f":case"%":{isNaN(l=wA(o))||(u.precision=l-(u.type==="%")*2);break}}return e(u)}}}let Cd;I3();function I3(){return Cd=z3({format:Kf,formatPrefix:R1})}function U3(t){return z3(AA(t))}function vf(t){return arguments.length?Cd=U3(t):Cd}function Ax(t,e,n){n=n||{},et(n)||$(`Invalid time multi-format specifier: ${n}`);const r=e(yn),i=e(an),a=e(rn),u=e(He),o=e(Nt),s=e(le),l=e(Ye),f=e(Jt),c=t(n[Bn]||".%L"),h=t(n[yn]||":%S"),d=t(n[an]||"%I:%M"),g=t(n[rn]||"%I %p"),p=t(n[He]||n[oe]||"%a %d"),m=t(n[Nt]||"%b %d"),y=t(n[le]||"%B"),x=t(n[Ye]||"%B"),v=t(n[Jt]||"%Y");return b=>(r(b)xt(r)?e(r):Ax(e,uu,r),utcFormat:r=>xt(r)?n(r):Ax(n,ou,r),timeParse:eo(t.parse),utcParse:eo(t.utcParse)}}let Dd;j3();function j3(){return Dd=q3({format:V1,parse:Iw,utcFormat:K1,utcParse:Uw})}function W3(t){return q3(Ow(t))}function To(t){return arguments.length?Dd=W3(t):Dd}const Fd=(t,e)=>nt({},t,e);function Y3(t,e){const n=t?U3(t):vf(),r=e?W3(e):To();return Fd(n,r)}function zg(t,e){const n=arguments.length;return n&&n!==2&&$("defaultLocale expects either zero or two arguments."),n?Fd(vf(t),To(e)):Fd(vf(),To())}function u7(){return I3(),j3(),zg()}const o7=/^(data:|([A-Za-z]+:)?\/\/)/,s7=/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|file|data):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,l7=/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205f\u3000]/g,wx="file://";function f7(t,e){return n=>({options:n||{},sanitize:h7,load:c7,fileAccess:!!e,file:d7(e),http:p7(t)})}async function c7(t,e){const n=await this.sanitize(t,e),r=n.href;return n.localFile?this.file(r):this.http(r,e)}async function h7(t,e){e=nt({},this.options,e);const n=this.fileAccess,r={href:null};let i,a,u;const o=s7.test(t.replace(l7,""));(t==null||typeof t!="string"||!o)&&$("Sanitize failure, invalid URI: "+Y(t));const s=o7.test(t);return (u=e.baseURL)&&!s&&(!t.startsWith("/")&&!u.endsWith("/")&&(t="/"+t),t=u+t),a=(i=t.startsWith(wx))||e.mode==="file"||e.mode!=="http"&&!s&&n,i?t=t.slice(wx.length):t.startsWith("//")&&(e.defaultProtocol==="file"?(t=t.slice(2),a=!0):t=(e.defaultProtocol||"http")+":"+t),Object.defineProperty(r,"localFile",{value:!!a}),r.href=t,e.target&&(r.target=e.target+""),e.rel&&(r.rel=e.rel+""),e.context==="image"&&e.crossOrigin&&(r.crossOrigin=e.crossOrigin+""),r}function d7(t){return t?e=>new Promise((n,r)=>{t.readFile(e,(i,a)=>{i?r(i):n(a);});}):g7}async function g7(){$("No file system access.");}function p7(t){return t?async function(e,n){const r=nt({},this.options.http,n),i=n&&n.response,a=await t(e,r);return a.ok?tt(a[i])?a[i]():a.text():$(a.status+""+a.statusText)}:m7}async function m7(){$("No HTTP fetch method available.");}const y7=t=>t!=null&&t===t,x7=t=>t==="true"||t==="false"||t===!0||t===!1,v7=t=>!Number.isNaN(Date.parse(t)),H3=t=>!Number.isNaN(+t)&&!(t instanceof Date),b7=t=>H3(t)&&Number.isInteger(+t),Md={boolean:xc,integer:Kt,number:Kt,date:vc,string:bc,unknown:ge},Gs=[x7,b7,H3,v7],A7=["boolean","integer","number","date"];function G3(t,e){if(!t||!t.length)return "unknown";const n=t.length,r=Gs.length,i=Gs.map((a,u)=>u+1);for(let a=0,u=0,o,s;aa===0?u:a,0)-1]}function X3(t,e){return e.reduce((n,r)=>(n[r]=G3(t,r),n),{})}function Ex(t){const e=function(n,r){const i={delimiter:t};return Ig(n,r?nt(r,i):i)};return e.responseType="text",e}function Ig(t,e){return e.header&&(t=e.header.map(Y).join(e.delimiter)+` +`+t),U5(e.delimiter).parse(t+"")}Ig.responseType="text";function w7(t){return typeof Buffer=="function"&&tt(Buffer.isBuffer)?Buffer.isBuffer(t):!1}function Ug(t,e){const n=e&&e.property?en(e.property):ge;return et(t)&&!w7(t)?E7(n(t),e):n(JSON.parse(t))}Ug.responseType="json";function E7(t,e){return !U(t)&&C3(t)&&(t=[...t]),e&&e.copy?JSON.parse(JSON.stringify(t)):t}const _7={interior:(t,e)=>t!==e,exterior:(t,e)=>t===e};function V3(t,e){let n,r,i,a;return t=Ug(t,e),e&&e.feature?(n=I4,i=e.feature):e&&e.mesh?(n=q4,i=e.mesh,a=_7[e.filter]):$("Missing TopoJSON feature or mesh parameter."),r=(r=t.objects[i])?n(t,r,a):$("Invalid TopoJSON object: "+i),r&&r.features||[r]}V3.responseType="json";const fl={dsv:Ig,csv:Ex(","),tsv:Ex(" "),json:Ug,topojson:V3};function qg(t,e){return arguments.length>1?(fl[t]=e,this):X(fl,t)?fl[t]:null}function K3(t){const e=qg(t);return e&&e.responseType||"text"}function Q3(t,e,n,r){e=e||{};const i=qg(e.type||"json");return i||$("Unknown data format type: "+e.type),t=i(t,e),e.parse&&C7(t,e.parse,n,r),X(t,"columns")&&delete t.columns,t}function C7(t,e,n,r){if(!t.length)return;const i=To();n=n||i.timeParse,r=r||i.utcParse;let a=t.columns||Object.keys(t[0]),u,o,s,l,f,c;e==="auto"&&(e=X3(t,a)),a=Object.keys(e);const h=a.map(d=>{const g=e[d];let p,m;if(g&&(g.startsWith("date:")||g.startsWith("utc:")))return p=g.split(/:(.+)?/,2),m=p[1],(m[0]==="'"&&m[m.length-1]==="'"||m[0]==='"'&&m[m.length-1]==='"')&&(m=m.slice(1,-1)),(p[0]==="utc"?r:n)(m);if(!Md[g])throw Error("Illegal format pattern: "+d+":"+g);return Md[g]});for(s=0,f=t.length,c=a.length;s{const a=e(i);return r[a]||(r[a]=1,n.push(i)),n},n.remove=i=>{const a=e(i);if(r[a]){r[a]=0;const u=n.indexOf(i);u>=0&&n.splice(u,1);}return n},n}async function cl(t,e){try{await e(t);}catch(n){t.error(n);}}const Z3=Symbol("vega_id");let D7=1;function su(t){return !!(t&&K(t))}function K(t){return t[Z3]}function J3(t,e){return t[Z3]=e,t}function gt(t){const e=t===Object(t)?t:{data:t};return K(e)?e:J3(e,D7++)}function jg(t){return _c(t,gt({}))}function _c(t,e){for(const n in t)e[n]=t[n];return e}function tE(t,e){return J3(e,K(t))}function na(t,e){return t?e?(n,r)=>t(n,r)||K(e(n))-K(e(r)):(n,r)=>t(n,r)||K(n)-K(r):null}function eE(t){return t&&t.constructor===ra}function ra(){const t=[],e=[],n=[],r=[],i=[];let a=null,u=!1;return {constructor:ra,insert(o){const s=H(o),l=s.length;for(let f=0;f{g(x)&&(l[K(x)]=-1);});for(c=0,h=t.length;c0&&(y(p,g,d.value),o.modifies(g));for(c=0,h=i.length;c{g(x)&&l[K(x)]>0&&y(x,d.field,d.value);}),o.modifies(d.field);if(u)o.mod=e.length||r.length?s.filter(x=>l[K(x)]>0):s.slice();else for(m in f)o.mod.push(f[m]);return (a||a==null&&(e.length||r.length))&&o.clean(!0),o}}}const hl="_:mod:_";function Cc(){Object.defineProperty(this,hl,{writable:!0,value:{}});}Cc.prototype={set(t,e,n,r){const i=this,a=i[t],u=i[hl];return e!=null&&e>=0?(a[e]!==n||r)&&(a[e]=n,u[e+":"+t]=-1,u[t]=-1):(a!==n||r)&&(i[t]=n,u[t]=U(n)?1+n.length:-1),i},modified(t,e){const n=this[hl];if(arguments.length){if(U(t)){for(let r=0;r=0?e+1{d instanceof At?(d!==this&&(e&&d.targets().add(this),a.push(d)),i.push({op:d,name:c,index:h})):r.set(c,h,d);};for(u in t)if(o=t[u],u===M7)H(o).forEach(c=>{c instanceof At?c!==this&&(c.targets().add(this),a.push(c)):$("Pulse parameters must be operator instances.");}),this.source=o;else if(U(o))for(r.set(u,-1,Array(s=o.length)),l=0;l{const n=Date.now();return n-e>t?(e=n,1):0})},debounce(t){const e=Or();return this.targets().add(Or(null,null,vg(t,n=>{const r=n.dataflow;e.receive(n),r&&r.run&&r.run();}))),e},between(t,e){let n=!1;return t.targets().add(Or(null,null,()=>n=!0)),e.targets().add(Or(null,null,()=>n=!1)),this.filter(()=>n)},detach(){this._filter=We,this._targets=null;}};function O7(t,e,n,r){const i=this,a=Or(n,r),u=function(l){l.dataflow=i;try{a.receive(l);}catch(f){i.error(f);}finally{i.run();}};let o;typeof t=="string"&&typeof document<"u"?o=document.querySelectorAll(t):o=H(t);const s=o.length;for(let l=0;le=r);return n.requests=0,n.done=()=>{--n.requests===0&&(t._pending=null,e(t));},t._pending=n}const U7={skip:!0};function q7(t,e,n,r,i){return (t instanceof At?W7:j7)(this,t,e,n,r,i),this}function j7(t,e,n,r,i,a){const u=nt({},a,U7);let o,s;tt(n)||(n=pe(n)),r===void 0?o=l=>t.touch(n(l)):tt(r)?(s=new At(null,r,i,!1),o=l=>{s.evaluate(l);const f=n(l),c=s.value;eE(c)?t.pulse(f,c,a):t.update(f,c,u);}):o=l=>t.update(n(l),r,u),e.apply(o);}function W7(t,e,n,r,i,a){if(r===void 0)e.targets().add(n);else {const u=a||{},o=new At(null,Y7(n,r),i,!1);o.modified(u.force),o.rank=e.rank,e.targets().add(o),n&&(o.skip(!0),o.value=n.value,o.targets().add(n),t.connect(n,[o]));}}function Y7(t,e){return e=tt(e)?e:pe(e),t?function(n,r){const i=e(n,r);return t.skip()||(t.skip(i!==this.value).value=i),i}:e}function H7(t){t.rank=++this._rank;}function G7(t){const e=[t];let n,r,i;for(;e.length;)if(this.rank(n=e.pop()),r=n._targets)for(i=r.length;--i>=0;)e.push(n=r[i]),n===t&&$("Cycle detected in dataflow graph.");}const bf={},Un=1,Pr=2,cr=4,X7=Un|Pr,Cx=Un|cr,ha=Un|Pr|cr,Dx=8,Fu=16,Fx=32,Mx=64;function Qr(t,e,n){this.dataflow=t,this.stamp=e??-1,this.add=[],this.rem=[],this.mod=[],this.fields=null,this.encode=n||null;}function Zh(t,e){const n=[];return Lr(t,e,r=>n.push(r)),n}function kx(t,e){const n={};return t.visit(e,r=>{n[K(r)]=1;}),r=>n[K(r)]?null:r}function Xs(t,e){return t?(n,r)=>t(n,r)&&e(n,r):e}Qr.prototype={StopPropagation:bf,ADD:Un,REM:Pr,MOD:cr,ADD_REM:X7,ADD_MOD:Cx,ALL:ha,REFLOW:Dx,SOURCE:Fu,NO_SOURCE:Fx,NO_FIELDS:Mx,fork(t){return new Qr(this.dataflow).init(this,t)},clone(){const t=this.fork(ha);return t.add=t.add.slice(),t.rem=t.rem.slice(),t.mod=t.mod.slice(),t.source&&(t.source=t.source.slice()),t.materialize(ha|Fu)},addAll(){let t=this;return !t.source||t.add===t.rem||!t.rem.length&&t.source.length===t.add.length||(t=new Qr(this.dataflow).init(this),t.add=t.source,t.rem=[]),t},init(t,e){const n=this;return n.stamp=t.stamp,n.encode=t.encode,t.fields&&!(e&Mx)&&(n.fields=t.fields),e&Un?(n.addF=t.addF,n.add=t.add):(n.addF=null,n.add=[]),e&Pr?(n.remF=t.remF,n.rem=t.rem):(n.remF=null,n.rem=[]),e&cr?(n.modF=t.modF,n.mod=t.mod):(n.modF=null,n.mod=[]),e&Fx?(n.srcF=null,n.source=null):(n.srcF=t.srcF,n.source=t.source,t.cleans&&(n.cleans=t.cleans)),n},runAfter(t){this.dataflow.runAfter(t);},changed(t){const e=t||ha;return e&Un&&this.add.length||e&Pr&&this.rem.length||e&cr&&this.mod.length},reflow(t){if(t)return this.fork(ha).reflow();const e=this.add.length,n=this.source&&this.source.length;return n&&n!==e&&(this.mod=this.source,e&&this.filter(cr,kx(this,Un))),this},clean(t){return arguments.length?(this.cleans=!!t,this):this.cleans},modifies(t){const e=this.fields||(this.fields={});return U(t)?t.forEach(n=>e[n]=!0):e[t]=!0,this},modified(t,e){const n=this.fields;return (e||this.mod.length)&&n?arguments.length?U(t)?t.some(r=>n[r]):n[t]:!!n:!1},filter(t,e){const n=this;return t&Un&&(n.addF=Xs(n.addF,e)),t&Pr&&(n.remF=Xs(n.remF,e)),t&cr&&(n.modF=Xs(n.modF,e)),t&Fu&&(n.srcF=Xs(n.srcF,e)),n},materialize(t){t=t||ha;const e=this;return t&Un&&e.addF&&(e.add=Zh(e.add,e.addF),e.addF=null),t&Pr&&e.remF&&(e.rem=Zh(e.rem,e.remF),e.remF=null),t&cr&&e.modF&&(e.mod=Zh(e.mod,e.modF),e.modF=null),t&Fu&&e.srcF&&(e.source=e.source.filter(e.srcF),e.srcF=null),e},visit(t,e){const n=this,r=e;if(t&Fu)return Lr(n.source,n.srcF,r),n;t&Un&&Lr(n.add,n.addF,r),t&Pr&&Lr(n.rem,n.remF,r),t&cr&&Lr(n.mod,n.modF,r);const i=n.source;if(t&Dx&&i){const a=n.add.length+n.mod.length;a===i.length||(a?Lr(i,kx(n,Cx),r):Lr(i,n.srcF,r));}return n}};function Wg(t,e,n,r){const i=this;let a=0;this.dataflow=t,this.stamp=e,this.fields=null,this.encode=r||null,this.pulses=n;for(const u of n)if(u.stamp===e){if(u.fields){const o=i.fields||(i.fields={});for(const s in u.fields)o[s]=1;}u.changed(i.ADD)&&(a|=i.ADD),u.changed(i.REM)&&(a|=i.REM),u.changed(i.MOD)&&(a|=i.MOD);}this.changes=a;}L(Wg,Qr,{fork(t){const e=new Qr(this.dataflow).init(this,t&this.NO_FIELDS);return t!==void 0&&(t&e.ADD&&this.visit(e.ADD,n=>e.add.push(n)),t&e.REM&&this.visit(e.REM,n=>e.rem.push(n)),t&e.MOD&&this.visit(e.MOD,n=>e.mod.push(n))),e},changed(t){return this.changes&t},modified(t){const e=this,n=e.fields;return n&&e.changes&e.MOD?U(t)?t.some(r=>n[r]):n[t]:0},filter(){$("MultiPulse does not support filtering.");},materialize(){$("MultiPulse does not support materialization.");},visit(t,e){const n=this,r=n.pulses,i=r.length;let a=0;if(t&n.SOURCE)for(;ar._enqueue(f,!0)),r._touched=Ec(ns);let u=0,o,s,l;try{for(;r._heap.size()>0;){if(o=r._heap.pop(),o.rank!==o.qrank){r._enqueue(o,!0);continue}s=o.run(r._getPulse(o,t)),s.then?s=await s:s.async&&(i.push(s.async),s=bf),s!==bf&&o._targets&&o._targets.forEach(f=>r._enqueue(f)),++u;}}catch(f){r._heap.clear(),l=f;}if(r._input={},r._pulse=null,r.debug(`Pulse ${a}: ${u} operators`),l&&(r._postrun=[],r.error(l)),r._postrun.length){const f=r._postrun.sort((c,h)=>h.priority-c.priority);r._postrun=[];for(let c=0;cr.runAsync(null,()=>{f.forEach(c=>{try{c(r);}catch(h){r.error(h);}});})),r}async function K7(t,e,n){for(;this._running;)await this._running;const r=()=>this._running=null;return (this._running=this.evaluate(t,e,n)).then(r,r),this._running}function Q7(t,e,n){return this._pulse?nE(this):(this.evaluate(t,e,n),this)}function Z7(t,e,n){if(this._pulse||e)this._postrun.push({priority:n||0,callback:t});else try{t(this);}catch(r){this.error(r);}}function nE(t){return t.error("Dataflow already running. Use runAsync() to chain invocations."),t}function J7(t,e){const n=t.stampi.pulse),e):this._input[t.id]||e$(this._pulse,n&&n.pulse)}function e$(t,e){return e&&e.stamp===t.stamp?e:(t=t.fork(),e&&e!==bf&&(t.source=e.source),t)}const Yg={skip:!1,force:!1};function n$(t,e){const n=e||Yg;return this._pulse?this._enqueue(t):this._touched.add(t),n.skip&&t.skip(!0),this}function r$(t,e,n){const r=n||Yg;return (t.set(e)||r.force)&&this.touch(t,r),this}function i$(t,e,n){this.touch(t,n||Yg);const r=new Qr(this,this._clock+(this._pulse?0:1)),i=t.pulse&&t.pulse.source||[];return r.target=t,this._input[t.id]=e.pulse(r,i),this}function a$(t){let e=[];return {clear:()=>e=[],size:()=>e.length,peek:()=>e[0],push:n=>(e.push(n),rE(e,0,e.length-1,t)),pop:()=>{const n=e.pop();let r;return e.length?(r=e[0],e[0]=n,u$(e,0,t)):r=n,r}}}function rE(t,e,n,r){let i,a;const u=t[n];for(;n>e;){if(a=n-1>>1,i=t[a],r(u,i)<0){t[n]=i,n=a;continue}break}return t[n]=u}function u$(t,e,n){const r=e,i=t.length,a=t[e];let u=(e<<1)+1,o;for(;u=0&&(u=o),t[e]=t[u],e=u,u=(e<<1)+1;return t[e]=a,rE(t,r,e,n)}function ka(){this.logger(x3()),this.logLevel(lg),this._clock=0,this._rank=0,this._locale=zg();try{this._loader=wc();}catch{}this._touched=Ec(ns),this._input={},this._pulse=null,this._heap=a$((t,e)=>t.qrank-e.qrank),this._postrun=[];}function Mu(t){return function(){return this._log[t].apply(this,arguments)}}ka.prototype={stamp(){return this._clock},loader(t){return arguments.length?(this._loader=t,this):this._loader},locale(t){return arguments.length?(this._locale=t,this):this._locale},logger(t){return arguments.length?(this._log=t,this):this._log},error:Mu("error"),warn:Mu("warn"),info:Mu("info"),debug:Mu("debug"),logLevel:Mu("level"),cleanThreshold:1e4,add:B7,connect:T7,rank:H7,rerank:G7,pulse:i$,touch:n$,update:r$,changeset:ra,ingest:L7,parse:N7,preload:z7,request:P7,events:O7,on:q7,evaluate:V7,run:Q7,runAsync:K7,runAfter:Z7,_enqueue:J7,_getPulse:t$};function S(t,e){At.call(this,t,null,e);}L(S,At,{run(t){if(t.stampthis.pulse=n):e!==t.StopPropagation&&(this.pulse=e),e},evaluate(t){const e=this.marshall(t.stamp),n=this.transform(e,t);return e.clear(),n},transform(){}});const qa={};function iE(t){const e=aE(t);return e&&e.Definition||null}function aE(t){return t=t&&t.toLowerCase(),X(qa,t)?qa[t]:null}function*uE(t,e){if(e==null)for(let n of t)n!=null&&n!==""&&(n=+n)>=n&&(yield n);else {let n=-1;for(let r of t)r=e(r,++n,t),r!=null&&r!==""&&(r=+r)>=r&&(yield r);}}function Hg(t,e,n){const r=Float64Array.from(uE(t,n));return r.sort(wr),e.map(i=>zb(r,i))}function Gg(t,e){return Hg(t,[.25,.5,.75],e)}function Xg(t,e){const n=t.length,r=G5(t,e),i=Gg(t,e),a=(i[2]-i[0])/1.34;return 1.06*(Math.min(r,a)||r||Math.abs(i[0])||1)*Math.pow(n,-.2)}function oE(t){const e=t.maxbins||20,n=t.base||10,r=Math.log(n),i=t.divide||[5,2];let a=t.extent[0],u=t.extent[1],o,s,l,f,c,h;const d=t.span||u-a||Math.abs(a)||1;if(t.step)o=t.step;else if(t.steps){for(f=d/e,c=0,h=t.steps.length;ce;)o*=n;for(c=0,h=i.length;c=l&&d/f<=e&&(o=f);}f=Math.log(o);const g=f>=0?0:~~(-f/r)+1,p=Math.pow(n,-g-1);return (t.nice||t.nice===void 0)&&(f=Math.floor(a/o+p)*o,a=ah);const i=t.length,a=new Float64Array(i);let u=0,o=1,s=r(t[0]),l=s,f=s+e,c;for(;o=f){for(l=(s+l)/2;u>1);ui;)t[u--]=t[r];}r=i,i=a;}return t}function l$(t){return function(){return t=(1103515245*t+12345)%2147483647,t/2147483647}}function f$(t,e){e==null&&(e=t,t=0);let n,r,i;const a={min(u){return arguments.length?(n=u||0,i=r-n,a):n},max(u){return arguments.length?(r=u||0,i=r-n,a):r},sample(){return n+Math.floor(i*un())},pdf(u){return u===Math.floor(u)&&u>=n&&u=r?1:(o-n+1)/i},icdf(u){return u>=0&&u<=1?n-1+Math.floor(u*i):NaN}};return a.min(t).max(e)}const fE=Math.sqrt(2*Math.PI),c$=Math.SQRT2;let ku=NaN;function rs(t,e){t=t||0,e=e??1;let n=0,r=0,i,a;if(ku===ku)n=ku,ku=NaN;else {do n=un()*2-1,r=un()*2-1,i=n*n+r*r;while(i===0||i>1);a=Math.sqrt(-2*Math.log(i)/i),n*=a,ku=r*a;}return t+n*e}function Fc(t,e,n){n=n??1;const r=(t-(e||0))/n;return Math.exp(-.5*r*r)/(n*fE)}function is(t,e,n){e=e||0,n=n??1;const r=(t-e)/n,i=Math.abs(r);let a;if(i>37)a=0;else {const u=Math.exp(-i*i/2);let o;i<7.07106781186547?(o=.0352624965998911*i+.700383064443688,o=o*i+6.37396220353165,o=o*i+33.912866078383,o=o*i+112.079291497871,o=o*i+221.213596169931,o=o*i+220.206867912376,a=u*o,o=.0883883476483184*i+1.75566716318264,o=o*i+16.064177579207,o=o*i+86.7807322029461,o=o*i+296.564248779674,o=o*i+637.333633378831,o=o*i+793.826512519948,o=o*i+440.413735824752,a=a/o):(o=i+.65,o=i+4/o,o=i+3/o,o=i+2/o,o=i+1/o,a=u/o/2.506628274631);}return r>0?1-a:a}function as(t,e,n){return t<0||t>1?NaN:(e||0)+(n??1)*c$*h$(2*t-1)}function h$(t){let e=-Math.log((1-t)*(1+t)),n;return e<6.25?(e-=3.125,n=-364441206401782e-35,n=-16850591381820166e-35+n*e,n=128584807152564e-32+n*e,n=11157877678025181e-33+n*e,n=-1333171662854621e-31+n*e,n=20972767875968562e-33+n*e,n=6637638134358324e-30+n*e,n=-4054566272975207e-29+n*e,n=-8151934197605472e-29+n*e,n=26335093153082323e-28+n*e,n=-12975133253453532e-27+n*e,n=-5415412054294628e-26+n*e,n=10512122733215323e-25+n*e,n=-4112633980346984e-24+n*e,n=-29070369957882005e-24+n*e,n=42347877827932404e-23+n*e,n=-13654692000834679e-22+n*e,n=-13882523362786469e-21+n*e,n=.00018673420803405714+n*e,n=-.000740702534166267+n*e,n=-.006033670871430149+n*e,n=.24015818242558962+n*e,n=1.6536545626831027+n*e):e<16?(e=Math.sqrt(e)-3.25,n=22137376921775787e-25,n=9075656193888539e-23+n*e,n=-27517406297064545e-23+n*e,n=18239629214389228e-24+n*e,n=15027403968909828e-22+n*e,n=-4013867526981546e-21+n*e,n=29234449089955446e-22+n*e,n=12475304481671779e-21+n*e,n=-47318229009055734e-21+n*e,n=6828485145957318e-20+n*e,n=24031110387097894e-21+n*e,n=-.0003550375203628475+n*e,n=.0009532893797373805+n*e,n=-.0016882755560235047+n*e,n=.002491442096107851+n*e,n=-.003751208507569241+n*e,n=.005370914553590064+n*e,n=1.0052589676941592+n*e,n=3.0838856104922208+n*e):Number.isFinite(e)?(e=Math.sqrt(e)-5,n=-27109920616438573e-27,n=-2555641816996525e-25+n*e,n=15076572693500548e-25+n*e,n=-3789465440126737e-24+n*e,n=761570120807834e-23+n*e,n=-1496002662714924e-23+n*e,n=2914795345090108e-23+n*e,n=-6771199775845234e-23+n*e,n=22900482228026655e-23+n*e,n=-99298272942317e-20+n*e,n=4526062597223154e-21+n*e,n=-1968177810553167e-20+n*e,n=7599527703001776e-20+n*e,n=-.00021503011930044477+n*e,n=-.00013871931833623122+n*e,n=1.0103004648645344+n*e,n=4.849906401408584+n*e):n=1/0,n*t}function Vg(t,e){let n,r;const i={mean(a){return arguments.length?(n=a||0,i):n},stdev(a){return arguments.length?(r=a??1,i):r},sample:()=>rs(n,r),pdf:a=>Fc(a,n,r),cdf:a=>is(a,n,r),icdf:a=>as(a,n,r)};return i.mean(t).stdev(e)}function Kg(t,e){const n=Vg();let r=0;const i={data(a){return arguments.length?(t=a,r=a?a.length:0,i.bandwidth(e)):t},bandwidth(a){return arguments.length?(e=a,!e&&t&&(e=Xg(t)),i):e},sample(){return t[~~(un()*r)]+e*n.sample()},pdf(a){let u=0,o=0;for(;oMc(n,r),pdf:a=>kc(a,n,r),cdf:a=>$c(a,n,r),icdf:a=>Sc(a,n,r)};return i.mean(t).stdev(e)}function hE(t,e){let n=0,r;function i(u){const o=[];let s=0,l;for(l=0;l=e&&t<=n?1/(n-e):0}function Rc(t,e,n){return n==null&&(n=e??1,e=0),tn?1:(t-e)/(n-e)}function Oc(t,e,n){return n==null&&(n=e??1,e=0),t>=0&&t<=1?e+t*(n-e):NaN}function dE(t,e){let n,r;const i={min(a){return arguments.length?(n=a||0,i):n},max(a){return arguments.length?(r=a??1,i):r},sample:()=>Bc(n,r),pdf:a=>Tc(a,n,r),cdf:a=>Rc(a,n,r),icdf:a=>Oc(a,n,r)};return e==null&&(e=t??1,t=0),i.min(t).max(e)}function us(t,e,n,r){const i=r-t*t,a=Math.abs(i)<1e-24?0:(n-t*e)/i;return [e-a*t,a]}function Nc(t,e,n,r){t=t.filter(d=>{let g=e(d),p=n(d);return g!=null&&(g=+g)>=g&&p!=null&&(p=+p)>=p}),r&&t.sort((d,g)=>e(d)-e(g));const i=t.length,a=new Float64Array(i),u=new Float64Array(i);let o=0,s=0,l=0,f,c,h;for(h of t)a[o]=f=+e(h),u[o]=c=+n(h),++o,s+=(f-s)/o,l+=(c-l)/o;for(o=0;o=a&&u!=null&&(u=+u)>=u&&r(a,u,++i);}function lu(t,e,n,r,i){let a=0,u=0;return os(t,e,n,(o,s)=>{const l=s-i(o),f=s-r;a+=l*l,u+=f*f;}),1-a/u}function Qg(t,e,n){let r=0,i=0,a=0,u=0,o=0;os(t,e,n,(f,c)=>{++o,r+=(f-r)/o,i+=(c-i)/o,a+=(f*c-a)/o,u+=(f*f-u)/o;});const s=us(r,i,a,u),l=f=>s[0]+s[1]*f;return {coef:s,predict:l,rSquared:lu(t,e,n,i,l)}}function gE(t,e,n){let r=0,i=0,a=0,u=0,o=0;os(t,e,n,(f,c)=>{++o,f=Math.log(f),r+=(f-r)/o,i+=(c-i)/o,a+=(f*c-a)/o,u+=(f*f-u)/o;});const s=us(r,i,a,u),l=f=>s[0]+s[1]*Math.log(f);return {coef:s,predict:l,rSquared:lu(t,e,n,i,l)}}function pE(t,e,n){const[r,i,a,u]=Nc(t,e,n);let o=0,s=0,l=0,f=0,c=0,h,d,g;os(t,e,n,(x,v)=>{h=r[c++],d=Math.log(v),g=h*v,o+=(v*d-o)/c,s+=(g-s)/c,l+=(g*d-l)/c,f+=(h*g-f)/c;});const[p,m]=us(s/u,o/u,l/u,f/u),y=x=>Math.exp(p+m*(x-a));return {coef:[Math.exp(p-m*a),m],predict:y,rSquared:lu(t,e,n,u,y)}}function mE(t,e,n){let r=0,i=0,a=0,u=0,o=0,s=0;os(t,e,n,(c,h)=>{const d=Math.log(c),g=Math.log(h);++s,r+=(d-r)/s,i+=(g-i)/s,a+=(d*g-a)/s,u+=(d*d-u)/s,o+=(h-o)/s;});const l=us(r,i,a,u),f=c=>l[0]*Math.pow(c,l[1]);return l[0]=Math.exp(l[0]),{coef:l,predict:f,rSquared:lu(t,e,n,o,f)}}function Zg(t,e,n){const[r,i,a,u]=Nc(t,e,n),o=r.length;let s=0,l=0,f=0,c=0,h=0,d,g,p,m;for(d=0;d(A=A-a,v*A*A+b*A+w+u);return {coef:[w-b*a+v*a*a+u,b-2*v*a,v],predict:E,rSquared:lu(t,e,n,u,E)}}function yE(t,e,n,r){if(r===1)return Qg(t,e,n);if(r===2)return Zg(t,e,n);const[i,a,u,o]=Nc(t,e,n),s=i.length,l=[],f=[],c=r+1;let h,d,g,p,m;for(h=0;h{v-=u;let b=o+y[0]+y[1]*v+y[2]*v*v;for(h=3;h=0;--a)for(o=e[a],s=1,i[a]+=o,u=1;u<=a;++u)s*=(a+1-u)/u,i[a-u]+=o*Math.pow(n,u)*s;return i[0]+=r,i}function g$(t){const e=t.length-1,n=[];let r,i,a,u,o;for(r=0;rMath.abs(t[r][u])&&(u=i);for(a=r;a=r;a--)t[a][i]-=t[a][r]*t[r][i]/t[r][r];}for(i=e-1;i>=0;--i){for(o=0,a=i+1;ai[v]-y?x:v;let w=0,E=0,A=0,_=0,C=0;const F=1/Math.abs(i[b]-y||1);for(let k=x;k<=v;++k){const N=i[k],M=a[k],O=p$(Math.abs(y-N)*F)*h[k],z=N*O;w+=O,E+=z,A+=M*O,_+=M*z,C+=N*z;}const[D,R]=us(E/w,A/w,_/w,C/w);f[m]=D+R*y,c[m]=Math.abs(a[m]-f[m]),m$(i,m+1,g);}if(d===$x)break;const p=Ib(c);if(Math.abs(p)=1?Sx:(x=1-y*y)*x;}return y$(i,f,u,o)}function p$(t){return (t=1-t*t*t)*t*t}function m$(t,e,n){const r=t[e];let i=n[0],a=n[1]+1;if(!(a>=t.length))for(;e>i&&t[a]-r<=r-t[i];)n[0]=++i,n[1]=a,++a;}function y$(t,e,n,r){const i=t.length,a=[];let u=0,o=0,s=[],l;for(;u[p,t(p)],a=e[0],u=e[1],o=u-a,s=o/r,l=[i(a)],f=[];if(n===r){for(let p=1;p0;)f.push(i(a+p/n*o));}let c=l[0],h=f[f.length-1];const d=1/o,g=v$(c[1],f);for(;h;){const p=i((c[0]+h[0])/2);p[0]-c[0]>=s&&b$(c,p,h,d,g)>x$?f.push(p):(c=h,l.push(h),f.pop()),h=f[f.length-1];}return l}function v$(t,e){let n=t,r=t;const i=e.length;for(let a=0;ar&&(r=u);}return 1/(r-n)}function b$(t,e,n,r,i){const a=Math.atan2(i*(n[1]-t[1]),r*(n[0]-t[0])),u=Math.atan2(i*(e[1]-t[1]),r*(e[0]-t[0]));return Math.abs(a-u)}function A$(t){return e=>{const n=t.length;let r=1,i=String(t[0](e));for(;r{},w$={init:Jh,add:Jh,rem:Jh,idx:0},Ro={values:{init:t=>t.cell.store=!0,value:t=>t.cell.data.values(),idx:-1},count:{value:t=>t.cell.num},__count__:{value:t=>t.missing+t.valid},missing:{value:t=>t.missing},valid:{value:t=>t.valid},sum:{init:t=>t.sum=0,value:t=>t.sum,add:(t,e)=>t.sum+=+e,rem:(t,e)=>t.sum-=e},product:{init:t=>t.product=1,value:t=>t.valid?t.product:void 0,add:(t,e)=>t.product*=e,rem:(t,e)=>t.product/=e},mean:{init:t=>t.mean=0,value:t=>t.valid?t.mean:void 0,add:(t,e)=>(t.mean_d=e-t.mean,t.mean+=t.mean_d/t.valid),rem:(t,e)=>(t.mean_d=e-t.mean,t.mean-=t.valid?t.mean_d/t.valid:t.mean)},average:{value:t=>t.valid?t.mean:void 0,req:["mean"],idx:1},variance:{init:t=>t.dev=0,value:t=>t.valid>1?t.dev/(t.valid-1):void 0,add:(t,e)=>t.dev+=t.mean_d*(e-t.mean),rem:(t,e)=>t.dev-=t.mean_d*(e-t.mean),req:["mean"],idx:1},variancep:{value:t=>t.valid>1?t.dev/t.valid:void 0,req:["variance"],idx:2},stdev:{value:t=>t.valid>1?Math.sqrt(t.dev/(t.valid-1)):void 0,req:["variance"],idx:2},stdevp:{value:t=>t.valid>1?Math.sqrt(t.dev/t.valid):void 0,req:["variance"],idx:2},stderr:{value:t=>t.valid>1?Math.sqrt(t.dev/(t.valid*(t.valid-1))):void 0,req:["variance"],idx:2},distinct:{value:t=>t.cell.data.distinct(t.get),req:["values"],idx:3},ci0:{value:t=>t.cell.data.ci0(t.get),req:["values"],idx:3},ci1:{value:t=>t.cell.data.ci1(t.get),req:["values"],idx:3},median:{value:t=>t.cell.data.q2(t.get),req:["values"],idx:3},q1:{value:t=>t.cell.data.q1(t.get),req:["values"],idx:3},q3:{value:t=>t.cell.data.q3(t.get),req:["values"],idx:3},min:{init:t=>t.min=void 0,value:t=>t.min=Number.isNaN(t.min)?t.cell.data.min(t.get):t.min,add:(t,e)=>{(e{e<=t.min&&(t.min=NaN);},req:["values"],idx:4},max:{init:t=>t.max=void 0,value:t=>t.max=Number.isNaN(t.max)?t.cell.data.max(t.get):t.max,add:(t,e)=>{(e>t.max||t.max===void 0)&&(t.max=e);},rem:(t,e)=>{e>=t.max&&(t.max=NaN);},req:["values"],idx:4},argmin:{init:t=>t.argmin=void 0,value:t=>t.argmin||t.cell.data.argmin(t.get),add:(t,e,n)=>{e{e<=t.min&&(t.argmin=void 0);},req:["min","values"],idx:3},argmax:{init:t=>t.argmax=void 0,value:t=>t.argmax||t.cell.data.argmax(t.get),add:(t,e,n)=>{e>t.max&&(t.argmax=n);},rem:(t,e)=>{e>=t.max&&(t.argmax=void 0);},req:["max","values"],idx:3}},ss=Object.keys(Ro).filter(t=>t!=="__count__");function E$(t,e){return n=>nt({name:t,out:n||t},w$,e)}[...ss,"__count__"].forEach(t=>{Ro[t]=E$(t,Ro[t]);});function bE(t,e){return Ro[t](e)}function AE(t,e){return t.idx-e.idx}function _$(t){const e={};t.forEach(r=>e[r.name]=r);const n=r=>{r.req&&r.req.forEach(i=>{e[i]||n(e[i]=Ro[i]());});};return t.forEach(n),Object.values(e).sort(AE)}function C$(){this.valid=0,this.missing=0,this._ops.forEach(t=>t.init(this));}function D$(t,e){if(t==null||t===""){++this.missing;return}t===t&&(++this.valid,this._ops.forEach(n=>n.add(this,t,e)));}function F$(t,e){if(t==null||t===""){--this.missing;return}t===t&&(--this.valid,this._ops.forEach(n=>n.rem(this,t,e)));}function M$(t){return this._out.forEach(e=>t[e.out]=e.value(this)),t}function wE(t,e){const n=e||ge,r=_$(t),i=t.slice().sort(AE);function a(u){this._ops=r,this._out=i,this.cell=u,this.init();}return a.prototype.init=C$,a.prototype.add=D$,a.prototype.rem=F$,a.prototype.set=M$,a.prototype.get=n,a.fields=t.map(u=>u.out),a}function Jg(t){this._key=t?en(t):K,this.reset();}const ee=Jg.prototype;ee.reset=function(){this._add=[],this._rem=[],this._ext=null,this._get=null,this._q=null;};ee.add=function(t){this._add.push(t);};ee.rem=function(t){this._rem.push(t);};ee.values=function(){if(this._get=null,this._rem.length===0)return this._add;const t=this._add,e=this._rem,n=this._key,r=t.length,i=e.length,a=Array(r-i),u={};let o,s,l;for(o=0;o=0;)a=t(e[r])+"",X(n,a)||(n[a]=1,++i);return i};ee.extent=function(t){if(this._get!==t||!this._ext){const e=this.values(),n=_3(e,t);this._ext=[e[n[0]],e[n[1]]],this._get=t;}return this._ext};ee.argmin=function(t){return this.extent(t)[0]||{}};ee.argmax=function(t){return this.extent(t)[1]||{}};ee.min=function(t){const e=this.extent(t)[0];return e!=null?t(e):void 0};ee.max=function(t){const e=this.extent(t)[1];return e!=null?t(e):void 0};ee.quartile=function(t){return (this._get!==t||!this._q)&&(this._q=Gg(this.values(),t),this._get=t),this._q};ee.q1=function(t){return this.quartile(t)[0]};ee.q2=function(t){return this.quartile(t)[1]};ee.q3=function(t){return this.quartile(t)[2]};ee.ci=function(t){return (this._get!==t||!this._ci)&&(this._ci=sE(this.values(),1e3,.05,t),this._get=t),this._ci};ee.ci0=function(t){return this.ci(t)[0]};ee.ci1=function(t){return this.ci(t)[1]};function ri(t){S.call(this,null,t),this._adds=[],this._mods=[],this._alen=0,this._mlen=0,this._drop=!0,this._cross=!1,this._dims=[],this._dnames=[],this._measures=[],this._countOnly=!1,this._counts=null,this._prev=null,this._inputs=null,this._outputs=null;}ri.Definition={type:"Aggregate",metadata:{generates:!0,changes:!0},params:[{name:"groupby",type:"field",array:!0},{name:"ops",type:"enum",array:!0,values:ss},{name:"fields",type:"field",null:!0,array:!0},{name:"as",type:"string",null:!0,array:!0},{name:"drop",type:"boolean",default:!0},{name:"cross",type:"boolean",default:!1},{name:"key",type:"field"}]};L(ri,S,{transform(t,e){const n=this,r=e.fork(e.NO_SOURCE|e.NO_FIELDS),i=t.modified();return n.stamp=r.stamp,n.value&&(i||e.modified(n._inputs,!0))?(n._prev=n.value,n.value=i?n.init(t):Object.create(null),e.visit(e.SOURCE,a=>n.add(a))):(n.value=n.value||n.init(t),e.visit(e.REM,a=>n.rem(a)),e.visit(e.ADD,a=>n.add(a))),r.modifies(n._outputs),n._drop=t.drop!==!1,t.cross&&n._dims.length>1&&(n._drop=!1,n.cross()),e.clean()&&n._drop&&r.clean(!0).runAfter(()=>this.clean()),n.changes(r)},cross(){const t=this,e=t.value,n=t._dnames,r=n.map(()=>({})),i=n.length;function a(o){let s,l,f,c;for(s in o)for(f=o[s].tuple,l=0;l{const y=$t(m);return i(m),n.push(y),y}),this.cellkey=t.key?t.key:kd(this._dims),this._countOnly=!0,this._counts=[],this._measures=[];const a=t.fields||[null],u=t.ops||["count"],o=t.as||[],s=a.length,l={};let f,c,h,d,g,p;for(s!==u.length&&$("Unmatched number of fields and aggregate ops."),p=0;pwE(m,m.field)),Object.create(null)},cellkey:kd(),cell(t,e){let n=this.value[t];return n?n.num===0&&this._drop&&n.stamp{const c=r(f);f[o]=c,f[s]=c==null?null:i+a*(1+(c-i)/a);}:f=>f[o]=r(f)),e.modifies(n?u:o)},_bins(t){if(this.value&&!t.modified())return this.value;const e=t.field,n=oE(t),r=n.step;let i=n.start,a=i+Math.ceil((n.stop-i)/r)*r,u,o;(u=t.anchor)!=null&&(o=u-(i+r*Math.floor((u-i)/r)),i+=o,a+=o);const s=function(l){let f=Kt(e(l));return f==null?null:fa?1/0:(f=Math.max(i,Math.min(f,a-r)),i+r*Math.floor(k$+(f-i)/r))};return s.start=i,s.stop=n.stop,s.step=r,this.value=Ge(s,se(e),t.name||"bin_"+$t(e))}});function EE(t,e,n){const r=t;let i=e||[],a=n||[],u={},o=0;return {add:s=>a.push(s),remove:s=>u[r(s)]=++o,size:()=>i.length,data:(s,l)=>(o&&(i=i.filter(f=>!u[r(f)]),u={},o=0),l&&s&&i.sort(s),a.length&&(i=s?F3(s,i,a.sort(s)):i.concat(a),a=[]),i)}}function ep(t){S.call(this,[],t);}ep.Definition={type:"Collect",metadata:{source:!0},params:[{name:"sort",type:"compare"}]};L(ep,S,{transform(t,e){const n=e.fork(e.ALL),r=EE(K,this.value,n.materialize(n.ADD).add),i=t.sort,a=e.changed()||i&&(t.modified("sort")||e.modified(i.fields));return n.visit(n.REM,r.remove),this.modified(a),this.value=n.source=r.data(na(i),a),e.source&&e.source.root&&(this.value.root=e.source.root),n}});function _E(t){At.call(this,null,$$,t);}L(_E,At);function $$(t){return this.value&&!t.modified()?this.value:xg(t.fields,t.orders)}function np(t){S.call(this,null,t);}np.Definition={type:"CountPattern",metadata:{generates:!0,changes:!0},params:[{name:"field",type:"field",required:!0},{name:"case",type:"enum",values:["upper","lower","mixed"],default:"mixed"},{name:"pattern",type:"string",default:'[\\w"]+'},{name:"stopwords",type:"string",default:""},{name:"as",type:"string",array:!0,length:2,default:["text","count"]}]};function S$(t,e,n){switch(e){case"upper":t=t.toUpperCase();break;case"lower":t=t.toLowerCase();break}return t.match(n)}L(np,S,{transform(t,e){const n=c=>h=>{for(var d=S$(o(h),t.case,a)||[],g,p=0,m=d.length;pi[c]=1+(i[c]||0)),f=n(c=>i[c]-=1);return r?e.visit(e.SOURCE,l):(e.visit(e.ADD,l),e.visit(e.REM,f)),this._finish(e,s)},_parameterCheck(t,e){let n=!1;return (t.modified("stopwords")||!this._stop)&&(this._stop=new RegExp("^"+(t.stopwords||"")+"$","i"),n=!0),(t.modified("pattern")||!this._match)&&(this._match=new RegExp(t.pattern||"[\\w']+","g"),n=!0),(t.modified("field")||e.modified(t.field.fields))&&(n=!0),n&&(this._counts={}),n},_finish(t,e){const n=this._counts,r=this._tuples||(this._tuples={}),i=e[0],a=e[1],u=t.fork(t.NO_SOURCE|t.NO_FIELDS);let o,s,l;for(o in n)s=r[o],l=n[o]||0,!s&&l?(r[o]=s=gt({}),s[i]=o,s[a]=l,u.add.push(s)):l===0?(s&&u.rem.push(s),n[o]=null,r[o]=null):s[a]!==l&&(s[a]=l,u.mod.push(s));return u.modifies(e)}});function rp(t){S.call(this,null,t);}rp.Definition={type:"Cross",metadata:{generates:!0},params:[{name:"filter",type:"expr"},{name:"as",type:"string",array:!0,length:2,default:["a","b"]}]};L(rp,S,{transform(t,e){const n=e.fork(e.NO_SOURCE),r=t.as||["a","b"],i=r[0],a=r[1],u=!this.value||e.changed(e.ADD_REM)||t.modified("as")||t.modified("filter");let o=this.value;return u?(o&&(n.rem=o),o=e.materialize(e.SOURCE).source,n.add=this.value=B$(o,i,a,t.filter||We)):n.mod=o,n.source=this.value,n.modifies(r)}});function B$(t,e,n,r){for(var i=[],a={},u=t.length,o=0,s,l;oCE(a,e))):typeof r[i]===Tx&&r[i](t[i]);return r}function ip(t){S.call(this,null,t);}const DE=[{key:{function:"normal"},params:[{name:"mean",type:"number",default:0},{name:"stdev",type:"number",default:1}]},{key:{function:"lognormal"},params:[{name:"mean",type:"number",default:0},{name:"stdev",type:"number",default:1}]},{key:{function:"uniform"},params:[{name:"min",type:"number",default:0},{name:"max",type:"number",default:1}]},{key:{function:"kde"},params:[{name:"field",type:"field",required:!0},{name:"from",type:"data"},{name:"bandwidth",type:"number",default:0}]}],O$={key:{function:"mixture"},params:[{name:"distributions",type:"param",array:!0,params:DE},{name:"weights",type:"number",array:!0}]};ip.Definition={type:"Density",metadata:{generates:!0},params:[{name:"extent",type:"number",array:!0,length:2},{name:"steps",type:"number"},{name:"minsteps",type:"number",default:25},{name:"maxsteps",type:"number",default:200},{name:"method",type:"string",default:"pdf",values:["pdf","cdf"]},{name:"distribution",type:"param",params:DE.concat(O$)},{name:"as",type:"string",array:!0,default:["value","density"]}]};L(ip,S,{transform(t,e){const n=e.fork(e.NO_SOURCE|e.NO_FIELDS);if(!this.value||e.changed()||t.modified()){const r=CE(t.distribution,N$(e)),i=t.steps||t.minsteps||25,a=t.steps||t.maxsteps||200;let u=t.method||"pdf";u!=="pdf"&&u!=="cdf"&&$("Invalid density method: "+u),!t.extent&&!r.data&&$("Missing density extent parameter."),u=r[u];const o=t.as||["value","density"],s=t.extent||Sn(r.data()),l=Lc(u,s,i,a).map(f=>{const c={};return c[o[0]]=f[0],c[o[1]]=f[1],gt(c)});this.value&&(n.rem=this.value),this.value=n.add=n.source=l;}return n}});function N$(t){return ()=>t.materialize(t.SOURCE).source}function FE(t,e){return t?t.map((n,r)=>e[r]||$t(n)):null}function ap(t,e,n){const r=[],i=c=>c(s);let a,u,o,s,l,f;if(e==null)r.push(t.map(n));else for(a={},u=0,o=t.length;uau(Sn(t,e))/30;L(up,S,{transform(t,e){if(this.value&&!(t.modified()||e.changed()))return e;const n=e.materialize(e.SOURCE).source,r=ap(e.source,t.groupby,ge),i=t.smooth||!1,a=t.field,u=t.step||L$(n,a),o=na((g,p)=>a(g)-a(p)),s=t.as||ME,l=r.length;let f=1/0,c=-1/0,h=0,d;for(;hc&&(c=p),g[++d][s]=p;}return this.value={start:f,stop:c,step:u},e.reflow(!0).modifies(s)}});function kE(t){At.call(this,null,P$,t),this.modified(!0);}L(kE,At);function P$(t){const e=t.expr;return this.value&&!t.modified("expr")?this.value:Ge(n=>e(n,t),se(e),$t(e))}function op(t){S.call(this,[void 0,void 0],t);}op.Definition={type:"Extent",metadata:{},params:[{name:"field",type:"field",required:!0}]};L(op,S,{transform(t,e){const n=this.value,r=t.field,i=e.changed()||e.modified(r.fields)||t.modified("field");let a=n[0],u=n[1];if((i||a==null)&&(a=1/0,u=-1/0),e.visit(i?e.SOURCE:e.ADD,o=>{const s=Kt(r(o));s!=null&&(su&&(u=s));}),!Number.isFinite(a)||!Number.isFinite(u)){let o=$t(r);o&&(o=` for field "${o}"`),e.dataflow.warn(`Infinite extent${o}: [${a}, ${u}]`),a=u=void 0;}this.value=[a,u];}});function sp(t,e){At.call(this,t),this.parent=e,this.count=0;}L(sp,At,{connect(t){return this.detachSubflow=t.detachSubflow,this.targets().add(t),t.source=this},add(t){this.count+=1,this.value.add.push(t);},rem(t){this.count-=1,this.value.rem.push(t);},mod(t){this.value.mod.push(t);},init(t){this.value.init(t,t.NO_SOURCE);},evaluate(){return this.value}});function Pc(t){S.call(this,{},t),this._keys=iu();const e=this._targets=[];e.active=0,e.forEach=n=>{for(let r=0,i=e.active;rr&&r.count>0);this.initTargets(n);}},initTargets(t){const e=this._targets,n=e.length,r=t?t.length:0;let i=0;for(;ithis.subflow(s,i,e);return this._group=t.group||{},this.initTargets(),e.visit(e.REM,s=>{const l=K(s),f=a.get(l);f!==void 0&&(a.delete(l),o(f).rem(s));}),e.visit(e.ADD,s=>{const l=r(s);a.set(K(s),l),o(l).add(s);}),u||e.modified(r.fields)?e.visit(e.MOD,s=>{const l=K(s),f=a.get(l),c=r(s);f===c?o(c).mod(s):(a.set(l,c),o(f).rem(s),o(c).add(s));}):e.changed(e.MOD)&&e.visit(e.MOD,s=>{o(a.get(K(s))).mod(s);}),u&&e.visit(e.REFLOW,s=>{const l=K(s),f=a.get(l),c=r(s);f!==c&&(a.set(l,c),o(f).rem(s),o(c).add(s));}),e.clean()?n.runAfter(()=>{this.clean(),a.clean();}):a.empty>n.cleanThreshold&&n.runAfter(a.clean),e}});function $E(t){At.call(this,null,z$,t);}L($E,At);function z$(t){return this.value&&!t.modified()?this.value:U(t.name)?H(t.name).map(e=>en(e)):en(t.name,t.as)}function lp(t){S.call(this,iu(),t);}lp.Definition={type:"Filter",metadata:{changes:!0},params:[{name:"expr",type:"expr",required:!0}]};L(lp,S,{transform(t,e){const n=e.dataflow,r=this.value,i=e.fork(),a=i.add,u=i.rem,o=i.mod,s=t.expr;let l=!0;e.visit(e.REM,c=>{const h=K(c);r.has(h)?r.delete(h):u.push(c);}),e.visit(e.ADD,c=>{s(c,t)?a.push(c):r.set(K(c),1);});function f(c){const h=K(c),d=s(c,t),g=r.get(h);d&&g?(r.delete(h),a.push(c)):!d&&!g?(r.set(h,1),u.push(c)):l&&d&&!g&&o.push(c);}return e.visit(e.MOD,f),t.modified()&&(l=!1,e.visit(e.REFLOW,f)),r.empty>n.cleanThreshold&&n.runAfter(r.clean),i}});function fp(t){S.call(this,[],t);}fp.Definition={type:"Flatten",metadata:{generates:!0},params:[{name:"fields",type:"field",array:!0,required:!0},{name:"index",type:"string"},{name:"as",type:"string",array:!0}]};L(fp,S,{transform(t,e){const n=e.fork(e.NO_SOURCE),r=t.fields,i=FE(r,t.as||[]),a=t.index||null,u=i.length;return n.rem=this.value,e.visit(e.SOURCE,o=>{const s=r.map(g=>g(o)),l=s.reduce((g,p)=>Math.max(g,p.length),0);let f=0,c,h,d;for(;f{for(let f=0,c;fu[r]=n(u,t))}});function SE(t){S.call(this,[],t);}L(SE,S,{transform(t,e){const n=e.fork(e.ALL),r=t.generator;let i=this.value,a=t.size-i.length,u,o,s;if(a>0){for(u=[];--a>=0;)u.push(s=gt(r(t))),i.push(s);n.add=n.add.length?n.materialize(n.ADD).add.concat(u):u;}else o=i.slice(0,-a),n.rem=n.rem.length?n.materialize(n.REM).rem.concat(o):o,i=i.slice(-a);return n.source=this.value=i,n}});const Vs={value:"value",median:Ib,mean:J5,min:O0,max:Ri},I$=[];function dp(t){S.call(this,[],t);}dp.Definition={type:"Impute",metadata:{changes:!0},params:[{name:"field",type:"field",required:!0},{name:"key",type:"field",required:!0},{name:"keyvals",array:!0},{name:"groupby",type:"field",array:!0},{name:"method",type:"enum",default:"value",values:["value","mean","median","max","min"]},{name:"value",default:0}]};function U$(t){var e=t.method||Vs.value,n;if(Vs[e]==null)$("Unrecognized imputation method: "+e);else return e===Vs.value?(n=t.value!==void 0?t.value:0,()=>n):Vs[e]}function q$(t){const e=t.field;return n=>n?e(n):NaN}L(dp,S,{transform(t,e){var n=e.fork(e.ALL),r=U$(t),i=q$(t),a=$t(t.field),u=$t(t.key),o=(t.groupby||[]).map($t),s=j$(e.source,t.groupby,t.key,t.keyvals),l=[],f=this.value,c=s.domain.length,h,d,g,p,m,y,x,v,b,w;for(m=0,v=s.length;my(m),a=[],u=r?r.slice():[],o={},s={},l,f,c,h,d,g,p,m;for(u.forEach((y,x)=>o[y]=x+1),h=0,p=t.length;hn.add(a))):(i=n.value=n.value||this.init(t),e.visit(e.REM,a=>n.rem(a)),e.visit(e.ADD,a=>n.add(a))),n.changes(),e.visit(e.SOURCE,a=>{nt(a,i[n.cellkey(a)].tuple);}),e.reflow(r).modifies(this._outputs)},changes(){const t=this._adds,e=this._mods;let n,r;for(n=0,r=this._alen;n{const g=Kg(d,u)[o],p=t.counts?d.length:1,m=f||Sn(d);Lc(g,m,c,h).forEach(y=>{const x={};for(let v=0;v(this._pending=H(i.data),a=>a.touch(this)))}:n.request(t.url,t.format).then(r=>t0(this,e,H(r.data)))}});function Y$(t){return t.modified("async")&&!(t.modified("values")||t.modified("url")||t.modified("format"))}function t0(t,e,n){n.forEach(gt);const r=e.fork(e.NO_FIELDS&e.NO_SOURCE);return r.rem=t.value,t.value=r.source=r.add=n,t._pending=null,r.rem.length&&r.clean(!0),r}function mp(t){S.call(this,{},t);}mp.Definition={type:"Lookup",metadata:{modifies:!0},params:[{name:"index",type:"index",params:[{name:"from",type:"data",required:!0},{name:"key",type:"field",required:!0}]},{name:"values",type:"field",array:!0},{name:"fields",type:"field",array:!0,required:!0},{name:"as",type:"string",array:!0},{name:"default",default:null}]};L(mp,S,{transform(t,e){const n=t.fields,r=t.index,i=t.values,a=t.default==null?null:t.default,u=t.modified(),o=n.length;let s=u?e.SOURCE:e.ADD,l=e,f=t.as,c,h,d;return i?(h=i.length,o>1&&!f&&$('Multi-field lookup requires explicit "as" parameter.'),f&&f.length!==o*h&&$('The "as" parameter has too few output field names.'),f=f||i.map($t),c=function(g){for(var p=0,m=0,y,x;pe.modified(g.fields)),s|=d?e.MOD:0),e.visit(s,c),l.modifies(f)}});function RE(t){At.call(this,null,H$,t);}L(RE,At);function H$(t){if(this.value&&!t.modified())return this.value;const e=t.extents,n=e.length;let r=1/0,i=-1/0,a,u;for(a=0;ai&&(i=u[1]);return [r,i]}function OE(t){At.call(this,null,G$,t);}L(OE,At);function G$(t){return this.value&&!t.modified()?this.value:t.values.reduce((e,n)=>e.concat(n),[])}function NE(t){S.call(this,null,t);}L(NE,S,{transform(t,e){return this.modified(t.modified()),this.value=t,e.fork(e.NO_SOURCE|e.NO_FIELDS)}});function yp(t){ri.call(this,t);}yp.Definition={type:"Pivot",metadata:{generates:!0,changes:!0},params:[{name:"groupby",type:"field",array:!0},{name:"field",type:"field",required:!0},{name:"value",type:"field",required:!0},{name:"op",type:"enum",values:ss,default:"sum"},{name:"limit",type:"number",default:0},{name:"key",type:"field"}]};L(yp,ri,{_transform:ri.prototype.transform,transform(t,e){return this._transform(X$(t,e),e)}});function X$(t,e){const n=t.field,r=t.value,i=(t.op==="count"?"__count__":t.op)||"sum",a=se(n).concat(se(r)),u=K$(n,t.limit||0,e);return e.changed()&&t.set("__pivot__",null,null,!0),{key:t.key,groupby:t.groupby,ops:u.map(()=>i),fields:u.map(o=>V$(o,n,r,a)),as:u.map(o=>o+""),modified:t.modified.bind(t)}}function V$(t,e,n,r){return Ge(i=>e(i)===t?n(i):NaN,r,t+"")}function K$(t,e,n){const r={},i=[];return n.visit(n.SOURCE,a=>{const u=t(a);r[u]||(r[u]=1,i.push(u));}),i.sort(yc),e?i.slice(0,e):i}function LE(t){Pc.call(this,t);}L(LE,Pc,{transform(t,e){const n=t.subflow,r=t.field,i=a=>this.subflow(K(a),n,e,a);return (t.modified("field")||r&&e.modified(se(r)))&&$("PreFacet does not support field modification."),this.initTargets(),r?(e.visit(e.MOD,a=>{const u=i(a);r(a).forEach(o=>u.mod(o));}),e.visit(e.ADD,a=>{const u=i(a);r(a).forEach(o=>u.add(gt(o)));}),e.visit(e.REM,a=>{const u=i(a);r(a).forEach(o=>u.rem(o));})):(e.visit(e.MOD,a=>i(a).mod(a)),e.visit(e.ADD,a=>i(a).add(a)),e.visit(e.REM,a=>i(a).rem(a))),e.clean()&&e.runAfter(()=>this.clean()),e}});function xp(t){S.call(this,null,t);}xp.Definition={type:"Project",metadata:{generates:!0,changes:!0},params:[{name:"fields",type:"field",array:!0},{name:"as",type:"string",null:!0,array:!0}]};L(xp,S,{transform(t,e){const n=e.fork(e.NO_SOURCE),r=t.fields,i=FE(t.fields,t.as||[]),a=r?(o,s)=>Q$(o,s,r,i):_c;let u;return this.value?u=this.value:(e=e.addAll(),u=this.value={}),e.visit(e.REM,o=>{const s=K(o);n.rem.push(u[s]),u[s]=null;}),e.visit(e.ADD,o=>{const s=a(o,gt({}));u[K(o)]=s,n.add.push(s);}),e.visit(e.MOD,o=>{n.mod.push(a(o,u[K(o)]));}),n}});function Q$(t,e,n,r){for(let i=0,a=n.length;i{const h=Hg(c,l);for(let d=0;d{const a=K(i);n.rem.push(r[a]),r[a]=null;}),e.visit(e.ADD,i=>{const a=jg(i);r[K(i)]=a,n.add.push(a);}),e.visit(e.MOD,i=>{const a=r[K(i)];for(const u in i)a[u]=i[u],n.modifies(u);n.mod.push(a);})),n}});function bp(t){S.call(this,[],t),this.count=0;}bp.Definition={type:"Sample",metadata:{},params:[{name:"size",type:"number",default:1e3}]};L(bp,S,{transform(t,e){const n=e.fork(e.NO_SOURCE),r=t.modified("size"),i=t.size,a=this.value.reduce((f,c)=>(f[K(c)]=1,f),{});let u=this.value,o=this.count,s=0;function l(f){let c,h;u.length=s&&(c=u[h],a[K(c)]&&n.rem.push(c),u[h]=f)),++o;}if(e.rem.length&&(e.visit(e.REM,f=>{const c=K(f);a[c]&&(a[c]=-1,n.rem.push(f)),--o;}),u=u.filter(f=>a[K(f)]!==-1)),(e.rem.length||r)&&u.length{a[K(f)]||l(f);}),s=-1),r&&u.length>i){const f=u.length-i;for(let c=0;c{a[K(f)]&&n.mod.push(f);}),e.add.length&&e.visit(e.ADD,l),(e.add.length||s<0)&&(n.add=u.filter(f=>!a[K(f)])),this.count=o,this.value=n.source=u,n}});function Ap(t){S.call(this,null,t);}Ap.Definition={type:"Sequence",metadata:{generates:!0,changes:!0},params:[{name:"start",type:"number",required:!0},{name:"stop",type:"number",required:!0},{name:"step",type:"number",default:1},{name:"as",type:"string",default:"data"}]};L(Ap,S,{transform(t,e){if(this.value&&!t.modified())return;const n=e.materialize().fork(e.MOD),r=t.as||"data";return n.rem=this.value?e.rem.concat(this.value):e.rem,this.value=Ie(t.start,t.stop,t.step||1).map(i=>{const a={};return a[r]=i,gt(a)}),n.add=e.add.concat(this.value),n}});function IE(t){S.call(this,null,t),this.modified(!0);}L(IE,S,{transform(t,e){return this.value=e.source,e.changed()?e.fork(e.NO_SOURCE|e.NO_FIELDS):e.StopPropagation}});function wp(t){S.call(this,null,t);}const UE=["unit0","unit1"];wp.Definition={type:"TimeUnit",metadata:{modifies:!0},params:[{name:"field",type:"field",required:!0},{name:"interval",type:"boolean",default:!0},{name:"units",type:"enum",values:Fg,array:!0},{name:"step",type:"number",default:1},{name:"maxbins",type:"number",default:40},{name:"extent",type:"date",array:!0},{name:"timezone",type:"enum",default:"local",values:["local","utc"]},{name:"as",type:"string",array:!0,length:2,default:UE}]};L(wp,S,{transform(t,e){const n=t.field,r=t.interval!==!1,i=t.timezone==="utc",a=this._floor(t,e),u=(i?ou:uu)(a.unit).offset,o=t.as||UE,s=o[0],l=o[1],f=a.step;let c=a.start||1/0,h=a.stop||-1/0,d=e.ADD;return (t.modified()||e.changed(e.REM)||e.modified(se(n)))&&(e=e.reflow(!0),d=e.SOURCE,c=1/0,h=-1/0),e.visit(d,g=>{const p=n(g);let m,y;p==null?(g[s]=null,r&&(g[l]=null)):(g[s]=m=y=a(p),r&&(g[l]=y=u(m,f)),mh&&(h=y));}),a.start=c,a.stop=h,e.modifies(r?o:s)},_floor(t,e){const n=t.timezone==="utc",{units:r,step:i}=t.units?{units:t.units,step:t.step||1}:P3({extent:t.extent||Sn(e.materialize(e.SOURCE).source,t.field),maxbins:t.maxbins}),a=Mg(r),u=this.value||{},o=(n?T3:B3)(a,i);return o.unit=ut(a),o.units=a,o.step=i,o.start=u.start,o.stop=u.stop,this.value=o}});function qE(t){S.call(this,iu(),t);}L(qE,S,{transform(t,e){const n=e.dataflow,r=t.field,i=this.value,a=o=>i.set(r(o),o);let u=!0;return t.modified("field")||e.modified(r.fields)?(i.clear(),e.visit(e.SOURCE,a)):e.changed()?(e.visit(e.REM,o=>i.delete(r(o))),e.visit(e.ADD,a)):u=!1,this.modified(u),i.empty>n.cleanThreshold&&n.runAfter(i.clean),e.fork()}});function jE(t){S.call(this,null,t);}L(jE,S,{transform(t,e){(!this.value||t.modified("field")||t.modified("sort")||e.changed()||t.sort&&e.modified(t.sort.fields))&&(this.value=(t.sort?e.source.slice().sort(na(t.sort)):e.source).map(t.field));}});function J$(t,e,n,r){const i=Oo[t](e,n);return {init:i.init||Ir,update:function(a,u){u[r]=i.next(a);}}}const Oo={row_number:function(){return {next:t=>t.index+1}},rank:function(){let t;return {init:()=>t=1,next:e=>{const n=e.index,r=e.data;return n&&e.compare(r[n-1],r[n])?t=n+1:t}}},dense_rank:function(){let t;return {init:()=>t=1,next:e=>{const n=e.index,r=e.data;return n&&e.compare(r[n-1],r[n])?++t:t}}},percent_rank:function(){const t=Oo.rank(),e=t.next;return {init:t.init,next:n=>(e(n)-1)/(n.data.length-1)}},cume_dist:function(){let t;return {init:()=>t=0,next:e=>{const n=e.data,r=e.compare;let i=e.index;if(t0||$("ntile num must be greater than zero.");const n=Oo.cume_dist(),r=n.next;return {init:n.init,next:i=>Math.ceil(e*r(i))}},lag:function(t,e){return e=+e||1,{next:n=>{const r=n.index-e;return r>=0?t(n.data[r]):null}}},lead:function(t,e){return e=+e||1,{next:n=>{const r=n.index+e,i=n.data;return rt(e.data[e.i0])}},last_value:function(t){return {next:e=>t(e.data[e.i1-1])}},nth_value:function(t,e){return e=+e,e>0||$("nth_value nth must be greater than zero."),{next:n=>{const r=n.i0+(e-1);return re=null,next:n=>{const r=t(n.data[n.index]);return r!=null?e=r:e}}},next_value:function(t){let e,n;return {init:()=>(e=null,n=-1),next:r=>{const i=r.data;return r.index<=n?e:(n=tS(t,i,r.index))<0?(n=i.length,e=null):e=t(i[n])}}}};function tS(t,e,n){for(let r=e.length;no[g]=1);}h(t.sort),e.forEach((d,g)=>{const p=n[g],m=$t(p),y=vE(d,m,i[g]);if(h(p),a.push(y),X(Oo,d))u.push(J$(d,n[g],r[g],y));else {if(p==null&&d!=="count"&&$("Null aggregate field specified."),d==="count"){l.push(y);return}c=!1;let x=s[m];x||(x=s[m]=[],x.field=p,f.push(x)),x.push(bE(d,y));}}),(l.length||f.length)&&(this.cell=nS(f,l,c)),this.inputs=Object.keys(o);}const YE=WE.prototype;YE.init=function(){this.windows.forEach(t=>t.init()),this.cell&&this.cell.init();};YE.update=function(t,e){const n=this.cell,r=this.windows,i=t.data,a=r&&r.length;let u;if(n){for(u=t.p0;uwE(s,s.field));const r={num:0,agg:null,store:!1,count:e};if(!n)for(var i=t.length,a=r.agg=Array(i),u=0;uthis.group(i(o));let u=this.state;(!u||n)&&(u=this.state=new WE(t)),n||e.modified(u.inputs)?(this.value={},e.visit(e.SOURCE,o=>a(o).add(o))):(e.visit(e.REM,o=>a(o).remove(o)),e.visit(e.ADD,o=>a(o).add(o)));for(let o=0,s=this._mlen;o0&&!i(a[n],a[n-1])&&(t.i0=e.left(a,a[n])),rtypeof Image<"u"?Image:null;let qr;try{qr=require("canvas"),qr&&qr.createCanvas||(qr=null);}catch{}function lS(t,e,n){if(qr)try{return new qr.Canvas(t,e,n)}catch{}return null}const fS=()=>qr&&qr.Image||null;function Zr(t,e,n){return oS(t,e)||lS(t,e,n)||null}function cS(){return sS()||fS()||null}function zc(t,e,n){const r=t-e+n*2;return t?r>0?r:1:0}const hS="identity",ja="linear",kr="log",ls="pow",fs="sqrt",Ic="symlog",Yi="time",Hi="utc",Xn="sequential",fu="diverging",Wa="quantile",Uc="quantize",qc="threshold",_p="ordinal",$d="point",HE="band",Cp="bin-ordinal",zt="continuous",cs="discrete",hs="discretizing",vn="interpolating",Dp="temporal";function dS(t){return function(e){let n=e[0],r=e[1],i;return r=r&&n[s]<=i&&(a<0&&(a=s),u=s);if(!(a<0))return r=t.invertExtent(n[a]),i=t.invertExtent(n[u]),[r[0]===void 0?r[1]:r[0],i[1]===void 0?i[0]:i[1]]}}function Fp(){const t=j1().unknown(void 0),e=t.domain,n=t.range;let r=[0,1],i,a,u=!1,o=0,s=0,l=.5;delete t.unknown;function f(){const c=e().length,h=r[1]p+i*y);return n(h?m.reverse():m)}return t.domain=function(c){return arguments.length?(e(c),f()):e()},t.range=function(c){return arguments.length?(r=[+c[0],+c[1]],f()):r.slice()},t.rangeRound=function(c){return r=[+c[0],+c[1]],u=!0,f()},t.bandwidth=function(){return a},t.step=function(){return i},t.round=function(c){return arguments.length?(u=!!c,f()):u},t.padding=function(c){return arguments.length?(s=Math.max(0,Math.min(1,c)),o=s,f()):o},t.paddingInner=function(c){return arguments.length?(o=Math.max(0,Math.min(1,c)),f()):o},t.paddingOuter=function(c){return arguments.length?(s=Math.max(0,Math.min(1,c)),f()):s},t.align=function(c){return arguments.length?(l=Math.max(0,Math.min(1,c)),f()):l},t.invertRange=function(c){if(c[0]==null||c[1]==null)return;const h=r[1]r[1-h])))return y=Math.max(0,ti(d,p)-1),x=p===m?y:ti(d,m)-1,p-d[y]>a+1e-10&&++y,h&&(v=y,y=g-x,x=g-v),y>x?void 0:e().slice(y,x+1)},t.invert=function(c){const h=t.invertRange([c,c]);return h&&h[0]},t.copy=function(){return Fp().domain(e()).range(r).round(u).paddingInner(o).paddingOuter(s).align(l)},f()}function GE(t){const e=t.copy;return t.padding=t.paddingOuter,delete t.paddingInner,t.copy=function(){return GE(e())},t}function pS(){return GE(Fp().paddingInner(1))}var mS=Array.prototype.map;function yS(t){return mS.call(t,Kt)}const xS=Array.prototype.slice;function XE(){let t=[],e=[];function n(r){return r==null||r!==r?void 0:e[(ti(t,r)-1)%e.length]}return n.domain=function(r){return arguments.length?(t=yS(r),n):t.slice()},n.range=function(r){return arguments.length?(e=xS.call(r),n):e.slice()},n.tickFormat=function(r,i){return _w(t[0],ut(t),r??10,i)},n.copy=function(){return XE().domain(n.domain()).range(n.range())},n}const Af=new Map,VE=Symbol("vega_scale");function KE(t){return t[VE]=!0,t}function QE(t){return t&&t[VE]===!0}function vS(t,e,n){const r=function(){const a=e();return a.invertRange||(a.invertRange=a.invert?dS(a):a.invertExtent?gS(a):void 0),a.type=t,KE(a)};return r.metadata=nn(H(n)),r}function ft(t,e,n){return arguments.length>1?(Af.set(t,vS(t,e,n)),this):ZE(t)?Af.get(t):void 0}ft(hS,Dw);ft(ja,Cw,zt);ft(kr,Mw,[zt,kr]);ft(ls,G1,zt);ft(fs,x8,zt);ft(Ic,kw,zt);ft(Yi,T9,[zt,Dp]);ft(Hi,R9,[zt,Dp]);ft(Xn,Z1,[zt,vn]);ft(`${Xn}-${ja}`,Z1,[zt,vn]);ft(`${Xn}-${kr}`,qw,[zt,vn,kr]);ft(`${Xn}-${ls}`,J1,[zt,vn]);ft(`${Xn}-${fs}`,O9,[zt,vn]);ft(`${Xn}-${Ic}`,jw,[zt,vn]);ft(`${fu}-${ja}`,Ww,[zt,vn]);ft(`${fu}-${kr}`,Yw,[zt,vn,kr]);ft(`${fu}-${ls}`,tg,[zt,vn]);ft(`${fu}-${fs}`,N9,[zt,vn]);ft(`${fu}-${Ic}`,Hw,[zt,vn]);ft(Wa,$w,[hs,Wa]);ft(Uc,Sw,hs);ft(qc,Bw,hs);ft(Cp,XE,[cs,hs]);ft(_p,j1,cs);ft(HE,Fp,cs);ft($d,pS,cs);function ZE(t){return Af.has(t)}function ia(t,e){const n=Af.get(t);return n&&n.metadata[e]}function Mp(t){return ia(t,zt)}function Ya(t){return ia(t,cs)}function Sd(t){return ia(t,hs)}function JE(t){return ia(t,kr)}function bS(t){return ia(t,Dp)}function t_(t){return ia(t,vn)}function e_(t){return ia(t,Wa)}const AS=["clamp","base","constant","exponent"];function n_(t,e){const n=e[0],r=ut(e)-n;return function(i){return t(n+i*r)}}function jc(t,e,n){return F1($p(e||"rgb",n),t)}function r_(t,e){const n=new Array(e),r=e+1;for(let i=0;it[o]?u[o](t[o]()):0),u)}function $p(t,e){const n=qF[wS(t)];return e!=null&&n&&n.gamma?n.gamma(e):n}function wS(t){return "interpolate"+t.toLowerCase().split("-").map(e=>e[0].toUpperCase()+e.slice(1)).join("")}const ES={blues:"cfe1f2bed8eca8cee58fc1de74b2d75ba3cf4592c63181bd206fb2125ca40a4a90",greens:"d3eecdc0e6baabdda594d3917bc77d60ba6c46ab5e329a512089430e7735036429",greys:"e2e2e2d4d4d4c4c4c4b1b1b19d9d9d8888887575756262624d4d4d3535351e1e1e",oranges:"fdd8b3fdc998fdb87bfda55efc9244f87f2cf06b18e4580bd14904b93d029f3303",purples:"e2e1efd4d4e8c4c5e0b4b3d6a3a0cc928ec3827cb97566ae684ea25c3696501f8c",reds:"fdc9b4fcb49afc9e80fc8767fa7051f6573fec3f2fdc2a25c81b1db21218970b13",blueGreen:"d5efedc1e8e0a7ddd18bd2be70c6a958ba9144ad77319c5d2089460e7736036429",bluePurple:"ccddecbad0e4a8c2dd9ab0d4919cc98d85be8b6db28a55a6873c99822287730f71",greenBlue:"d3eecec5e8c3b1e1bb9bd8bb82cec269c2ca51b2cd3c9fc7288abd1675b10b60a1",orangeRed:"fddcaffdcf9bfdc18afdad77fb9562f67d53ee6545e24932d32d1ebf130da70403",purpleBlue:"dbdaebc8cee4b1c3de97b7d87bacd15b9fc93a90c01e7fb70b70ab056199045281",purpleBlueGreen:"dbd8eac8cee4b0c3de93b7d872acd1549fc83892bb1c88a3097f8702736b016353",purpleRed:"dcc9e2d3b3d7ce9eccd186c0da6bb2e14da0e23189d91e6fc61159ab07498f023a",redPurple:"fccfccfcbec0faa9b8f98faff571a5ec539ddb3695c41b8aa908808d0179700174",yellowGreen:"e4f4acd1eca0b9e2949ed68880c97c62bb6e47aa5e3297502083440e723b036034",yellowOrangeBrown:"feeaa1fedd84fecc63feb746fca031f68921eb7215db5e0bc54c05ab3d038f3204",yellowOrangeRed:"fee087fed16ffebd59fea849fd903efc7335f9522bee3423de1b20ca0b22af0225",blueOrange:"134b852f78b35da2cb9dcae1d2e5eff2f0ebfce0bafbbf74e8932fc5690d994a07",brownBlueGreen:"704108a0651ac79548e3c78af3e6c6eef1eac9e9e48ed1c74da79e187a72025147",purpleGreen:"5b1667834792a67fb6c9aed3e6d6e8eff0efd9efd5aedda971bb75368e490e5e29",purpleOrange:"4114696647968f83b7b9b4d6dadbebf3eeeafce0bafbbf74e8932fc5690d994a07",redBlue:"8c0d25bf363adf745ef4ae91fbdbc9f2efeed2e5ef9dcae15da2cb2f78b3134b85",redGrey:"8c0d25bf363adf745ef4ae91fcdccbfaf4f1e2e2e2c0c0c0969696646464343434",yellowGreenBlue:"eff9bddbf1b4bde5b594d5b969c5be45b4c22c9ec02182b82163aa23479c1c3185",redYellowBlue:"a50026d4322cf16e43fcac64fedd90faf8c1dcf1ecabd6e875abd04a74b4313695",redYellowGreen:"a50026d4322cf16e43fcac63fedd8df9f7aed7ee8ea4d86e64bc6122964f006837",pinkYellowGreen:"8e0152c0267edd72adf0b3d6faddedf5f3efe1f2cab6de8780bb474f9125276419",spectral:"9e0142d13c4bf0704afcac63fedd8dfbf8b0e0f3a1a9dda269bda94288b55e4fa2",viridis:"440154470e61481a6c482575472f7d443a834144873d4e8a39568c35608d31688e2d708e2a788e27818e23888e21918d1f988b1fa08822a8842ab07f35b77943bf7154c56866cc5d7ad1518fd744a5db36bcdf27d2e21be9e51afde725",magma:"0000040404130b0924150e3720114b2c11603b0f704a107957157e651a80721f817f24828c29819a2e80a8327db6377ac43c75d1426fde4968e95462f1605df76f5cfa7f5efc8f65fe9f6dfeaf78febf84fece91fddea0fcedaffcfdbf",inferno:"0000040403130c0826170c3b240c4f330a5f420a68500d6c5d126e6b176e781c6d86216b932667a12b62ae305cbb3755c73e4cd24644dd513ae65c30ed6925f3771af8850ffb9506fca50afcb519fac62df6d645f2e661f3f484fcffa4",plasma:"0d088723069033059742039d5002a25d01a66a00a87801a88405a7900da49c179ea72198b12a90ba3488c33d80cb4779d35171da5a69e16462e76e5bed7953f2834cf68f44fa9a3dfca636fdb32ffec029fcce25f9dc24f5ea27f0f921",cividis:"00205100235800265d002961012b65042e670831690d346b11366c16396d1c3c6e213f6e26426e2c456e31476e374a6e3c4d6e42506e47536d4c566d51586e555b6e5a5e6e5e616e62646f66676f6a6a706e6d717270717573727976737c79747f7c75827f758682768985778c8877908b78938e789691789a94789e9778a19b78a59e77a9a177aea575b2a874b6ab73bbaf71c0b26fc5b66dc9b96acebd68d3c065d8c462ddc85fe2cb5ce7cf58ebd355f0d652f3da4ff7de4cfae249fce647",rainbow:"6e40aa883eb1a43db3bf3cafd83fa4ee4395fe4b83ff576eff6659ff7847ff8c38f3a130e2b72fcfcc36bee044aff05b8ff4576ff65b52f6673af27828ea8d1ddfa319d0b81cbecb23abd82f96e03d82e14c6edb5a5dd0664dbf6e40aa",sinebow:"ff4040fc582af47218e78d0bd5a703bfbf00a7d5038de70b72f41858fc2a40ff402afc5818f4720be78d03d5a700bfbf03a7d50b8de71872f42a58fc4040ff582afc7218f48d0be7a703d5bf00bfd503a7e70b8df41872fc2a58ff4040",turbo:"23171b32204a3e2a71453493493eae4b49c54a53d7485ee44569ee4074f53c7ff8378af93295f72e9ff42ba9ef28b3e926bce125c5d925cdcf27d5c629dcbc2de3b232e9a738ee9d3ff39347f68950f9805afc7765fd6e70fe667cfd5e88fc5795fb51a1f84badf545b9f140c5ec3cd0e637dae034e4d931ecd12ef4c92bfac029ffb626ffad24ffa223ff9821ff8d1fff821dff771cfd6c1af76118f05616e84b14df4111d5380fcb2f0dc0260ab61f07ac1805a313029b0f00950c00910b00",browns:"eedbbdecca96e9b97ae4a865dc9856d18954c7784cc0673fb85536ad44339f3632",tealBlues:"bce4d89dd3d181c3cb65b3c245a2b9368fae347da0306a932c5985",teals:"bbdfdfa2d4d58ac9c975bcbb61b0af4da5a43799982b8b8c1e7f7f127273006667",warmGreys:"dcd4d0cec5c1c0b8b4b3aaa7a59c9998908c8b827f7e7673726866665c5a59504e",goldGreen:"f4d166d5ca60b6c35c98bb597cb25760a6564b9c533f8f4f33834a257740146c36",goldOrange:"f4d166f8be5cf8aa4cf5983bf3852aef701be2621fd65322c54923b142239e3a26",goldRed:"f4d166f6be59f9aa51fc964ef6834bee734ae56249db5247cf4244c43141b71d3e",lightGreyRed:"efe9e6e1dad7d5cbc8c8bdb9bbaea9cd967ddc7b43e15f19df4011dc000b",lightGreyTeal:"e4eaead6dcddc8ced2b7c2c7a6b4bc64b0bf22a6c32295c11f85be1876bc",lightMulti:"e0f1f2c4e9d0b0de9fd0e181f6e072f6c053f3993ef77440ef4a3c",lightOrange:"f2e7daf7d5baf9c499fab184fa9c73f68967ef7860e8645bde515bd43d5b",lightTealBlue:"e3e9e0c0dccf9aceca7abfc859afc0389fb9328dad2f7ca0276b95255988",darkBlue:"3232322d46681a5c930074af008cbf05a7ce25c0dd38daed50f3faffffff",darkGold:"3c3c3c584b37725e348c7631ae8b2bcfa424ecc31ef9de30fff184ffffff",darkGreen:"3a3a3a215748006f4d048942489e4276b340a6c63dd2d836ffeb2cffffaa",darkMulti:"3737371f5287197d8c29a86995ce3fffe800ffffff",darkRed:"3434347036339e3c38cc4037e75d1eec8620eeab29f0ce32ffeb2c"},_S={category10:"1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf",category20:"1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5",category20b:"393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6",category20c:"3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9",tableau10:"4c78a8f58518e4575672b7b254a24beeca3bb279a2ff9da69d755dbab0ac",tableau20:"4c78a89ecae9f58518ffbf7954a24b88d27ab79a20f2cf5b43989483bcb6e45756ff9d9879706ebab0acd67195fcbfd2b279a2d6a5c99e765fd8b5a5",accent:"7fc97fbeaed4fdc086ffff99386cb0f0027fbf5b17666666",dark2:"1b9e77d95f027570b3e7298a66a61ee6ab02a6761d666666",paired:"a6cee31f78b4b2df8a33a02cfb9a99e31a1cfdbf6fff7f00cab2d66a3d9affff99b15928",pastel1:"fbb4aeb3cde3ccebc5decbe4fed9a6ffffcce5d8bdfddaecf2f2f2",pastel2:"b3e2cdfdcdaccbd5e8f4cae4e6f5c9fff2aef1e2cccccccc",set1:"e41a1c377eb84daf4a984ea3ff7f00ffff33a65628f781bf999999",set2:"66c2a5fc8d628da0cbe78ac3a6d854ffd92fe5c494b3b3b3",set3:"8dd3c7ffffb3bebadafb807280b1d3fdb462b3de69fccde5d9d9d9bc80bdccebc5ffed6f"};function i_(t){const e=t.length/6|0,n=new Array(e);for(let r=0;rjc(i_(t)));function Sp(t,e){return t=t&&t.toLowerCase(),arguments.length>1?(Rx[t]=e,this):Rx[t]}const dl="symbol",CS="discrete",DS="gradient",FS=t=>U(t)?t.map(e=>String(e)):String(t),MS=(t,e)=>t[1]-e[1],kS=(t,e)=>e[1]-t[1];function Bp(t,e,n){let r;return Mr(e)&&(t.bins&&(e=Math.max(e,t.bins.length)),n!=null&&(e=Math.min(e,Math.floor(au(t.domain())/n||1)+1))),et(e)&&(r=e.step,e=e.interval),xt(e)&&(e=t.type===Yi?uu(e):t.type==Hi?ou(e):$("Only time and utc scales accept interval strings."),r&&(e=e.every(r))),e}function u_(t,e,n){let r=t.range(),i=r[0],a=ut(r),u=MS;if(i>a&&(r=a,a=i,i=r,u=kS),i=Math.floor(i),a=Math.ceil(a),e=e.map(o=>[o,t(o)]).filter(o=>i<=o[1]&&o[1]<=a).sort(u).map(o=>o[0]),n>0&&e.length>1){const o=[e[0],ut(e)];for(;e.length>n&&e.length>=3;)e=e.filter((s,l)=>!(l%2));e.length<3&&(e=o);}return e}function Tp(t,e){return t.bins?u_(t,t.bins):t.ticks?t.ticks(e):t.domain()}function o_(t,e,n,r,i,a){const u=e.type;let o=FS;if(u===Yi||i===Yi)o=t.timeFormat(r);else if(u===Hi||i===Hi)o=t.utcFormat(r);else if(JE(u)){const s=t.formatFloat(r);if(a||e.bins)o=s;else {const l=s_(e,n,!1);o=f=>l(f)?s(f):"";}}else if(e.tickFormat){const s=e.domain();o=t.formatSpan(s[0],s[s.length-1],n,r);}else r&&(o=t.format(r));return o}function s_(t,e,n){const r=Tp(t,e),i=t.base(),a=Math.log(i),u=Math.max(1,i*e/r.length),o=s=>{let l=s/Math.pow(i,Math.round(Math.log(s)/a));return l*i1?r[1]-r[0]:r[0],u;for(u=1;uBd[t.type]||t.bins;function c_(t,e,n,r,i,a,u){const o=l_[e.type]&&a!==Yi&&a!==Hi?$S(t,e,i):o_(t,e,n,i,a,u);return r===dl&&TS(e)?RS(o):r===CS?OS(o):NS(o)}const RS=t=>(e,n,r)=>{const i=Ox(r[n+1],Ox(r.max,1/0)),a=Nx(e,t),u=Nx(i,t);return a&&u?a+" – "+u:u?"< "+u:"≥ "+a},Ox=(t,e)=>t??e,OS=t=>(e,n)=>n?t(e):null,NS=t=>e=>t(e),Nx=(t,e)=>Number.isFinite(t)?e(t):null;function LS(t){const e=t.domain(),n=e.length-1;let r=+e[0],i=+ut(e),a=i-r;if(t.type===qc){const u=n?a/n:.1;r-=u,i+=u,a=i-r;}return u=>(u-r)/a}function PS(t,e,n,r){const i=r||e.type;return xt(n)&&bS(i)&&(n=n.replace(/%a/g,"%A").replace(/%b/g,"%B")),!n&&i===Yi?t.timeFormat("%A, %d %B %Y, %X"):!n&&i===Hi?t.utcFormat("%A, %d %B %Y, %X UTC"):c_(t,e,5,null,n,r,!0)}function h_(t,e,n){n=n||{};const r=Math.max(3,n.maxlen||7),i=PS(t,e,n.format,n.formatType);if(Sd(e.type)){const a=f_(e).slice(1).map(i),u=a.length;return `${u} boundar${u===1?"y":"ies"}: ${a.join(", ")}`}else if(Ya(e.type)){const a=e.domain(),u=a.length,o=u>r?a.slice(0,r-2).map(i).join(", ")+", ending with "+a.slice(-1).map(i):a.map(i).join(", ");return `${u} value${u===1?"":"s"}: ${o}`}else {const a=e.domain();return `values from ${i(a[0])} to ${i(ut(a))}`}}let d_=0;function zS(){d_=0;}const wf="p_";function Rp(t){return t&&t.gradient}function g_(t,e,n){const r=t.gradient;let i=t.id,a=r==="radial"?wf:"";return i||(i=t.id="gradient_"+d_++,r==="radial"?(t.x1=In(t.x1,.5),t.y1=In(t.y1,.5),t.r1=In(t.r1,0),t.x2=In(t.x2,.5),t.y2=In(t.y2,.5),t.r2=In(t.r2,.5),a=wf):(t.x1=In(t.x1,0),t.y1=In(t.y1,0),t.x2=In(t.x2,1),t.y2=In(t.y2,0))),e[i]=t,"url("+(n||"")+"#"+a+i+")"}function In(t,e){return t??e}function Op(t,e){var n=[],r;return r={gradient:"linear",x1:t?t[0]:0,y1:t?t[1]:0,x2:e?e[0]:1,y2:e?e[1]:0,stops:n,stop:function(i,a){return n.push({offset:i,color:a}),r}}}const Lx={basis:{curve:X9},"basis-closed":{curve:V9},"basis-open":{curve:K9},bundle:{curve:Q9,tension:"beta",value:.85},cardinal:{curve:Z9,tension:"tension",value:0},"cardinal-open":{curve:t4,tension:"tension",value:0},"cardinal-closed":{curve:J9,tension:"tension",value:0},"catmull-rom":{curve:e4,tension:"alpha",value:.5},"catmull-rom-closed":{curve:n4,tension:"alpha",value:.5},"catmull-rom-open":{curve:r4,tension:"alpha",value:.5},linear:{curve:eg},"linear-closed":{curve:i4},monotone:{horizontal:u4,vertical:a4},natural:{curve:o4},step:{curve:s4},"step-after":{curve:f4},"step-before":{curve:l4}};function Np(t,e,n){var r=X(Lx,t)&&Lx[t],i=null;return r&&(i=r.curve||r[e||"vertical"],r.tension&&n!=null&&(i=i[r.tension](n))),i}const IS={m:2,l:2,h:1,v:1,z:0,c:6,s:4,q:4,t:2,a:7},US=/[mlhvzcsqta]([^mlhvzcsqta]+|$)/gi,qS=/^[+-]?(([0-9]*\.[0-9]+)|([0-9]+\.)|([0-9]+))([eE][+-]?[0-9]+)?/,jS=/^((\s+,?\s*)|(,\s*))/,WS=/^[01]/;function Gi(t){const e=[];return (t.match(US)||[]).forEach(r=>{let i=r[0];const a=i.toLowerCase(),u=IS[a],o=YS(a,u,r.slice(1).trim()),s=o.length;if(s1&&(p=Math.sqrt(p),n*=p,r*=p);const m=h/n,y=c/n,x=-c/r,v=h/r,b=m*o+y*s,w=x*o+v*s,E=m*t+y*e,A=x*t+v*e;let C=1/((E-b)*(E-b)+(A-w)*(A-w))-.25;C<0&&(C=0);let F=Math.sqrt(C);a==i&&(F=-F);const D=.5*(b+E)-F*(A-w),R=.5*(w+A)+F*(E-b),k=Math.atan2(w-R,b-D);let M=Math.atan2(A-R,E-D)-k;M<0&&a===1?M+=Yn:M>0&&a===0&&(M-=Yn);const O=Math.ceil(Math.abs(M/(Di+.001))),z=[];for(let G=0;G+t}function Ks(t,e,n){return Math.max(e,Math.min(t,n))}function y_(){var t=QS,e=ZS,n=JS,r=tB,i=sr(0),a=i,u=i,o=i,s=null;function l(f,c,h){var d,g=c??+t.call(this,f),p=h??+e.call(this,f),m=+n.call(this,f),y=+r.call(this,f),x=Math.min(m,y)/2,v=Ks(+i.call(this,f),0,x),b=Ks(+a.call(this,f),0,x),w=Ks(+u.call(this,f),0,x),E=Ks(+o.call(this,f),0,x);if(s||(s=d=Vf()),v<=0&&b<=0&&w<=0&&E<=0)s.rect(g,p,m,y);else {var A=g+m,_=p+y;s.moveTo(g+v,p),s.lineTo(A-b,p),s.bezierCurveTo(A-Tr*b,p,A,p+Tr*b,A,p+b),s.lineTo(A,_-E),s.bezierCurveTo(A,_-Tr*E,A-Tr*E,_,A-E,_),s.lineTo(g+w,_),s.bezierCurveTo(g+Tr*w,_,g,_-Tr*w,g,_-w),s.lineTo(g,p+v),s.bezierCurveTo(g,p+Tr*v,g+Tr*v,p,g+v,p),s.closePath();}if(d)return s=null,d+""||null}return l.x=function(f){return arguments.length?(t=sr(f),l):t},l.y=function(f){return arguments.length?(e=sr(f),l):e},l.width=function(f){return arguments.length?(n=sr(f),l):n},l.height=function(f){return arguments.length?(r=sr(f),l):r},l.cornerRadius=function(f,c,h,d){return arguments.length?(i=sr(f),a=c!=null?sr(c):i,o=h!=null?sr(h):i,u=d!=null?sr(d):a,l):i},l.context=function(f){return arguments.length?(s=f??null,l):s},l}function x_(){var t,e,n,r,i=null,a,u,o,s;function l(c,h,d){const g=d/2;if(a){var p=o-h,m=c-u;if(p||m){var y=Math.sqrt(p*p+m*m),x=(p/=y)*s,v=(m/=y)*s,b=Math.atan2(m,p);i.moveTo(u-x,o-v),i.lineTo(c-p*g,h-m*g),i.arc(c,h,g,b-Math.PI,b),i.lineTo(u+x,o+v),i.arc(u,o,s,b,b+Math.PI);}else i.arc(c,h,g,0,Yn);i.closePath();}else a=1;u=c,o=h,s=g;}function f(c){var h,d=c.length,g,p=!1,m;for(i==null&&(i=m=Vf()),h=0;h<=d;++h)!(ht.x||0,ps=t=>t.y||0,eB=t=>t.width||0,nB=t=>t.height||0,rB=t=>(t.x||0)+(t.width||0),iB=t=>(t.y||0)+(t.height||0),aB=t=>t.startAngle||0,uB=t=>t.endAngle||0,oB=t=>t.padAngle||0,sB=t=>t.innerRadius||0,lB=t=>t.outerRadius||0,fB=t=>t.cornerRadius||0,cB=t=>ds(t.cornerRadiusTopLeft,t.cornerRadius)||0,hB=t=>ds(t.cornerRadiusTopRight,t.cornerRadius)||0,dB=t=>ds(t.cornerRadiusBottomRight,t.cornerRadius)||0,gB=t=>ds(t.cornerRadiusBottomLeft,t.cornerRadius)||0,pB=t=>ds(t.size,64),mB=t=>t.size||1,Wc=t=>t.defined!==!1,yB=t=>m_(t.shape||"circle"),xB=Y9().startAngle(aB).endAngle(uB).padAngle(oB).innerRadius(sB).outerRadius(lB).cornerRadius(fB),vB=Jw().x(gs).y1(ps).y0(iB).defined(Wc),bB=Jw().y(ps).x1(gs).x0(rB).defined(Wc),AB=Zw().x(gs).y(ps).defined(Wc),wB=y_().x(gs).y(ps).width(eB).height(nB).cornerRadius(cB,hB,dB,gB),EB=G9().type(yB).size(pB),_B=x_().x(gs).y(ps).defined(Wc).size(mB);function Lp(t){return t.cornerRadius||t.cornerRadiusTopLeft||t.cornerRadiusTopRight||t.cornerRadiusBottomRight||t.cornerRadiusBottomLeft}function CB(t,e){return xB.context(t)(e)}function DB(t,e){const n=e[0],r=n.interpolate||"linear";return (n.orient==="horizontal"?bB:vB).curve(Np(r,n.orient,n.tension)).context(t)(e)}function FB(t,e){const n=e[0],r=n.interpolate||"linear";return AB.curve(Np(r,n.orient,n.tension)).context(t)(e)}function cu(t,e,n,r){return wB.context(t)(e,n,r)}function MB(t,e){return (e.mark.shape||e.shape).context(t)(e)}function kB(t,e){return EB.context(t)(e)}function $B(t,e){return _B.context(t)(e)}var v_=1;function b_(){v_=1;}function Pp(t,e,n){var r=e.clip,i=t._defs,a=e.clip_id||(e.clip_id="clip"+v_++),u=i.clipping[a]||(i.clipping[a]={id:a});return tt(r)?u.path=r(null):Lp(n)?u.path=cu(null,n,0,0):(u.width=n.width||0,u.height=n.height||0),"url(#"+a+")"}function St(t){this.clear(),t&&this.union(t);}St.prototype={clone(){return new St(this)},clear(){return this.x1=+Number.MAX_VALUE,this.y1=+Number.MAX_VALUE,this.x2=-Number.MAX_VALUE,this.y2=-Number.MAX_VALUE,this},empty(){return this.x1===+Number.MAX_VALUE&&this.y1===+Number.MAX_VALUE&&this.x2===-Number.MAX_VALUE&&this.y2===-Number.MAX_VALUE},equals(t){return this.x1===t.x1&&this.y1===t.y1&&this.x2===t.x2&&this.y2===t.y2},set(t,e,n,r){return nthis.x2&&(this.x2=t),e>this.y2&&(this.y2=e),this},expand(t){return this.x1-=t,this.y1-=t,this.x2+=t,this.y2+=t,this},round(){return this.x1=Math.floor(this.x1),this.y1=Math.floor(this.y1),this.x2=Math.ceil(this.x2),this.y2=Math.ceil(this.y2),this},scale(t){return this.x1*=t,this.y1*=t,this.x2*=t,this.y2*=t,this},translate(t,e){return this.x1+=t,this.x2+=t,this.y1+=e,this.y2+=e,this},rotate(t,e,n){const r=this.rotatedPoints(t,e,n);return this.clear().add(r[0],r[1]).add(r[2],r[3]).add(r[4],r[5]).add(r[6],r[7])},rotatedPoints(t,e,n){var{x1:r,y1:i,x2:a,y2:u}=this,o=Math.cos(t),s=Math.sin(t),l=e-e*o+n*s,f=n-e*s-n*o;return [o*r-s*i+l,s*r+o*i+f,o*r-s*u+l,s*r+o*u+f,o*a-s*i+l,s*a+o*i+f,o*a-s*u+l,s*a+o*u+f]},union(t){return t.x1this.x2&&(this.x2=t.x2),t.y2>this.y2&&(this.y2=t.y2),this},intersect(t){return t.x1>this.x1&&(this.x1=t.x1),t.y1>this.y1&&(this.y1=t.y1),t.x2=t.x2&&this.y1<=t.y1&&this.y2>=t.y2},alignsWith(t){return t&&(this.x1==t.x1||this.x2==t.x2||this.y1==t.y1||this.y2==t.y2)},intersects(t){return t&&!(this.x2t.x2||this.y2t.y2)},contains(t,e){return !(tthis.x2||ethis.y2)},width(){return this.x2-this.x1},height(){return this.y2-this.y1}};function Yc(t){this.mark=t,this.bounds=this.bounds||new St;}function Hc(t){Yc.call(this,t),this.items=this.items||[];}L(Hc,Yc);function zp(t){this._pending=0,this._loader=t||wc();}function Ux(t){t._pending+=1;}function $u(t){t._pending-=1;}zp.prototype={pending(){return this._pending},sanitizeURL(t){const e=this;return Ux(e),e._loader.sanitize(t,{context:"href"}).then(n=>($u(e),n)).catch(()=>($u(e),null))},loadImage(t){const e=this,n=cS();return Ux(e),e._loader.sanitize(t,{context:"image"}).then(r=>{const i=r.href;if(!i||!n)throw {url:i};const a=new n,u=X(r,"crossOrigin")?r.crossOrigin:"anonymous";return u!=null&&(a.crossOrigin=u),a.onload=()=>$u(e),a.onerror=()=>$u(e),a.src=i,a}).catch(r=>($u(e),{complete:!1,width:0,height:0,src:r&&r.url||""}))},ready(){const t=this;return new Promise(e=>{function n(r){t.pending()?setTimeout(()=>{n(!0);},10):e(r);}n(!1);})}};function $r(t,e,n){if(e.stroke&&e.opacity!==0&&e.strokeOpacity!==0){const r=e.strokeWidth!=null?+e.strokeWidth:1;t.expand(r+(n?SB(e,r):0));}return t}function SB(t,e){return t.strokeJoin&&t.strokeJoin!=="miter"?0:e}const BB=Yn-1e-8;let Gc,gl,pl,Ti,Td,ml,Rd,Od;const jr=(t,e)=>Gc.add(t,e),yl=(t,e)=>jr(gl=t,pl=e),qx=t=>jr(t,Gc.y1),jx=t=>jr(Gc.x1,t),Fi=(t,e)=>Td*t+Rd*e,Mi=(t,e)=>ml*t+Od*e,i0=(t,e)=>jr(Fi(t,e),Mi(t,e)),a0=(t,e)=>yl(Fi(t,e),Mi(t,e));function ms(t,e){return Gc=t,e?(Ti=e*ii,Td=Od=Math.cos(Ti),ml=Math.sin(Ti),Rd=-ml):(Td=Od=1,Ti=ml=Rd=0),TB}const TB={beginPath(){},closePath(){},moveTo:a0,lineTo:a0,rect(t,e,n,r){Ti?(i0(t+n,e),i0(t+n,e+r),i0(t,e+r),a0(t,e)):(jr(t+n,e+r),yl(t,e));},quadraticCurveTo(t,e,n,r){const i=Fi(t,e),a=Mi(t,e),u=Fi(n,r),o=Mi(n,r);Wx(gl,i,u,qx),Wx(pl,a,o,jx),yl(u,o);},bezierCurveTo(t,e,n,r,i,a){const u=Fi(t,e),o=Mi(t,e),s=Fi(n,r),l=Mi(n,r),f=Fi(i,a),c=Mi(i,a);Yx(gl,u,s,f,qx),Yx(pl,o,l,c,jx),yl(f,c);},arc(t,e,n,r,i,a){if(r+=Ti,i+=Ti,gl=n*Math.cos(i)+t,pl=n*Math.sin(i)+e,Math.abs(i-r)>BB)jr(t-n,e-n),jr(t+n,e+n);else {const u=l=>jr(n*Math.cos(l)+t,n*Math.sin(l)+e);let o,s;if(u(r),u(i),i!==r)if(r=r%Yn,r<0&&(r+=Yn),i=i%Yn,i<0&&(i+=Yn),ii;++s,o-=Di)u(o);else for(o=r-r%Di+Di,s=0;s<4&&oHS?(f=u*u+o*a,f>=0&&(f=Math.sqrt(f),s=(-u+f)/a,l=(-u-f)/a)):s=.5*o/u,0h)return !1;p>c&&(c=p);}else if(d>0){if(p0?(t.globalAlpha=n,t.fillStyle=E_(t,e,e.fill),!0):!1}var OB=[];function Xa(t,e,n){var r=(r=e.strokeWidth)!=null?r:1;return r<=0?!1:(n*=e.strokeOpacity==null?1:e.strokeOpacity,n>0?(t.globalAlpha=n,t.strokeStyle=E_(t,e,e.stroke),t.lineWidth=r,t.lineCap=e.strokeCap||"butt",t.lineJoin=e.strokeJoin||"miter",t.miterLimit=e.strokeMiterLimit||10,t.setLineDash&&(t.setLineDash(e.strokeDash||OB),t.lineDashOffset=e.strokeDashOffset||0),!0):!1)}function NB(t,e){return t.zindex-e.zindex||t.index-e.index}function qp(t){if(!t.zdirty)return t.zitems;var e=t.items,n=[],r,i,a;for(i=0,a=e.length;i=0;)if(r=e(n[i]))return r;if(n===a){for(n=t.items,i=n.length;--i>=0;)if(!n[i].zindex&&(r=e(n[i])))return r}return null}function jp(t){return function(e,n,r){Tn(n,i=>{(!r||r.intersects(i.bounds))&&__(t,e,i,i);});}}function LB(t){return function(e,n,r){n.items.length&&(!r||r.intersects(n.bounds))&&__(t,e,n.items[0],n.items);}}function __(t,e,n,r){var i=n.opacity==null?1:n.opacity;i!==0&&(t(e,r)||(Ga(e,n),n.fill&&Ef(e,n,i)&&e.fill(),n.stroke&&Xa(e,n,i)&&e.stroke()));}function Xc(t){return t=t||We,function(e,n,r,i,a,u){return r*=e.pixelRatio,i*=e.pixelRatio,_f(n,o=>{const s=o.bounds;if(!(s&&!s.contains(a,u)||!s)&&t(e,o,r,i,a,u))return o})}}function ys(t,e){return function(n,r,i,a){var u=Array.isArray(r)?r[0]:r,o=e??u.fill,s=u.stroke&&n.isPointInStroke,l,f;return s&&(l=u.strokeWidth,f=u.strokeCap,n.lineWidth=l??1,n.lineCap=f??"butt"),t(n,r)?!1:o&&n.isPointInPath(i,a)||s&&n.isPointInStroke(i,a)}}function Wp(t){return Xc(ys(t))}function Pi(t,e){return "translate("+t+","+e+")"}function Yp(t){return "rotate("+t+")"}function PB(t,e){return "scale("+t+","+e+")"}function C_(t){return Pi(t.x||0,t.y||0)}function zB(t){return Pi(t.x||0,t.y||0)+(t.angle?" "+Yp(t.angle):"")}function IB(t){return Pi(t.x||0,t.y||0)+(t.angle?" "+Yp(t.angle):"")+(t.scaleX||t.scaleY?" "+PB(t.scaleX||1,t.scaleY||1):"")}function Hp(t,e,n){function r(u,o){u("transform",zB(o)),u("d",e(null,o));}function i(u,o){return e(ms(u,o.angle),o),$r(u,o).translate(o.x||0,o.y||0)}function a(u,o){var s=o.x||0,l=o.y||0,f=o.angle||0;u.translate(s,l),f&&u.rotate(f*=ii),u.beginPath(),e(u,o),f&&u.rotate(-f),u.translate(-s,-l);}return {type:t,tag:"path",nested:!1,attr:r,bound:i,draw:jp(a),pick:Wp(a),isect:n||Ip(a)}}var UB=Hp("arc",CB);function qB(t,e){for(var n=t[0].orient==="horizontal"?e[1]:e[0],r=t[0].orient==="horizontal"?"y":"x",i=t.length,a=1/0,u,o;--i>=0;)t[i].defined!==!1&&(o=Math.abs(t[i][r]-n),o=0;)if(t[r].defined!==!1&&(i=t[r].x-e[0],a=t[r].y-e[1],u=i*i+a*a,u=0;)if(t[n].defined!==!1&&(r=t[n].x-e[0],i=t[n].y-e[1],a=r*r+i*i,r=t[n].size||1,a.5&&e<1.5?.5-Math.abs(e-1):0}function GB(t,e){t("transform",C_(e));}function M_(t,e){const n=F_(e);t("d",cu(null,e,n,n));}function XB(t,e){t("class","background"),t("aria-hidden",!0),M_(t,e);}function VB(t,e){t("class","foreground"),t("aria-hidden",!0),e.strokeForeground?M_(t,e):t("d","");}function KB(t,e,n){const r=e.clip?Pp(n,e,e):null;t("clip-path",r);}function QB(t,e){if(!e.clip&&e.items){const n=e.items,r=n.length;for(let i=0;i{const i=r.x||0,a=r.y||0,u=r.strokeForeground,o=r.opacity==null?1:r.opacity;(r.stroke||r.fill)&&o&&(No(t,r,i,a),Ga(t,r),r.fill&&Ef(t,r,o)&&t.fill(),r.stroke&&!u&&Xa(t,r,o)&&t.stroke()),t.save(),t.translate(i,a),r.clip&&D_(t,r),n&&n.translate(-i,-a),Tn(r,s=>{this.draw(t,s,n);}),n&&n.translate(i,a),t.restore(),u&&r.stroke&&o&&(No(t,r,i,a),Ga(t,r),Xa(t,r,o)&&t.stroke());});}function nT(t,e,n,r,i,a){if(e.bounds&&!e.bounds.contains(i,a)||!e.items)return null;const u=n*t.pixelRatio,o=r*t.pixelRatio;return _f(e,s=>{let l,f,c;const h=s.bounds;if(h&&!h.contains(i,a))return;f=s.x||0,c=s.y||0;const d=f+(s.width||0),g=c+(s.height||0),p=s.clip;if(p&&(id||ag))return;if(t.save(),t.translate(f,c),f=i-f,c=a-c,p&&Lp(s)&&!tT(t,s,u,o))return t.restore(),null;const m=s.strokeForeground,y=e.interactive!==!1;return y&&m&&s.stroke&&JB(t,s,u,o)?(t.restore(),s):(l=_f(s,x=>rT(x,f,c)?this.pick(x,n,r,f,c):null),!l&&y&&(s.fill||!m&&s.stroke)&&ZB(t,s,u,o)&&(l=s),t.restore(),l||null)})}function rT(t,e,n){return (t.interactive!==!1||t.marktype==="group")&&t.bounds&&t.bounds.contains(e,n)}var iT={type:"group",tag:"g",nested:!1,attr:GB,bound:QB,draw:eT,pick:nT,isect:A_,content:KB,background:XB,foreground:VB},Lo={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",version:"1.1"};function Xp(t,e){var n=t.image;return (!n||t.url&&t.url!==n.url)&&(n={complete:!1,width:0,height:0},e.loadImage(t.url).then(r=>{t.image=r,t.image.url=t.url;})),n}function Vp(t,e){return t.width!=null?t.width:!e||!e.width?0:t.aspect!==!1&&t.height?t.height*e.width/e.height:e.width}function Kp(t,e){return t.height!=null?t.height:!e||!e.height?0:t.aspect!==!1&&t.width?t.width*e.height/e.width:e.height}function Vc(t,e){return t==="center"?e/2:t==="right"?e:0}function Kc(t,e){return t==="middle"?e/2:t==="bottom"?e:0}function aT(t,e,n){const r=Xp(e,n),i=Vp(e,r),a=Kp(e,r),u=(e.x||0)-Vc(e.align,i),o=(e.y||0)-Kc(e.baseline,a),s=!r.src&&r.toDataURL?r.toDataURL():r.src||"";t("href",s,Lo["xmlns:xlink"],"xlink:href"),t("transform",Pi(u,o)),t("width",i),t("height",a),t("preserveAspectRatio",e.aspect===!1?"none":"xMidYMid");}function uT(t,e){const n=e.image,r=Vp(e,n),i=Kp(e,n),a=(e.x||0)-Vc(e.align,r),u=(e.y||0)-Kc(e.baseline,i);return t.set(a,u,a+r,u+i)}function oT(t,e,n){Tn(e,r=>{if(n&&!n.intersects(r.bounds))return;const i=Xp(r,this);let a=Vp(r,i),u=Kp(r,i);if(a===0||u===0)return;let o=(r.x||0)-Vc(r.align,a),s=(r.y||0)-Kc(r.baseline,u),l,f,c,h;r.aspect!==!1&&(f=i.width/i.height,c=r.width/r.height,f===f&&c===c&&f!==c&&(c{if(!(n&&!n.intersects(r.bounds))){var i=r.opacity==null?1:r.opacity;i&&k_(t,r,i)&&(Ga(t,r),t.stroke());}});}function vT(t,e,n,r){return t.isPointInStroke?k_(t,e,1)&&t.isPointInStroke(n,r):!1}var bT={type:"rule",tag:"line",nested:!1,attr:mT,bound:yT,draw:xT,pick:Xc(vT),isect:w_},AT=Hp("shape",MB),wT=Hp("symbol",kB,Up);const Vx=D3();var kn={height:rr,measureWidth:Qp,estimateWidth:Ld,width:Ld,canvas:$_};$_(!0);function $_(t){kn.width=t&&Jr?Qp:Ld;}function Ld(t,e){return S_(ui(t,e),rr(t))}function S_(t,e){return ~~(.8*t.length*e)}function Qp(t,e){return rr(t)<=0||!(e=ui(t,e))?0:B_(e,Qc(t))}function B_(t,e){const n=`(${e}) ${t}`;let r=Vx.get(n);return r===void 0&&(Jr.font=e,r=Jr.measureText(t).width,Vx.set(n,r)),r}function rr(t){return t.fontSize!=null?+t.fontSize||0:11}function ai(t){return t.lineHeight!=null?t.lineHeight:rr(t)+2}function ET(t){return U(t)?t.length>1?t:t[0]:t}function xs(t){return ET(t.lineBreak&&t.text&&!U(t.text)?t.text.split(t.lineBreak):t.text)}function Zp(t){const e=xs(t);return (U(e)?e.length-1:0)*ai(t)}function ui(t,e){const n=e==null?"":(e+"").trim();return t.limit>0&&n.length?CT(t,n):n}function _T(t){if(kn.width===Qp){const e=Qc(t);return n=>B_(n,e)}else {const e=rr(t);return n=>S_(n,e)}}function CT(t,e){var n=+t.limit,r=_T(t);if(r(e)>>1,r(e.slice(s))>n?u=s+1:o=s;return i+e.slice(u)}else {for(;u>>1),r(e.slice(0,s))Math.max(h,kn.width(e,d)),0)):c=kn.width(e,f),i==="center"?s-=c/2:i==="right"&&(s-=c),t.set(s+=u,l+=o,s+c,l+r),e.angle&&!n)t.rotate(e.angle*ii,u,o);else if(n===2)return t.rotatedPoints(e.angle*ii,u,o);return t}function MT(t,e,n){Tn(e,r=>{var i=r.opacity==null?1:r.opacity,a,u,o,s,l,f,c;if(!(n&&!n.intersects(r.bounds)||i===0||r.fontSize<=0||r.text==null||r.text.length===0)){if(t.font=Qc(r),t.textAlign=r.align||"left",a=Zc(r),u=a.x1,o=a.y1,r.angle&&(t.save(),t.translate(u,o),t.rotate(r.angle*ii),u=o=0),u+=r.dx||0,o+=(r.dy||0)+Jp(r),f=xs(r),Ga(t,r),U(f))for(l=ai(r),s=0;se;)t.removeChild(n[--r]);return t}function P_(t){return "mark-"+t.marktype+(t.role?" role-"+t.role:"")+(t.name?" "+t.name:"")}function Jc(t,e){const n=e.getBoundingClientRect();return [t.clientX-n.left-(e.clientLeft||0),t.clientY-n.top-(e.clientTop||0)]}function RT(t,e,n,r){var i=t&&t.mark,a,u;if(i&&(a=on[i.marktype]).tip){for(u=Jc(e,n),u[0]-=r[0],u[1]-=r[1];t=t.mark.group;)u[0]-=t.x||0,u[1]-=t.y||0;t=a.tip(i.items,u);}return t}function oi(t,e){this._active=null,this._handlers={},this._loader=t||wc(),this._tooltip=e||OT;}function OT(t,e,n,r){t.element().setAttribute("title",r||"");}oi.prototype={initialize(t,e,n){return this._el=t,this._obj=n||null,this.origin(e)},element(){return this._el},canvas(){return this._el&&this._el.firstChild},origin(t){return arguments.length?(this._origin=t||[0,0],this):this._origin.slice()},scene(t){return arguments.length?(this._scene=t,this):this._scene},on(){},off(){},_handlerIndex(t,e,n){for(let r=t?t.length:0;--r>=0;)if(t[r].type===e&&(!n||t[r].handler===n))return r;return -1},handlers(t){const e=this._handlers,n=[];if(t)n.push(...e[this.eventName(t)]);else for(const r in e)n.push(...e[r]);return n},eventName(t){const e=t.indexOf(".");return e<0?t:t.slice(0,e)},handleHref(t,e,n){this._loader.sanitize(n,{context:"href"}).then(r=>{const i=new MouseEvent(t.type,t),a=Wr(null,"a");for(const u in r)a.setAttribute(u,r[u]);a.dispatchEvent(i);}).catch(()=>{});},handleTooltip(t,e,n){if(e&&e.tooltip!=null){e=RT(e,t,this.canvas(),this._origin);const r=n&&e&&e.tooltip||null;this._tooltip.call(this._obj,this,t,e,r);}},getItemBoundingClientRect(t){const e=this.canvas();if(!e)return;const n=e.getBoundingClientRect(),r=this._origin,i=t.bounds,a=i.width(),u=i.height();let o=i.x1+r[0]+n.left,s=i.y1+r[1]+n.top;for(;t.mark&&(t=t.mark.group);)o+=t.x||0,s+=t.y||0;return {x:o,y:s,width:a,height:u,left:o,top:s,right:o+a,bottom:s+u}}};function ir(t){this._el=null,this._bgcolor=null,this._loader=new zp(t);}ir.prototype={initialize(t,e,n,r,i){return this._el=t,this.resize(e,n,r,i)},element(){return this._el},canvas(){return this._el&&this._el.firstChild},background(t){return arguments.length===0?this._bgcolor:(this._bgcolor=t,this)},resize(t,e,n,r){return this._width=t,this._height=e,this._origin=n||[0,0],this._scale=r||1,this},dirty(){},render(t){const e=this;return e._call=function(){e._render(t);},e._call(),e._call=null,e},_render(){},renderAsync(t){const e=this.render(t);return this._ready?this._ready.then(()=>e):Promise.resolve(e)},_load(t,e){var n=this,r=n._loader[t](e);if(!n._ready){const i=n._call;n._ready=n._loader.ready().then(a=>{a&&i(),n._ready=null;});}return r},sanitizeURL(t){return this._load("sanitizeURL",t)},loadImage(t){return this._load("loadImage",t)}};const NT="keydown",LT="keypress",PT="keyup",z_="dragenter",vl="dragleave",I_="dragover",zd="mousedown",zT="mouseup",Cf="mousemove",ho="mouseout",U_="mouseover",Df="click",IT="dblclick",UT="wheel",q_="mousewheel",Ff="touchstart",Mf="touchmove",kf="touchend",qT=[NT,LT,PT,z_,vl,I_,zd,zT,Cf,ho,U_,Df,IT,UT,q_,Ff,Mf,kf],Id=Cf,Po=ho,Ud=Df;function bs(t,e){oi.call(this,t,e),this._down=null,this._touch=null,this._first=!0,this._events={};}const jT=t=>t===Ff||t===Mf||t===kf?[Ff,Mf,kf]:[t];function Qx(t,e){jT(e).forEach(n=>WT(t,n));}function WT(t,e){const n=t.canvas();n&&!t._events[e]&&(t._events[e]=1,n.addEventListener(e,t[e]?r=>t[e](r):r=>t.fire(e,r)));}function Zx(t,e,n){return function(r){const i=this._active,a=this.pickEvent(r);a===i?this.fire(t,r):((!i||!i.exit)&&this.fire(n,r),this._active=a,this.fire(e,r),this.fire(t,r));}}function Jx(t){return function(e){this.fire(t,e),this._active=null;}}L(bs,oi,{initialize(t,e,n){return this._canvas=t&&nm(t,"canvas"),[Df,zd,Cf,ho,vl].forEach(r=>Qx(this,r)),oi.prototype.initialize.call(this,t,e,n)},canvas(){return this._canvas},context(){return this._canvas.getContext("2d")},events:qT,DOMMouseScroll(t){this.fire(q_,t);},mousemove:Zx(Cf,U_,ho),dragover:Zx(I_,z_,vl),mouseout:Jx(ho),dragleave:Jx(vl),mousedown(t){this._down=this._active,this.fire(zd,t);},click(t){this._down===this._active&&(this.fire(Df,t),this._down=null);},touchstart(t){this._touch=this.pickEvent(t.changedTouches[0]),this._first&&(this._active=this._touch,this._first=!1),this.fire(Ff,t,!0);},touchmove(t){this.fire(Mf,t,!0);},touchend(t){this.fire(kf,t,!0),this._touch=null;},fire(t,e,n){const r=n?this._touch:this._active,i=this._handlers[t];if(e.vegaType=t,t===Ud&&r&&r.href?this.handleHref(e,r,r.href):(t===Id||t===Po)&&this.handleTooltip(e,r,t!==Po),i)for(let a=0,u=i.length;a=0&&r.splice(i,1),this},pickEvent(t){const e=Jc(t,this._canvas),n=this._origin;return this.pick(this._scene,e[0],e[1],e[0]-n[0],e[1]-n[1])},pick(t,e,n,r,i){const a=this.context();return on[t.marktype].pick.call(this,a,t,e,n,r,i)}});function YT(){return typeof window<"u"&&window.devicePixelRatio||1}var HT=YT();function GT(t,e,n,r,i,a){const u=typeof HTMLElement<"u"&&t instanceof HTMLElement&&t.parentNode!=null,o=t.getContext("2d"),s=u?HT:i;t.width=e*s,t.height=n*s;for(const l in a)o[l]=a[l];return u&&s!==1&&(t.style.width=e+"px",t.style.height=n+"px"),o.pixelRatio=s,o.setTransform(s,0,0,s,s*r[0],s*r[1]),t}function $f(t){ir.call(this,t),this._options={},this._redraw=!1,this._dirty=new St,this._tempb=new St;}const tv=ir.prototype,XT=(t,e,n)=>new St().set(0,0,e,n).translate(-t[0],-t[1]);function VT(t,e,n){return e.expand(1).round(),t.pixelRatio%1&&e.scale(t.pixelRatio).round().scale(1/t.pixelRatio),e.translate(-(n[0]%1),-(n[1]%1)),t.beginPath(),t.rect(e.x1,e.y1,e.width(),e.height()),t.clip(),e}L($f,ir,{initialize(t,e,n,r,i,a){return this._options=a||{},this._canvas=this._options.externalContext?null:Zr(1,1,this._options.type),t&&this._canvas&&(Cn(t,0).appendChild(this._canvas),this._canvas.setAttribute("class","marks")),tv.initialize.call(this,t,e,n,r,i)},resize(t,e,n,r){if(tv.resize.call(this,t,e,n,r),this._canvas)GT(this._canvas,this._width,this._height,this._origin,this._scale,this._options.context);else {const i=this._options.externalContext;i||$("CanvasRenderer is missing a valid canvas or context"),i.scale(this._scale,this._scale),i.translate(this._origin[0],this._origin[1]);}return this._redraw=!0,this},canvas(){return this._canvas},context(){return this._options.externalContext||(this._canvas?this._canvas.getContext("2d"):null)},dirty(t){const e=this._tempb.clear().union(t.bounds);let n=t.mark.group;for(;n;)e.translate(n.x||0,n.y||0),n=n.mark.group;this._dirty.union(e);},_render(t){const e=this.context(),n=this._origin,r=this._width,i=this._height,a=this._dirty,u=XT(n,r,i);e.save();const o=this._redraw||a.empty()?(this._redraw=!1,u.expand(1)):VT(e,u.intersect(a),n);return this.clear(-n[0],-n[1],r,i),this.draw(e,t,o),e.restore(),a.clear(),this},draw(t,e,n){const r=on[e.marktype];e.clip&&HB(t,e),r.draw.call(this,t,e,n),e.clip&&t.restore();},clear(t,e,n,r){const i=this._options,a=this.context();i.type!=="pdf"&&!i.externalContext&&a.clearRect(t,e,n,r),this._bgcolor!=null&&(a.fillStyle=this._bgcolor,a.fillRect(t,e,n,r));}});function rm(t,e){oi.call(this,t,e);const n=this;n._hrefHandler=qd(n,(r,i)=>{i&&i.href&&n.handleHref(r,i,i.href);}),n._tooltipHandler=qd(n,(r,i)=>{n.handleTooltip(r,i,r.type!==Po);});}const qd=(t,e)=>n=>{let r=n.target.__data__;r=Array.isArray(r)?r[0]:r,n.vegaType=n.type,e.call(t._obj,n,r);};L(rm,oi,{initialize(t,e,n){let r=this._svg;return r&&(r.removeEventListener(Ud,this._hrefHandler),r.removeEventListener(Id,this._tooltipHandler),r.removeEventListener(Po,this._tooltipHandler)),this._svg=r=t&&nm(t,"svg"),r&&(r.addEventListener(Ud,this._hrefHandler),r.addEventListener(Id,this._tooltipHandler),r.addEventListener(Po,this._tooltipHandler)),oi.prototype.initialize.call(this,t,e,n)},canvas(){return this._svg},on(t,e){const n=this.eventName(t),r=this._handlers;if(this._handlerIndex(r[n],t,e)<0){const a={type:t,handler:e,listener:qd(this,e)};(r[n]||(r[n]=[])).push(a),this._svg&&this._svg.addEventListener(n,a.listener);}return this},off(t,e){const n=this.eventName(t),r=this._handlers[n],i=this._handlerIndex(r,t,e);return i>=0&&(this._svg&&this._svg.removeEventListener(n,r[i].listener),r.splice(i,1)),this}});const j_="aria-hidden",im="aria-label",am="role",um="aria-roledescription",W_="graphics-object",om="graphics-symbol",Y_=(t,e,n)=>({[am]:t,[um]:e,[im]:n||void 0}),KT=nn(["axis-domain","axis-grid","axis-label","axis-tick","axis-title","legend-band","legend-entry","legend-gradient","legend-label","legend-title","legend-symbol","title"]),ev={axis:{desc:"axis",caption:JT},legend:{desc:"legend",caption:tR},"title-text":{desc:"title",caption:t=>`Title text '${rv(t)}'`},"title-subtitle":{desc:"subtitle",caption:t=>`Subtitle text '${rv(t)}'`}},nv={ariaRole:am,ariaRoleDescription:um,description:im};function H_(t,e){const n=e.aria===!1;if(t(j_,n||void 0),n||e.description==null)for(const r in nv)t(nv[r],void 0);else {const r=e.mark.marktype;t(im,e.description),t(am,e.ariaRole||(r==="group"?W_:om)),t(um,e.ariaRoleDescription||`${r} mark`);}}function G_(t){return t.aria===!1?{[j_]:!0}:KT[t.role]?null:ev[t.role]?ZT(t,ev[t.role]):QT(t)}function QT(t){const e=t.marktype,n=e==="group"||e==="text"||t.items.some(r=>r.description!=null&&r.aria!==!1);return Y_(n?W_:om,`${e} mark container`,t.description)}function ZT(t,e){try{const n=t.items[0],r=e.caption||(()=>"");return Y_(e.role||om,e.desc,n.description||r(n))}catch{return null}}function rv(t){return H(t.text).join(" ")}function JT(t){const e=t.datum,n=t.orient,r=e.title?X_(t):null,i=t.context,a=i.scales[e.scale].value,u=i.dataflow.locale(),o=a.type;return `${n==="left"||n==="right"?"Y":"X"}-axis`+(r?` titled '${r}'`:"")+` for a ${Ya(o)?"discrete":o} scale with ${h_(u,a,t)}`}function tR(t){const e=t.datum,n=e.title?X_(t):null,r=`${e.type||""} legend`.trim(),i=e.scales,a=Object.keys(i),u=t.context,o=u.scales[i[a[0]]].value,s=u.dataflow.locale();return nR(r)+(n?` titled '${n}'`:"")+` for ${eR(a)} with ${h_(s,o,t)}`}function X_(t){try{return H(ut(t.items).items[0].text).join(" ")}catch{return null}}function eR(t){return t=t.map(e=>e+(e==="fill"||e==="stroke"?" color":"")),t.length<2?t[0]:t.slice(0,-1).join(", ")+" and "+ut(t)}function nR(t){return t.length?t[0].toUpperCase()+t.slice(1):t}const V_=t=>(t+"").replace(/&/g,"&").replace(//g,">"),rR=t=>V_(t).replace(/"/g,""").replace(/\t/g," ").replace(/\n/g," ").replace(/\r/g," ");function sm(){let t="",e="",n="";const r=[],i=()=>e=n="",a=s=>{e&&(t+=`${e}>${n}`,i()),r.push(s);},u=(s,l)=>(l!=null&&(e+=` ${s}="${rR(l)}"`),o),o={open(s){a(s),e="<"+s;for(var l=arguments.length,f=new Array(l>1?l-1:0),c=1;c${n}`:"/>"):t+=``,i(),o},attr:u,text:s=>(n+=V_(s),o),toString:()=>t};return o}const K_=t=>Q_(sm(),t)+"";function Q_(t,e){if(t.open(e.tagName),e.hasAttributes()){const n=e.attributes,r=n.length;for(let i=0;i{l.dirty=e;})),!r.zdirty){if(n.exit){a.nested&&r.items.length?(s=r.items[0],s._svg&&this._update(a,s._svg,s)):n._svg&&(s=n._svg.parentNode,s&&s.removeChild(n._svg)),n._svg=null;continue}n=a.nested?r.items[0]:n,n._update!==e&&(!n._svg||!n._svg.ownerSVGElement?(this._dirtyAll=!1,av(n,e)):this._update(a,n._svg,n),n._update=e);}return !this._dirtyAll},mark(t,e,n){if(!this.isDirty(e))return e._svg;const r=this._svg,i=on[e.marktype],a=e.interactive===!1?"none":null,u=i.tag==="g",o=uv(e,t,n,"g",r);o.setAttribute("class",P_(e));const s=G_(e);for(const h in s)ve(o,h,s[h]);u||ve(o,"pointer-events",a),ve(o,"clip-path",e.clip?Pp(this,e,e.group):null);let l=null,f=0;const c=h=>{const d=this.isDirty(h),g=uv(h,o,l,i.tag,r);d&&(this._update(i,g,h),u&&uR(this,g,h)),l=g,++f;};return i.nested?e.items.length&&c(e.items[0]):Tn(e,c),Cn(o,f),o},_update(t,e,n){Ar=e,ue=e.__values__,H_(go,n),t.attr(go,n,this);const r=sR[t.type];r&&r.call(this,t,e,n),Ar&&this.style(Ar,n);},style(t,e){if(e!=null){for(const n in Sf){let r=n==="font"?vs(e):e[n];if(r===ue[n])continue;const i=Sf[n];r==null?t.removeAttribute(i):(Rp(r)&&(r=g_(r,this._defs.gradient,J_())),t.setAttribute(i,r+"")),ue[n]=r;}for(const n in Bf)bl(t,Bf[n],e[n]);}},defs(){const t=this._svg,e=this._defs;let n=e.el,r=0;for(const i in e.gradient)n||(e.el=n=Le(t,Su+1,"defs",Ot)),r=iR(n,e.gradient[i],r);for(const i in e.clipping)n||(e.el=n=Le(t,Su+1,"defs",Ot)),r=aR(n,e.clipping[i],r);n&&(r===0?(t.removeChild(n),e.el=null):Cn(n,r));},_clearDefs(){const t=this._defs;t.gradient={},t.clipping={};}});function av(t,e){for(;t&&t.dirty!==e;t=t.mark.group)if(t.dirty=e,t.mark&&t.mark.dirty!==e)t.mark.dirty=e;else return}function iR(t,e,n){let r,i,a;if(e.gradient==="radial"){let u=Le(t,n++,"pattern",Ot);Yr(u,{id:wf+e.id,viewBox:"0,0,1,1",width:"100%",height:"100%",preserveAspectRatio:"xMidYMid slice"}),u=Le(u,0,"rect",Ot),Yr(u,{width:1,height:1,fill:`url(${J_()}#${e.id})`}),t=Le(t,n++,"radialGradient",Ot),Yr(t,{id:e.id,fx:e.x1,fy:e.y1,fr:e.r1,cx:e.x2,cy:e.y2,r:e.r2});}else t=Le(t,n++,"linearGradient",Ot),Yr(t,{id:e.id,x1:e.x1,x2:e.x2,y1:e.y1,y2:e.y2});for(r=0,i=e.stops.length;r{r=t.mark(e,a,r),++i;}),Cn(e,1+i);}function uv(t,e,n,r,i){let a=t._svg,u;if(!a&&(u=e.ownerDocument,a=Wr(u,r,Ot),t._svg=a,t.mark&&(a.__data__=t,a.__values__={fill:"default"},r==="g"))){const o=Wr(u,"path",Ot);a.appendChild(o),o.__data__=t;const s=Wr(u,"g",Ot);a.appendChild(s),s.__data__=t;const l=Wr(u,"path",Ot);a.appendChild(l),l.__data__=t,l.__values__={fill:"default"};}return (a.ownerSVGElement!==i||oR(a,n))&&e.insertBefore(a,n?n.nextSibling:e.firstChild),a}function oR(t,e){return t.parentNode&&t.parentNode.childNodes.length>1&&t.previousSibling!=e}let Ar=null,ue=null;const sR={group(t,e,n){const r=Ar=e.childNodes[2];ue=r.__values__,t.foreground(go,n,this),ue=e.__values__,Ar=e.childNodes[1],t.content(go,n,this);const i=Ar=e.childNodes[0];t.background(go,n,this);const a=n.mark.interactive===!1?"none":null;if(a!==ue.events&&(ve(r,"pointer-events",a),ve(i,"pointer-events",a),ue.events=a),n.strokeForeground&&n.stroke){const u=n.fill;ve(r,"display",null),this.style(i,n),ve(i,"stroke",null),u&&(n.fill=null),ue=r.__values__,this.style(r,n),u&&(n.fill=u),Ar=null;}else ve(r,"display","none");},image(t,e,n){n.smooth===!1?(bl(e,"image-rendering","optimizeSpeed"),bl(e,"image-rendering","pixelated")):bl(e,"image-rendering",null);},text(t,e,n){const r=xs(n);let i,a,u,o;U(r)?(a=r.map(s=>ui(n,s)),i=a.join(` +`),i!==ue.text&&(Cn(e,0),u=e.ownerDocument,o=ai(n),a.forEach((s,l)=>{const f=Wr(u,"tspan",Ot);f.__data__=n,f.textContent=s,l&&(f.setAttribute("x",0),f.setAttribute("dy",o)),e.appendChild(f);}),ue.text=i)):(a=ui(n,r),a!==ue.text&&(e.textContent=a,ue.text=a)),ve(e,"font-family",vs(n)),ve(e,"font-size",rr(n)+"px"),ve(e,"font-style",n.fontStyle),ve(e,"font-variant",n.fontVariant),ve(e,"font-weight",n.fontWeight);}};function go(t,e,n){e!==ue[t]&&(n?lR(Ar,t,e,n):ve(Ar,t,e),ue[t]=e);}function bl(t,e,n){n!==ue[e]&&(n==null?t.style.removeProperty(e):t.style.setProperty(e,n+""),ue[e]=n);}function Yr(t,e){for(const n in e)ve(t,n,e[n]);}function ve(t,e,n){n!=null?t.setAttribute(e,n):t.removeAttribute(e);}function lR(t,e,n,r){n!=null?t.setAttributeNS(r,e,n):t.removeAttributeNS(r,e);}function J_(){let t;return typeof window>"u"?"":(t=window.location).hash?t.href.slice(0,-t.hash.length):t.href}function fm(t){ir.call(this,t),this._text=null,this._defs={gradient:{},clipping:{}};}L(fm,ir,{svg(){return this._text},_render(t){const e=sm();e.open("svg",nt({},Lo,{class:"marks",width:this._width*this._scale,height:this._height*this._scale,viewBox:`0 0 ${this._width} ${this._height}`}));const n=this._bgcolor;return n&&n!=="transparent"&&n!=="none"&&e.open("rect",{width:this._width,height:this._height,fill:n}).close(),e.open("g",Z_,{transform:"translate("+this._origin+")"}),this.mark(e,t),e.close(),this.defs(e),this._text=e.close()+"",this},mark(t,e){const n=on[e.marktype],r=n.tag,i=[H_,n.attr];t.open("g",{class:P_(e),"clip-path":e.clip?Pp(this,e,e.group):null},G_(e),{"pointer-events":r!=="g"&&e.interactive===!1?"none":null});const a=u=>{const o=this.href(u);if(o&&t.open("a",o),t.open(r,this.attr(e,u,i,r!=="g"?r:null)),r==="text"){const s=xs(u);if(U(s)){const l={x:0,dy:ai(u)};for(let f=0;fthis.mark(t,c)),t.close(),s&&f?(l&&(u.fill=null),u.stroke=f,t.open("path",this.attr(e,u,n.foreground,"bgrect")).close(),l&&(u.fill=l)):t.open("path",this.attr(e,u,n.foreground,"bgfore")).close();}t.close(),o&&t.close();};return n.nested?e.items&&e.items.length&&a(e.items[0]):Tn(e,a),t.close()},href(t){const e=t.href;let n;if(e){if(n=this._hrefs&&this._hrefs[e])return n;this.sanitizeURL(e).then(r=>{r["xlink:href"]=r.href,r.href=null,(this._hrefs||(this._hrefs={}))[e]=r;});}return null},attr(t,e,n,r){const i={},a=(u,o,s,l)=>{i[l||u]=o;};return Array.isArray(n)?n.forEach(u=>u(a,e,this)):n(a,e,this),r&&fR(i,e,t,r,this._defs),i},defs(t){const e=this._defs.gradient,n=this._defs.clipping;if(Object.keys(e).length+Object.keys(n).length!==0){t.open("defs");for(const i in e){const a=e[i],u=a.stops;a.gradient==="radial"?(t.open("pattern",{id:wf+i,viewBox:"0,0,1,1",width:"100%",height:"100%",preserveAspectRatio:"xMidYMid slice"}),t.open("rect",{width:"1",height:"1",fill:"url(#"+i+")"}).close(),t.close(),t.open("radialGradient",{id:i,fx:a.x1,fy:a.y1,fr:a.r1,cx:a.x2,cy:a.y2,r:a.r2})):t.open("linearGradient",{id:i,x1:a.x1,x2:a.x2,y1:a.y1,y2:a.y2});for(let o=0;o1?(Va[t]=e,this):Va[t]}function cm(t,e,n){const r=[],i=new St().union(e),a=t.marktype;return a?iC(t,i,n,r):a==="group"?aC(t,i,n,r):$("Intersect scene must be mark node or group item.")}function iC(t,e,n,r){if(cR(t,e,n)){const i=t.items,a=t.marktype,u=i.length;let o=0;if(a==="group")for(;o=0;a--)if(n[a]!=r[a])return !1;for(a=n.length-1;a>=0;a--)if(i=n[a],!hm(t[i],e[i],i))return !1;return typeof t==typeof e}function gR(){b_(),zS();}const Ka="top",Dn="left",Mn="right",si="bottom",pR="top-left",mR="top-right",yR="bottom-left",xR="bottom-right",dm="start",jd="middle",be="end",vR="x",bR="y",eh="group",gm="axis",pm="title",AR="frame",wR="scope",mm="legend",lC="row-header",fC="row-footer",cC="row-title",hC="column-header",dC="column-footer",gC="column-title",ER="padding",_R="symbol",pC="fit",mC="fit-x",yC="fit-y",CR="pad",ym="none",Qs="all",Wd="each",xm="flush",Gr="column",Xr="row";function xC(t){S.call(this,null,t);}L(xC,S,{transform(t,e){const n=e.dataflow,r=t.mark,i=r.marktype,a=on[i],u=a.bound;let o=r.bounds,s;if(a.nested)r.items.length&&n.dirty(r.items[0]),o=Zs(r,u),r.items.forEach(l=>{l.bounds.clear().union(o);});else if(i===eh||t.modified())switch(e.visit(e.MOD,l=>n.dirty(l)),o.clear(),r.items.forEach(l=>o.union(Zs(l,u))),r.role){case gm:case mm:case pm:e.reflow();}else s=e.changed(e.REM),e.visit(e.ADD,l=>{o.union(Zs(l,u));}),e.visit(e.MOD,l=>{s=s||o.alignsWith(l.bounds),n.dirty(l),o.union(Zs(l,u));}),s&&(o.clear(),r.items.forEach(l=>o.union(l.bounds)));return oC(r),e.modifies("bounds")}});function Zs(t,e,n){return e(t.bounds.clear(),t,n)}const ov=":vega_identifier:";function vm(t){S.call(this,0,t);}vm.Definition={type:"Identifier",metadata:{modifies:!0},params:[{name:"as",type:"string",required:!0}]};L(vm,S,{transform(t,e){const n=DR(e.dataflow),r=t.as;let i=n.value;return e.visit(e.ADD,a=>a[r]=a[r]||++i),n.set(this.value=i),e}});function DR(t){return t._signals[ov]||(t._signals[ov]=t.add(0))}function vC(t){S.call(this,null,t);}L(vC,S,{transform(t,e){let n=this.value;n||(n=e.dataflow.scenegraph().mark(t.markdef,FR(t),t.index),n.group.context=t.context,t.context.group||(t.context.group=n.group),n.source=this.source,n.clip=t.clip,n.interactive=t.interactive,this.value=n);const r=n.marktype===eh?Hc:Yc;return e.visit(e.ADD,i=>r.call(i,n)),(t.modified("clip")||t.modified("interactive"))&&(n.clip=t.clip,n.interactive=!!t.interactive,n.zdirty=!0,e.reflow()),n.items=e.source,e}});function FR(t){const e=t.groups,n=t.parent;return e&&e.size===1?e.get(Object.keys(e.object)[0]):e&&n?e.lookup(n):null}function bC(t){S.call(this,null,t);}const sv={parity:t=>t.filter((e,n)=>n%2?e.opacity=0:1),greedy:(t,e)=>{let n;return t.filter((r,i)=>!i||!AC(n.bounds,r.bounds,e)?(n=r,1):r.opacity=0)}},AC=(t,e,n)=>n>Math.max(e.x1-t.x2,t.x1-e.x2,e.y1-t.y2,t.y1-e.y2),lv=(t,e)=>{for(var n=1,r=t.length,i=t[0].bounds,a;n{const e=t.bounds;return e.width()>1&&e.height()>1},kR=(t,e,n)=>{var r=t.range(),i=new St;return e===Ka||e===si?i.set(r[0],-1/0,r[1],1/0):i.set(-1/0,r[0],1/0,r[1]),i.expand(n||1),a=>i.encloses(a.bounds)},fv=t=>(t.forEach(e=>e.opacity=1),t),cv=(t,e)=>t.reflow(e.modified()).modifies("opacity");L(bC,S,{transform(t,e){const n=sv[t.method]||sv.parity,r=t.separation||0;let i=e.materialize(e.SOURCE).source,a,u;if(!i||!i.length)return;if(!t.method)return t.modified("method")&&(fv(i),e=cv(e,t)),e;if(i=i.filter(MR),!i.length)return;if(t.sort&&(i=i.slice().sort(t.sort)),a=fv(i),e=cv(e,t),a.length>=3&&lv(a,r)){do a=n(a,r);while(a.length>=3&&lv(a,r));a.length<3&&!ut(i).opacity&&(a.length>1&&(ut(a).opacity=0),ut(i).opacity=1);}t.boundScale&&t.boundTolerance>=0&&(u=kR(t.boundScale,t.boundOrient,+t.boundTolerance),i.forEach(s=>{u(s)||(s.opacity=0);}));const o=a[0].mark.bounds.clear();return i.forEach(s=>{s.opacity&&o.union(s.bounds);}),e}});function wC(t){S.call(this,null,t);}L(wC,S,{transform(t,e){const n=e.dataflow;if(e.visit(e.ALL,r=>n.dirty(r)),e.fields&&e.fields.zindex){const r=e.source&&e.source[0];r&&(r.mark.zdirty=!0);}}});const ae=new St;function _a(t,e,n){return t[e]===n?0:(t[e]=n,1)}function $R(t){var e=t.items[0].orient;return e===Dn||e===Mn}function SR(t){let e=+t.grid;return [t.ticks?e++:-1,t.labels?e++:-1,e+ +t.domain]}function BR(t,e,n,r){var i=e.items[0],a=i.datum,u=i.translate!=null?i.translate:.5,o=i.orient,s=SR(a),l=i.range,f=i.offset,c=i.position,h=i.minExtent,d=i.maxExtent,g=a.title&&i.items[s[2]].items[0],p=i.titlePadding,m=i.bounds,y=g&&Zp(g),x=0,v=0,b,w;switch(ae.clear().union(m),m.clear(),(b=s[0])>-1&&m.union(i.items[b].bounds),(b=s[1])>-1&&m.union(i.items[b].bounds),o){case Ka:x=c||0,v=-f,w=Math.max(h,Math.min(d,-m.y1)),m.add(0,-w).add(l,0),g&&Js(t,g,w,p,y,0,-1,m);break;case Dn:x=-f,v=c||0,w=Math.max(h,Math.min(d,-m.x1)),m.add(-w,0).add(0,l),g&&Js(t,g,w,p,y,1,-1,m);break;case Mn:x=n+f,v=c||0,w=Math.max(h,Math.min(d,m.x2)),m.add(0,0).add(w,l),g&&Js(t,g,w,p,y,1,1,m);break;case si:x=c||0,v=r+f,w=Math.max(h,Math.min(d,m.y2)),m.add(0,0).add(l,w),g&&Js(t,g,w,p,0,0,1,m);break;default:x=i.x,v=i.y;}return $r(m.translate(x,v),i),_a(i,"x",x+u)|_a(i,"y",v+u)&&(i.bounds=ae,t.dirty(i),i.bounds=m,t.dirty(i)),i.mark.bounds.clear().union(m)}function Js(t,e,n,r,i,a,u,o){const s=e.bounds;if(e.auto){const l=u*(n+i+r);let f=0,c=0;t.dirty(e),a?f=(e.x||0)-(e.x=l):c=(e.y||0)-(e.y=l),e.mark.bounds.clear().union(s.translate(-f,-c)),t.dirty(e);}o.union(s);}const hv=(t,e)=>Math.floor(Math.min(t,e)),dv=(t,e)=>Math.ceil(Math.max(t,e));function TR(t){var e=t.items,n=e.length,r=0,i,a;const u={marks:[],rowheaders:[],rowfooters:[],colheaders:[],colfooters:[],rowtitle:null,coltitle:null};for(;r1)for(A=0;A0&&(v[A]+=N/2);if(o&&Ct(n.center,Xr)&&f!==1)for(A=0;A0&&(b[A]+=M/2);for(A=0;Ai&&(t.warn("Grid headers exceed limit: "+i),e=e.slice(0,i)),p+=a,x=0,b=e.length;x=0&&(A=n[v])==null;v-=h);o?(_=d==null?A.x:Math.round(A.bounds.x1+d*A.bounds.width()),C=p):(_=p,C=d==null?A.y:Math.round(A.bounds.y1+d*A.bounds.height())),w.union(E.bounds.translate(_-(E.x||0),C-(E.y||0))),E.x=_,E.y=C,t.dirty(E),m=u(m,w[l]);}return m}function pv(t,e,n,r,i,a){if(e){t.dirty(e);var u=n,o=n;r?u=Math.round(i.x1+a*i.width()):o=Math.round(i.y1+a*i.height()),e.bounds.translate(u-(e.x||0),o-(e.y||0)),e.mark.bounds.clear().union(e.bounds),e.x=u,e.y=o,t.dirty(e);}}function zR(t,e){const n=t[e]||{};return (r,i)=>n[r]!=null?n[r]:t[r]!=null?t[r]:i}function IR(t,e){let n=-1/0;return t.forEach(r=>{r.offset!=null&&(n=Math.max(n,r.offset));}),n>-1/0?n:e}function UR(t,e,n,r,i,a,u){const o=zR(n,e),s=IR(t,o("offset",0)),l=o("anchor",dm),f=l===be?1:l===jd?.5:0,c={align:Wd,bounds:o("bounds",xm),columns:o("direction")==="vertical"?1:t.length,padding:o("margin",8),center:o("center"),nodirty:!0};switch(e){case Dn:c.anchor={x:Math.floor(r.x1)-s,column:be,y:f*(u||r.height()+2*r.y1),row:l};break;case Mn:c.anchor={x:Math.ceil(r.x2)+s,y:f*(u||r.height()+2*r.y1),row:l};break;case Ka:c.anchor={y:Math.floor(i.y1)-s,row:be,x:f*(a||i.width()+2*i.x1),column:l};break;case si:c.anchor={y:Math.ceil(i.y2)+s,x:f*(a||i.width()+2*i.x1),column:l};break;case pR:c.anchor={x:s,y:s};break;case mR:c.anchor={x:a-s,y:s,column:be};break;case yR:c.anchor={x:s,y:u-s,row:be};break;case xR:c.anchor={x:a-s,y:u-s,column:be,row:be};break}return c}function qR(t,e){var n=e.items[0],r=n.datum,i=n.orient,a=n.bounds,u=n.x,o=n.y,s,l;return n._bounds?n._bounds.clear().union(a):n._bounds=a.clone(),a.clear(),WR(t,n,n.items[0].items[0]),a=jR(n,a),s=2*n.padding,l=2*n.padding,a.empty()||(s=Math.ceil(a.width()+s),l=Math.ceil(a.height()+l)),r.type===_R&&YR(n.items[0].items[0].items[0].items),i!==ym&&(n.x=u=0,n.y=o=0),n.width=s,n.height=l,$r(a.set(u,o,u+s,o+l),n),n.mark.bounds.clear().union(a),n}function jR(t,e){return t.items.forEach(n=>e.union(n.bounds)),e.x1=t.padding,e.y1=t.padding,e}function WR(t,e,n){var r=e.padding,i=r-n.x,a=r-n.y;if(!e.datum.title)(i||a)&&Bu(t,n,i,a);else {var u=e.items[1].items[0],o=u.anchor,s=e.titlePadding||0,l=r-u.x,f=r-u.y;switch(u.orient){case Dn:i+=Math.ceil(u.bounds.width())+s;break;case Mn:case si:break;default:a+=u.bounds.height()+s;}switch((i||a)&&Bu(t,n,i,a),u.orient){case Dn:f+=ga(e,n,u,o,1,1);break;case Mn:l+=ga(e,n,u,be,0,0)+s,f+=ga(e,n,u,o,1,1);break;case si:l+=ga(e,n,u,o,0,0),f+=ga(e,n,u,be,-1,0,1)+s;break;default:l+=ga(e,n,u,o,0,0);}(l||f)&&Bu(t,u,l,f),(l=Math.round(u.bounds.x1-r))<0&&(Bu(t,n,-l,0),Bu(t,u,-l,0));}}function ga(t,e,n,r,i,a,u){const o=t.datum.type!=="symbol",s=n.datum.vgrad,l=o&&(a||!s)&&!u?e.items[0]:e,f=l.bounds[i?"y2":"x2"]-t.padding,c=s&&a?f:0,h=s&&a?0:f,d=i<=0?0:Zp(n);return Math.round(r===dm?c:r===be?h-d:.5*(f-d))}function Bu(t,e,n,r){e.x+=n,e.y+=r,e.bounds.translate(n,r),e.mark.bounds.translate(n,r),t.dirty(e);}function YR(t){const e=t.reduce((n,r)=>(n[r.column]=Math.max(r.bounds.x2-r.x,n[r.column]||0),n),{});t.forEach(n=>{n.width=e[n.column],n.height=n.bounds.y2-n.y;});}function HR(t,e,n,r,i){var a=e.items[0],u=a.frame,o=a.orient,s=a.anchor,l=a.offset,f=a.padding,c=a.items[0].items[0],h=a.items[1]&&a.items[1].items[0],d=o===Dn||o===Mn?r:n,g=0,p=0,m=0,y=0,x=0,v;if(u!==eh?o===Dn?(g=i.y2,d=i.y1):o===Mn?(g=i.y1,d=i.y2):(g=i.x1,d=i.x2):o===Dn&&(g=r,d=0),v=s===dm?g:s===be?d:(g+d)/2,h&&h.text){switch(o){case Ka:case si:x=c.bounds.height()+f;break;case Dn:y=c.bounds.width()+f;break;case Mn:y=-c.bounds.width()-f;break}ae.clear().union(h.bounds),ae.translate(y-(h.x||0),x-(h.y||0)),_a(h,"x",y)|_a(h,"y",x)&&(t.dirty(h),h.bounds.clear().union(ae),h.mark.bounds.clear().union(ae),t.dirty(h)),ae.clear().union(h.bounds);}else ae.clear();switch(ae.union(c.bounds),o){case Ka:p=v,m=i.y1-ae.height()-l;break;case Dn:p=i.x1-ae.width()-l,m=v;break;case Mn:p=i.x2+ae.width()+l,m=v;break;case si:p=v,m=i.y2+l;break;default:p=a.x,m=a.y;}return _a(a,"x",p)|_a(a,"y",m)&&(ae.translate(p,m),t.dirty(a),a.bounds.clear().union(ae),e.bounds.clear().union(ae),t.dirty(a)),a.bounds}function _C(t){S.call(this,null,t);}L(_C,S,{transform(t,e){const n=e.dataflow;return t.mark.items.forEach(r=>{t.layout&&NR(n,r,t.layout),XR(n,r,t);}),GR(t.mark.group)?e.reflow():e}});function GR(t){return t&&t.mark.role!=="legend-entry"}function XR(t,e,n){var r=e.items,i=Math.max(0,e.width||0),a=Math.max(0,e.height||0),u=new St().set(0,0,i,a),o=u.clone(),s=u.clone(),l=[],f,c,h,d,g,p;for(g=0,p=r.length;g{h=y.orient||Mn,h!==ym&&(m[h]||(m[h]=[])).push(y);});for(const y in m){const x=m[y];EC(t,x,UR(x,y,n.legends,o,s,i,a));}l.forEach(y=>{const x=y.bounds;if(x.equals(y._bounds)||(y.bounds=y._bounds,t.dirty(y),y.bounds=x,t.dirty(y)),n.autosize&&(n.autosize.type===pC||n.autosize.type===mC||n.autosize.type===yC))switch(y.orient){case Dn:case Mn:u.add(x.x1,0).add(x.x2,0);break;case Ka:case si:u.add(0,x.y1).add(0,x.y2);}else u.union(x);});}u.union(o).union(s),f&&u.union(HR(t,f,i,a,u)),e.clip&&u.set(0,0,e.width||0,e.height||0),VR(t,e,u,n);}function VR(t,e,n,r){const i=r.autosize||{},a=i.type;if(t._autosize<1||!a)return;let u=t._width,o=t._height,s=Math.max(0,e.width||0),l=Math.max(0,Math.ceil(-n.x1)),f=Math.max(0,e.height||0),c=Math.max(0,Math.ceil(-n.y1));const h=Math.max(0,Math.ceil(n.x2-s)),d=Math.max(0,Math.ceil(n.y2-f));if(i.contains===ER){const g=t.padding();u-=g.left+g.right,o-=g.top+g.bottom;}a===ym?(l=0,c=0,s=u,f=o):a===pC?(s=Math.max(0,u-l-h),f=Math.max(0,o-c-d)):a===mC?(s=Math.max(0,u-l-h),o=f+c+d):a===yC?(u=s+l+h,f=Math.max(0,o-c-d)):a===CR&&(u=s+l+h,o=f+c+d),t._resizeView(u,o,s,f,[l,c],i.resize);}const KR=Object.freeze(Object.defineProperty({__proto__:null,bound:xC,identifier:vm,mark:vC,overlap:bC,render:wC,viewlayout:_C},Symbol.toStringTag,{value:"Module"}));function CC(t){S.call(this,null,t);}L(CC,S,{transform(t,e){if(this.value&&!t.modified())return e.StopPropagation;var n=e.dataflow.locale(),r=e.fork(e.NO_SOURCE|e.NO_FIELDS),i=this.value,a=t.scale,u=t.count==null?t.values?t.values.length:10:t.count,o=Bp(a,u,t.minstep),s=t.format||o_(n,a,o,t.formatSpecifier,t.formatType,!!t.values),l=t.values?u_(a,t.values,o):Tp(a,o);return i&&(r.rem=i),i=l.map((f,c)=>gt({index:c/(l.length-1||1),value:f,label:s(f)})),t.extra&&i.length&&i.push(gt({index:-1,extra:{value:i[0].value},label:""})),r.source=i,r.add=i,this.value=i,r}});function DC(t){S.call(this,null,t);}function QR(){return gt({})}function ZR(t){const e=iu().test(n=>n.exit);return e.lookup=n=>e.get(t(n)),e}L(DC,S,{transform(t,e){var n=e.dataflow,r=e.fork(e.NO_SOURCE|e.NO_FIELDS),i=t.item||QR,a=t.key||K,u=this.value;return U(r.encode)&&(r.encode=null),u&&(t.modified("key")||e.modified(a))&&$("DataJoin does not support modified key function or fields."),u||(e=e.addAll(),this.value=u=ZR(a)),e.visit(e.ADD,o=>{const s=a(o);let l=u.get(s);l?l.exit?(u.empty--,r.add.push(l)):r.mod.push(l):(l=i(o),u.set(s,l),r.add.push(l)),l.datum=o,l.exit=!1;}),e.visit(e.MOD,o=>{const s=a(o),l=u.get(s);l&&(l.datum=o,r.mod.push(l));}),e.visit(e.REM,o=>{const s=a(o),l=u.get(s);o===l.datum&&!l.exit&&(r.rem.push(l),l.exit=!0,++u.empty);}),e.changed(e.ADD_MOD)&&r.modifies("datum"),(e.clean()||t.clean&&u.empty>n.cleanThreshold)&&n.runAfter(u.clean),r}});function FC(t){S.call(this,null,t);}L(FC,S,{transform(t,e){var n=e.fork(e.ADD_REM),r=t.mod||!1,i=t.encoders,a=e.encode;if(U(a))if(n.changed()||a.every(c=>i[c]))a=a[0],n.encode=null;else return e.StopPropagation;var u=a==="enter",o=i.update||Rr,s=i.enter||Rr,l=i.exit||Rr,f=(a&&!u?i[a]:o)||Rr;if(e.changed(e.ADD)&&(e.visit(e.ADD,c=>{s(c,t),o(c,t);}),n.modifies(s.output),n.modifies(o.output),f!==Rr&&f!==o&&(e.visit(e.ADD,c=>{f(c,t);}),n.modifies(f.output))),e.changed(e.REM)&&l!==Rr&&(e.visit(e.REM,c=>{l(c,t);}),n.modifies(l.output)),u||f!==Rr){const c=e.MOD|(t.modified()?e.REFLOW:0);u?(e.visit(c,h=>{const d=s(h,t)||r;(f(h,t)||d)&&n.mod.push(h);}),n.mod.length&&n.modifies(s.output)):e.visit(c,h=>{(f(h,t)||r)&&n.mod.push(h);}),n.mod.length&&n.modifies(f.output);}return n.changed()?n:e.StopPropagation}});function MC(t){S.call(this,[],t);}L(MC,S,{transform(t,e){if(this.value!=null&&!t.modified())return e.StopPropagation;var n=e.dataflow.locale(),r=e.fork(e.NO_SOURCE|e.NO_FIELDS),i=this.value,a=t.type||dl,u=t.scale,o=+t.limit,s=Bp(u,t.count==null?5:t.count,t.minstep),l=!!t.values||a===dl,f=t.format||c_(n,u,s,a,t.formatSpecifier,t.formatType,l),c=t.values||f_(u,s),h,d,g,p,m;return i&&(r.rem=i),a===dl?(o&&c.length>o?(e.dataflow.warn("Symbol legend count exceeds limit, filtering items."),i=c.slice(0,o-1),m=!0):i=c,tt(g=t.size)?(!t.values&&u(i[0])===0&&(i=i.slice(1)),p=i.reduce((y,x)=>Math.max(y,g(x,t)),0)):g=pe(p=g||8),i=i.map((y,x)=>gt({index:x,label:f(y,x,i),value:y,offset:p,size:g(y,t)})),m&&(m=c[i.length],i.push(gt({index:i.length,label:`…${c.length-i.length} entries`,value:m,offset:p,size:g(m,t)})))):a===DS?(h=u.domain(),d=kp(u,h[0],ut(h)),c.length<3&&!t.values&&h[0]!==ut(h)&&(c=[h[0],ut(h)]),i=c.map((y,x)=>gt({index:x,label:f(y,x,c),value:y,perc:d(y)}))):(g=c.length-1,d=LS(u),i=c.map((y,x)=>gt({index:x,label:f(y,x,c),value:y,perc:x?d(y):0,perc2:x===g?1:d(c[x+1])}))),r.source=i,r.add=i,this.value=i,r}});const JR=t=>t.source.x,tO=t=>t.source.y,eO=t=>t.target.x,nO=t=>t.target.y;function bm(t){S.call(this,{},t);}bm.Definition={type:"LinkPath",metadata:{modifies:!0},params:[{name:"sourceX",type:"field",default:"source.x"},{name:"sourceY",type:"field",default:"source.y"},{name:"targetX",type:"field",default:"target.x"},{name:"targetY",type:"field",default:"target.y"},{name:"orient",type:"enum",default:"vertical",values:["horizontal","vertical","radial"]},{name:"shape",type:"enum",default:"line",values:["line","arc","curve","diagonal","orthogonal"]},{name:"require",type:"signal"},{name:"as",type:"string",default:"path"}]};L(bm,S,{transform(t,e){var n=t.sourceX||JR,r=t.sourceY||tO,i=t.targetX||eO,a=t.targetY||nO,u=t.as||"path",o=t.orient||"vertical",s=t.shape||"line",l=mv.get(s+"-"+o)||mv.get(s);return l||$("LinkPath unsupported type: "+t.shape+(t.orient?"-"+t.orient:"")),e.visit(e.SOURCE,f=>{f[u]=l(n(f),r(f),i(f),a(f));}),e.reflow(t.modified()).modifies(u)}});const kC=(t,e,n,r)=>"M"+t+","+e+"L"+n+","+r,rO=(t,e,n,r)=>kC(e*Math.cos(t),e*Math.sin(t),r*Math.cos(n),r*Math.sin(n)),$C=(t,e,n,r)=>{var i=n-t,a=r-e,u=Math.hypot(i,a)/2,o=180*Math.atan2(a,i)/Math.PI;return "M"+t+","+e+"A"+u+","+u+" "+o+" 0 1 "+n+","+r},iO=(t,e,n,r)=>$C(e*Math.cos(t),e*Math.sin(t),r*Math.cos(n),r*Math.sin(n)),SC=(t,e,n,r)=>{const i=n-t,a=r-e,u=.2*(i+a),o=.2*(a-i);return "M"+t+","+e+"C"+(t+u)+","+(e+o)+" "+(n+o)+","+(r-u)+" "+n+","+r},aO=(t,e,n,r)=>SC(e*Math.cos(t),e*Math.sin(t),r*Math.cos(n),r*Math.sin(n)),uO=(t,e,n,r)=>"M"+t+","+e+"V"+r+"H"+n,oO=(t,e,n,r)=>"M"+t+","+e+"H"+n+"V"+r,sO=(t,e,n,r)=>{const i=Math.cos(t),a=Math.sin(t),u=Math.cos(n),o=Math.sin(n),s=Math.abs(n-t)>Math.PI?n<=t:n>t;return "M"+e*i+","+e*a+"A"+e+","+e+" 0 0,"+(s?1:0)+" "+e*u+","+e*o+"L"+r*u+","+r*o},lO=(t,e,n,r)=>{const i=(t+n)/2;return "M"+t+","+e+"C"+i+","+e+" "+i+","+r+" "+n+","+r},fO=(t,e,n,r)=>{const i=(e+r)/2;return "M"+t+","+e+"C"+t+","+i+" "+n+","+i+" "+n+","+r},cO=(t,e,n,r)=>{const i=Math.cos(t),a=Math.sin(t),u=Math.cos(n),o=Math.sin(n),s=(e+r)/2;return "M"+e*i+","+e*a+"C"+s*i+","+s*a+" "+s*u+","+s*o+" "+r*u+","+r*o},mv=iu({line:kC,"line-radial":rO,arc:$C,"arc-radial":iO,curve:SC,"curve-radial":aO,"orthogonal-horizontal":uO,"orthogonal-vertical":oO,"orthogonal-radial":sO,"diagonal-horizontal":lO,"diagonal-vertical":fO,"diagonal-radial":cO});function Am(t){S.call(this,null,t);}Am.Definition={type:"Pie",metadata:{modifies:!0},params:[{name:"field",type:"field"},{name:"startAngle",type:"number",default:0},{name:"endAngle",type:"number",default:6.283185307179586},{name:"sort",type:"boolean",default:!1},{name:"as",type:"string",array:!0,length:2,default:["startAngle","endAngle"]}]};L(Am,S,{transform(t,e){var n=t.as||["startAngle","endAngle"],r=n[0],i=n[1],a=t.field||ru,u=t.startAngle||0,o=t.endAngle!=null?t.endAngle:2*Math.PI,s=e.source,l=s.map(a),f=l.length,c=u,h=(o-u)/qb(l),d=Ie(f),g,p,m;for(t.sort&&d.sort((y,x)=>l[y]-l[x]),g=0;g-1)return r;var i=e.domain,a=t.type,u=e.zero||e.zero===void 0&&dO(t),o,s;if(!i)return 0;if(BC(a)&&e.padding&&i[0]!==ut(i)&&(i=vO(a,i,e.range,e.padding,e.exponent,e.constant)),(u||e.domainMin!=null||e.domainMax!=null||e.domainMid!=null)&&(o=(i=i.slice()).length-1||1,u&&(i[0]>0&&(i[0]=0),i[o]<0&&(i[o]=0)),e.domainMin!=null&&(i[0]=e.domainMin),e.domainMax!=null&&(i[o]=e.domainMax),e.domainMid!=null)){s=e.domainMid;const l=s>i[o]?o+1:si+(a<0?-1:a>0?1:0),0));r!==e.length&&n.warn("Log scale domain includes zero: "+Y(e));}return e}function bO(t,e,n){let r=e.bins;if(r&&!U(r)){const i=t.domain(),a=i[0],u=ut(i),o=r.step;let s=r.start==null?a:r.start,l=r.stop==null?u:r.stop;o||$("Scale bins parameter missing step property."),su&&(l=o*Math.floor(u/o)),r=Ie(s,l+o/2,o);}return r?t.bins=r:t.bins&&delete t.bins,t.type===Cp&&(r?!e.domain&&!e.domainRaw&&(t.domain(r),n=r.length):t.bins=t.domain()),n}function AO(t,e,n){var r=t.type,i=e.round||!1,a=e.range;if(e.rangeStep!=null)a=wO(r,e,n);else if(e.scheme&&(a=EO(r,e,n),tt(a))){if(t.interpolator)return t.interpolator(a);$(`Scale type ${r} does not support interpolating color schemes.`);}if(a&&t_(r))return t.interpolator(jc(Yd(a,e.reverse),e.interpolate,e.interpolateGamma));a&&e.interpolate&&t.interpolate?t.interpolate($p(e.interpolate,e.interpolateGamma)):tt(t.round)?t.round(i):tt(t.rangeRound)&&t.interpolate(i?Ko:ci),a&&t.range(Yd(a,e.reverse));}function wO(t,e,n){t!==HE&&t!==$d&&$("Only band and point scales support rangeStep.");var r=(e.paddingOuter!=null?e.paddingOuter:e.padding)||0,i=t===$d?1:(e.paddingInner!=null?e.paddingInner:e.padding)||0;return [0,e.rangeStep*zc(n,i,r)]}function EO(t,e,n){var r=e.schemeExtent,i,a;return U(e.scheme)?a=jc(e.scheme,e.interpolate,e.interpolateGamma):(i=e.scheme.toLowerCase(),a=Sp(i),a||$(`Unrecognized scheme name: ${e.scheme}`)),n=t===qc?n+1:t===Cp?n-1:t===Wa||t===Uc?+e.schemeCount||hO:n,t_(t)?yv(a,r,e.reverse):tt(a)?r_(yv(a,r),n):t===_p?a:a.slice(0,n)}function yv(t,e,n){return tt(t)&&(e||n)?n_(t,Yd(e||[0,1],n)):t}function Yd(t,e){return e?t.slice().reverse():t}function OC(t){S.call(this,null,t);}L(OC,S,{transform(t,e){const n=t.modified("sort")||e.changed(e.ADD)||e.modified(t.sort.fields)||e.modified("datum");return n&&e.source.sort(na(t.sort)),this.modified(n),e}});const xv="zero",NC="center",LC="normalize",PC=["y0","y1"];function wm(t){S.call(this,null,t);}wm.Definition={type:"Stack",metadata:{modifies:!0},params:[{name:"field",type:"field"},{name:"groupby",type:"field",array:!0},{name:"sort",type:"compare"},{name:"offset",type:"enum",default:xv,values:[xv,NC,LC]},{name:"as",type:"string",array:!0,length:2,default:PC}]};L(wm,S,{transform(t,e){var n=t.as||PC,r=n[0],i=n[1],a=na(t.sort),u=t.field||ru,o=t.offset===NC?_O:t.offset===LC?CO:DO,s,l,f,c;for(s=FO(e.source,t.groupby,a,u),l=0,f=s.length,c=s.max;lp(f),u,o,s,l,f,c,h,d,g;if(e==null)i.push(t.slice());else for(u={},o=0,s=t.length;og&&(g=d),n&&h.sort(n);}return i.max=g,i}const MO=Object.freeze(Object.defineProperty({__proto__:null,axisticks:CC,datajoin:DC,encode:FC,legendentries:MC,linkpath:bm,pie:Am,scale:TC,sortitems:OC,stack:wm},Symbol.toStringTag,{value:"Module"}));var kO=Math.abs,Hd=Math.cos,Tf=Math.sin,$O=1e-6,zC=Math.PI,Gd=zC/2,vv=SO(2);function bv(t){return t>1?Gd:t<-1?-Gd:Math.asin(t)}function SO(t){return Math.sqrt(t)}function BO(t,e){var n=t*Tf(e),r=30,i;do e-=i=(e+Tf(e)-n)/(1+Hd(e));while(kO(i)>$O&&--r>0);return e/2}function TO(t,e,n){function r(i,a){return [t*i*Hd(a=BO(n,a)),e*Tf(a)]}return r.invert=function(i,a){return a=bv(a/e),[i/(t*Hd(a)),bv((2*a+Tf(2*a))/n)]},r}var RO=TO(vv/Gd,vv,zC);function OO(){return er(RO).scale(169.529)}const NO=nw(),Xd=["clipAngle","clipExtent","scale","translate","center","rotate","parallels","precision","reflectX","reflectY","coefficient","distance","fraction","lobes","parallel","radius","ratio","spacing","tilt"];function LO(t,e){return function n(){const r=e();return r.type=t,r.path=nw().projection(r),r.copy=r.copy||function(){const i=n();return Xd.forEach(a=>{r[a]&&i[a](r[a]());}),i.path.pointRadius(r.path.pointRadius()),i},KE(r)}}function Em(t,e){if(!t||typeof t!="string")throw new Error("Projection type must be a name string.");return t=t.toLowerCase(),arguments.length>1?(Rf[t]=LO(t,e),this):Rf[t]||null}function IC(t){return t&&t.path||NO}const Rf={albers:iw,albersusa:W6,azimuthalequalarea:Y6,azimuthalequidistant:H6,conicconformal:V6,conicequalarea:of,conicequidistant:Z6,equalEarth:tk,equirectangular:K6,gnomonic:ek,identity:nk,mercator:G6,mollweide:OO,naturalEarth1:rk,orthographic:ik,stereographic:ak,transversemercator:uk};for(const t in Rf)Em(t,Rf[t]);function PO(){}const lr=[[],[[[1,1.5],[.5,1]]],[[[1.5,1],[1,1.5]]],[[[1.5,1],[.5,1]]],[[[1,.5],[1.5,1]]],[[[1,1.5],[.5,1]],[[1,.5],[1.5,1]]],[[[1,.5],[1,1.5]]],[[[1,.5],[.5,1]]],[[[.5,1],[1,.5]]],[[[1,1.5],[1,.5]]],[[[.5,1],[1,.5]],[[1.5,1],[1,1.5]]],[[[1.5,1],[1,.5]]],[[[.5,1],[1.5,1]]],[[[1,1.5],[1.5,1]]],[[[.5,1],[1,1.5]]],[]];function UC(){var t=1,e=1,n=o;function r(s,l){return l.map(f=>i(s,f))}function i(s,l){var f=[],c=[];return a(s,l,h=>{n(h,s,l),zO(h)>0?f.push([h]):c.push(h);}),c.forEach(h=>{for(var d=0,g=f.length,p;d=l,lr[m<<1].forEach(v);++d=l,lr[p|m<<1].forEach(v);for(lr[m<<0].forEach(v);++g=l,y=s[g*t]>=l,lr[m<<1|y<<2].forEach(v);++d=l,x=y,y=s[g*t+d+1]>=l,lr[p|m<<1|y<<2|x<<3].forEach(v);lr[m|y<<3].forEach(v);}for(d=-1,y=s[g*t]>=l,lr[y<<2].forEach(v);++d=l,lr[y<<2|x<<3].forEach(v);lr[y<<3].forEach(v);function v(b){var w=[b[0][0]+d,b[0][1]+g],E=[b[1][0]+d,b[1][1]+g],A=u(w),_=u(E),C,F;(C=h[A])?(F=c[_])?(delete h[C.end],delete c[F.start],C===F?(C.ring.push(E),f(C.ring)):c[C.start]=h[F.end]={start:C.start,end:F.end,ring:C.ring.concat(F.ring)}):(delete h[C.end],C.ring.push(E),h[C.end=_]=C):(C=c[_])?(F=h[A])?(delete c[C.start],delete h[F.end],C===F?(C.ring.push(E),f(C.ring)):c[F.start]=h[C.end]={start:F.start,end:C.end,ring:F.ring.concat(C.ring)}):(delete c[C.start],C.ring.unshift(w),c[C.start=A]=C):c[A]=h[_]={start:A,end:_,ring:[w,E]};}}function u(s){return s[0]*2+s[1]*(t+1)*4}function o(s,l,f){s.forEach(c=>{var h=c[0],d=c[1],g=h|0,p=d|0,m,y=l[p*t+g];h>0&&h0&&d=0&&f>=0||$("invalid size"),t=l,e=f,r},r.smooth=function(s){return arguments.length?(n=s?o:PO,r):n===o},r}function zO(t){for(var e=0,n=t.length,r=t[n-1][1]*t[0][0]-t[n-1][0]*t[0][1];++er!=d>r&&n<(h-l)*(r-f)/(d-f)+l&&(i=-i);}return i}function qO(t,e,n){var r;return jO(t,e,n)&&WO(t[r=+(t[0]===e[0])],n[r],e[r])}function jO(t,e,n){return (e[0]-t[0])*(n[1]-t[1])===(n[0]-t[0])*(e[1]-t[1])}function WO(t,e,n){return t<=e&&e<=n||n<=e&&e<=t}function qC(t,e,n){return function(r){var i=Sn(r),a=n?Math.min(i[0],0):i[0],u=i[1],o=u-a,s=e?ei(a,u,t):o/(t+1);return Ie(a+s,u,s)}}function _m(t){S.call(this,null,t);}_m.Definition={type:"Isocontour",metadata:{generates:!0},params:[{name:"field",type:"field"},{name:"thresholds",type:"number",array:!0},{name:"levels",type:"number"},{name:"nice",type:"boolean",default:!1},{name:"resolve",type:"enum",values:["shared","independent"],default:"independent"},{name:"zero",type:"boolean",default:!0},{name:"smooth",type:"boolean",default:!0},{name:"scale",type:"number",expr:!0},{name:"translate",type:"number",array:!0,expr:!0},{name:"as",type:"string",null:!0,default:"contour"}]};L(_m,S,{transform(t,e){if(this.value&&!e.changed()&&!t.modified())return e.StopPropagation;var n=e.fork(e.NO_SOURCE|e.NO_FIELDS),r=e.materialize(e.SOURCE).source,i=t.field||ge,a=UC().smooth(t.smooth!==!1),u=t.thresholds||YO(r,i,t),o=t.as===null?null:t.as||"contour",s=[];return r.forEach(l=>{const f=i(l),c=a.size([f.width,f.height])(f.values,U(u)?u:u(f.values));HO(c,f,l,t),c.forEach(h=>{s.push(_c(l,gt(o!=null?{[o]:h}:h)));});}),this.value&&(n.rem=this.value),this.value=n.source=n.add=s,n}});function YO(t,e,n){const r=qC(n.levels||10,n.nice,n.zero!==!1);return n.resolve!=="shared"?r:r(t.map(i=>Ri(e(i).values)))}function HO(t,e,n,r){let i=r.scale||e.scale,a=r.translate||e.translate;if(tt(i)&&(i=i(n,r)),tt(a)&&(a=a(n,r)),(i===1||i==null)&&!a)return;const u=(Mr(i)?i:i[0])||1,o=(Mr(i)?i:i[1])||1,s=a&&a[0]||0,l=a&&a[1]||0;t.forEach(jC(e,u,o,s,l));}function jC(t,e,n,r,i){const a=t.x1||0,u=t.y1||0,o=e*n<0;function s(c){c.forEach(l);}function l(c){o&&c.reverse(),c.forEach(f);}function f(c){c[0]=(c[0]-a)*e+r,c[1]=(c[1]-u)*n+i;}return function(c){return c.coordinates.forEach(s),c}}function Av(t,e,n){const r=t>=0?t:Xg(e,n);return Math.round((Math.sqrt(4*r*r+1)-1)/2)}function s0(t){return tt(t)?t:pe(+t)}function WC(){var t=s=>s[0],e=s=>s[1],n=ru,r=[-1,-1],i=960,a=500,u=2;function o(s,l){const f=Av(r[0],s,t)>>u,c=Av(r[1],s,e)>>u,h=f?f+2:0,d=c?c+2:0,g=2*h+(i>>u),p=2*d+(a>>u),m=new Float32Array(g*p),y=new Float32Array(g*p);let x=m;s.forEach(b=>{const w=h+(+t(b)>>u),E=d+(+e(b)>>u);w>=0&&w=0&&E0&&c>0?(pa(g,p,m,y,f),ma(g,p,y,m,c),pa(g,p,m,y,f),ma(g,p,y,m,c),pa(g,p,m,y,f),ma(g,p,y,m,c)):f>0?(pa(g,p,m,y,f),pa(g,p,y,m,f),pa(g,p,m,y,f),x=y):c>0&&(ma(g,p,m,y,c),ma(g,p,y,m,c),ma(g,p,m,y,c),x=y);const v=l?Math.pow(2,-2*u):1/qb(x);for(let b=0,w=g*p;b>u),y2:d+(a>>u)}}return o.x=function(s){return arguments.length?(t=s0(s),o):t},o.y=function(s){return arguments.length?(e=s0(s),o):e},o.weight=function(s){return arguments.length?(n=s0(s),o):n},o.size=function(s){if(!arguments.length)return [i,a];var l=+s[0],f=+s[1];return l>=0&&f>=0||$("invalid size"),i=l,a=f,o},o.cellSize=function(s){return arguments.length?((s=+s)>=1||$("invalid cell size"),u=Math.floor(Math.log(s)/Math.LN2),o):1<=i&&(o>=a&&(s-=n[o-a+u*t]),r[o-i+u*t]=s/Math.min(o+1,t-1+a-o,a));}function ma(t,e,n,r,i){const a=(i<<1)+1;for(let u=0;u=i&&(o>=a&&(s-=n[u+(o-a)*t]),r[u+(o-i)*t]=s/Math.min(o+1,e-1+a-o,a));}function Cm(t){S.call(this,null,t);}Cm.Definition={type:"KDE2D",metadata:{generates:!0},params:[{name:"size",type:"number",array:!0,length:2,required:!0},{name:"x",type:"field",required:!0},{name:"y",type:"field",required:!0},{name:"weight",type:"field"},{name:"groupby",type:"field",array:!0},{name:"cellSize",type:"number"},{name:"bandwidth",type:"number",array:!0,length:2},{name:"counts",type:"boolean",default:!1},{name:"as",type:"string",default:"grid"}]};const GO=["x","y","weight","size","cellSize","bandwidth"];function YC(t,e){return GO.forEach(n=>e[n]!=null?t[n](e[n]):0),t}L(Cm,S,{transform(t,e){if(this.value&&!e.changed()&&!t.modified())return e.StopPropagation;var n=e.fork(e.NO_SOURCE|e.NO_FIELDS),r=e.materialize(e.SOURCE).source,i=XO(r,t.groupby),a=(t.groupby||[]).map($t),u=YC(WC(),t),o=t.as||"grid",s=[];function l(f,c){for(let h=0;hgt(l({[o]:u(f,t.counts)},f.dims))),this.value&&(n.rem=this.value),this.value=n.source=n.add=s,n}});function XO(t,e){var n=[],r=f=>f(o),i,a,u,o,s,l;if(e==null)n.push(t);else for(i={},a=0,u=t.length;an.push(o(f))),a&&u&&(e.visit(s,f=>{var c=a(f),h=u(f);c!=null&&h!=null&&(c=+c)===c&&(h=+h)===h&&r.push([c,h]);}),n=n.concat({type:Vd,geometry:{type:VO,coordinates:r}})),this.value={type:Fm,features:n};}});function km(t){S.call(this,null,t);}km.Definition={type:"GeoPath",metadata:{modifies:!0},params:[{name:"projection",type:"projection"},{name:"field",type:"field"},{name:"pointRadius",type:"number",expr:!0},{name:"as",type:"string",default:"path"}]};L(km,S,{transform(t,e){var n=e.fork(e.ALL),r=this.value,i=t.field||ge,a=t.as||"path",u=n.SOURCE;!r||t.modified()?(this.value=r=IC(t.projection),n.materialize().reflow()):u=i===ge||e.modified(i.fields)?n.ADD_MOD:n.ADD;const o=KO(r,t.pointRadius);return n.visit(u,s=>s[a]=r(i(s))),r.pointRadius(o),n.modifies(a)}});function KO(t,e){const n=t.pointRadius();return t.context(null),e!=null&&t.pointRadius(e),n}function $m(t){S.call(this,null,t);}$m.Definition={type:"GeoPoint",metadata:{modifies:!0},params:[{name:"projection",type:"projection",required:!0},{name:"fields",type:"field",array:!0,required:!0,length:2},{name:"as",type:"string",array:!0,length:2,default:["x","y"]}]};L($m,S,{transform(t,e){var n=t.projection,r=t.fields[0],i=t.fields[1],a=t.as||["x","y"],u=a[0],o=a[1],s;function l(f){const c=n([r(f),i(f)]);c?(f[u]=c[0],f[o]=c[1]):(f[u]=void 0,f[o]=void 0);}return t.modified()?e=e.materialize().reflow(!0).visit(e.SOURCE,l):(s=e.modified(r.fields)||e.modified(i.fields),e.visit(s?e.ADD_MOD:e.ADD,l)),e.modifies(a)}});function Sm(t){S.call(this,null,t);}Sm.Definition={type:"GeoShape",metadata:{modifies:!0,nomod:!0},params:[{name:"projection",type:"projection"},{name:"field",type:"field",default:"datum"},{name:"pointRadius",type:"number",expr:!0},{name:"as",type:"string",default:"shape"}]};L(Sm,S,{transform(t,e){var n=e.fork(e.ALL),r=this.value,i=t.as||"shape",a=n.ADD;return (!r||t.modified())&&(this.value=r=QO(IC(t.projection),t.field||en("datum"),t.pointRadius),n.materialize().reflow(),a=n.SOURCE),n.visit(a,u=>u[i]=r),n.modifies(i)}});function QO(t,e,n){const r=n==null?i=>t(e(i)):i=>{var a=t.pointRadius(),u=t.pointRadius(n)(e(i));return t.pointRadius(a),u};return r.context=i=>(t.context(i),r),r}function Bm(t){S.call(this,[],t),this.generator=E6();}Bm.Definition={type:"Graticule",metadata:{changes:!0,generates:!0},params:[{name:"extent",type:"array",array:!0,length:2,content:{type:"number",array:!0,length:2}},{name:"extentMajor",type:"array",array:!0,length:2,content:{type:"number",array:!0,length:2}},{name:"extentMinor",type:"array",array:!0,length:2,content:{type:"number",array:!0,length:2}},{name:"step",type:"number",array:!0,length:2},{name:"stepMajor",type:"number",array:!0,length:2,default:[90,360]},{name:"stepMinor",type:"number",array:!0,length:2,default:[10,10]},{name:"precision",type:"number",default:2.5}]};L(Bm,S,{transform(t,e){var n=this.value,r=this.generator,i;if(!n.length||t.modified())for(const a in t)tt(r[a])&&r[a](t[a]);return i=r(),n.length?e.mod.push(tE(n[0],i)):e.add.push(gt(i)),n[0]=i,e}});function Tm(t){S.call(this,null,t);}Tm.Definition={type:"heatmap",metadata:{modifies:!0},params:[{name:"field",type:"field"},{name:"color",type:"string",expr:!0},{name:"opacity",type:"number",expr:!0},{name:"resolve",type:"enum",values:["shared","independent"],default:"independent"},{name:"as",type:"string",default:"image"}]};L(Tm,S,{transform(t,e){if(!e.changed()&&!t.modified())return e.StopPropagation;var n=e.materialize(e.SOURCE).source,r=t.resolve==="shared",i=t.field||ge,a=JO(t.opacity,t),u=ZO(t.color,t),o=t.as||"image",s={$x:0,$y:0,$value:0,$max:r?Ri(n.map(l=>Ri(i(l).values))):0};return n.forEach(l=>{const f=i(l),c=nt({},l,s);r||(c.$max=Ri(f.values||[])),l[o]=tN(f,c,u.dep?u:pe(u(c)),a.dep?a:pe(a(c)));}),e.reflow(!0).modifies(o)}});function ZO(t,e){let n;return tt(t)?(n=r=>Vn(t(r,e)),n.dep=HC(t)):n=pe(Vn(t||"#888")),n}function JO(t,e){let n;return tt(t)?(n=r=>t(r,e),n.dep=HC(t)):t?n=pe(t):(n=r=>r.$value/r.$max||0,n.dep=!0),n}function HC(t){if(!tt(t))return !1;const e=nn(se(t));return e.$x||e.$y||e.$value||e.$max}function tN(t,e,n,r){const i=t.width,a=t.height,u=t.x1||0,o=t.y1||0,s=t.x2||i,l=t.y2||a,f=t.values,c=f?m=>f[m]:Ir,h=Zr(s-u,l-o),d=h.getContext("2d"),g=d.getImageData(0,0,s-u,l-o),p=g.data;for(let m=o,y=0;m{t[r]!=null&&wv(n,r,t[r]);})):Xd.forEach(r=>{t.modified(r)&&wv(n,r,t[r]);}),t.pointRadius!=null&&n.path.pointRadius(t.pointRadius),t.fit&&eN(n,t),e.fork(e.NO_SOURCE|e.NO_FIELDS)}});function eN(t,e){const n=rN(e.fit);e.extent?t.fitExtent(e.extent,n):e.size&&t.fitSize(e.size,n);}function nN(t){const e=Em((t||"mercator").toLowerCase());return e||$("Unrecognized projection type: "+t),e()}function wv(t,e,n){tt(t[e])&&t[e](n);}function rN(t){return t=H(t),t.length===1?t[0]:{type:Fm,features:t.reduce((e,n)=>e.concat(iN(n)),[])}}function iN(t){return t.type===Fm?t.features:H(t).filter(e=>e!=null).map(e=>e.type===Vd?e:{type:Vd,geometry:e})}const aN=Object.freeze(Object.defineProperty({__proto__:null,contour:Dm,geojson:Mm,geopath:km,geopoint:$m,geoshape:Sm,graticule:Bm,heatmap:Tm,isocontour:_m,kde2d:Cm,projection:GC},Symbol.toStringTag,{value:"Module"})),Ev={center:mM,collide:OM,nbody:HM,link:LM,x:GM,y:XM},no="forces",Kd=["alpha","alphaMin","alphaTarget","velocityDecay","forces"],uN=["static","iterations"],XC=["x","y","vx","vy"];function Rm(t){S.call(this,null,t);}Rm.Definition={type:"Force",metadata:{modifies:!0},params:[{name:"static",type:"boolean",default:!1},{name:"restart",type:"boolean",default:!1},{name:"iterations",type:"number",default:300},{name:"alpha",type:"number",default:1},{name:"alphaMin",type:"number",default:.001},{name:"alphaTarget",type:"number",default:0},{name:"velocityDecay",type:"number",default:.4},{name:"forces",type:"param",array:!0,params:[{key:{force:"center"},params:[{name:"x",type:"number",default:0},{name:"y",type:"number",default:0}]},{key:{force:"collide"},params:[{name:"radius",type:"number",expr:!0},{name:"strength",type:"number",default:.7},{name:"iterations",type:"number",default:1}]},{key:{force:"nbody"},params:[{name:"strength",type:"number",default:-30},{name:"theta",type:"number",default:.9},{name:"distanceMin",type:"number",default:1},{name:"distanceMax",type:"number"}]},{key:{force:"link"},params:[{name:"links",type:"data"},{name:"id",type:"field"},{name:"distance",type:"number",default:30,expr:!0},{name:"strength",type:"number",expr:!0},{name:"iterations",type:"number",default:1}]},{key:{force:"x"},params:[{name:"strength",type:"number",default:.1},{name:"x",type:"field"}]},{key:{force:"y"},params:[{name:"strength",type:"number",default:.1},{name:"y",type:"field"}]}]},{name:"as",type:"string",array:!0,modify:!1,default:XC}]};L(Rm,S,{transform(t,e){var n=this.value,r=e.changed(e.ADD_REM),i=t.modified(Kd),a=t.iterations||300;if(n?(r&&(e.modifies("index"),n.nodes(e.source)),(i||e.changed(e.MOD))&&VC(n,t,0,e)):(this.value=n=sN(e.source,t),n.on("tick",oN(e.dataflow,this)),t.static||(r=!0,n.tick()),e.modifies("index")),i||r||t.modified(uN)||e.changed()&&t.restart){if(n.alpha(Math.max(n.alpha(),t.alpha||1)).alphaDecay(1-Math.pow(n.alphaMin(),1/a)),t.static)for(n.stop();--a>=0;)n.tick();else if(n.stopped()&&n.restart(),!r)return e.StopPropagation}return this.finish(t,e)},finish(t,e){const n=e.dataflow;for(let o=this._argops,s=0,l=o.length,f;st.touch(e).run()}function sN(t,e){const n=YM(t),r=n.stop,i=n.restart;let a=!1;return n.stopped=()=>a,n.restart=()=>(a=!1,i()),n.stop=()=>(a=!0,r()),VC(n,e,!0).on("end",()=>a=!0)}function VC(t,e,n,r){var i=H(e.forces),a,u,o,s;for(a=0,u=Kd.length;ae(r,n):e);}const hN=Object.freeze(Object.defineProperty({__proto__:null,force:Rm},Symbol.toStringTag,{value:"Module"}));function Qd(t,e,n){const r={};return t.each(i=>{const a=i.data;n(a)&&(r[e(a)]=i);}),t.lookup=r,t}function Om(t){S.call(this,null,t);}Om.Definition={type:"Nest",metadata:{treesource:!0,changes:!0},params:[{name:"keys",type:"field",array:!0},{name:"generate",type:"boolean"}]};const dN=t=>t.values;L(Om,S,{transform(t,e){e.source||$("Nest transform requires an upstream data source.");var n=t.generate,r=t.modified(),i=e.clone(),a=this.value;return (!a||r||e.changed())&&(a&&a.each(u=>{u.children&&su(u.data)&&i.rem.push(u.data);}),this.value=a=q1({values:H(t.keys).reduce((u,o)=>(u.key(o),u),gN()).entries(i.source)},dN),n&&a.each(u=>{u.children&&(u=gt(u.data),i.add.push(u),i.source.push(u));}),Qd(a,K,K)),i.source.root=a,i}});function gN(){const t=[],e={entries:i=>r(n(i,0),0),key:i=>(t.push(i),e)};function n(i,a){if(a>=t.length)return i;const u=i.length,o=t[a++],s={},l={};let f=-1,c,h,d;for(;++ft.length)return i;const u=[];for(const o in i)u.push({key:o,values:r(i[o],a)});return u}return e}function Sr(t){S.call(this,null,t);}const pN=(t,e)=>t.parent===e.parent?1:2;L(Sr,S,{transform(t,e){(!e.source||!e.source.root)&&$(this.constructor.name+" transform requires a backing tree data source.");const n=this.layout(t.method),r=this.fields,i=e.source.root,a=t.as||r;t.field?i.sum(t.field):i.count(),t.sort&&i.sort(na(t.sort,u=>u.data)),mN(n,this.params,t),n.separation&&n.separation(t.separation!==!1?pN:ru);try{this.value=n(i);}catch(u){$(u);}return i.each(u=>yN(u,r,a)),e.reflow(t.modified()).modifies(a).modifies("leaf")}});function mN(t,e,n){for(let r,i=0,a=e.length;ia[K(u)]=1),r.each(u=>{const o=u.data,s=u.parent&&u.parent.data;s&&a[K(o)]&&a[K(s)]&&i.add.push(gt({source:s,target:o}));}),this.value=i.add):e.changed(e.MOD)&&(e.visit(e.MOD,u=>a[K(u)]=1),n.forEach(u=>{(a[K(u.source)]||a[K(u.target)])&&i.mod.push(u);})),i}});const Cv={binary:i8,dice:ts,slice:tc,slicedice:a8,squarify:ww,resquarify:u8},e1=["x0","y0","x1","y1","depth","children"];function Um(t){Sr.call(this,t);}Um.Definition={type:"Treemap",metadata:{tree:!0,modifies:!0},params:[{name:"field",type:"field"},{name:"sort",type:"compare"},{name:"method",type:"enum",default:"squarify",values:["squarify","resquarify","binary","dice","slice","slicedice"]},{name:"padding",type:"number",default:0},{name:"paddingInner",type:"number",default:0},{name:"paddingOuter",type:"number",default:0},{name:"paddingTop",type:"number",default:0},{name:"paddingRight",type:"number",default:0},{name:"paddingBottom",type:"number",default:0},{name:"paddingLeft",type:"number",default:0},{name:"ratio",type:"number",default:1.618033988749895},{name:"round",type:"boolean",default:!1},{name:"size",type:"number",array:!0,length:2},{name:"as",type:"string",array:!0,length:e1.length,default:e1}]};L(Um,Sr,{layout(){const t=r8();return t.ratio=e=>{const n=t.tile();n.ratio&&t.tile(n.ratio(e));},t.method=e=>{X(Cv,e)?t.tile(Cv[e]):$("Unrecognized Treemap layout method: "+e);},t},params:["method","ratio","size","round","padding","paddingInner","paddingOuter","paddingTop","paddingRight","paddingBottom","paddingLeft"],fields:e1});const xN=Object.freeze(Object.defineProperty({__proto__:null,nest:Om,pack:Nm,partition:Lm,stratify:Pm,tree:zm,treelinks:Im,treemap:Um},Symbol.toStringTag,{value:"Module"})),l0=4278190080;function vN(t,e){const n=t.bitmap();return (e||[]).forEach(r=>n.set(t(r.boundary[0]),t(r.boundary[3]))),[n,void 0]}function bN(t,e,n,r,i){const a=t.width,u=t.height,o=r||i,s=Zr(a,u).getContext("2d"),l=Zr(a,u).getContext("2d"),f=o&&Zr(a,u).getContext("2d");n.forEach(_=>Al(s,_,!1)),Al(l,e,!1),o&&Al(f,e,!0);const c=f0(s,a,u),h=f0(l,a,u),d=o&&f0(f,a,u),g=t.bitmap(),p=o&&t.bitmap();let m,y,x,v,b,w,E,A;for(y=0;y{i.items.forEach(a=>Al(t,a.items,n));}):on[r].draw(t,{items:n?e.map(AN):e});}function AN(t){const e=_c(t,{});return e.stroke&&e.strokeOpacity!==0||e.fill&&e.fillOpacity!==0?{...e,strokeOpacity:1,stroke:"#000",fillOpacity:0}:e}const fr=5,xe=31,zo=32,zr=new Uint32Array(zo+1),En=new Uint32Array(zo+1);En[0]=0;zr[0]=~En[0];for(let t=1;t<=zo;++t)En[t]=En[t-1]<<1|1,zr[t]=~En[t];function wN(t,e){const n=new Uint32Array(~~((t*e+zo)/zo));function r(a,u){n[a]|=u;}function i(a,u){n[a]&=u;}return {array:n,get:(a,u)=>{const o=u*t+a;return n[o>>>fr]&1<<(o&xe)},set:(a,u)=>{const o=u*t+a;r(o>>>fr,1<<(o&xe));},clear:(a,u)=>{const o=u*t+a;i(o>>>fr,~(1<<(o&xe)));},getRange:(a,u,o,s)=>{let l=s,f,c,h,d;for(;l>=u;--l)if(f=l*t+a,c=l*t+o,h=f>>>fr,d=c>>>fr,h===d){if(n[h]&zr[f&xe]&En[(c&xe)+1])return !0}else {if(n[h]&zr[f&xe]||n[d]&En[(c&xe)+1])return !0;for(let g=h+1;g{let l,f,c,h,d;for(;u<=s;++u)if(l=u*t+a,f=u*t+o,c=l>>>fr,h=f>>>fr,c===h)r(c,zr[l&xe]&En[(f&xe)+1]);else for(r(c,zr[l&xe]),r(h,En[(f&xe)+1]),d=c+1;d{let l,f,c,h,d;for(;u<=s;++u)if(l=u*t+a,f=u*t+o,c=l>>>fr,h=f>>>fr,c===h)i(c,En[l&xe]|zr[(f&xe)+1]);else for(i(c,En[l&xe]),i(h,zr[(f&xe)+1]),d=c+1;da<0||u<0||s>=e||o>=t}}function EN(t,e,n){const r=Math.max(1,Math.sqrt(t*e/1e6)),i=~~((t+2*n+r)/r),a=~~((e+2*n+r)/r),u=o=>~~((o+n)/r);return u.invert=o=>o*r-n,u.bitmap=()=>wN(i,a),u.ratio=r,u.padding=n,u.width=t,u.height=e,u}function _N(t,e,n,r){const i=t.width,a=t.height;return function(u){const o=u.datum.datum.items[r].items,s=o.length,l=u.datum.fontSize,f=kn.width(u.datum,u.datum.text);let c=0,h,d,g,p,m,y,x;for(let v=0;v=c&&(c=x,u.x=m,u.y=y);return m=f/2,y=l/2,h=u.x-m,d=u.x+m,g=u.y-y,p=u.y+y,u.align="center",h<0&&d<=i?u.align="left":0<=h&&ii||e-(u=r/2)<0||e+u>a}function Vr(t,e,n,r,i,a,u,o){const s=i*a/(r*2),l=t(e-s),f=t(e+s),c=t(n-(a=a/2)),h=t(n+a);return u.outOfBounds(l,c,f,h)||u.getRange(l,c,f,h)||o&&o.getRange(l,c,f,h)}function CN(t,e,n,r){const i=t.width,a=t.height,u=e[0],o=e[1];function s(l,f,c,h,d){const g=t.invert(l),p=t.invert(f);let m=c,y=a,x;if(!Of(g,p,h,d,i,a)&&!Vr(t,g,p,d,h,m,u,o)&&!Vr(t,g,p,d,h,d,u,null)){for(;y-m>=1;)x=(m+y)/2,Vr(t,g,p,d,h,x,u,o)?y=x:m=x;if(m>c)return [g,p,m,!0]}}return function(l){const f=l.datum.datum.items[r].items,c=f.length,h=l.datum.fontSize,d=kn.width(l.datum,l.datum.text);let g=n?h:0,p=!1,m=!1,y=0,x,v,b,w,E,A,_,C,F,D,R,k,N,M,O,z,G;for(let W=0;Wv&&(G=x,x=v,v=G),b>w&&(G=b,b=w,w=G),F=t(x),R=t(v),D=~~((F+R)/2),k=t(b),M=t(w),N=~~((k+M)/2),_=D;_>=F;--_)for(C=N;C>=k;--C)z=s(_,C,g,d,h),z&&([l.x,l.y,g,p]=z);for(_=D;_<=R;++_)for(C=N;C<=M;++C)z=s(_,C,g,d,h),z&&([l.x,l.y,g,p]=z);!p&&!n&&(O=Math.abs(v-x+w-b),E=(x+v)/2,A=(b+w)/2,O>=y&&!Of(E,A,d,h,i,a)&&!Vr(t,E,A,h,d,h,u,null)&&(y=O,l.x=E,l.y=A,m=!0));}return p||m?(E=d/2,A=h/2,u.setRange(t(l.x-E),t(l.y-A),t(l.x+E),t(l.y+A)),l.align="center",l.baseline="middle",!0):!1}}const DN=[-1,-1,1,1],FN=[-1,1,-1,1];function MN(t,e,n,r){const i=t.width,a=t.height,u=e[0],o=e[1],s=t.bitmap();return function(l){const f=l.datum.datum.items[r].items,c=f.length,h=l.datum.fontSize,d=kn.width(l.datum,l.datum.text),g=[];let p=n?h:0,m=!1,y=!1,x=0,v,b,w,E,A,_,C,F,D,R,k,N;for(let M=0;M=1;)k=(D+R)/2,Vr(t,A,_,h,d,k,u,o)?R=k:D=k;D>p&&(l.x=A,l.y=_,p=D,m=!0);}}!m&&!n&&(N=Math.abs(b-v+E-w),A=(v+b)/2,_=(w+E)/2,N>=x&&!Of(A,_,d,h,i,a)&&!Vr(t,A,_,h,d,h,u,null)&&(x=N,l.x=A,l.y=_,y=!0));}return m||y?(A=d/2,_=h/2,u.setRange(t(l.x-A),t(l.y-_),t(l.x+A),t(l.y+_)),l.align="center",l.baseline="middle",!0):!1}}const kN=["right","center","left"],$N=["bottom","middle","top"];function SN(t,e,n,r){const i=t.width,a=t.height,u=e[0],o=e[1],s=r.length;return function(l){const f=l.boundary,c=l.datum.fontSize;if(f[2]<0||f[5]<0||f[0]>i||f[3]>a)return !1;let h=l.textWidth??0,d,g,p,m,y,x,v,b,w,E,A,_,C,F,D;for(let R=0;R>>2&3)-1,p=d===0&&g===0||r[R]<0,m=d&&g?Math.SQRT1_2:1,y=r[R]<0?-1:1,x=f[1+d]+r[R]*d*m,A=f[4+g]+y*c*g/2+r[R]*g*m,b=A-c/2,w=A+c/2,_=t(x),F=t(b),D=t(w),!h)if(Dv(_,_,F,D,u,o,x,x,b,w,f,p))h=kn.width(l.datum,l.datum.text);else continue;if(E=x+y*h*d/2,x=E-h/2,v=E+h/2,_=t(x),C=t(v),Dv(_,C,F,D,u,o,x,v,b,w,f,p))return l.x=d?d*y<0?v:x:E,l.y=g?g*y<0?w:b:A,l.align=kN[d*y+1],l.baseline=$N[g*y+1],u.setRange(_,F,C,D),!0}return !1}}function Dv(t,e,n,r,i,a,u,o,s,l,f,c){return !(i.outOfBounds(t,n,e,r)||(c&&a||i).getRange(t,n,e,r))}const c0=0,h0=4,d0=8,g0=0,p0=1,m0=2,BN={"top-left":c0+g0,top:c0+p0,"top-right":c0+m0,left:h0+g0,middle:h0+p0,right:h0+m0,"bottom-left":d0+g0,bottom:d0+p0,"bottom-right":d0+m0},TN={naive:_N,"reduced-search":CN,floodfill:MN};function RN(t,e,n,r,i,a,u,o,s,l,f){if(!t.length)return t;const c=Math.max(r.length,i.length),h=ON(r,c),d=NN(i,c),g=LN(t[0].datum),p=g==="group"&&t[0].datum.items[s].marktype,m=p==="area",y=PN(g,p,o,s),x=l===null||l===1/0,v=m&&f==="naive";let b=-1,w=-1;const E=t.map(F=>{const D=x?kn.width(F,F.text):void 0;return b=Math.max(b,D),w=Math.max(w,F.fontSize),{datum:F,opacity:0,x:void 0,y:void 0,align:void 0,baseline:void 0,boundary:y(F),textWidth:D}});l=l===null||l===1/0?Math.max(b,w)+Math.max(...r):l;const A=EN(e[0],e[1],l);let _;if(!v){n&&E.sort((R,k)=>n(R.datum,k.datum));let F=!1;for(let R=0;RR.datum);_=a.length||D?bN(A,D||[],a,F,m):vN(A,u&&E);}const C=m?TN[f](A,_,u,s):SN(A,_,d,h);return E.forEach(F=>F.opacity=+C(F)),E}function ON(t,e){const n=new Float64Array(e),r=t.length;for(let i=0;i[a.x,a.x,a.x,a.y,a.y,a.y];return t?t==="line"||t==="area"?a=>i(a.datum):e==="line"?a=>{const u=a.datum.items[r].items;return i(u.length?u[n==="start"?0:u.length-1]:{x:NaN,y:NaN})}:a=>{const u=a.datum.bounds;return [u.x1,(u.x1+u.x2)/2,u.x2,u.y1,(u.y1+u.y2)/2,u.y2]}:i}const n1=["x","y","opacity","align","baseline"],KC=["top-left","left","bottom-left","top","bottom","top-right","right","bottom-right"];function qm(t){S.call(this,null,t);}qm.Definition={type:"Label",metadata:{modifies:!0},params:[{name:"size",type:"number",array:!0,length:2,required:!0},{name:"sort",type:"compare"},{name:"anchor",type:"string",array:!0,default:KC},{name:"offset",type:"number",array:!0,default:[1]},{name:"padding",type:"number",default:0,null:!0},{name:"lineAnchor",type:"string",values:["start","end"],default:"end"},{name:"markIndex",type:"number",default:0},{name:"avoidBaseMark",type:"boolean",default:!0},{name:"avoidMarks",type:"data",array:!0},{name:"method",type:"string",default:"naive"},{name:"as",type:"string",array:!0,length:n1.length,default:n1}]};L(qm,S,{transform(t,e){function n(a){const u=t[a];return tt(u)&&e.modified(u.fields)}const r=t.modified();if(!(r||e.changed(e.ADD_REM)||n("sort")))return;(!t.size||t.size.length!==2)&&$("Size parameter should be specified as a [width, height] array.");const i=t.as||n1;return RN(e.materialize(e.SOURCE).source||[],t.size,t.sort,H(t.offset==null?1:t.offset),H(t.anchor||KC),t.avoidMarks||[],t.avoidBaseMark!==!1,t.lineAnchor||"end",t.markIndex||0,t.padding===void 0?0:t.padding,t.method||"naive").forEach(a=>{const u=a.datum;u[i[0]]=a.x,u[i[1]]=a.y,u[i[2]]=a.opacity,u[i[3]]=a.align,u[i[4]]=a.baseline;}),e.reflow(r).modifies(i)}});const zN=Object.freeze(Object.defineProperty({__proto__:null,label:qm},Symbol.toStringTag,{value:"Module"}));function QC(t,e){var n=[],r=function(f){return f(o)},i,a,u,o,s,l;if(e==null)n.push(t);else for(i={},a=0,u=t.length;a{xE(l,t.x,t.y,t.bandwidth||.3).forEach(f=>{const c={};for(let h=0;ht==="poly"?e:t==="quad"?2:1;function Wm(t){S.call(this,null,t);}Wm.Definition={type:"Regression",metadata:{generates:!0},params:[{name:"x",type:"field",required:!0},{name:"y",type:"field",required:!0},{name:"groupby",type:"field",array:!0},{name:"method",type:"string",default:"linear",values:Object.keys(r1)},{name:"order",type:"number",default:3},{name:"extent",type:"number",array:!0,length:2},{name:"params",type:"boolean",default:!1},{name:"as",type:"string",array:!0}]};L(Wm,S,{transform(t,e){const n=e.fork(e.NO_SOURCE|e.NO_FIELDS);if(!this.value||e.changed()||t.modified()){const r=e.materialize(e.SOURCE).source,i=QC(r,t.groupby),a=(t.groupby||[]).map($t),u=t.method||"linear",o=t.order||3,s=IN(u,o),l=t.as||[$t(t.x),$t(t.y)],f=r1[u],c=[];let h=t.extent;X(r1,u)||$("Invalid regression method: "+u),h!=null&&u==="log"&&h[0]<=0&&(e.dataflow.warn("Ignoring extent with values <= 0 for log regression."),h=null),i.forEach(d=>{if(d.length<=s){e.dataflow.warn("Skipping regression with more parameters than data points.");return}const p=f(d,t.x,t.y,o);if(t.params){c.push(gt({keys:d.dims,coef:p.coef,rSquared:p.rSquared}));return}const m=h||Sn(d,t.x),y=x=>{const v={};for(let b=0;by([x,p.predict(x)])):Lc(p.predict,m,25,200).forEach(y);}),this.value&&(n.rem=this.value),this.value=n.add=n.source=c;}return n}});const UN=Object.freeze(Object.defineProperty({__proto__:null,loess:jm,regression:Wm},Symbol.toStringTag,{value:"Module"}));function Ym(t){S.call(this,null,t);}Ym.Definition={type:"Voronoi",metadata:{modifies:!0},params:[{name:"x",type:"field",required:!0},{name:"y",type:"field",required:!0},{name:"size",type:"number",array:!0,length:2},{name:"extent",type:"array",array:!0,length:2,default:[[-1e5,-1e5],[1e5,1e5]],content:{type:"number",array:!0,length:2}},{name:"as",type:"string",default:"path"}]};const qN=[-1e5,-1e5,1e5,1e5];L(Ym,S,{transform(t,e){const n=t.as||"path",r=e.source;if(!r||!r.length)return e;let i=t.size;i=i?[0,0,i[0],i[1]]:(i=t.extent)?[i[0][0],i[0][1],i[1][0],i[1][1]]:qN;const a=this.value=$1.from(r,t.x,t.y).voronoi(i);for(let u=0,o=r.length;u>5)*t[1]),m=null,y=l.length,x=-1,v=[],b=l.map(E=>({text:e(E),font:n(E),style:i(E),weight:a(E),rotate:u(E),size:~~(r(E)+1e-14),padding:o(E),xoff:0,yoff:0,x1:0,y1:0,x0:0,y0:0,hasText:!1,sprite:null,datum:E})).sort((E,A)=>A.size-E.size);++x>1,w.y=t[1]*(f()+.5)>>1,GN(g,w,b,x),w.hasText&&d(p,w,m)&&(v.push(w),m?VN(m,w):m=[{x:w.x+w.x0,y:w.y+w.y0},{x:w.x+w.x1,y:w.y+w.y1}],w.x-=t[0]>>1,w.y-=t[1]>>1);}return v};function h(g){g.width=g.height=1;var p=Math.sqrt(g.getContext("2d").getImageData(0,0,1,1).data.length>>2);g.width=(ro<<5)/p,g.height=wl/p;var m=g.getContext("2d");return m.fillStyle=m.strokeStyle="red",m.textAlign="center",{context:m,ratio:p}}function d(g,p,m){for(var y=p.x,x=p.y,v=Math.sqrt(t[0]*t[0]+t[1]*t[1]),b=s(t),w=f()<.5?1:-1,E=-w,A,_,C;(A=b(E+=w))&&(_=~~A[0],C=~~A[1],!(Math.min(Math.abs(_),Math.abs(C))>=v));)if(p.x=y+_,p.y=x+C,!(p.x+p.x0<0||p.y+p.y0<0||p.x+p.x1>t[0]||p.y+p.y1>t[1])&&(!m||!XN(p,g,t[0]))&&(!m||KN(p,m))){for(var F=p.sprite,D=p.width>>5,R=t[0]>>5,k=p.x-(D<<4),N=k&127,M=32-N,O=p.y1-p.y0,z=(p.y+p.y0)*R+(k>>5),G,W=0;W>>N:0);z+=R;}return p.sprite=null,!0}return !1}return c.words=function(g){return arguments.length?(l=g,c):l},c.size=function(g){return arguments.length?(t=[+g[0],+g[1]],c):t},c.font=function(g){return arguments.length?(n=xi(g),c):n},c.fontStyle=function(g){return arguments.length?(i=xi(g),c):i},c.fontWeight=function(g){return arguments.length?(a=xi(g),c):a},c.rotate=function(g){return arguments.length?(u=xi(g),c):u},c.text=function(g){return arguments.length?(e=xi(g),c):e},c.spiral=function(g){return arguments.length?(s=JN[g]||g,c):s},c.fontSize=function(g){return arguments.length?(r=xi(g),c):r},c.padding=function(g){return arguments.length?(o=xi(g),c):o},c.random=function(g){return arguments.length?(f=g,c):f},c}function GN(t,e,n,r){if(!e.sprite){var i=t.context,a=t.ratio;i.clearRect(0,0,(ro<<5)/a,wl/a);var u=0,o=0,s=0,l=n.length,f,c,h,d,g;for(--r;++r>5<<5,h=~~Math.max(Math.abs(x+v),Math.abs(x-v));}else f=f+31>>5<<5;if(h>s&&(s=h),u+f>=ro<<5&&(u=0,o+=s,s=0),o+h>=wl)break;i.translate((u+(f>>1))/a,(o+(h>>1))/a),e.rotate&&i.rotate(e.rotate*y0),i.fillText(e.text,0,0),e.padding&&(i.lineWidth=2*e.padding,i.strokeText(e.text,0,0)),i.restore(),e.width=f,e.height=h,e.xoff=u,e.yoff=o,e.x1=f>>1,e.y1=h>>1,e.x0=-e.x1,e.y0=-e.y1,e.hasText=!0,u+=f;}for(var w=i.getImageData(0,0,(ro<<5)/a,wl/a).data,E=[];--r>=0;)if(e=n[r],!!e.hasText){for(f=e.width,c=f>>5,h=e.y1-e.y0,d=0;d>5),F=w[(o+g)*(ro<<5)+(u+d)<<2]?1<<31-d%32:0;E[C]|=F,A|=F;}A?_=g:(e.y0++,h--,g--,o++);}e.y1=e.y0+_,e.sprite=E.slice(0,(e.y1-e.y0)*c);}}}function XN(t,e,n){n>>=5;for(var r=t.sprite,i=t.width>>5,a=t.x-(i<<4),u=a&127,o=32-u,s=t.y1-t.y0,l=(t.y+t.y0)*n+(a>>5),f,c=0;c>>u:0))&e[l+h])return !0;l+=n;}return !1}function VN(t,e){var n=t[0],r=t[1];e.x+e.x0r.x&&(r.x=e.x+e.x1),e.y+e.y1>r.y&&(r.y=e.y+e.y1);}function KN(t,e){return t.x+t.x1>e[0].x&&t.x+t.x0e[0].y&&t.y+t.y0p(g(m));}i.forEach(g=>{g[u[0]]=NaN,g[u[1]]=NaN,g[u[3]]=0;});const l=a.words(i).text(t.text).size(t.size||[500,500]).padding(t.padding||1).spiral(t.spiral||"archimedean").rotate(t.rotate||0).font(t.font||"sans-serif").fontStyle(t.fontStyle||"normal").fontWeight(t.fontWeight||"normal").fontSize(o).random(un).layout(),f=a.size(),c=f[0]>>1,h=f[1]>>1,d=l.length;for(let g=0,p,m;gnew Uint8Array(t),rL=t=>new Uint16Array(t),po=t=>new Uint32Array(t);function iL(){let t=8,e=[],n=po(0),r=el(0,t),i=el(0,t);return {data:()=>e,seen:()=>n=aL(n,e.length),add(a){for(let u=0,o=e.length,s=a.length,l;ue.length,curr:()=>r,prev:()=>i,reset:a=>i[a]=r[a],all:()=>t<257?255:t<65537?65535:4294967295,set(a,u){r[a]|=u;},clear(a,u){r[a]&=~u;},resize(a,u){const o=r.length;(a>o||u>t)&&(t=Math.max(u,t),r=el(a,t,r),i=el(a,t));}}}function aL(t,e,n){return t.length>=e?t:(n=n||new t.constructor(e),n.set(t),n)}function el(t,e,n){const r=(e<257?nL:e<65537?rL:po)(t);return n&&r.set(n),r}function Fv(t,e,n){const r=1<0)for(m=0;mt,size:()=>n}}function uL(t,e){return t.sort.call(e,(n,r)=>{const i=t[n],a=t[r];return ia?1:0}),X5(t,e)}function oL(t,e,n,r,i,a,u,o,s){let l=0,f=0,c;for(c=0;le.modified(r.fields));return n?this.reinit(t,e):this.eval(t,e)}else return this.init(t,e)},init(t,e){const n=t.fields,r=t.query,i=this._indices={},a=this._dims=[],u=r.length;let o=0,s,l;for(;o{const a=i.remove(e,n);for(const u in r)r[u].reindex(a);});},update(t,e,n){const r=this._dims,i=t.query,a=e.stamp,u=r.length;let o=0,s,l;for(n.filters=0,l=0;ld)for(m=d,y=Math.min(c,g);mg)for(m=Math.max(c,g),y=h;mc)for(g=c,p=Math.min(l,h);gh)for(g=Math.max(l,h),p=f;go[f]&n?null:u[f];return a.filter(a.MOD,l),i&i-1?(a.filter(a.ADD,f=>{const c=o[f]&n;return !c&&c^s[f]&n?u[f]:null}),a.filter(a.REM,f=>{const c=o[f]&n;return c&&!(c^(c^s[f]&n))?u[f]:null})):(a.filter(a.ADD,l),a.filter(a.REM,f=>(o[f]&n)===i?u[f]:null)),a.filter(a.SOURCE,f=>l(f._index))}});const sL=Object.freeze(Object.defineProperty({__proto__:null,crossfilter:Gm,resolvefilter:Xm},Symbol.toStringTag,{value:"Module"})),lL="RawCode",xn="Literal",fL="Property",cL="Identifier",hL="ArrayExpression",dL="BinaryExpression",tD="CallExpression",gL="ConditionalExpression",pL="LogicalExpression",mL="MemberExpression",yL="ObjectExpression",xL="UnaryExpression";function Rn(t){this.type=t;}Rn.prototype.visit=function(t){let e,n,r;if(t(this))return 1;for(e=vL(this),n=0,r=e.length;n";ar[Xi]="Identifier";ar[gi]="Keyword";ar[rh]="Null";ar[aa]="Numeric";ar[Re]="Punctuator";ar[ws]="String";ar[bL]="RegularExpression";var AL="ArrayExpression",wL="BinaryExpression",EL="CallExpression",_L="ConditionalExpression",eD="Identifier",CL="Literal",DL="LogicalExpression",FL="MemberExpression",ML="ObjectExpression",kL="Property",$L="UnaryExpression",Wt="Unexpected token %0",SL="Unexpected number",BL="Unexpected string",TL="Unexpected identifier",RL="Unexpected reserved word",OL="Unexpected end of input",i1="Invalid regular expression",x0="Invalid regular expression: missing /",nD="Octal literals are not allowed in strict mode.",NL="Duplicate data property in object literal not allowed in strict mode",Qt="ILLEGAL",Io="Disabled.",LL=new RegExp("[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0-\\u08B2\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6EF\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA7AD\\uA7B0\\uA7B1\\uA7F7-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB5F\\uAB64\\uAB65\\uABC0-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"),PL=new RegExp("[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0300-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u0483-\\u0487\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0610-\\u061A\\u0620-\\u0669\\u066E-\\u06D3\\u06D5-\\u06DC\\u06DF-\\u06E8\\u06EA-\\u06FC\\u06FF\\u0710-\\u074A\\u074D-\\u07B1\\u07C0-\\u07F5\\u07FA\\u0800-\\u082D\\u0840-\\u085B\\u08A0-\\u08B2\\u08E4-\\u0963\\u0966-\\u096F\\u0971-\\u0983\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BC-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CE\\u09D7\\u09DC\\u09DD\\u09DF-\\u09E3\\u09E6-\\u09F1\\u0A01-\\u0A03\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A59-\\u0A5C\\u0A5E\\u0A66-\\u0A75\\u0A81-\\u0A83\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABC-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AD0\\u0AE0-\\u0AE3\\u0AE6-\\u0AEF\\u0B01-\\u0B03\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3C-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B5C\\u0B5D\\u0B5F-\\u0B63\\u0B66-\\u0B6F\\u0B71\\u0B82\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD0\\u0BD7\\u0BE6-\\u0BEF\\u0C00-\\u0C03\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C58\\u0C59\\u0C60-\\u0C63\\u0C66-\\u0C6F\\u0C81-\\u0C83\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBC-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CDE\\u0CE0-\\u0CE3\\u0CE6-\\u0CEF\\u0CF1\\u0CF2\\u0D01-\\u0D03\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4E\\u0D57\\u0D60-\\u0D63\\u0D66-\\u0D6F\\u0D7A-\\u0D7F\\u0D82\\u0D83\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DE6-\\u0DEF\\u0DF2\\u0DF3\\u0E01-\\u0E3A\\u0E40-\\u0E4E\\u0E50-\\u0E59\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB9\\u0EBB-\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EC8-\\u0ECD\\u0ED0-\\u0ED9\\u0EDC-\\u0EDF\\u0F00\\u0F18\\u0F19\\u0F20-\\u0F29\\u0F35\\u0F37\\u0F39\\u0F3E-\\u0F47\\u0F49-\\u0F6C\\u0F71-\\u0F84\\u0F86-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u1000-\\u1049\\u1050-\\u109D\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u135D-\\u135F\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1714\\u1720-\\u1734\\u1740-\\u1753\\u1760-\\u176C\\u176E-\\u1770\\u1772\\u1773\\u1780-\\u17D3\\u17D7\\u17DC\\u17DD\\u17E0-\\u17E9\\u180B-\\u180D\\u1810-\\u1819\\u1820-\\u1877\\u1880-\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1920-\\u192B\\u1930-\\u193B\\u1946-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u19D0-\\u19D9\\u1A00-\\u1A1B\\u1A20-\\u1A5E\\u1A60-\\u1A7C\\u1A7F-\\u1A89\\u1A90-\\u1A99\\u1AA7\\u1AB0-\\u1ABD\\u1B00-\\u1B4B\\u1B50-\\u1B59\\u1B6B-\\u1B73\\u1B80-\\u1BF3\\u1C00-\\u1C37\\u1C40-\\u1C49\\u1C4D-\\u1C7D\\u1CD0-\\u1CD2\\u1CD4-\\u1CF6\\u1CF8\\u1CF9\\u1D00-\\u1DF5\\u1DFC-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u200C\\u200D\\u203F\\u2040\\u2054\\u2071\\u207F\\u2090-\\u209C\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D7F-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2DE0-\\u2DFF\\u2E2F\\u3005-\\u3007\\u3021-\\u302F\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u3099\\u309A\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA62B\\uA640-\\uA66F\\uA674-\\uA67D\\uA67F-\\uA69D\\uA69F-\\uA6F1\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA7AD\\uA7B0\\uA7B1\\uA7F7-\\uA827\\uA840-\\uA873\\uA880-\\uA8C4\\uA8D0-\\uA8D9\\uA8E0-\\uA8F7\\uA8FB\\uA900-\\uA92D\\uA930-\\uA953\\uA960-\\uA97C\\uA980-\\uA9C0\\uA9CF-\\uA9D9\\uA9E0-\\uA9FE\\uAA00-\\uAA36\\uAA40-\\uAA4D\\uAA50-\\uAA59\\uAA60-\\uAA76\\uAA7A-\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEF\\uAAF2-\\uAAF6\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB5F\\uAB64\\uAB65\\uABC0-\\uABEA\\uABEC\\uABED\\uABF0-\\uABF9\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE00-\\uFE0F\\uFE20-\\uFE2D\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF10-\\uFF19\\uFF21-\\uFF3A\\uFF3F\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]");function ih(t,e){if(!t)throw new Error("ASSERT: "+e)}function dr(t){return t>=48&&t<=57}function Vm(t){return "0123456789abcdefABCDEF".indexOf(t)>=0}function mo(t){return "01234567".indexOf(t)>=0}function zL(t){return t===32||t===9||t===11||t===12||t===160||t>=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(t)>=0}function Uo(t){return t===10||t===13||t===8232||t===8233}function Es(t){return t===36||t===95||t>=65&&t<=90||t>=97&&t<=122||t===92||t>=128&&LL.test(String.fromCharCode(t))}function Nf(t){return t===36||t===95||t>=65&&t<=90||t>=97&&t<=122||t>=48&&t<=57||t===92||t>=128&&PL.test(String.fromCharCode(t))}const IL={if:1,in:1,do:1,var:1,for:1,new:1,try:1,let:1,this:1,else:1,case:1,void:1,with:1,enum:1,while:1,break:1,catch:1,throw:1,const:1,yield:1,class:1,super:1,return:1,typeof:1,delete:1,switch:1,export:1,import:1,public:1,static:1,default:1,finally:1,extends:1,package:1,private:1,function:1,continue:1,debugger:1,interface:1,protected:1,instanceof:1,implements:1};function rD(){for(;B1114111||t!=="}")&&ct({},Wt,Qt),e<=65535?String.fromCharCode(e):(n=(e-65536>>10)+55296,r=(e-65536&1023)+56320,String.fromCharCode(n,r))}function iD(){var t,e;for(t=q.charCodeAt(B++),e=String.fromCharCode(t),t===92&&(q.charCodeAt(B)!==117&&ct({},Wt,Qt),++B,t=a1("u"),(!t||t==="\\"||!Es(t.charCodeAt(0)))&&ct({},Wt,Qt),e=t);B>>=")return B+=4,{type:Re,value:u,start:t,end:B};if(a=u.substr(0,3),a===">>>"||a==="<<="||a===">>=")return B+=3,{type:Re,value:a,start:t,end:B};if(i=a.substr(0,2),r===i[1]&&"+-<>&|".indexOf(r)>=0||i==="=>")return B+=2,{type:Re,value:i,start:t,end:B};if(i==="//"&&ct({},Wt,Qt),"<>=!+-*%&|^/".indexOf(r)>=0)return ++B,{type:Re,value:r,start:t,end:B};ct({},Wt,Qt);}function WL(t){let e="";for(;B=0&&B=0&&(n=n.replace(/\\u\{([0-9a-fA-F]+)\}/g,(r,i)=>{if(parseInt(i,16)<=1114111)return "x";ct({},i1);}).replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"x"));try{new RegExp(n);}catch{ct({},i1);}try{return new RegExp(t,e)}catch{return null}}function XL(){var t,e,n,r,i;for(t=q[B],ih(t==="/","Regular expression literal must start with a slash"),e=q[B++],n=!1,r=!1;B=0&&ct({},i1,n),{value:n,literal:e}}function KL(){var t,e,n,r;return mt=null,rD(),t=B,e=XL(),n=VL(),r=GL(e.value,n.value),{literal:e.literal+n.literal,value:r,regex:{pattern:e.value,flags:n.value},start:t,end:B}}function QL(t){return t.type===Xi||t.type===gi||t.type===nh||t.type===rh}function aD(){if(rD(),B>=fe)return {type:As,start:B,end:B};const t=q.charCodeAt(B);return Es(t)?jL():t===40||t===41||t===59?v0():t===39||t===34?HL():t===46?dr(q.charCodeAt(B+1))?kv():v0():dr(t)?kv():v0()}function Pe(){const t=mt;return B=t.end,mt=aD(),B=t.end,t}function uD(){const t=B;mt=aD(),B=t;}function ZL(t){const e=new Rn(AL);return e.elements=t,e}function $v(t,e,n){const r=new Rn(t==="||"||t==="&&"?DL:wL);return r.operator=t,r.left=e,r.right=n,r}function JL(t,e){const n=new Rn(EL);return n.callee=t,n.arguments=e,n}function tP(t,e,n){const r=new Rn(_L);return r.test=t,r.consequent=e,r.alternate=n,r}function Km(t){const e=new Rn(eD);return e.name=t,e}function io(t){const e=new Rn(CL);return e.value=t.value,e.raw=q.slice(t.start,t.end),t.regex&&(e.raw==="//"&&(e.raw="/(?:)/"),e.regex=t.regex),e}function Sv(t,e,n){const r=new Rn(FL);return r.computed=t==="[",r.object=e,r.property=n,r.computed||(n.member=!0),r}function eP(t){const e=new Rn(ML);return e.properties=t,e}function Bv(t,e,n){const r=new Rn(kL);return r.key=e,r.value=n,r.kind=t,r}function nP(t,e){const n=new Rn($L);return n.operator=t,n.argument=e,n.prefix=!0,n}function ct(t,e){var n,r=Array.prototype.slice.call(arguments,2),i=e.replace(/%(\d)/g,(a,u)=>(ih(u":case"<=":case">=":case"instanceof":case"in":e=7;break;case"<<":case">>":case">>>":e=8;break;case"+":case"-":e=9;break;case"*":case"/":case"%":e=11;break}return e}function gP(){var t,e,n,r,i,a,u,o,s,l;if(t=mt,s=El(),r=mt,i=Ov(r),i===0)return s;for(r.prec=i,Pe(),e=[t,mt],u=El(),a=[s,r,u];(i=Ov(mt))>0;){for(;a.length>2&&i<=a[a.length-2].prec;)u=a.pop(),o=a.pop().value,s=a.pop(),e.pop(),n=$v(o,s,u),a.push(n);r=Pe(),r.prec=i,a.push(r),e.push(mt),n=El(),a.push(n);}for(l=a.length-1,n=a[l],e.pop();l>1;)e.pop(),n=$v(a[l-1].value,a[l-2],n),l-=2;return n}function Vi(){var t,e,n;return t=gP(),Et("?")&&(Pe(),e=Vi(),ce(":"),n=Vi(),t=tP(t,e,n)),t}function Qm(){const t=Vi();if(Et(","))throw new Error(Io);return t}function pP(t){q=t,B=0,fe=q.length,mt=null,uD();const e=Qm();if(mt.type!==As)throw new Error("Unexpect token after expression.");return e}var Zm={NaN:"NaN",E:"Math.E",LN2:"Math.LN2",LN10:"Math.LN10",LOG2E:"Math.LOG2E",LOG10E:"Math.LOG10E",PI:"Math.PI",SQRT1_2:"Math.SQRT1_2",SQRT2:"Math.SQRT2",MIN_VALUE:"Number.MIN_VALUE",MAX_VALUE:"Number.MAX_VALUE"};function Jm(t){function e(u,o,s,l){let f=t(o[0]);return s&&(f=s+"("+f+")",s.lastIndexOf("new ",0)===0&&(f="("+f+")")),f+"."+u+(l<0?"":l===0?"()":"("+o.slice(1).map(t).join(",")+")")}function n(u,o,s){return l=>e(u,l,o,s)}const r="new Date",i="String",a="RegExp";return {isNaN:"Number.isNaN",isFinite:"Number.isFinite",abs:"Math.abs",acos:"Math.acos",asin:"Math.asin",atan:"Math.atan",atan2:"Math.atan2",ceil:"Math.ceil",cos:"Math.cos",exp:"Math.exp",floor:"Math.floor",hypot:"Math.hypot",log:"Math.log",max:"Math.max",min:"Math.min",pow:"Math.pow",random:"Math.random",round:"Math.round",sin:"Math.sin",sqrt:"Math.sqrt",tan:"Math.tan",clamp:function(u){u.length<3&&$("Missing arguments to clamp function."),u.length>3&&$("Too many arguments to clamp function.");const o=u.map(t);return "Math.max("+o[1]+", Math.min("+o[2]+","+o[0]+"))"},now:"Date.now",utc:"Date.UTC",datetime:r,date:n("getDate",r,0),day:n("getDay",r,0),year:n("getFullYear",r,0),month:n("getMonth",r,0),hours:n("getHours",r,0),minutes:n("getMinutes",r,0),seconds:n("getSeconds",r,0),milliseconds:n("getMilliseconds",r,0),time:n("getTime",r,0),timezoneoffset:n("getTimezoneOffset",r,0),utcdate:n("getUTCDate",r,0),utcday:n("getUTCDay",r,0),utcyear:n("getUTCFullYear",r,0),utcmonth:n("getUTCMonth",r,0),utchours:n("getUTCHours",r,0),utcminutes:n("getUTCMinutes",r,0),utcseconds:n("getUTCSeconds",r,0),utcmilliseconds:n("getUTCMilliseconds",r,0),length:n("length",null,-1),parseFloat:"parseFloat",parseInt:"parseInt",upper:n("toUpperCase",i,0),lower:n("toLowerCase",i,0),substring:n("substring",i),split:n("split",i),trim:n("trim",i,0),regexp:a,test:n("test",a),if:function(u){u.length<3&&$("Missing arguments to if function."),u.length>3&&$("Too many arguments to if function.");const o=u.map(t);return "("+o[0]+"?"+o[1]+":"+o[2]+")"}}}function mP(t){const e=t&&t.length-1;return e&&(t[0]==='"'&&t[e]==='"'||t[0]==="'"&&t[e]==="'")?t.slice(1,-1):t}function oD(t){t=t||{};const e=t.allowed?nn(t.allowed):{},n=t.forbidden?nn(t.forbidden):{},r=t.constants||Zm,i=(t.functions||Jm)(c),a=t.globalvar,u=t.fieldvar,o=tt(a)?a:g=>`${a}["${g}"]`;let s={},l={},f=0;function c(g){if(xt(g))return g;const p=h[g.type];return p==null&&$("Unsupported type: "+g.type),p(g)}const h={Literal:g=>g.raw,Identifier:g=>{const p=g.name;return f>0?p:X(n,p)?$("Illegal identifier: "+p):X(r,p)?r[p]:X(e,p)?p:(s[p]=1,o(p))},MemberExpression:g=>{const p=!g.computed,m=c(g.object);p&&(f+=1);const y=c(g.property);return m===u&&(l[mP(y)]=1),p&&(f-=1),m+(p?"."+y:"["+y+"]")},CallExpression:g=>{g.callee.type!=="Identifier"&&$("Illegal callee type: "+g.callee.type);const p=g.callee.name,m=g.arguments,y=X(i,p)&&i[p];return y||$("Unrecognized function: "+p),tt(y)?y(m):y+"("+m.map(c).join(",")+")"},ArrayExpression:g=>"["+g.elements.map(c).join(",")+"]",BinaryExpression:g=>"("+c(g.left)+" "+g.operator+" "+c(g.right)+")",UnaryExpression:g=>"("+g.operator+c(g.argument)+")",ConditionalExpression:g=>"("+c(g.test)+"?"+c(g.consequent)+":"+c(g.alternate)+")",LogicalExpression:g=>"("+c(g.left)+g.operator+c(g.right)+")",ObjectExpression:g=>"{"+g.properties.map(c).join(",")+"}",Property:g=>{f+=1;const p=c(g.key);return f-=1,p+":"+c(g.value)}};function d(g){const p={code:c(g),globals:Object.keys(s),fields:Object.keys(l)};return s={},l={},p}return d.functions=i,d.constants=r,d}const Nv=Symbol("vega_selection_getter");function sD(t){return (!t.getter||!t.getter[Nv])&&(t.getter=en(t.field),t.getter[Nv]=!0),t.getter}const ty="intersect",Lv="union",yP="vlMulti",xP="vlPoint",Pv="or",vP="and",qn="_vgsid_",qo=en(qn),bP="E",AP="R",wP="R-E",EP="R-LE",_P="R-RE",Lf="index:unit";function zv(t,e){for(var n=e.fields,r=e.values,i=n.length,a=0,u,o;ant(e.fields?{values:e.fields.map(r=>sD(r)(n.datum))}:{[qn]:qo(n.datum)},e))}function dD(t,e,n,r){for(var i=this.context.data[t],a=i?i.values.value:[],u={},o={},s={},l,f,c,h,d,g,p,m,y,x,v=a.length,b=0,w,E;b(A[f[C].field]=_,A),{})));}else d=qn,g=qo(l),p=u[d]||(u[d]={}),m=p[h]||(p[h]=[]),m.push(g),n&&(m=o[h]||(o[h]=[]),m.push({[qn]:g}));if(e=e||Lv,u[qn]?u[qn]=A0[`${qn}_${e}`](...Object.values(u[qn])):Object.keys(u).forEach(A=>{u[A]=Object.keys(u[A]).map(_=>u[A][_]).reduce((_,C)=>_===void 0?C:A0[`${s[A]}_${e}`](_,C));}),a=Object.keys(o),n&&a.length){const A=r?xP:yP;u[A]=e===Lv?{[Pv]:a.reduce((_,C)=>(_.push(...o[C]),_),[])}:{[vP]:a.map(_=>({[Pv]:o[_]}))};}return u}var A0={[`${qn}_union`]:rF,[`${qn}_intersect`]:eF,E_union:function(t,e){if(!t.length)return e;for(var n=0,r=e.length;ne.indexOf(n)>=0):e},R_union:function(t,e){var n=Kt(e[0]),r=Kt(e[1]);return n>r&&(n=e[1],r=e[0]),t.length?(t[0]>n&&(t[0]=n),t[1]r&&(n=e[1],r=e[0]),t.length?rr&&(t[1]=r),t):[n,r]}};const FP=":",MP="@";function hu(t,e,n,r){e[0].type!==xn&&$("First argument to selection functions must be a string literal.");const i=e[0].value,a=e.length>=2&&ut(e).value,u="unit",o=MP+u,s=FP+i;a===ty&&!X(r,o)&&(r[o]=n.getData(i).indataRef(n,u)),X(r,s)||(r[s]=n.getData(i).tuplesRef());}function gD(t){const e=this.context.data[t];return e?e.values.value:[]}function kP(t,e,n){const r=this.context.data[t]["index:"+e],i=r?r.value.get(n):void 0;return i&&i.count}function $P(t,e){const n=this.context.dataflow,r=this.context.data[t],i=r.input;return n.pulse(i,n.changeset().remove(We).insert(e)),1}function SP(t,e,n){if(t){const r=this.context.dataflow,i=t.mark.source;r.pulse(i,r.changeset().encode(t,e));}return n!==void 0?n:t}const _s=t=>function(e,n){return this.context.dataflow.locale()[t](n)(e)},BP=_s("format"),pD=_s("timeFormat"),TP=_s("utcFormat"),RP=_s("timeParse"),OP=_s("utcParse"),nl=new Date(2e3,0,1);function uh(t,e,n){return !Number.isInteger(t)||!Number.isInteger(e)?"":(nl.setYear(2e3),nl.setMonth(t),nl.setDate(e),pD.call(this,nl,n))}function NP(t){return uh.call(this,t,1,"%B")}function LP(t){return uh.call(this,t,1,"%b")}function PP(t){return uh.call(this,0,2+t,"%A")}function zP(t){return uh.call(this,0,2+t,"%a")}const IP=":",UP="@",u1="%",mD="$";function ey(t,e,n,r){e[0].type!==xn&&$("First argument to data functions must be a string literal.");const i=e[0].value,a=IP+i;if(!X(a,r))try{r[a]=n.getData(i).tuplesRef();}catch{}}function qP(t,e,n,r){e[0].type!==xn&&$("First argument to indata must be a string literal."),e[1].type!==xn&&$("Second argument to indata must be a string literal.");const i=e[0].value,a=e[1].value,u=UP+a;X(u,r)||(r[u]=n.getData(i).indataRef(n,a));}function Fe(t,e,n,r){if(e[0].type===xn)Iv(n,r,e[0].value);else for(t in n.scales)Iv(n,r,t);}function Iv(t,e,n){const r=u1+n;if(!X(e,r))try{e[r]=t.scaleRef(n);}catch{}}function ur(t,e){if(tt(t))return t;if(xt(t)){const n=e.scales[t];return n&&QE(n.value)?n.value:void 0}}function jP(t,e,n){e.__bandwidth=i=>i&&i.bandwidth?i.bandwidth():0,n._bandwidth=Fe,n._range=Fe,n._scale=Fe;const r=i=>"_["+(i.type===xn?Y(u1+i.value):Y(u1)+"+"+t(i))+"]";return {_bandwidth:i=>`this.__bandwidth(${r(i[0])})`,_range:i=>`${r(i[0])}.range()`,_scale:i=>`${r(i[0])}(${t(i[1])})`}}function ny(t,e){return function(n,r,i){if(n){const a=ur(n,(i||this).context);return a&&a.path[t](r)}else return e(r)}}const WP=ny("area",$A),YP=ny("bounds",OA),HP=ny("centroid",zA);function GP(t,e){const n=ur(t,(e||this).context);return n&&n.scale()}function XP(t){const e=this.context.group;let n=!1;if(e)for(;t;){if(t===e){n=!0;break}t=t.mark.group;}return n}function ry(t,e,n){try{t[e].apply(t,["EXPRESSION"].concat([].slice.call(n)));}catch(r){t.warn(r);}return n[n.length-1]}function VP(){return ry(this.context.dataflow,"warn",arguments)}function KP(){return ry(this.context.dataflow,"info",arguments)}function QP(){return ry(this.context.dataflow,"debug",arguments)}function w0(t){const e=t/255;return e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4)}function o1(t){const e=Vn(t),n=w0(e.r),r=w0(e.g),i=w0(e.b);return .2126*n+.7152*r+.0722*i}function ZP(t,e){const n=o1(t),r=o1(e),i=Math.max(n,r),a=Math.min(n,r);return (i+.05)/(a+.05)}function JP(){const t=[].slice.call(arguments);return t.unshift({}),nt(...t)}function yD(t,e){return t===e||t!==t&&e!==e?!0:U(t)?U(e)&&t.length===e.length?tz(t,e):!1:et(t)&&et(e)?xD(t,e):!1}function tz(t,e){for(let n=0,r=t.length;nxD(t,e)}function ez(t,e,n,r,i,a){const u=this.context.dataflow,o=this.context.data[t],s=o.input,l=u.stamp();let f=o.changes,c,h;if(u._trigger===!1||!(s.value.length||e||r))return 0;if((!f||f.stamp{o.modified=!0,u.pulse(s,f).run();},!0,1)),n&&(c=n===!0?We:U(n)||su(n)?n:Uv(n),f.remove(c)),e&&f.insert(e),r&&(c=Uv(r),s.value.some(c)?f.remove(c):f.insert(r)),i)for(h in a)f.modify(i,h,a[h]);return 1}function nz(t){const e=t.touches,n=e[0].clientX-e[1].clientX,r=e[0].clientY-e[1].clientY;return Math.hypot(n,r)}function rz(t){const e=t.touches;return Math.atan2(e[0].clientY-e[1].clientY,e[0].clientX-e[1].clientX)}const qv={};function iz(t,e){const n=qv[e]||(qv[e]=en(e));return U(t)?t.map(n):n(t)}function iy(t){return U(t)||ArrayBuffer.isView(t)?t:null}function ay(t){return iy(t)||(xt(t)?t:null)}function az(t){for(var e=arguments.length,n=new Array(e>1?e-1:0),r=1;r1?e-1:0),r=1;r1?e-1:0),r=1;r1?e-1:0),r=1;ra.stop(l(f),t(f))),a}function vz(t,e,n){const r=ur(t,(n||this).context);return function(i){return r?r.path.context(i)(e):""}}function bz(t){let e=null;return function(n){return n?Ha(n,e=e||Gi(t)):t}}const vD=t=>t.data;function bD(t,e){const n=gD.call(e,t);return n.root&&n.root.lookup||{}}function Az(t,e,n){const r=bD(t,this),i=r[e],a=r[n];return i&&a?i.path(a).map(vD):void 0}function wz(t,e){const n=bD(t,this)[e];return n?n.ancestors().map(vD):void 0}const AD=()=>typeof window<"u"&&window||null;function Ez(){const t=AD();return t?t.screen:{}}function _z(){const t=AD();return t?[t.innerWidth,t.innerHeight]:[void 0,void 0]}function Cz(){const t=this.context.dataflow,e=t.container&&t.container();return e?[e.clientWidth,e.clientHeight]:[void 0,void 0]}function wD(t,e,n){if(!t)return [];const[r,i]=t,a=new St().set(r[0],r[1],i[0],i[1]),u=n||this.context.dataflow.scenegraph().root;return cm(u,a,Dz(e))}function Dz(t){let e=null;if(t){const n=H(t.marktype),r=H(t.markname);e=i=>(!n.length||n.some(a=>i.marktype===a))&&(!r.length||r.some(a=>i.name===a));}return e}function Fz(t,e,n){let r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:5;t=H(t);const i=t[t.length-1];return i===void 0||Math.hypot(i[0]-e,i[1]-n)>r?[...t,[e,n]]:t}function Mz(t){return H(t).reduce((e,n,r)=>{let[i,a]=n;return e+=r==0?`M ${i},${a} `:r===t.length-1?" Z":`L ${i},${a} `},"")}function kz(t,e,n){const{x:r,y:i,mark:a}=n,u=new St().set(Number.MAX_SAFE_INTEGER,Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER,Number.MIN_SAFE_INTEGER);for(const[s,l]of e)su.x2&&(u.x2=s),lu.y2&&(u.y2=l);return u.translate(r,i),wD([[u.x1,u.y1],[u.x2,u.y2]],t,a).filter(s=>$z(s.x,s.y,e))}function $z(t,e,n){let r=0;for(let i=0,a=n.length-1;ie!=o>e&&t<(u-s)*(e-l)/(o-l)+s&&r++;}return r&1}const jo={random(){return un()},cumulativeNormal:is,cumulativeLogNormal:$c,cumulativeUniform:Rc,densityNormal:Fc,densityLogNormal:kc,densityUniform:Tc,quantileNormal:as,quantileLogNormal:Sc,quantileUniform:Oc,sampleNormal:rs,sampleLogNormal:Mc,sampleUniform:Bc,isArray:U,isBoolean:Ag,isDate:Cr,isDefined(t){return t!==void 0},isNumber:Mr,isObject:et,isRegExp:wg,isString:xt,isTuple:su,isValid(t){return t!=null&&t===t},toBoolean:xc,toDate(t){return vc(t)},toNumber:Kt,toString:bc,indexof:uz,join:az,lastindexof:oz,replace:lz,reverse:fz,slice:sz,flush:bg,lerp:_g,merge:JP,pad:Cg,peek:ut,pluck:iz,span:au,inrange:Bi,truncate:Dg,rgb:Vn,lab:wo,hcl:Eo,hsl:Ao,luminance:o1,contrast:ZP,sequence:Ie,format:BP,utcFormat:TP,utcParse:OP,utcOffset:Ng,utcSequence:Pg,timeFormat:pD,timeParse:RP,timeOffset:Og,timeSequence:Lg,timeUnitSpecifier:kg,monthFormat:NP,monthAbbrevFormat:LP,dayFormat:PP,dayAbbrevFormat:zP,quarter:pg,utcquarter:mg,week:Bg,utcweek:Rg,dayofyear:Sg,utcdayofyear:Tg,warn:VP,info:KP,debug:QP,extent(t){return Sn(t)},inScope:XP,intersect:wD,clampRange:yg,pinchDistance:nz,pinchAngle:rz,screen:Ez,containerSize:Cz,windowSize:_z,bandspace:cz,setdata:$P,pathShape:bz,panLinear:cg,panLog:hg,panPow:dg,panSymlog:gg,zoomLinear:gc,zoomLog:pc,zoomPow:Bo,zoomSymlog:mc,encode:SP,modify:ez,lassoAppend:Fz,lassoPath:Mz,intersectLasso:kz},Sz=["view","item","group","xy","x","y"],Bz="event.vega.",ED="this.",uy={},_D={forbidden:["_"],allowed:["datum","event","item"],fieldvar:"datum",globalvar:t=>`_[${Y(mD+t)}]`,functions:Tz,constants:Zm,visitors:uy},s1=oD(_D);function Tz(t){const e=Jm(t);Sz.forEach(n=>e[n]=Bz+n);for(const n in jo)e[n]=ED+n;return nt(e,jP(t,jo,uy)),e}function Tt(t,e,n){return arguments.length===1?jo[t]:(jo[t]=e,n&&(uy[t]=n),s1&&(s1.functions[t]=ED+t),this)}Tt("bandwidth",hz,Fe);Tt("copy",dz,Fe);Tt("domain",gz,Fe);Tt("range",mz,Fe);Tt("invert",pz,Fe);Tt("scale",yz,Fe);Tt("gradient",xz,Fe);Tt("geoArea",WP,Fe);Tt("geoBounds",YP,Fe);Tt("geoCentroid",HP,Fe);Tt("geoShape",vz,Fe);Tt("geoScale",GP,Fe);Tt("indata",kP,qP);Tt("data",gD,ey);Tt("treePath",Az,ey);Tt("treeAncestors",wz,ey);Tt("vlSelectionTest",lD,hu);Tt("vlSelectionIdTest",cD,hu);Tt("vlSelectionResolve",dD,hu);Tt("vlSelectionTuples",hD);function tr(t,e){const n={};let r;try{t=xt(t)?t:Y(t)+"",r=pP(t);}catch{$("Expression parse error: "+t);}r.visit(a=>{if(a.type!==tD)return;const u=a.callee.name,o=_D.visitors[u];o&&o(u,a.arguments,e,n);});const i=s1(r);return i.globals.forEach(a=>{const u=mD+a;!X(n,u)&&e.getSignal(a)&&(n[u]=e.signalRef(a));}),{$expr:nt({code:i.code},e.options.ast?{ast:r}:null),$fields:i.fields,$params:n}}function Rz(t){const e=this,n=t.operators||[];return t.background&&(e.background=t.background),t.eventConfig&&(e.eventConfig=t.eventConfig),t.locale&&(e.locale=t.locale),n.forEach(r=>e.parseOperator(r)),n.forEach(r=>e.parseOperatorParameters(r)),(t.streams||[]).forEach(r=>e.parseStream(r)),(t.updates||[]).forEach(r=>e.parseUpdate(r)),e.resolve()}const Oz=nn(["rule"]),jv=nn(["group","image","rect"]);function Nz(t,e){let n="";return Oz[e]||(t.x2&&(t.x?(jv[e]&&(n+="if(o.x>o.x2)$=o.x,o.x=o.x2,o.x2=$;"),n+="o.width=o.x2-o.x;"):n+="o.x=o.x2-(o.width||0);"),t.xc&&(n+="o.x=o.xc-(o.width||0)/2;"),t.y2&&(t.y?(jv[e]&&(n+="if(o.y>o.y2)$=o.y,o.y=o.y2,o.y2=$;"),n+="o.height=o.y2-o.y;"):n+="o.y=o.y2-(o.height||0);"),t.yc&&(n+="o.y=o.yc-(o.height||0)/2;")),n}function oy(t){return (t+"").toLowerCase()}function Lz(t){return oy(t)==="operator"}function Pz(t){return oy(t)==="collect"}function Tu(t,e,n){n.endsWith(";")||(n="return("+n+");");const r=Function(...e.concat(n));return t&&t.functions?r.bind(t.functions):r}function zz(t,e,n,r){return `((u = ${t}) < (v = ${e}) || u == null) && v != null ? ${n} + : (u > v || v == null) && u != null ? ${r} + : ((v = v instanceof Date ? +v : v), (u = u instanceof Date ? +u : u)) !== u && v === v ? ${n} + : v !== v && u === u ? ${r} : `}var Iz={operator:(t,e)=>Tu(t,["_"],e.code),parameter:(t,e)=>Tu(t,["datum","_"],e.code),event:(t,e)=>Tu(t,["event"],e.code),handler:(t,e)=>{const n=`var datum=event.item&&event.item.datum;return ${e.code};`;return Tu(t,["_","event"],n)},encode:(t,e)=>{const{marktype:n,channels:r}=e;let i="var o=item,datum=o.datum,m=0,$;";for(const a in r){const u="o["+Y(a)+"]";i+=`$=${r[a].code};if(${u}!==$)${u}=$,m=1;`;}return i+=Nz(r,n),i+="return m;",Tu(t,["item","_"],i)},codegen:{get(t){const e=`[${t.map(Y).join("][")}]`,n=Function("_",`return _${e};`);return n.path=e,n},comparator(t,e){let n;const r=(a,u)=>{const o=e[u];let s,l;return a.path?(s=`a${a.path}`,l=`b${a.path}`):((n=n||{})["f"+u]=a,s=`this.f${u}(a)`,l=`this.f${u}(b)`),zz(s,l,-o,o)},i=Function("a","b","var u, v; return "+t.map(r).join("")+"0;");return n?i.bind(n):i}}};function Uz(t){const e=this;Lz(t.type)||!t.type?e.operator(t,t.update?e.operatorExpression(t.update):null):e.transform(t,t.type);}function qz(t){const e=this;if(t.params){const n=e.get(t.id);n||$("Invalid operator id: "+t.id),e.dataflow.connect(n,n.parameters(e.parseParameters(t.params),t.react,t.initonly));}}function jz(t,e){e=e||{};const n=this;for(const r in t){const i=t[r];e[r]=U(i)?i.map(a=>Wv(a,n,e)):Wv(i,n,e);}return e}function Wv(t,e,n){if(!t||!et(t))return t;for(let r=0,i=Yv.length,a;ri&&i.$tupleid?K:i);return e.fn[n]||(e.fn[n]=xg(r,t.$order,e.expr.codegen))}function Vz(t,e){const n=t.$encode,r={};for(const i in n){const a=n[i];r[i]=Ge(e.encodeExpression(a.$expr),a.$fields),r[i].output=a.$output;}return r}function Kz(t,e){return e}function Qz(t,e){const n=t.$subflow;return function(r,i,a){const u=e.fork().parse(n),o=u.get(n.operators[0].id),s=u.signals.parent;return s&&s.set(a),o.detachSubflow=()=>e.detach(u),o}}function Zz(){return K}function Jz(t){var e=this,n=t.filter!=null?e.eventExpression(t.filter):void 0,r=t.stream!=null?e.get(t.stream):void 0,i;t.source?r=e.events(t.source,t.type,n):t.merge&&(i=t.merge.map(a=>e.get(a)),r=i[0].merge.apply(i[0],i.slice(1))),t.between&&(i=t.between.map(a=>e.get(a)),r=r.between(i[0],i[1])),t.filter&&(r=r.filter(n)),t.throttle!=null&&(r=r.throttle(+t.throttle)),t.debounce!=null&&(r=r.debounce(+t.debounce)),r==null&&$("Invalid stream definition: "+JSON.stringify(t)),t.consume&&r.consume(!0),e.stream(t,r);}function tI(t){var e=this,n=et(n=t.source)?n.$ref:n,r=e.get(n),i=null,a=t.update,u=void 0;r||$("Source not defined: "+t.source),i=t.target&&t.target.$expr?e.eventExpression(t.target.$expr):e.get(t.target),a&&a.$expr&&(a.$params&&(u=e.parseParameters(a.$params)),a=e.handlerExpression(a.$expr)),e.update(t,r,i,a,u);}const eI={skip:!0};function nI(t){var e=this,n={};if(t.signals){var r=n.signals={};Object.keys(e.signals).forEach(a=>{const u=e.signals[a];t.signals(a,u)&&(r[a]=u.value);});}if(t.data){var i=n.data={};Object.keys(e.data).forEach(a=>{const u=e.data[a];t.data(a,u)&&(i[a]=u.input.value);});}return e.subcontext&&t.recurse!==!1&&(n.subcontext=e.subcontext.map(a=>a.getState(t))),n}function rI(t){var e=this,n=e.dataflow,r=t.data,i=t.signals;Object.keys(i||{}).forEach(a=>{n.update(e.signals[a],i[a],eI);}),Object.keys(r||{}).forEach(a=>{n.pulse(e.data[a].input,n.changeset().remove(We).insert(r[a]));}),(t.subcontext||[]).forEach((a,u)=>{const o=e.subcontext[u];o&&o.setState(a);});}function CD(t,e,n,r){return new DD(t,e,n,r)}function DD(t,e,n,r){this.dataflow=t,this.transforms=e,this.events=t.events.bind(t),this.expr=r||Iz,this.signals={},this.scales={},this.nodes={},this.data={},this.fn={},n&&(this.functions=Object.create(n),this.functions.context=this);}function Hv(t){this.dataflow=t.dataflow,this.transforms=t.transforms,this.events=t.events,this.expr=t.expr,this.signals=Object.create(t.signals),this.scales=Object.create(t.scales),this.nodes=Object.create(t.nodes),this.data=Object.create(t.data),this.fn=Object.create(t.fn),t.functions&&(this.functions=Object.create(t.functions),this.functions.context=this);}DD.prototype=Hv.prototype={fork(){const t=new Hv(this);return (this.subcontext||(this.subcontext=[])).push(t),t},detach(t){this.subcontext=this.subcontext.filter(n=>n!==t);const e=Object.keys(t.nodes);for(const n of e)t.nodes[n]._targets=null;for(const n of e)t.nodes[n].detach();t.nodes=null;},get(t){return this.nodes[t]},set(t,e){return this.nodes[t]=e},add(t,e){const n=this,r=n.dataflow,i=t.value;if(n.set(t.id,e),Pz(t.type)&&i&&(i.$ingest?r.ingest(e,i.$ingest,i.$format):i.$request?r.preload(e,i.$request,i.$format):r.pulse(e,r.changeset().insert(i))),t.root&&(n.root=e),t.parent){let a=n.get(t.parent.$ref);a?(r.connect(a,[e]),e.targets().add(a)):(n.unresolved=n.unresolved||[]).push(()=>{a=n.get(t.parent.$ref),r.connect(a,[e]),e.targets().add(a);});}if(t.signal&&(n.signals[t.signal]=e),t.scale&&(n.scales[t.scale]=e),t.data)for(const a in t.data){const u=n.data[a]||(n.data[a]={});t.data[a].forEach(o=>u[o]=e);}},resolve(){return (this.unresolved||[]).forEach(t=>t()),delete this.unresolved,this},operator(t,e){this.add(t,this.dataflow.add(t.value,e));},transform(t,e){this.add(t,this.dataflow.add(this.transforms[oy(e)]));},stream(t,e){this.set(t.id,e);},update(t,e,n,r,i){this.dataflow.on(e,n,r,i,t.options);},operatorExpression(t){return this.expr.operator(this,t)},parameterExpression(t){return this.expr.parameter(this,t)},eventExpression(t){return this.expr.event(this,t)},handlerExpression(t){return this.expr.handler(this,t)},encodeExpression(t){return this.expr.encode(this,t)},parse:Rz,parseOperator:Uz,parseOperatorParameters:qz,parseParameters:jz,parseStream:Jz,parseUpdate:tI,getState:nI,setState:rI};function iI(t){const e=t.container();e&&(e.setAttribute("role","graphics-document"),e.setAttribute("aria-roleDescription","visualization"),FD(e,t.description()));}function FD(t,e){t&&(e==null?t.removeAttribute("aria-label"):t.setAttribute("aria-label",e));}function aI(t){t.add(null,e=>(t._background=e.bg,t._resize=1,e.bg),{bg:t._signals.background});}const E0="default";function uI(t){const e=t._signals.cursor||(t._signals.cursor=t.add({user:E0,item:null}));t.on(t.events("view","mousemove"),e,(n,r)=>{const i=e.value,a=i?xt(i)?i:i.user:E0,u=r.item&&r.item.cursor||null;return i&&a===i.user&&u==i.item?i:{user:a,item:u}}),t.add(null,function(n){let r=n.cursor,i=this.value;return xt(r)||(i=r.item,r=r.user),l1(t,r&&r!==E0?r:i||r),i},{cursor:e});}function l1(t,e){const n=t.globalCursor()?typeof document<"u"&&document.body:t.container();if(n)return e==null?n.style.removeProperty("cursor"):n.style.cursor=e}function Pf(t,e){var n=t._runtime.data;return X(n,e)||$("Unrecognized data set: "+e),n[e]}function oI(t,e){return arguments.length<2?Pf(this,t).values.value:oh.call(this,t,ra().remove(We).insert(e))}function oh(t,e){eE(e)||$("Second argument to changes must be a changeset.");const n=Pf(this,t);return n.modified=!0,this.pulse(n.input,e)}function sI(t,e){return oh.call(this,t,ra().insert(e))}function lI(t,e){return oh.call(this,t,ra().remove(e))}function MD(t){var e=t.padding();return Math.max(0,t._viewWidth+e.left+e.right)}function kD(t){var e=t.padding();return Math.max(0,t._viewHeight+e.top+e.bottom)}function sh(t){var e=t.padding(),n=t._origin;return [e.left+n[0],e.top+n[1]]}function fI(t){var e=sh(t),n=MD(t),r=kD(t);t._renderer.background(t.background()),t._renderer.resize(n,r,e),t._handler.origin(e),t._resizeListeners.forEach(i=>{try{i(n,r);}catch(a){t.error(a);}});}function cI(t,e,n){var r=t._renderer,i=r&&r.canvas(),a,u,o;return i&&(o=sh(t),u=e.changedTouches?e.changedTouches[0]:e,a=Jc(u,i),a[0]-=o[0],a[1]-=o[1]),e.dataflow=t,e.item=n,e.vega=hI(t,n,a),e}function hI(t,e,n){const r=e?e.mark.marktype==="group"?e:e.mark.group:null;function i(u){var o=r,s;if(u){for(s=e;s;s=s.mark.group)if(s.mark.name===u){o=s;break}}return o&&o.mark&&o.mark.interactive?o:{}}function a(u){if(!u)return n;xt(u)&&(u=i(u));const o=n.slice();for(;u;)o[0]-=u.x||0,o[1]-=u.y||0,u=u.mark&&u.mark.group;return o}return {view:pe(t),item:pe(e||{}),group:i,xy:a,x:u=>a(u)[0],y:u=>a(u)[1]}}const Gv="view",dI="timer",gI="window",pI={trap:!1};function mI(t){const e=nt({defaults:{}},t),n=(r,i)=>{i.forEach(a=>{U(r[a])&&(r[a]=nn(r[a]));});};return n(e.defaults,["prevent","allow"]),n(e,["view","window","selector"]),e}function $D(t,e,n,r){t._eventListeners.push({type:n,sources:H(e),handler:r});}function yI(t,e){var n=t._eventConfig.defaults,r=n.prevent,i=n.allow;return r===!1||i===!0?!1:r===!0||i===!1?!0:r?r[e]:i?!i[e]:t.preventDefault()}function rl(t,e,n){const r=t._eventConfig&&t._eventConfig[e];return r===!1||et(r)&&!r[n]?(t.warn(`Blocked ${e} ${n} event listener.`),!1):!0}function xI(t,e,n){var r=this,i=new Dc(n),a=function(l,f){r.runAsync(null,()=>{t===Gv&&yI(r,e)&&l.preventDefault(),i.receive(cI(r,l,f));});},u;if(t===dI)rl(r,"timer",e)&&r.timer(a,e);else if(t===Gv)rl(r,"view",e)&&r.addEventListener(e,a,pI);else if(t===gI?rl(r,"window",e)&&typeof window<"u"&&(u=[window]):typeof document<"u"&&rl(r,"selector",e)&&(u=Array.from(document.querySelectorAll(t))),!u)r.warn("Can not resolve event source: "+t);else {for(var o=0,s=u.length;o=0;)e[r].stop();for(r=n.length;--r>=0;)for(a=n[r],i=a.sources.length;--i>=0;)a.sources[i].removeEventListener(a.type,a.handler);return t&&t.call(this,this._handler,null,null,null),this}function tn(t,e,n){const r=document.createElement(t);for(const i in e)r.setAttribute(i,e[i]);return n!=null&&(r.textContent=n),r}const AI="vega-bind",wI="vega-bind-name",EI="vega-bind-radio";function _I(t,e,n){if(!e)return;const r=n.param;let i=n.state;return i||(i=n.state={elements:null,active:!1,set:null,update:u=>{u!=t.signal(r.signal)&&t.runAsync(null,()=>{i.source=!0,t.signal(r.signal,u);});}},r.debounce&&(i.update=vg(r.debounce,i.update))),(r.input==null&&r.element?CI:FI)(i,e,r,t),i.active||(t.on(t._signals[r.signal],null,()=>{i.source?i.source=!1:i.set(t.signal(r.signal));}),i.active=!0),i}function CI(t,e,n,r){const i=n.event||"input",a=()=>t.update(e.value);r.signal(n.signal,e.value),e.addEventListener(i,a),$D(r,e,i,a),t.set=u=>{e.value=u,e.dispatchEvent(DI(i));};}function DI(t){return typeof Event<"u"?new Event(t):{type:t}}function FI(t,e,n,r){const i=r.signal(n.signal),a=tn("div",{class:AI}),u=n.input==="radio"?a:a.appendChild(tn("label"));u.appendChild(tn("span",{class:wI},n.name||n.signal)),e.appendChild(a);let o=MI;switch(n.input){case"checkbox":o=kI;break;case"select":o=$I;break;case"radio":o=SI;break;case"range":o=BI;break}o(t,u,n,i);}function MI(t,e,n,r){const i=tn("input");for(const a in n)a!=="signal"&&a!=="element"&&i.setAttribute(a==="input"?"type":a,n[a]);i.setAttribute("name",n.signal),i.value=r,e.appendChild(i),i.addEventListener("input",()=>t.update(i.value)),t.elements=[i],t.set=a=>i.value=a;}function kI(t,e,n,r){const i={type:"checkbox",name:n.signal};r&&(i.checked=!0);const a=tn("input",i);e.appendChild(a),a.addEventListener("change",()=>t.update(a.checked)),t.elements=[a],t.set=u=>a.checked=!!u||null;}function $I(t,e,n,r){const i=tn("select",{name:n.signal}),a=n.labels||[];n.options.forEach((u,o)=>{const s={value:u};zf(u,r)&&(s.selected=!0),i.appendChild(tn("option",s,(a[o]||u)+""));}),e.appendChild(i),i.addEventListener("change",()=>{t.update(n.options[i.selectedIndex]);}),t.elements=[i],t.set=u=>{for(let o=0,s=n.options.length;o{const s={type:"radio",name:n.signal,value:u};zf(u,r)&&(s.checked=!0);const l=tn("input",s);l.addEventListener("change",()=>t.update(u));const f=tn("label",{},(a[o]||u)+"");return f.prepend(l),i.appendChild(f),l}),t.set=u=>{const o=t.elements,s=o.length;for(let l=0;l{s.textContent=o.value,t.update(+o.value);};o.addEventListener("input",l),o.addEventListener("change",l),t.elements=[o],t.set=f=>{o.value=f,s.textContent=f;};}function zf(t,e){return t===e||t+""==e+""}function SD(t,e,n,r,i,a){return e=e||new r(t.loader()),e.initialize(n,MD(t),kD(t),sh(t),i,a).background(t.background())}function sy(t,e){return e?function(){try{e.apply(this,arguments);}catch(n){t.error(n);}}:null}function TI(t,e,n,r){const i=new r(t.loader(),sy(t,t.tooltip())).scene(t.scenegraph().root).initialize(n,sh(t),t);return e&&e.handlers().forEach(a=>{i.on(a.type,a.handler);}),i}function RI(t,e){const n=this,r=n._renderType,i=n._eventConfig.bind,a=th(r);t=n._el=t?_0(n,t,!0):null,iI(n),a||n.error("Unrecognized renderer type: "+r);const u=a.handler||bs,o=t?a.renderer:a.headless;return n._renderer=o?SD(n,n._renderer,t,o):null,n._handler=TI(n,n._handler,t,u),n._redraw=!0,t&&i!=="none"&&(e=e?n._elBind=_0(n,e,!0):t.appendChild(tn("form",{class:"vega-bindings"})),n._bind.forEach(s=>{s.param.element&&i!=="container"&&(s.element=_0(n,s.param.element,!!s.param.input));}),n._bind.forEach(s=>{_I(n,s.element||e,s);})),n}function _0(t,e,n){if(typeof e=="string")if(typeof document<"u"){if(e=document.querySelector(e),!e)return t.error("Signal bind element not found: "+e),null}else return t.error("DOM document instance not found."),null;if(e&&n)try{e.textContent="";}catch(r){e=null,t.error(r);}return e}const Ru=t=>+t||0,OI=t=>({top:t,bottom:t,left:t,right:t});function Qv(t){return et(t)?{top:Ru(t.top),bottom:Ru(t.bottom),left:Ru(t.left),right:Ru(t.right)}:OI(Ru(t))}async function ly(t,e,n,r){const i=th(e),a=i&&i.headless;return a||$("Unrecognized renderer type: "+e),await t.runAsync(),SD(t,null,null,a,n,r).renderAsync(t._scenegraph.root)}async function NI(t,e){t!==Hr.Canvas&&t!==Hr.SVG&&t!==Hr.PNG&&$("Unrecognized image type: "+t);const n=await ly(this,t,e);return t===Hr.SVG?LI(n.svg(),"image/svg+xml"):n.canvas().toDataURL("image/png")}function LI(t,e){const n=new Blob([t],{type:e});return window.URL.createObjectURL(n)}async function PI(t,e){return (await ly(this,Hr.Canvas,t,e)).canvas()}async function zI(t){return (await ly(this,Hr.SVG,t)).svg()}function II(t,e,n){return CD(t,qa,jo,n).parse(e)}function UI(t){var e=this._runtime.scales;return X(e,t)||$("Unrecognized scale or projection: "+t),e[t].value}var BD="width",TD="height",fy="padding",Zv={skip:!0};function RD(t,e){var n=t.autosize(),r=t.padding();return e-(n&&n.contains===fy?r.left+r.right:0)}function OD(t,e){var n=t.autosize(),r=t.padding();return e-(n&&n.contains===fy?r.top+r.bottom:0)}function qI(t){var e=t._signals,n=e[BD],r=e[TD],i=e[fy];function a(){t._autosize=t._resize=1;}t._resizeWidth=t.add(null,o=>{t._width=o.size,t._viewWidth=RD(t,o.size),a();},{size:n}),t._resizeHeight=t.add(null,o=>{t._height=o.size,t._viewHeight=OD(t,o.size),a();},{size:r});const u=t.add(null,a,{pad:i});t._resizeWidth.rank=n.rank+1,t._resizeHeight.rank=r.rank+1,u.rank=i.rank+1;}function jI(t,e,n,r,i,a){this.runAfter(u=>{let o=0;u._autosize=0,u.width()!==n&&(o=1,u.signal(BD,n,Zv),u._resizeWidth.skip(!0)),u.height()!==r&&(o=1,u.signal(TD,r,Zv),u._resizeHeight.skip(!0)),u._viewWidth!==t&&(u._resize=1,u._viewWidth=t),u._viewHeight!==e&&(u._resize=1,u._viewHeight=e),(u._origin[0]!==i[0]||u._origin[1]!==i[1])&&(u._resize=1,u._origin=i),o&&u.run("enter"),a&&u.runAfter(s=>s.resize());},!1,1);}function WI(t){return this._runtime.getState(t||{data:YI,signals:HI,recurse:!0})}function YI(t,e){return e.modified&&U(e.input.value)&&t.indexOf("_:vega:_")}function HI(t,e){return !(t==="parent"||e instanceof qa.proxy)}function GI(t){return this.runAsync(null,e=>{e._trigger=!1,e._runtime.setState(t);},e=>{e._trigger=!0;}),this}function XI(t,e){function n(r){t({timestamp:Date.now(),elapsed:r});}this._timers.push(GF(n,e));}function VI(t,e,n,r){const i=t.element();i&&i.setAttribute("title",KI(r));}function KI(t){return t==null?"":U(t)?ND(t):et(t)&&!Cr(t)?QI(t):t+""}function QI(t){return Object.keys(t).map(e=>{const n=t[e];return e+": "+(U(n)?ND(n):LD(n))}).join(` +`)}function ND(t){return "["+t.map(LD).join(", ")+"]"}function LD(t){return U(t)?"[…]":et(t)&&!Cr(t)?"{…}":t}function PD(t,e){const n=this;if(e=e||{},ka.call(n),e.loader&&n.loader(e.loader),e.logger&&n.logger(e.logger),e.logLevel!=null&&n.logLevel(e.logLevel),e.locale||t.locale){const a=nt({},t.locale,e.locale);n.locale(Y3(a.number,a.time));}n._el=null,n._elBind=null,n._renderType=e.renderer||Hr.Canvas,n._scenegraph=new em;const r=n._scenegraph.root;n._renderer=null,n._tooltip=e.tooltip||VI,n._redraw=!0,n._handler=new bs().scene(r),n._globalCursor=!1,n._preventDefault=!1,n._timers=[],n._eventListeners=[],n._resizeListeners=[],n._eventConfig=mI(t.eventConfig),n.globalCursor(n._eventConfig.globalCursor);const i=II(n,t,e.expr);n._runtime=i,n._signals=i.signals,n._bind=(t.bindings||[]).map(a=>({state:null,param:nt({},a)})),i.root&&i.root.set(r),r.source=i.data.root.input,n.pulse(i.data.root.input,n.changeset().insert(r.items)),n._width=n.width(),n._height=n.height(),n._viewWidth=RD(n,n._width),n._viewHeight=OD(n,n._height),n._origin=[0,0],n._resize=0,n._autosize=1,qI(n),aI(n),uI(n),n.description(t.description),e.hover&&n.hover(),e.container&&n.initialize(e.container,e.bind);}function il(t,e){return X(t._signals,e)?t._signals[e]:$("Unrecognized signal name: "+Y(e))}function zD(t,e){const n=(t._targets||[]).filter(r=>r._update&&r._update.handler===e);return n.length?n[0]:null}function Jv(t,e,n,r){let i=zD(n,r);return i||(i=sy(t,()=>r(e,n.value)),i.handler=r,t.on(n,null,i)),t}function tb(t,e,n){const r=zD(e,n);return r&&e._targets.remove(r),t}L(PD,ka,{async evaluate(t,e,n){if(await ka.prototype.evaluate.call(this,t,e),this._redraw||this._resize)try{this._renderer&&(this._resize&&(this._resize=0,fI(this)),await this._renderer.renderAsync(this._scenegraph.root)),this._redraw=!1;}catch(r){this.error(r);}return n&&cl(this,n),this},dirty(t){this._redraw=!0,this._renderer&&this._renderer.dirty(t);},description(t){if(arguments.length){const e=t!=null?t+"":null;return e!==this._desc&&FD(this._el,this._desc=e),this}return this._desc},container(){return this._el},scenegraph(){return this._scenegraph},origin(){return this._origin.slice()},signal(t,e,n){const r=il(this,t);return arguments.length===1?r.value:this.update(r,e,n)},width(t){return arguments.length?this.signal("width",t):this.signal("width")},height(t){return arguments.length?this.signal("height",t):this.signal("height")},padding(t){return arguments.length?this.signal("padding",Qv(t)):Qv(this.signal("padding"))},autosize(t){return arguments.length?this.signal("autosize",t):this.signal("autosize")},background(t){return arguments.length?this.signal("background",t):this.signal("background")},renderer(t){return arguments.length?(th(t)||$("Unrecognized renderer type: "+t),t!==this._renderType&&(this._renderType=t,this._resetRenderer()),this):this._renderType},tooltip(t){return arguments.length?(t!==this._tooltip&&(this._tooltip=t,this._resetRenderer()),this):this._tooltip},loader(t){return arguments.length?(t!==this._loader&&(ka.prototype.loader.call(this,t),this._resetRenderer()),this):this._loader},resize(){return this._autosize=1,this.touch(il(this,"autosize"))},_resetRenderer(){this._renderer&&(this._renderer=null,this.initialize(this._el,this._elBind));},_resizeView:jI,addEventListener(t,e,n){let r=e;return n&&n.trap===!1||(r=sy(this,e),r.raw=e),this._handler.on(t,r),this},removeEventListener(t,e){for(var n=this._handler.handlers(t),r=n.length,i,a;--r>=0;)if(a=n[r].type,i=n[r].handler,t===a&&(e===i||e===i.raw)){this._handler.off(a,i);break}return this},addResizeListener(t){const e=this._resizeListeners;return e.indexOf(t)<0&&e.push(t),this},removeResizeListener(t){var e=this._resizeListeners,n=e.indexOf(t);return n>=0&&e.splice(n,1),this},addSignalListener(t,e){return Jv(this,t,il(this,t),e)},removeSignalListener(t,e){return tb(this,il(this,t),e)},addDataListener(t,e){return Jv(this,t,Pf(this,t).values,e)},removeDataListener(t,e){return tb(this,Pf(this,t).values,e)},globalCursor(t){if(arguments.length){if(this._globalCursor!==!!t){const e=l1(this,null);this._globalCursor=!!t,e&&l1(this,e);}return this}else return this._globalCursor},preventDefault(t){return arguments.length?(this._preventDefault=t,this):this._preventDefault},timer:XI,events:xI,finalize:bI,hover:vI,data:oI,change:oh,insert:sI,remove:lI,scale:UI,initialize:RI,toImageURL:NI,toCanvas:PI,toSVG:zI,getState:WI,setState:GI});function ID(t){const e=this.context.data[t];return e?e.values.value:[]}function ZI(t,e,n){const r=this.context.data[t]["index:"+e],i=r?r.value.get(n):void 0;return i&&i.count}function JI(t,e){const n=this.context.dataflow,r=this.context.data[t],i=r.input;return n.pulse(i,n.changeset().remove(We).insert(e)),1}function tU(t,e,n){if(t){const r=this.context.dataflow,i=t.mark.source;r.pulse(i,r.changeset().encode(t,e));}return n!==void 0?n:t}const Cs=t=>function(e,n){return this.context.dataflow.locale()[t](n)(e)},eU=Cs("format"),UD=Cs("timeFormat"),nU=Cs("utcFormat"),rU=Cs("timeParse"),iU=Cs("utcParse"),al=new Date(2e3,0,1);function lh(t,e,n){return !Number.isInteger(t)||!Number.isInteger(e)?"":(al.setYear(2e3),al.setMonth(t),al.setDate(e),UD.call(this,al,n))}function aU(t){return lh.call(this,t,1,"%B")}function uU(t){return lh.call(this,t,1,"%b")}function oU(t){return lh.call(this,0,2+t,"%A")}function sU(t){return lh.call(this,0,2+t,"%a")}const lU=":",fU="@",f1="%",cU="$";function cy(t,e,n,r){e[0].type!==xn&&$("First argument to data functions must be a string literal.");const i=e[0].value,a=lU+i;if(!X(a,r))try{r[a]=n.getData(i).tuplesRef();}catch{}}function hU(t,e,n,r){e[0].type!==xn&&$("First argument to indata must be a string literal."),e[1].type!==xn&&$("Second argument to indata must be a string literal.");const i=e[0].value,a=e[1].value,u=fU+a;X(u,r)||(r[u]=n.getData(i).indataRef(n,a));}function qe(t,e,n,r){if(e[0].type===xn)eb(n,r,e[0].value);else for(t in n.scales)eb(n,r,t);}function eb(t,e,n){const r=f1+n;if(!X(e,r))try{e[r]=t.scaleRef(n);}catch{}}function Br(t,e){if(tt(t))return t;if(xt(t)){const n=e.scales[t];return n&&QE(n.value)?n.value:void 0}}function dU(t,e,n){e.__bandwidth=i=>i&&i.bandwidth?i.bandwidth():0,n._bandwidth=qe,n._range=qe,n._scale=qe;const r=i=>"_["+(i.type===xn?Y(f1+i.value):Y(f1)+"+"+t(i))+"]";return {_bandwidth:i=>`this.__bandwidth(${r(i[0])})`,_range:i=>`${r(i[0])}.range()`,_scale:i=>`${r(i[0])}(${t(i[1])})`}}function hy(t,e){return function(n,r,i){if(n){const a=Br(n,(i||this).context);return a&&a.path[t](r)}else return e(r)}}const gU=hy("area",$A),pU=hy("bounds",OA),mU=hy("centroid",zA);function yU(t){const e=this.context.group;let n=!1;if(e)for(;t;){if(t===e){n=!0;break}t=t.mark.group;}return n}function dy(t,e,n){try{t[e].apply(t,["EXPRESSION"].concat([].slice.call(n)));}catch(r){t.warn(r);}return n[n.length-1]}function xU(){return dy(this.context.dataflow,"warn",arguments)}function vU(){return dy(this.context.dataflow,"info",arguments)}function bU(){return dy(this.context.dataflow,"debug",arguments)}function C0(t){const e=t/255;return e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4)}function c1(t){const e=Vn(t),n=C0(e.r),r=C0(e.g),i=C0(e.b);return .2126*n+.7152*r+.0722*i}function AU(t,e){const n=c1(t),r=c1(e),i=Math.max(n,r),a=Math.min(n,r);return (i+.05)/(a+.05)}function wU(){const t=[].slice.call(arguments);return t.unshift({}),nt(...t)}function qD(t,e){return t===e||t!==t&&e!==e?!0:U(t)?U(e)&&t.length===e.length?EU(t,e):!1:et(t)&&et(e)?jD(t,e):!1}function EU(t,e){for(let n=0,r=t.length;njD(t,e)}function _U(t,e,n,r,i,a){const u=this.context.dataflow,o=this.context.data[t],s=o.input,l=u.stamp();let f=o.changes,c,h;if(u._trigger===!1||!(s.value.length||e||r))return 0;if((!f||f.stamp{o.modified=!0,u.pulse(s,f).run();},!0,1)),n&&(c=n===!0?We:U(n)||su(n)?n:nb(n),f.remove(c)),e&&f.insert(e),r&&(c=nb(r),s.value.some(c)?f.remove(c):f.insert(r)),i)for(h in a)f.modify(i,h,a[h]);return 1}function CU(t){const e=t.touches,n=e[0].clientX-e[1].clientX,r=e[0].clientY-e[1].clientY;return Math.hypot(n,r)}function DU(t){const e=t.touches;return Math.atan2(e[0].clientY-e[1].clientY,e[0].clientX-e[1].clientX)}const rb={};function FU(t,e){const n=rb[e]||(rb[e]=en(e));return U(t)?t.map(n):n(t)}function gy(t){return U(t)||ArrayBuffer.isView(t)?t:null}function py(t){return gy(t)||(xt(t)?t:null)}function MU(t){for(var e=arguments.length,n=new Array(e>1?e-1:0),r=1;r1?e-1:0),r=1;r1?e-1:0),r=1;r1?e-1:0),r=1;ra.stop(l(f),t(f))),a}function qU(t,e,n){const r=Br(t,(n||this).context);return function(i){return r?r.path.context(i)(e):""}}function jU(t){let e=null;return function(n){return n?Ha(n,e=e||Gi(t)):t}}const WD=t=>t.data;function YD(t,e){const n=ID.call(e,t);return n.root&&n.root.lookup||{}}function WU(t,e,n){const r=YD(t,this),i=r[e],a=r[n];return i&&a?i.path(a).map(WD):void 0}function YU(t,e){const n=YD(t,this)[e];return n?n.ancestors().map(WD):void 0}const HD=()=>typeof window<"u"&&window||null;function HU(){const t=HD();return t?t.screen:{}}function GU(){const t=HD();return t?[t.innerWidth,t.innerHeight]:[void 0,void 0]}function XU(){const t=this.context.dataflow,e=t.container&&t.container();return e?[e.clientWidth,e.clientHeight]:[void 0,void 0]}function GD(t,e,n){if(!t)return [];const[r,i]=t,a=new St().set(r[0],r[1],i[0],i[1]),u=n||this.context.dataflow.scenegraph().root;return cm(u,a,VU(e))}function VU(t){let e=null;if(t){const n=H(t.marktype),r=H(t.markname);e=i=>(!n.length||n.some(a=>i.marktype===a))&&(!r.length||r.some(a=>i.name===a));}return e}function KU(t,e,n){let r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:5;t=H(t);const i=t[t.length-1];return i===void 0||Math.hypot(i[0]-e,i[1]-n)>r?[...t,[e,n]]:t}function QU(t){return H(t).reduce((e,n,r)=>{let[i,a]=n;return e+=r==0?`M ${i},${a} `:r===t.length-1?" Z":`L ${i},${a} `},"")}function ZU(t,e,n){const{x:r,y:i,mark:a}=n,u=new St().set(Number.MAX_SAFE_INTEGER,Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER,Number.MIN_SAFE_INTEGER);for(const[s,l]of e)su.x2&&(u.x2=s),lu.y2&&(u.y2=l);return u.translate(r,i),GD([[u.x1,u.y1],[u.x2,u.y2]],t,a).filter(s=>JU(s.x,s.y,e))}function JU(t,e,n){let r=0;for(let i=0,a=n.length-1;ie!=o>e&&t<(u-s)*(e-l)/(o-l)+s&&r++;}return r&1}const If={random(){return un()},cumulativeNormal:is,cumulativeLogNormal:$c,cumulativeUniform:Rc,densityNormal:Fc,densityLogNormal:kc,densityUniform:Tc,quantileNormal:as,quantileLogNormal:Sc,quantileUniform:Oc,sampleNormal:rs,sampleLogNormal:Mc,sampleUniform:Bc,isArray:U,isBoolean:Ag,isDate:Cr,isDefined(t){return t!==void 0},isNumber:Mr,isObject:et,isRegExp:wg,isString:xt,isTuple:su,isValid(t){return t!=null&&t===t},toBoolean:xc,toDate(t){return vc(t)},toNumber:Kt,toString:bc,indexof:kU,join:MU,lastindexof:$U,replace:BU,reverse:TU,slice:SU,flush:bg,lerp:_g,merge:wU,pad:Cg,peek:ut,pluck:FU,span:au,inrange:Bi,truncate:Dg,rgb:Vn,lab:wo,hcl:Eo,hsl:Ao,luminance:c1,contrast:AU,sequence:Ie,format:eU,utcFormat:nU,utcParse:iU,utcOffset:Ng,utcSequence:Pg,timeFormat:UD,timeParse:rU,timeOffset:Og,timeSequence:Lg,timeUnitSpecifier:kg,monthFormat:aU,monthAbbrevFormat:uU,dayFormat:oU,dayAbbrevFormat:sU,quarter:pg,utcquarter:mg,week:Bg,utcweek:Rg,dayofyear:Sg,utcdayofyear:Tg,warn:xU,info:vU,debug:bU,extent(t){return Sn(t)},inScope:yU,intersect:GD,clampRange:yg,pinchDistance:CU,pinchAngle:DU,screen:HU,containerSize:XU,windowSize:GU,bandspace:RU,setdata:JI,pathShape:jU,panLinear:cg,panLog:hg,panPow:dg,panSymlog:gg,zoomLinear:gc,zoomLog:pc,zoomPow:Bo,zoomSymlog:mc,encode:tU,modify:_U,lassoAppend:KU,lassoPath:QU,intersectLasso:ZU},tq=["view","item","group","xy","x","y"],eq="event.vega.",XD="this.",my={},nq={forbidden:["_"],allowed:["datum","event","item"],fieldvar:"datum",globalvar:t=>`_[${Y(cU+t)}]`,functions:rq,constants:Zm,visitors:my},ib=oD(nq);function rq(t){const e=Jm(t);tq.forEach(n=>e[n]=eq+n);for(const n in If)e[n]=XD+n;return nt(e,dU(t,If,my)),e}function Rt(t,e,n){return arguments.length===1?If[t]:(If[t]=e,n&&(my[t]=n),ib&&(ib.functions[t]=XD+t),this)}Rt("bandwidth",OU,qe);Rt("copy",NU,qe);Rt("domain",LU,qe);Rt("range",zU,qe);Rt("invert",PU,qe);Rt("scale",IU,qe);Rt("gradient",UU,qe);Rt("geoArea",gU,qe);Rt("geoBounds",pU,qe);Rt("geoCentroid",mU,qe);Rt("geoShape",qU,qe);Rt("indata",ZI,hU);Rt("data",ID,cy);Rt("treePath",WU,cy);Rt("treeAncestors",YU,cy);Rt("vlSelectionTest",lD,hu);Rt("vlSelectionIdTest",cD,hu);Rt("vlSelectionResolve",dD,hu);Rt("vlSelectionTuples",hD);const iq="view",Uf="[",qf="]",VD="{",KD="}",aq=":",QD=",",uq="@",oq=">",sq=/[[\]{}]/,lq={"*":1,arc:1,area:1,group:1,image:1,line:1,path:1,rect:1,rule:1,shape:1,symbol:1,text:1,trail:1};let ZD,JD;function t5(t,e,n){return ZD=e||iq,JD=n||lq,e5(t.trim()).map(h1)}function fq(t){return JD[t]}function yo(t,e,n,r,i){const a=t.length;let u=0,o;for(;e=0?--u:r&&r.indexOf(o)>=0&&++u;}return e}function e5(t){const e=[],n=t.length;let r=0,i=0;for(;i' after between selector: "+t;r=r.map(h1);const i=h1(t.slice(1).trim());return i.between?{between:r,stream:i}:(i.between=r,i)}function hq(t){const e={source:ZD},n=[];let r=[0,0],i=0,a=0,u=t.length,o=0,s,l;if(t[u-1]===KD){if(o=t.lastIndexOf(VD),o>=0){try{r=dq(t.substring(o+1,u-1));}catch{throw "Invalid throttle specification: "+t}t=t.slice(0,o).trim(),u=t.length;}else throw "Unmatched right brace: "+t;o=0;}if(!u)throw t;if(t[0]===uq&&(i=++o),s=yo(t,o,aq),s1?(e.type=n[1],i?e.markname=n[0].slice(1):fq(n[0])?e.marktype=n[0]:e.source=n[0]):e.type=n[0],e.type.slice(-1)==="!"&&(e.consume=!0,e.type=e.type.slice(0,-1)),l!=null&&(e.filter=l),r[0]&&(e.throttle=r[0]),r[1]&&(e.debounce=r[1]),e}function dq(t){const e=t.split(QD);if(!t.length||e.length>2)throw t;return e.map(n=>{const r=+n;if(r!==r)throw t;return r})}function gq(t){return et(t)?t:{type:t||"pad"}}const Ou=t=>+t||0,pq=t=>({top:t,bottom:t,left:t,right:t});function mq(t){return et(t)?t.signal?t:{top:Ou(t.top),bottom:Ou(t.bottom),left:Ou(t.left),right:Ou(t.right)}:pq(Ou(t))}const Yt=t=>et(t)&&!U(t)?nt({},t):{value:t};function ab(t,e,n,r){return n!=null?(et(n)&&!U(n)||U(n)&&n.length&&et(n[0])?t.update[e]=n:t[r||"enter"][e]={value:n},1):0}function te(t,e,n){for(const r in e)ab(t,r,e[r]);for(const r in n)ab(t,r,n[r],"update");}function du(t,e,n){for(const r in e)n&&X(n,r)||(t[r]=nt(t[r]||{},e[r]));return t}function va(t,e){return e&&(e.enter&&e.enter[t]||e.update&&e.update[t])}const yy="mark",xy="frame",vy="scope",yq="axis",xq="axis-domain",vq="axis-grid",bq="axis-label",Aq="axis-tick",wq="axis-title",Eq="legend",_q="legend-band",Cq="legend-entry",Dq="legend-gradient",n5="legend-label",Fq="legend-symbol",Mq="legend-title",kq="title",$q="title-text",Sq="title-subtitle";function Bq(t,e,n,r,i){const a={},u={};let o,s,l,f;s="lineBreak",e==="text"&&i[s]!=null&&!va(s,t)&&D0(a,s,i[s]),(n=="legend"||String(n).startsWith("axis"))&&(n=null),f=n===xy?i.group:n===yy?nt({},i.mark,i[e]):null;for(s in f)l=va(s,t)||(s==="fill"||s==="stroke")&&(va("fill",t)||va("stroke",t)),l||D0(a,s,f[s]);H(r).forEach(c=>{const h=i.style&&i.style[c];for(const d in h)va(d,t)||D0(a,d,h[d]);}),t=nt({},t);for(s in a)f=a[s],f.signal?(o=o||{})[s]=f:u[s]=f;return t.enter=nt(u,t.enter),o&&(t.update=nt(o,t.update)),t}function D0(t,e,n){t[e]=n&&n.signal?{signal:n.signal}:{value:n};}const r5=t=>xt(t)?Y(t):t.signal?`(${t.signal})`:i5(t);function fh(t){if(t.gradient!=null)return Rq(t);let e=t.signal?`(${t.signal})`:t.color?Tq(t.color):t.field!=null?i5(t.field):t.value!==void 0?Y(t.value):void 0;return t.scale!=null&&(e=Oq(t,e)),e===void 0&&(e=null),t.exponent!=null&&(e=`pow(${e},${_l(t.exponent)})`),t.mult!=null&&(e+=`*${_l(t.mult)}`),t.offset!=null&&(e+=`+${_l(t.offset)}`),t.round&&(e=`round(${e})`),e}const ul=(t,e,n,r)=>`(${t}(${[e,n,r].map(fh).join(",")})+'')`;function Tq(t){return t.c?ul("hcl",t.h,t.c,t.l):t.h||t.s?ul("hsl",t.h,t.s,t.l):t.l||t.a?ul("lab",t.l,t.a,t.b):t.r||t.g||t.b?ul("rgb",t.r,t.g,t.b):null}function Rq(t){const e=[t.start,t.stop,t.count].map(n=>n==null?null:Y(n));for(;e.length&&ut(e)==null;)e.pop();return e.unshift(r5(t.gradient)),`gradient(${e.join(",")})`}function _l(t){return et(t)?"("+fh(t)+")":t}function i5(t){return a5(et(t)?t:{datum:t})}function a5(t){let e,n,r;if(t.signal)e="datum",r=t.signal;else if(t.group||t.parent){for(n=Math.max(1,t.level||1),e="item";n-- >0;)e+=".mark.group";t.parent?(r=t.parent,e+=".datum"):r=t.group;}else t.datum?(e="datum",r=t.datum):$("Invalid field reference: "+Y(t));return t.signal||(r=xt(r)?cc(r).map(Y).join("]["):a5(r)),e+"["+r+"]"}function Oq(t,e){const n=r5(t.scale);return t.range!=null?e=`lerp(_range(${n}), ${+t.range})`:(e!==void 0&&(e=`_scale(${n}, ${e})`),t.band&&(e=(e?e+"+":"")+`_bandwidth(${n})`+(+t.band==1?"":"*"+_l(t.band)),t.extra&&(e=`(datum.extra ? _scale(${n}, datum.extra.value) : ${e})`)),e==null&&(e="0")),e}function Nq(t){let e="";return t.forEach(n=>{const r=fh(n);e+=n.test?`(${n.test})?${r}:`:r;}),ut(e)===":"&&(e+="null"),e}function u5(t,e,n,r,i,a){const u={};a=a||{},a.encoders={$encode:u},t=Bq(t,e,n,r,i.config);for(const o in t)u[o]=Lq(t[o],e,a,i);return a}function Lq(t,e,n,r){const i={},a={};for(const u in t)t[u]!=null&&(i[u]=zq(Pq(t[u]),r,n,a));return {$expr:{marktype:e,channels:i},$fields:Object.keys(a),$output:Object.keys(t)}}function Pq(t){return U(t)?Nq(t):fh(t)}function zq(t,e,n,r){const i=tr(t,e);return i.$fields.forEach(a=>r[a]=1),nt(n,i.$params),i.$expr}const Iq="outer",Uq=["value","update","init","react","bind"];function ub(t,e){$(t+' for "outer" push: '+Y(e));}function o5(t,e){const n=t.name;if(t.push===Iq)e.signals[n]||ub("No prior signal definition",n),Uq.forEach(r=>{t[r]!==void 0&&ub("Invalid property ",r);});else {const r=e.addSignal(n,t.value);t.react===!1&&(r.react=!1),t.bind&&e.addBinding(n,t.bind);}}function d1(t,e,n,r){this.id=-1,this.type=t,this.value=e,this.params=n,r&&(this.parent=r);}function ch(t,e,n,r){return new d1(t,e,n,r)}function jf(t,e){return ch("operator",t,e)}function V(t){const e={$ref:t.id};return t.id<0&&(t.refs=t.refs||[]).push(e),e}function Wo(t,e){return e?{$field:t,$name:e}:{$field:t}}const g1=Wo("key");function ob(t,e){return {$compare:t,$order:e}}function qq(t,e){const n={$key:t};return e&&(n.$flat=!0),n}const jq="ascending",Wq="descending";function Yq(t){return et(t)?(t.order===Wq?"-":"+")+hh(t.op,t.field):""}function hh(t,e){return (t&&t.signal?"$"+t.signal:t||"")+(t&&e?"_":"")+(e&&e.signal?"$"+e.signal:e||"")}const by="scope",p1="view";function Lt(t){return t&&t.signal}function Hq(t){return t&&t.expr}function Cl(t){if(Lt(t))return !0;if(et(t)){for(const e in t)if(Cl(t[e]))return !0}return !1}function An(t,e){return t??e}function zi(t){return t&&t.signal||t}const sb="timer";function Yo(t,e){return (t.merge?Xq:t.stream?Vq:t.type?Kq:$("Invalid stream specification: "+Y(t)))(t,e)}function Gq(t){return t===by?p1:t||p1}function Xq(t,e){const n=t.merge.map(i=>Yo(i,e)),r=Ay({merge:n},t,e);return e.addStream(r).id}function Vq(t,e){const n=Yo(t.stream,e),r=Ay({stream:n},t,e);return e.addStream(r).id}function Kq(t,e){let n;t.type===sb?(n=e.event(sb,t.throttle),t={between:t.between,filter:t.filter}):n=e.event(Gq(t.source),t.type);const r=Ay({stream:n},t,e);return Object.keys(r).length===1?n:e.addStream(r).id}function Ay(t,e,n){let r=e.between;return r&&(r.length!==2&&$('Stream "between" parameter must have 2 entries: '+Y(e)),t.between=[Yo(r[0],n),Yo(r[1],n)]),r=e.filter?[].concat(e.filter):[],(e.marktype||e.markname||e.markrole)&&r.push(Qq(e.marktype,e.markname,e.markrole)),e.source===by&&r.push("inScope(event.item)"),r.length&&(t.filter=tr("("+r.join(")&&(")+")",n).$expr),(r=e.throttle)!=null&&(t.throttle=+r),(r=e.debounce)!=null&&(t.debounce=+r),e.consume&&(t.consume=!0),t}function Qq(t,e,n){const r="event.item";return r+(t&&t!=="*"?"&&"+r+".mark.marktype==='"+t+"'":"")+(n?"&&"+r+".mark.role==='"+n+"'":"")+(e?"&&"+r+".mark.name==='"+e+"'":"")}const Zq={code:"_.$value",ast:{type:"Identifier",value:"value"}};function Jq(t,e,n){const r=t.encode,i={target:n};let a=t.events,u=t.update,o=[];a||$("Signal update missing events specification."),xt(a)&&(a=t5(a,e.isSubscope()?by:p1)),a=H(a).filter(s=>s.signal||s.scale?(o.push(s),0):1),o.length>1&&(o=[ej(o)]),a.length&&o.push(a.length>1?{merge:a}:a[0]),r!=null&&(u&&$("Signal encode and update are mutually exclusive."),u="encode(item(),"+Y(r)+")"),i.update=xt(u)?tr(u,e):u.expr!=null?tr(u.expr,e):u.value!=null?u.value:u.signal!=null?{$expr:Zq,$params:{$value:e.signalRef(u.signal)}}:$("Invalid signal update specification."),t.force&&(i.options={force:!0}),o.forEach(s=>e.addUpdate(nt(tj(s,e),i)));}function tj(t,e){return {source:t.signal?e.signalRef(t.signal):t.scale?e.scaleRef(t.scale):Yo(t,e)}}function ej(t){return {signal:"["+t.map(e=>e.scale?'scale("'+e.scale+'")':e.signal)+"]"}}function nj(t,e){const n=e.getSignal(t.name);let r=t.update;t.init&&(r?$("Signals can not include both init and update expressions."):(r=t.init,n.initonly=!0)),r&&(r=tr(r,e),n.update=r.$expr,n.params=r.$params),t.on&&t.on.forEach(i=>Jq(i,e,n.id));}const vt=t=>(e,n,r)=>ch(t,n,e||void 0,r),s5=vt("aggregate"),rj=vt("axisticks"),l5=vt("bound"),On=vt("collect"),lb=vt("compare"),ij=vt("datajoin"),f5=vt("encode"),aj=vt("expression"),uj=vt("facet"),oj=vt("field"),sj=vt("key"),lj=vt("legendentries"),fj=vt("load"),cj=vt("mark"),hj=vt("multiextent"),dj=vt("multivalues"),gj=vt("overlap"),pj=vt("params"),c5=vt("prefacet"),mj=vt("projection"),yj=vt("proxy"),xj=vt("relay"),h5=vt("render"),vj=vt("scale"),ua=vt("sieve"),bj=vt("sortitems"),d5=vt("viewlayout"),Aj=vt("values");let wj=0;const g5={min:"min",max:"max",count:"sum"};function Ej(t,e){const n=t.type||"linear";ZE(n)||$("Unrecognized scale type: "+Y(n)),e.addScale(t.name,{type:n,domain:void 0});}function _j(t,e){const n=e.getScale(t.name).params;let r;n.domain=p5(t.domain,t,e),t.range!=null&&(n.range=y5(t,e,n)),t.interpolate!=null&&Rj(t.interpolate,n),t.nice!=null&&(n.nice=Tj(t.nice)),t.bins!=null&&(n.bins=Bj(t.bins,e));for(r in t)X(n,r)||r==="name"||(n[r]=dn(t[r],e));}function dn(t,e){return et(t)?t.signal?e.signalRef(t.signal):$("Unsupported object: "+Y(t)):t}function Dl(t,e){return t.signal?e.signalRef(t.signal):t.map(n=>dn(n,e))}function dh(t){$("Can not find data set: "+Y(t));}function p5(t,e,n){if(!t){(e.domainMin!=null||e.domainMax!=null)&&$("No scale domain defined for domainMin/domainMax to override.");return}return t.signal?n.signalRef(t.signal):(U(t)?Cj:t.fields?Fj:Dj)(t,e,n)}function Cj(t,e,n){return t.map(r=>dn(r,n))}function Dj(t,e,n){const r=n.getData(t.data);return r||dh(t.data),Ya(e.type)?r.valuesRef(n,t.field,m5(t.sort,!1)):e_(e.type)?r.domainRef(n,t.field):r.extentRef(n,t.field)}function Fj(t,e,n){const r=t.data,i=t.fields.reduce((a,u)=>(u=xt(u)?{data:r,field:u}:U(u)||u.signal?Mj(u,n):u,a.push(u),a),[]);return (Ya(e.type)?kj:e_(e.type)?$j:Sj)(t,n,i)}function Mj(t,e){const n="_:vega:_"+wj++,r=On({});if(U(t))r.value={$ingest:t};else if(t.signal){const i="setdata("+Y(n)+","+t.signal+")";r.params.input=e.signalRef(i);}return e.addDataPipeline(n,[r,ua({})]),{data:n,field:"data"}}function kj(t,e,n){const r=m5(t.sort,!0);let i,a;const u=n.map(l=>{const f=e.getData(l.data);return f||dh(l.data),f.countsRef(e,l.field,r)}),o={groupby:g1,pulse:u};r&&(i=r.op||"count",a=r.field?hh(i,r.field):"count",o.ops=[g5[i]],o.fields=[e.fieldRef(a)],o.as=[a]),i=e.add(s5(o));const s=e.add(On({pulse:V(i)}));return a=e.add(Aj({field:g1,sort:e.sortRef(r),pulse:V(s)})),V(a)}function m5(t,e){return t&&(!t.field&&!t.op?et(t)?t.field="key":t={field:"key"}:!t.field&&t.op!=="count"?$("No field provided for sort aggregate op: "+t.op):e&&t.field&&t.op&&!g5[t.op]&&$("Multiple domain scales can not be sorted using "+t.op)),t}function $j(t,e,n){const r=n.map(i=>{const a=e.getData(i.data);return a||dh(i.data),a.domainRef(e,i.field)});return V(e.add(dj({values:r})))}function Sj(t,e,n){const r=n.map(i=>{const a=e.getData(i.data);return a||dh(i.data),a.extentRef(e,i.field)});return V(e.add(hj({extents:r})))}function Bj(t,e){return t.signal||U(t)?Dl(t,e):e.objectProperty(t)}function Tj(t){return et(t)?{interval:dn(t.interval),step:dn(t.step)}:dn(t)}function Rj(t,e){e.interpolate=dn(t.type||t),t.gamma!=null&&(e.interpolateGamma=dn(t.gamma));}function y5(t,e,n){const r=e.config.range;let i=t.range;if(i.signal)return e.signalRef(i.signal);if(xt(i)){if(r&&X(r,i))return t=nt({},t,{range:r[i]}),y5(t,e,n);i==="width"?i=[0,{signal:"width"}]:i==="height"?i=Ya(t.type)?[0,{signal:"height"}]:[{signal:"height"},0]:$("Unrecognized scale range value: "+Y(i));}else if(i.scheme){n.scheme=U(i.scheme)?Dl(i.scheme,e):dn(i.scheme,e),i.extent&&(n.schemeExtent=Dl(i.extent,e)),i.count&&(n.schemeCount=dn(i.count,e));return}else if(i.step){n.rangeStep=dn(i.step,e);return}else {if(Ya(t.type)&&!U(i))return p5(i,t,e);U(i)||$("Unsupported range type: "+Y(i));}return i.map(a=>(U(a)?Dl:dn)(a,e))}function Oj(t,e){const n=e.config.projection||{},r={};for(const i in t)i!=="name"&&(r[i]=m1(t[i],i,e));for(const i in n)r[i]==null&&(r[i]=m1(n[i],i,e));e.addProjection(t.name,r);}function m1(t,e,n){return U(t)?t.map(r=>m1(r,e,n)):et(t)?t.signal?n.signalRef(t.signal):e==="fit"?t:$("Unsupported parameter object: "+Y(t)):t}const Nn="top",gu="left",pu="right",li="bottom",x5="center",Nj="vertical",Lj="start",Pj="middle",zj="end",y1="index",wy="label",Ij="offset",Qa="perc",Uj="perc2",gn="value",Ds="guide-label",Ey="guide-title",qj="group-title",jj="group-subtitle",fb="symbol",Fl="gradient",x1="discrete",v1="size",Wj="shape",Yj="fill",Hj="stroke",Gj="strokeWidth",Xj="strokeDash",Vj="opacity",_y=[v1,Wj,Yj,Hj,Gj,Xj,Vj],Fs={name:1,style:1,interactive:1},lt={value:0},pn={value:1},gh="group",v5="rect",Cy="rule",Kj="symbol",oa="text";function Ho(t){return t.type=gh,t.interactive=t.interactive||!1,t}function Xe(t,e){const n=(r,i)=>An(t[r],An(e[r],i));return n.isVertical=r=>Nj===An(t.direction,e.direction||(r?e.symbolDirection:e.gradientDirection)),n.gradientLength=()=>An(t.gradientLength,e.gradientLength||e.gradientWidth),n.gradientThickness=()=>An(t.gradientThickness,e.gradientThickness||e.gradientHeight),n.entryColumns=()=>An(t.columns,An(e.columns,+n.isVertical(!0))),n}function b5(t,e){const n=e&&(e.update&&e.update[t]||e.enter&&e.enter[t]);return n&&n.signal?n:n?n.value:null}function Qj(t,e,n){const r=e.config.style[n];return r&&r[t]}function ph(t,e,n){return `item.anchor === '${Lj}' ? ${t} : item.anchor === '${zj}' ? ${e} : ${n}`}const Dy=ph(Y(gu),Y(pu),Y(x5));function Zj(t){const e=t("tickBand");let n=t("tickOffset"),r,i;return e?e.signal?(r={signal:`(${e.signal}) === 'extent' ? 1 : 0.5`},i={signal:`(${e.signal}) === 'extent'`},et(n)||(n={signal:`(${e.signal}) === 'extent' ? 0 : ${n}`})):e==="extent"?(r=1,i=!0,n=0):(r=.5,i=!1):(r=t("bandPosition"),i=t("tickExtra")),{extra:i,band:r,offset:n}}function A5(t,e){return e?t?et(t)?Object.assign({},t,{offset:A5(t.offset,e)}):{value:t,offset:e}:e:t}function sn(t,e){return e?(t.name=e.name,t.style=e.style||t.style,t.interactive=!!e.interactive,t.encode=du(t.encode,e,Fs)):t.interactive=!1,t}function Jj(t,e,n,r){const i=Xe(t,n),a=i.isVertical(),u=i.gradientThickness(),o=i.gradientLength();let s,l,f,c,h;a?(l=[0,1],f=[0,0],c=u,h=o):(l=[0,0],f=[1,0],c=o,h=u);const d={enter:s={opacity:lt,x:lt,y:lt,width:Yt(c),height:Yt(h)},update:nt({},s,{opacity:pn,fill:{gradient:e,start:l,stop:f}}),exit:{opacity:lt}};return te(d,{stroke:i("gradientStrokeColor"),strokeWidth:i("gradientStrokeWidth")},{opacity:i("gradientOpacity")}),sn({type:v5,role:Dq,encode:d},r)}function tW(t,e,n,r,i){const a=Xe(t,n),u=a.isVertical(),o=a.gradientThickness(),s=a.gradientLength();let l,f,c,h,d="";u?(l="y",c="y2",f="x",h="width",d="1-"):(l="x",c="x2",f="y",h="height");const g={opacity:lt,fill:{scale:e,field:gn}};g[l]={signal:d+"datum."+Qa,mult:s},g[f]=lt,g[c]={signal:d+"datum."+Uj,mult:s},g[h]=Yt(o);const p={enter:g,update:nt({},g,{opacity:pn}),exit:{opacity:lt}};return te(p,{stroke:a("gradientStrokeColor"),strokeWidth:a("gradientStrokeWidth")},{opacity:a("gradientOpacity")}),sn({type:v5,role:_q,key:gn,from:i,encode:p},r)}const eW=`datum.${Qa}<=0?"${gu}":datum.${Qa}>=1?"${pu}":"${x5}"`,nW=`datum.${Qa}<=0?"${li}":datum.${Qa}>=1?"${Nn}":"${Pj}"`;function cb(t,e,n,r){const i=Xe(t,e),a=i.isVertical(),u=Yt(i.gradientThickness()),o=i.gradientLength();let s=i("labelOverlap"),l,f,c,h,d="";const g={enter:l={opacity:lt},update:f={opacity:pn,text:{field:wy}},exit:{opacity:lt}};return te(g,{fill:i("labelColor"),fillOpacity:i("labelOpacity"),font:i("labelFont"),fontSize:i("labelFontSize"),fontStyle:i("labelFontStyle"),fontWeight:i("labelFontWeight"),limit:An(t.labelLimit,e.gradientLabelLimit)}),a?(l.align={value:"left"},l.baseline=f.baseline={signal:nW},c="y",h="x",d="1-"):(l.align=f.align={signal:eW},l.baseline={value:"top"},c="x",h="y"),l[c]=f[c]={signal:d+"datum."+Qa,mult:o},l[h]=f[h]=u,u.offset=An(t.labelOffset,e.gradientLabelOffset)||0,s=s?{separation:i("labelSeparation"),method:s,order:"datum."+y1}:void 0,sn({type:oa,role:n5,style:Ds,key:gn,from:r,encode:g,overlap:s},n)}function rW(t,e,n,r,i){const a=Xe(t,e),u=n.entries,o=!!(u&&u.interactive),s=u?u.name:void 0,l=a("clipHeight"),f=a("symbolOffset"),c={data:"value"},h=`(${i}) ? datum.${Ij} : datum.${v1}`,d=l?Yt(l):{field:v1},g=`datum.${y1}`,p=`max(1, ${i})`;let m,y,x,v,b;d.mult=.5,m={enter:y={opacity:lt,x:{signal:h,mult:.5,offset:f},y:d},update:x={opacity:pn,x:y.x,y:y.y},exit:{opacity:lt}};let w=null,E=null;t.fill||(w=e.symbolBaseFillColor,E=e.symbolBaseStrokeColor),te(m,{fill:a("symbolFillColor",w),shape:a("symbolType"),size:a("symbolSize"),stroke:a("symbolStrokeColor",E),strokeDash:a("symbolDash"),strokeDashOffset:a("symbolDashOffset"),strokeWidth:a("symbolStrokeWidth")},{opacity:a("symbolOpacity")}),_y.forEach(F=>{t[F]&&(x[F]=y[F]={scale:t[F],field:gn});});const A=sn({type:Kj,role:Fq,key:gn,from:c,clip:l?!0:void 0,encode:m},n.symbols),_=Yt(f);_.offset=a("labelOffset"),m={enter:y={opacity:lt,x:{signal:h,offset:_},y:d},update:x={opacity:pn,text:{field:wy},x:y.x,y:y.y},exit:{opacity:lt}},te(m,{align:a("labelAlign"),baseline:a("labelBaseline"),fill:a("labelColor"),fillOpacity:a("labelOpacity"),font:a("labelFont"),fontSize:a("labelFontSize"),fontStyle:a("labelFontStyle"),fontWeight:a("labelFontWeight"),limit:a("labelLimit")});const C=sn({type:oa,role:n5,style:Ds,key:gn,from:c,encode:m},n.labels);return m={enter:{noBound:{value:!l},width:lt,height:l?Yt(l):lt,opacity:lt},exit:{opacity:lt},update:x={opacity:pn,row:{signal:null},column:{signal:null}}},a.isVertical(!0)?(v=`ceil(item.mark.items.length / ${p})`,x.row.signal=`${g}%${v}`,x.column.signal=`floor(${g} / ${v})`,b={field:["row",g]}):(x.row.signal=`floor(${g} / ${p})`,x.column.signal=`${g} % ${p}`,b={field:g}),x.column.signal=`(${i})?${x.column.signal}:${g}`,r={facet:{data:r,name:"value",groupby:y1}},Ho({role:vy,from:r,encode:du(m,u,Fs),marks:[A,C],name:s,interactive:o,sort:b})}function iW(t,e){const n=Xe(t,e);return {align:n("gridAlign"),columns:n.entryColumns(),center:{row:!0,column:!1},padding:{row:n("rowPadding"),column:n("columnPadding")}}}const Fy='item.orient === "left"',My='item.orient === "right"',mh=`(${Fy} || ${My})`,aW=`datum.vgrad && ${mh}`,uW=ph('"top"','"bottom"','"middle"'),oW=ph('"right"','"left"','"center"'),sW=`datum.vgrad && ${My} ? (${oW}) : (${mh} && !(datum.vgrad && ${Fy})) ? "left" : ${Dy}`,lW=`item._anchor || (${mh} ? "middle" : "start")`,fW=`${aW} ? (${Fy} ? -90 : 90) : 0`,cW=`${mh} ? (datum.vgrad ? (${My} ? "bottom" : "top") : ${uW}) : "top"`;function hW(t,e,n,r){const i=Xe(t,e),a={enter:{opacity:lt},update:{opacity:pn,x:{field:{group:"padding"}},y:{field:{group:"padding"}}},exit:{opacity:lt}};return te(a,{orient:i("titleOrient"),_anchor:i("titleAnchor"),anchor:{signal:lW},angle:{signal:fW},align:{signal:sW},baseline:{signal:cW},text:t.title,fill:i("titleColor"),fillOpacity:i("titleOpacity"),font:i("titleFont"),fontSize:i("titleFontSize"),fontStyle:i("titleFontStyle"),fontWeight:i("titleFontWeight"),limit:i("titleLimit"),lineHeight:i("titleLineHeight")},{align:i("titleAlign"),baseline:i("titleBaseline")}),sn({type:oa,role:Mq,style:Ey,from:r,encode:a},n)}function dW(t,e){let n;return et(t)&&(t.signal?n=t.signal:t.path?n="pathShape("+hb(t.path)+")":t.sphere&&(n="geoShape("+hb(t.sphere)+', {type: "Sphere"})')),n?e.signalRef(n):!!t}function hb(t){return et(t)&&t.signal?t.signal:Y(t)}function w5(t){const e=t.role||"";return !e.indexOf("axis")||!e.indexOf("legend")||!e.indexOf("title")?e:t.type===gh?vy:e||yy}function gW(t){return {marktype:t.type,name:t.name||void 0,role:t.role||w5(t),zindex:+t.zindex||void 0,aria:t.aria,description:t.description}}function pW(t,e){return t&&t.signal?e.signalRef(t.signal):t!==!1}function ky(t,e){const n=iE(t.type);n||$("Unrecognized transform type: "+Y(t.type));const r=ch(n.type.toLowerCase(),null,E5(n,t,e));return t.signal&&e.addSignal(t.signal,e.proxy(r)),r.metadata=n.metadata||{},r}function E5(t,e,n){const r={},i=t.params.length;for(let a=0;adb(t,a,n)):db(t,i,n)}function db(t,e,n){const r=t.type;if(Lt(e))return pb(r)?$("Expression references can not be signals."):F0(r)?n.fieldRef(e):mb(r)?n.compareRef(e):n.signalRef(e.signal);{const i=t.expr||F0(r);return i&&vW(e)?n.exprRef(e.expr,e.as):i&&bW(e)?Wo(e.field,e.as):pb(r)?tr(e,n):AW(r)?V(n.getData(e).values):F0(r)?Wo(e):mb(r)?n.compareRef(e):e}}function yW(t,e,n){return xt(e.from)||$('Lookup "from" parameter must be a string literal.'),n.getData(e.from).lookupRef(n,e.key)}function xW(t,e,n){const r=e[t.name];return t.array?(U(r)||$("Expected an array of sub-parameters. Instead: "+Y(r)),r.map(i=>gb(t,i,n))):gb(t,r,n)}function gb(t,e,n){const r=t.params.length;let i;for(let u=0;ut&&t.expr,bW=t=>t&&t.field,AW=t=>t==="data",pb=t=>t==="expr",F0=t=>t==="field",mb=t=>t==="compare";function wW(t,e,n){let r,i,a,u,o;return t?(r=t.facet)&&(e||$("Only group marks can be faceted."),r.field!=null?u=o=Ml(r,n):(t.data?o=V(n.getData(t.data).aggregate):(a=ky(nt({type:"aggregate",groupby:H(r.groupby)},r.aggregate),n),a.params.key=n.keyRef(r.groupby),a.params.pulse=Ml(r,n),u=o=V(n.add(a))),i=n.keyRef(r.groupby,!0))):u=V(n.add(On(null,[{}]))),u||(u=Ml(t,n)),{key:i,pulse:u,parent:o}}function Ml(t,e){return t.$ref?t:t.data&&t.data.$ref?t.data:V(e.getData(t.data).output)}function Ki(t,e,n,r,i){this.scope=t,this.input=e,this.output=n,this.values=r,this.aggregate=i,this.index={};}Ki.fromEntries=function(t,e){const n=e.length,r=e[n-1],i=e[n-2];let a=e[0],u=null,o=1;for(a&&a.type==="load"&&(a=e[1]),t.add(e[0]);oc??"null").join(",")+"),0)",f=tr(l,e);s.update=f.$expr,s.params=f.$params;}function yh(t,e){const n=w5(t),r=t.type===gh,i=t.from&&t.from.facet,a=t.overlap;let u=t.layout||n===vy||n===xy,o,s,l,f,c,h,d;const g=n===yy||u||i,p=wW(t.from,r,e);s=e.add(ij({key:p.key||(t.key?Wo(t.key):void 0),pulse:p.pulse,clean:!r}));const m=V(s);s=l=e.add(On({pulse:m})),s=e.add(cj({markdef:gW(t),interactive:pW(t.interactive,e),clip:dW(t.clip,e),context:{$context:!0},groups:e.lookup(),parent:e.signals.parent?e.signalRef("parent"):null,index:e.markpath(),pulse:V(s)}));const y=V(s);s=f=e.add(f5(u5(t.encode,t.type,n,t.style,e,{mod:!1,pulse:y}))),s.params.parent=e.encode(),t.transform&&t.transform.forEach(E=>{const A=ky(E,e),_=A.metadata;(_.generates||_.changes)&&$("Mark transforms should not generate new data."),_.nomod||(f.params.mod=!0),A.params.pulse=V(s),e.add(s=A);}),t.sort&&(s=e.add(bj({sort:e.compareRef(t.sort),pulse:V(s)})));const x=V(s);(i||u)&&(u=e.add(d5({layout:e.objectProperty(t.layout),legends:e.legends,mark:y,pulse:x})),h=V(u));const v=e.add(l5({mark:y,pulse:h||x}));d=V(v),r&&(g&&(o=e.operators,o.pop(),u&&o.pop()),e.pushState(x,h||d,m),i?EW(t,e,p):g?_W(t,e,p):e.parse(t),e.popState(),g&&(u&&o.push(u),o.push(v))),a&&(d=CW(a,d,e));const b=e.add(h5({pulse:d})),w=e.add(ua({pulse:V(b)},void 0,e.parent()));t.name!=null&&(c=t.name,e.addData(c,new Ki(e,l,b,w)),t.on&&t.on.forEach(E=>{(E.insert||E.remove||E.toggle)&&$("Marks only support modify triggers."),C5(E,e,c);}));}function CW(t,e,n){const r=t.method,i=t.bound,a=t.separation,u={separation:Lt(a)?n.signalRef(a.signal):a,method:Lt(r)?n.signalRef(r.signal):r,pulse:e};if(t.order&&(u.sort=n.compareRef({field:t.order})),i){const o=i.tolerance;u.boundTolerance=Lt(o)?n.signalRef(o.signal):+o,u.boundScale=n.scaleRef(i.scale),u.boundOrient=i.orient;}return V(n.add(gj(u)))}function DW(t,e){const n=e.config.legend,r=t.encode||{},i=Xe(t,n),a=r.legend||{},u=a.name||void 0,o=a.interactive,s=a.style,l={};let f=0,c,h,d;_y.forEach(v=>t[v]?(l[v]=t[v],f=f||t[v]):0),f||$("Missing valid scale for legend.");const g=FW(t,e.scaleType(f)),p={title:t.title!=null,scales:l,type:g,vgrad:g!=="symbol"&&i.isVertical()},m=V(e.add(On(null,[p]))),y={enter:{x:{value:0},y:{value:0}}},x=V(e.add(lj(h={type:g,scale:e.scaleRef(f),count:e.objectProperty(i("tickCount")),limit:e.property(i("symbolLimit")),values:e.objectProperty(t.values),minstep:e.property(t.tickMinStep),formatType:e.property(t.formatType),formatSpecifier:e.property(t.format)})));return g===Fl?(d=[Jj(t,f,n,r.gradient),cb(t,n,r.labels,x)],h.count=h.count||e.signalRef(`max(2,2*floor((${zi(i.gradientLength())})/100))`)):g===x1?d=[tW(t,f,n,r.gradient,x),cb(t,n,r.labels,x)]:(c=iW(t,n),d=[rW(t,n,r,x,zi(c.columns))],h.size=$W(t,e,d[0].marks)),d=[Ho({role:Cq,from:m,encode:y,marks:d,layout:c,interactive:o})],p.title&&d.push(hW(t,n,r.title,m)),yh(Ho({role:Eq,from:m,encode:du(kW(i,t,n),a,Fs),marks:d,aria:i("aria"),description:i("description"),zindex:i("zindex"),name:u,interactive:o,style:s}),e)}function FW(t,e){let n=t.type||fb;return !t.type&&MW(t)===1&&(t.fill||t.stroke)&&(n=Mp(e)?Fl:Sd(e)?x1:fb),n!==Fl?n:Sd(e)?x1:Fl}function MW(t){return _y.reduce((e,n)=>e+(t[n]?1:0),0)}function kW(t,e,n){const r={enter:{},update:{}};return te(r,{orient:t("orient"),offset:t("offset"),padding:t("padding"),titlePadding:t("titlePadding"),cornerRadius:t("cornerRadius"),fill:t("fillColor"),stroke:t("strokeColor"),strokeWidth:n.strokeWidth,strokeDash:n.strokeDash,x:t("legendX"),y:t("legendY"),format:e.format,formatType:e.formatType}),r}function $W(t,e,n){const r=zi(xb("size",t,n)),i=zi(xb("strokeWidth",t,n)),a=zi(SW(n[1].encode,e,Ds));return tr(`max(ceil(sqrt(${r})+${i}),${a})`,e)}function xb(t,e,n){return e[t]?`scale("${e[t]}",datum)`:b5(t,n[0].encode)}function SW(t,e,n){return b5("fontSize",t)||Qj("fontSize",e,n)}const BW=`item.orient==="${gu}"?-90:item.orient==="${pu}"?90:0`;function TW(t,e){t=xt(t)?{text:t}:t;const n=Xe(t,e.config.title),r=t.encode||{},i=r.group||{},a=i.name||void 0,u=i.interactive,o=i.style,s=[],l={},f=V(e.add(On(null,[l])));return s.push(NW(t,n,RW(t),f)),t.subtitle&&s.push(LW(t,n,r.subtitle,f)),yh(Ho({role:kq,from:f,encode:OW(n,i),marks:s,aria:n("aria"),description:n("description"),zindex:n("zindex"),name:a,interactive:u,style:o}),e)}function RW(t){const e=t.encode;return e&&e.title||nt({name:t.name,interactive:t.interactive,style:t.style},e)}function OW(t,e){const n={enter:{},update:{}};return te(n,{orient:t("orient"),anchor:t("anchor"),align:{signal:Dy},angle:{signal:BW},limit:t("limit"),frame:t("frame"),offset:t("offset")||0,padding:t("subtitlePadding")}),du(n,e,Fs)}function NW(t,e,n,r){const i={value:0},a=t.text,u={enter:{opacity:i},update:{opacity:{value:1}},exit:{opacity:i}};return te(u,{text:a,align:{signal:"item.mark.group.align"},angle:{signal:"item.mark.group.angle"},limit:{signal:"item.mark.group.limit"},baseline:"top",dx:e("dx"),dy:e("dy"),fill:e("color"),font:e("font"),fontSize:e("fontSize"),fontStyle:e("fontStyle"),fontWeight:e("fontWeight"),lineHeight:e("lineHeight")},{align:e("align"),angle:e("angle"),baseline:e("baseline")}),sn({type:oa,role:$q,style:qj,from:r,encode:u},n)}function LW(t,e,n,r){const i={value:0},a=t.subtitle,u={enter:{opacity:i},update:{opacity:{value:1}},exit:{opacity:i}};return te(u,{text:a,align:{signal:"item.mark.group.align"},angle:{signal:"item.mark.group.angle"},limit:{signal:"item.mark.group.limit"},baseline:"top",dx:e("dx"),dy:e("dy"),fill:e("subtitleColor"),font:e("subtitleFont"),fontSize:e("subtitleFontSize"),fontStyle:e("subtitleFontStyle"),fontWeight:e("subtitleFontWeight"),lineHeight:e("subtitleLineHeight")},{align:e("align"),angle:e("angle"),baseline:e("baseline")}),sn({type:oa,role:Sq,style:jj,from:r,encode:u},n)}function PW(t,e){const n=[];t.transform&&t.transform.forEach(r=>{n.push(ky(r,e));}),t.on&&t.on.forEach(r=>{C5(r,e,t.name);}),e.addDataPipeline(t.name,zW(t,e,n));}function zW(t,e,n){const r=[];let i=null,a=!1,u=!1,o,s,l,f,c;for(t.values?Lt(t.values)||Cl(t.format)?(r.push(vb(e,t)),r.push(i=vi())):r.push(i=vi({$ingest:t.values,$format:t.format})):t.url?Cl(t.url)||Cl(t.format)?(r.push(vb(e,t)),r.push(i=vi())):r.push(i=vi({$request:t.url,$format:t.format})):t.source&&(i=o=H(t.source).map(h=>V(e.getData(h).output)),r.push(null)),s=0,l=n.length;st===li||t===Nn,xh=(t,e,n)=>Lt(t)?jW(t.signal,e,n):t===gu||t===Nn?e:n,Ht=(t,e,n)=>Lt(t)?UW(t.signal,e,n):D5(t)?e:n,$n=(t,e,n)=>Lt(t)?qW(t.signal,e,n):D5(t)?n:e,F5=(t,e,n)=>Lt(t)?WW(t.signal,e,n):t===Nn?{value:e}:{value:n},IW=(t,e,n)=>Lt(t)?YW(t.signal,e,n):t===pu?{value:e}:{value:n},UW=(t,e,n)=>M5(`${t} === '${Nn}' || ${t} === '${li}'`,e,n),qW=(t,e,n)=>M5(`${t} !== '${Nn}' && ${t} !== '${li}'`,e,n),jW=(t,e,n)=>$y(`${t} === '${gu}' || ${t} === '${Nn}'`,e,n),WW=(t,e,n)=>$y(`${t} === '${Nn}'`,e,n),YW=(t,e,n)=>$y(`${t} === '${pu}'`,e,n),M5=(t,e,n)=>(e=e!=null?Yt(e):e,n=n!=null?Yt(n):n,bb(e)&&bb(n)?(e=e?e.signal||Y(e.value):null,n=n?n.signal||Y(n.value):null,{signal:`${t} ? (${e}) : (${n})`}):[nt({test:t},e)].concat(n||[])),bb=t=>t==null||Object.keys(t).length===1,$y=(t,e,n)=>({signal:`${t} ? (${Ca(e)}) : (${Ca(n)})`}),HW=(t,e,n,r,i)=>({signal:(r!=null?`${t} === '${gu}' ? (${Ca(r)}) : `:"")+(n!=null?`${t} === '${li}' ? (${Ca(n)}) : `:"")+(i!=null?`${t} === '${pu}' ? (${Ca(i)}) : `:"")+(e!=null?`${t} === '${Nn}' ? (${Ca(e)}) : `:"")+"(null)"}),Ca=t=>Lt(t)?t.signal:t==null?null:Y(t),GW=(t,e)=>e===0?0:Lt(t)?{signal:`(${t.signal}) * ${e}`}:{value:t*e},$a=(t,e)=>{const n=t.signal;return n&&n.endsWith("(null)")?{signal:n.slice(0,-6)+e.signal}:t};function ya(t,e,n,r){let i;if(e&&X(e,t))return e[t];if(X(n,t))return n[t];if(t.startsWith("title")){switch(t){case"titleColor":i="fill";break;case"titleFont":case"titleFontSize":case"titleFontWeight":i=t[5].toLowerCase()+t.slice(6);}return r[Ey][i]}else if(t.startsWith("label")){switch(t){case"labelColor":i="fill";break;case"labelFont":case"labelFontSize":i=t[5].toLowerCase()+t.slice(6);}return r[Ds][i]}return null}function Ab(t){const e={};for(const n of t)if(n)for(const r in n)e[r]=1;return Object.keys(e)}function XW(t,e){var n=e.config,r=n.style,i=n.axis,a=e.scaleType(t.scale)==="band"&&n.axisBand,u=t.orient,o,s,l;if(Lt(u)){const c=Ab([n.axisX,n.axisY]),h=Ab([n.axisTop,n.axisBottom,n.axisLeft,n.axisRight]);o={};for(l of c)o[l]=Ht(u,ya(l,n.axisX,i,r),ya(l,n.axisY,i,r));s={};for(l of h)s[l]=HW(u.signal,ya(l,n.axisTop,i,r),ya(l,n.axisBottom,i,r),ya(l,n.axisLeft,i,r),ya(l,n.axisRight,i,r));}else o=u===Nn||u===li?n.axisX:n.axisY,s=n["axis"+u[0].toUpperCase()+u.slice(1)];return o||s||a?nt({},i,o,s,a):i}function VW(t,e,n,r){const i=Xe(t,e),a=t.orient;let u,o;const s={enter:u={opacity:lt},update:o={opacity:pn},exit:{opacity:lt}};te(s,{stroke:i("domainColor"),strokeCap:i("domainCap"),strokeDash:i("domainDash"),strokeDashOffset:i("domainDashOffset"),strokeWidth:i("domainWidth"),strokeOpacity:i("domainOpacity")});const l=wb(t,0),f=wb(t,1);return u.x=o.x=Ht(a,l,lt),u.x2=o.x2=Ht(a,f),u.y=o.y=$n(a,l,lt),u.y2=o.y2=$n(a,f),sn({type:Cy,role:xq,from:r,encode:s},n)}function wb(t,e){return {scale:t.scale,range:e}}function KW(t,e,n,r,i){const a=Xe(t,e),u=t.orient,o=t.gridScale,s=xh(u,1,-1),l=QW(t.offset,s);let f,c,h;const d={enter:f={opacity:lt},update:h={opacity:pn},exit:c={opacity:lt}};te(d,{stroke:a("gridColor"),strokeCap:a("gridCap"),strokeDash:a("gridDash"),strokeDashOffset:a("gridDashOffset"),strokeOpacity:a("gridOpacity"),strokeWidth:a("gridWidth")});const g={scale:t.scale,field:gn,band:i.band,extra:i.extra,offset:i.offset,round:a("tickRound")},p=Ht(u,{signal:"height"},{signal:"width"}),m=o?{scale:o,range:0,mult:s,offset:l}:{value:0,offset:l},y=o?{scale:o,range:1,mult:s,offset:l}:nt(p,{mult:s,offset:l});return f.x=h.x=Ht(u,g,m),f.y=h.y=$n(u,g,m),f.x2=h.x2=$n(u,y),f.y2=h.y2=Ht(u,y),c.x=Ht(u,g),c.y=$n(u,g),sn({type:Cy,role:vq,key:gn,from:r,encode:d},n)}function QW(t,e){if(e!==1)if(!et(t))t=Lt(e)?{signal:`(${e.signal}) * (${t||0})`}:e*(t||0);else {let n=t=nt({},t);for(;n.mult!=null;)if(et(n.mult))n=n.mult=nt({},n.mult);else return n.mult=Lt(e)?{signal:`(${n.mult}) * (${e.signal})`}:n.mult*e,t;n.mult=e;}return t}function ZW(t,e,n,r,i,a){const u=Xe(t,e),o=t.orient,s=xh(o,-1,1);let l,f,c;const h={enter:l={opacity:lt},update:c={opacity:pn},exit:f={opacity:lt}};te(h,{stroke:u("tickColor"),strokeCap:u("tickCap"),strokeDash:u("tickDash"),strokeDashOffset:u("tickDashOffset"),strokeOpacity:u("tickOpacity"),strokeWidth:u("tickWidth")});const d=Yt(i);d.mult=s;const g={scale:t.scale,field:gn,band:a.band,extra:a.extra,offset:a.offset,round:u("tickRound")};return c.y=l.y=Ht(o,lt,g),c.y2=l.y2=Ht(o,d),f.x=Ht(o,g),c.x=l.x=$n(o,lt,g),c.x2=l.x2=$n(o,d),f.y=$n(o,g),sn({type:Cy,role:Aq,key:gn,from:r,encode:h},n)}function M0(t,e,n,r,i){return {signal:'flush(range("'+t+'"), scale("'+t+'", datum.value), '+e+","+n+","+r+","+i+")"}}function JW(t,e,n,r,i,a){const u=Xe(t,e),o=t.orient,s=t.scale,l=xh(o,-1,1),f=zi(u("labelFlush")),c=zi(u("labelFlushOffset")),h=u("labelAlign"),d=u("labelBaseline");let g=f===0||!!f,p;const m=Yt(i);m.mult=l,m.offset=Yt(u("labelPadding")||0),m.offset.mult=l;const y={scale:s,field:gn,band:.5,offset:A5(a.offset,u("labelOffset"))},x=Ht(o,g?M0(s,f,'"left"','"right"','"center"'):{value:"center"},IW(o,"left","right")),v=Ht(o,F5(o,"bottom","top"),g?M0(s,f,'"top"','"bottom"','"middle"'):{value:"middle"}),b=M0(s,f,`-(${c})`,c,0);g=g&&c;const w={opacity:lt,x:Ht(o,y,m),y:$n(o,y,m)},E={enter:w,update:p={opacity:pn,text:{field:wy},x:w.x,y:w.y,align:x,baseline:v},exit:{opacity:lt,x:w.x,y:w.y}};te(E,{dx:!h&&g?Ht(o,b):null,dy:!d&&g?$n(o,b):null}),te(E,{angle:u("labelAngle"),fill:u("labelColor"),fillOpacity:u("labelOpacity"),font:u("labelFont"),fontSize:u("labelFontSize"),fontWeight:u("labelFontWeight"),fontStyle:u("labelFontStyle"),limit:u("labelLimit"),lineHeight:u("labelLineHeight")},{align:h,baseline:d});const A=u("labelBound");let _=u("labelOverlap");return _=_||A?{separation:u("labelSeparation"),method:_,order:"datum.index",bound:A?{scale:s,orient:o,tolerance:A}:null}:void 0,p.align!==x&&(p.align=$a(p.align,x)),p.baseline!==v&&(p.baseline=$a(p.baseline,v)),sn({type:oa,role:bq,style:Ds,key:gn,from:r,encode:E,overlap:_},n)}function tY(t,e,n,r){const i=Xe(t,e),a=t.orient,u=xh(a,-1,1);let o,s;const l={enter:o={opacity:lt,anchor:Yt(i("titleAnchor",null)),align:{signal:Dy}},update:s=nt({},o,{opacity:pn,text:Yt(t.title)}),exit:{opacity:lt}},f={signal:`lerp(range("${t.scale}"), ${ph(0,1,.5)})`};return s.x=Ht(a,f),s.y=$n(a,f),o.angle=Ht(a,lt,GW(u,90)),o.baseline=Ht(a,F5(a,li,Nn),{value:li}),s.angle=o.angle,s.baseline=o.baseline,te(l,{fill:i("titleColor"),fillOpacity:i("titleOpacity"),font:i("titleFont"),fontSize:i("titleFontSize"),fontStyle:i("titleFontStyle"),fontWeight:i("titleFontWeight"),limit:i("titleLimit"),lineHeight:i("titleLineHeight")},{align:i("titleAlign"),angle:i("titleAngle"),baseline:i("titleBaseline")}),eY(i,a,l,n),l.update.align=$a(l.update.align,o.align),l.update.angle=$a(l.update.angle,o.angle),l.update.baseline=$a(l.update.baseline,o.baseline),sn({type:oa,role:wq,style:Ey,from:r,encode:l},n)}function eY(t,e,n,r){const i=(o,s)=>o!=null?(n.update[s]=$a(Yt(o),n.update[s]),!1):!va(s,r),a=i(t("titleX"),"x"),u=i(t("titleY"),"y");n.enter.auto=u===a?Yt(u):Ht(e,Yt(u),Yt(a));}function nY(t,e){const n=XW(t,e),r=t.encode||{},i=r.axis||{},a=i.name||void 0,u=i.interactive,o=i.style,s=Xe(t,n),l=Zj(s),f={scale:t.scale,ticks:!!s("ticks"),labels:!!s("labels"),grid:!!s("grid"),domain:!!s("domain"),title:t.title!=null},c=V(e.add(On({},[f]))),h=V(e.add(rj({scale:e.scaleRef(t.scale),extra:e.property(l.extra),count:e.objectProperty(t.tickCount),values:e.objectProperty(t.values),minstep:e.property(t.tickMinStep),formatType:e.property(t.formatType),formatSpecifier:e.property(t.format)}))),d=[];let g;return f.grid&&d.push(KW(t,n,r.grid,h,l)),f.ticks&&(g=s("tickSize"),d.push(ZW(t,n,r.ticks,h,g,l))),f.labels&&(g=f.ticks?g:0,d.push(JW(t,n,r.labels,h,g,l))),f.domain&&d.push(VW(t,n,r.domain,c)),f.title&&d.push(tY(t,n,r.title,c)),yh(Ho({role:yq,from:c,encode:du(rY(s,t),i,Fs),marks:d,aria:s("aria"),description:s("description"),zindex:s("zindex"),name:a,interactive:u,style:o}),e)}function rY(t,e){const n={enter:{},update:{}};return te(n,{orient:t("orient"),offset:t("offset")||0,position:An(e.position,0),titlePadding:t("titlePadding"),minExtent:t("minExtent"),maxExtent:t("maxExtent"),range:{signal:`abs(span(range("${e.scale}")))`},translate:t("translate"),format:e.format,formatType:e.formatType}),n}function k5(t,e,n){const r=H(t.signals),i=H(t.scales);return n||r.forEach(a=>o5(a,e)),H(t.projections).forEach(a=>Oj(a,e)),i.forEach(a=>Ej(a,e)),H(t.data).forEach(a=>PW(a,e)),i.forEach(a=>_j(a,e)),(n||r).forEach(a=>nj(a,e)),H(t.axes).forEach(a=>nY(a,e)),H(t.marks).forEach(a=>yh(a,e)),H(t.legends).forEach(a=>DW(a,e)),t.title&&TW(t.title,e),e.parseLambdas(),e}const iY=t=>du({enter:{x:{value:0},y:{value:0}},update:{width:{signal:"width"},height:{signal:"height"}}},t);function aY(t,e){const n=e.config,r=V(e.root=e.add(jf())),i=uY(t,n);i.forEach(l=>o5(l,e)),e.description=t.description||n.description,e.eventConfig=n.events,e.legends=e.objectProperty(n.legend&&n.legend.layout),e.locale=n.locale;const a=e.add(On()),u=e.add(f5(u5(iY(t.encode),gh,xy,t.style,e,{pulse:V(a)}))),o=e.add(d5({layout:e.objectProperty(t.layout),legends:e.legends,autosize:e.signalRef("autosize"),mark:r,pulse:V(u)}));e.operators.pop(),e.pushState(V(u),V(o),null),k5(t,e,i),e.operators.push(o);let s=e.add(l5({mark:r,pulse:V(o)}));return s=e.add(h5({pulse:V(s)})),s=e.add(ua({pulse:V(s)})),e.addData("root",new Ki(e,a,a,s)),e}function Lu(t,e){return e&&e.signal?{name:t,update:e.signal}:{name:t,value:e}}function uY(t,e){const n=u=>An(t[u],e[u]),r=[Lu("background",n("background")),Lu("autosize",gq(n("autosize"))),Lu("padding",mq(n("padding"))),Lu("width",n("width")||0),Lu("height",n("height")||0)],i=r.reduce((u,o)=>(u[o.name]=o,u),{}),a={};return H(t.signals).forEach(u=>{X(i,u.name)?u=nt(i[u.name],u):r.push(u),a[u.name]=u;}),H(e.signals).forEach(u=>{!X(a,u.name)&&!X(i,u.name)&&r.push(u);}),r}function $5(t,e){this.config=t||{},this.options=e||{},this.bindings=[],this.field={},this.signals={},this.lambdas={},this.scales={},this.events={},this.data={},this.streams=[],this.updates=[],this.operators=[],this.eventConfig=null,this.locale=null,this._id=0,this._subid=0,this._nextsub=[0],this._parent=[],this._encode=[],this._lookup=[],this._markpath=[];}function Eb(t){this.config=t.config,this.options=t.options,this.legends=t.legends,this.field=Object.create(t.field),this.signals=Object.create(t.signals),this.lambdas=Object.create(t.lambdas),this.scales=Object.create(t.scales),this.events=Object.create(t.events),this.data=Object.create(t.data),this.streams=[],this.updates=[],this.operators=[],this._id=0,this._subid=++t._nextsub[0],this._nextsub=t._nextsub,this._parent=t._parent.slice(),this._encode=t._encode.slice(),this._lookup=t._lookup.slice(),this._markpath=t._markpath;}$5.prototype=Eb.prototype={parse(t){return k5(t,this)},fork(){return new Eb(this)},isSubscope(){return this._subid>0},toRuntime(){return this.finish(),{description:this.description,operators:this.operators,streams:this.streams,updates:this.updates,bindings:this.bindings,eventConfig:this.eventConfig,locale:this.locale}},id(){return (this._subid?this._subid+":":0)+this._id++},add(t){return this.operators.push(t),t.id=this.id(),t.refs&&(t.refs.forEach(e=>{e.$ref=t.id;}),t.refs=null),t},proxy(t){const e=t instanceof d1?V(t):t;return this.add(yj({value:e}))},addStream(t){return this.streams.push(t),t.id=this.id(),t},addUpdate(t){return this.updates.push(t),t},finish(){let t,e;this.root&&(this.root.root=!0);for(t in this.signals)this.signals[t].signal=t;for(t in this.scales)this.scales[t].scale=t;function n(r,i,a){let u,o;r&&(u=r.data||(r.data={}),o=u[i]||(u[i]=[]),o.push(a));}for(t in this.data){e=this.data[t],n(e.input,t,"input"),n(e.output,t,"output"),n(e.values,t,"values");for(const r in e.index)n(e.index[r],t,"index:"+r);}return this},pushState(t,e,n){this._encode.push(V(this.add(ua({pulse:t})))),this._parent.push(e),this._lookup.push(n?V(this.proxy(n)):null),this._markpath.push(-1);},popState(){this._encode.pop(),this._parent.pop(),this._lookup.pop(),this._markpath.pop();},parent(){return ut(this._parent)},encode(){return ut(this._encode)},lookup(){return ut(this._lookup)},markpath(){const t=this._markpath;return ++t[t.length-1]},fieldRef(t,e){if(xt(t))return Wo(t,e);t.signal||$("Unsupported field reference: "+Y(t));const n=t.signal;let r=this.field[n];if(!r){const i={name:this.signalRef(n)};e&&(i.as=e),this.field[n]=r=V(this.add(oj(i)));}return r},compareRef(t){let e=!1;const n=a=>Lt(a)?(e=!0,this.signalRef(a.signal)):Hq(a)?(e=!0,this.exprRef(a.expr)):a,r=H(t.field).map(n),i=H(t.order).map(n);return e?V(this.add(lb({fields:r,orders:i}))):ob(r,i)},keyRef(t,e){let n=!1;const r=a=>Lt(a)?(n=!0,V(i[a.signal])):a,i=this.signals;return t=H(t).map(r),n?V(this.add(sj({fields:t,flat:e}))):qq(t,e)},sortRef(t){if(!t)return t;const e=hh(t.op,t.field),n=t.order||jq;return n.signal?V(this.add(lb({fields:e,orders:this.signalRef(n.signal)}))):ob(e,n)},event(t,e){const n=t+":"+e;if(!this.events[n]){const r=this.id();this.streams.push({id:r,source:t,type:e}),this.events[n]=r;}return this.events[n]},hasOwnSignal(t){return X(this.signals,t)},addSignal(t,e){this.hasOwnSignal(t)&&$("Duplicate signal name: "+Y(t));const n=e instanceof d1?e:this.add(jf(e));return this.signals[t]=n},getSignal(t){return this.signals[t]||$("Unrecognized signal name: "+Y(t)),this.signals[t]},signalRef(t){return this.signals[t]?V(this.signals[t]):(X(this.lambdas,t)||(this.lambdas[t]=this.add(jf(null))),V(this.lambdas[t]))},parseLambdas(){const t=Object.keys(this.lambdas);for(let e=0,n=t.length;e0?",":"")+(et(i)?i.signal||Sy(i):Y(i));}return n+"]"}function sY(t){let e="{",n=0,r,i;for(r in t)i=t[r],e+=(++n>1?",":"")+Y(r)+":"+(et(i)?i.signal||Sy(i):Y(i));return e+"}"}function lY(){const t="sans-serif",r="#4c78a8",i="#000",a="#888",u="#ddd";return {description:"Vega visualization",padding:0,autosize:"pad",background:null,events:{defaults:{allow:["wheel"]}},group:null,mark:null,arc:{fill:r},area:{fill:r},image:null,line:{stroke:r,strokeWidth:2},path:{stroke:r},rect:{fill:r},rule:{stroke:i},shape:{stroke:r},symbol:{fill:r,size:64},text:{fill:i,font:t,fontSize:11},trail:{fill:r,size:2},style:{"guide-label":{fill:i,font:t,fontSize:10},"guide-title":{fill:i,font:t,fontSize:11,fontWeight:"bold"},"group-title":{fill:i,font:t,fontSize:13,fontWeight:"bold"},"group-subtitle":{fill:i,font:t,fontSize:12},point:{size:30,strokeWidth:2,shape:"circle"},circle:{size:30,strokeWidth:2},square:{size:30,strokeWidth:2,shape:"square"},cell:{fill:"transparent",stroke:u},view:{fill:"transparent"}},title:{orient:"top",anchor:"middle",offset:4,subtitlePadding:3},axis:{minExtent:0,maxExtent:200,bandPosition:.5,domain:!0,domainWidth:1,domainColor:a,grid:!1,gridWidth:1,gridColor:u,labels:!0,labelAngle:0,labelLimit:180,labelOffset:0,labelPadding:2,ticks:!0,tickColor:a,tickOffset:0,tickRound:!0,tickSize:5,tickWidth:1,titlePadding:4},axisBand:{tickOffset:-.5},projection:{type:"mercator"},legend:{orient:"right",padding:0,gridAlign:"each",columnPadding:10,rowPadding:2,symbolDirection:"vertical",gradientDirection:"vertical",gradientLength:200,gradientThickness:16,gradientStrokeColor:u,gradientStrokeWidth:0,gradientLabelOffset:2,labelAlign:"left",labelBaseline:"middle",labelLimit:160,labelOffset:4,labelOverlap:!0,symbolLimit:30,symbolType:"circle",symbolSize:100,symbolOffset:0,symbolStrokeWidth:1.5,symbolBaseFillColor:"transparent",symbolBaseStrokeColor:a,titleLimit:180,titleOrient:"top",titlePadding:5,layout:{offset:18,direction:"horizontal",left:{direction:"vertical"},right:{direction:"vertical"}}},range:{category:{scheme:"tableau10"},ordinal:{scheme:"blues"},heatmap:{scheme:"yellowgreenblue"},ramp:{scheme:"blues"},diverging:{scheme:"blueorange",extent:[1,0]},symbol:["circle","square","triangle-up","cross","diamond","triangle-right","triangle-down","triangle-left"]}}}function fY(t,e,n){return et(t)||$("Input Vega specification must be an object."),e=v3(lY(),e,t.config),aY(t,new $5(e,n)).toRuntime()}const cY="RawCode",hY="Literal",dY="Property",gY="Identifier",pY="ArrayExpression",mY="BinaryExpression",yY="CallExpression",xY="ConditionalExpression",vY="LogicalExpression",bY="MemberExpression",AY="ObjectExpression",wY="UnaryExpression";function Ln(t){this.type=t;}Ln.prototype.visit=function(t){let e,n,r;if(t(this))return 1;for(e=EY(this),n=0,r=e.length;n";or[Qi]="Identifier";or[pi]="Keyword";or[bh]="Null";or[sa]="Numeric";or[Oe]="Punctuator";or[ks]="String";or[_Y]="RegularExpression";var CY="ArrayExpression",DY="BinaryExpression",FY="CallExpression",MY="ConditionalExpression",S5="Identifier",kY="Literal",$Y="LogicalExpression",SY="MemberExpression",BY="ObjectExpression",TY="Property",RY="UnaryExpression",Gt="Unexpected token %0",OY="Unexpected number",NY="Unexpected string",LY="Unexpected identifier",PY="Unexpected reserved word",zY="Unexpected end of input",b1="Invalid regular expression",k0="Invalid regular expression: missing /",B5="Octal literals are not allowed in strict mode.",IY="Duplicate data property in object literal not allowed in strict mode",Zt="ILLEGAL",Go="Disabled.",UY=new RegExp("[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0-\\u08B2\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6EF\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA7AD\\uA7B0\\uA7B1\\uA7F7-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB5F\\uAB64\\uAB65\\uABC0-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"),qY=new RegExp("[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0300-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u0483-\\u0487\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0610-\\u061A\\u0620-\\u0669\\u066E-\\u06D3\\u06D5-\\u06DC\\u06DF-\\u06E8\\u06EA-\\u06FC\\u06FF\\u0710-\\u074A\\u074D-\\u07B1\\u07C0-\\u07F5\\u07FA\\u0800-\\u082D\\u0840-\\u085B\\u08A0-\\u08B2\\u08E4-\\u0963\\u0966-\\u096F\\u0971-\\u0983\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BC-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CE\\u09D7\\u09DC\\u09DD\\u09DF-\\u09E3\\u09E6-\\u09F1\\u0A01-\\u0A03\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A59-\\u0A5C\\u0A5E\\u0A66-\\u0A75\\u0A81-\\u0A83\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABC-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AD0\\u0AE0-\\u0AE3\\u0AE6-\\u0AEF\\u0B01-\\u0B03\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3C-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B5C\\u0B5D\\u0B5F-\\u0B63\\u0B66-\\u0B6F\\u0B71\\u0B82\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD0\\u0BD7\\u0BE6-\\u0BEF\\u0C00-\\u0C03\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C58\\u0C59\\u0C60-\\u0C63\\u0C66-\\u0C6F\\u0C81-\\u0C83\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBC-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CDE\\u0CE0-\\u0CE3\\u0CE6-\\u0CEF\\u0CF1\\u0CF2\\u0D01-\\u0D03\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4E\\u0D57\\u0D60-\\u0D63\\u0D66-\\u0D6F\\u0D7A-\\u0D7F\\u0D82\\u0D83\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DE6-\\u0DEF\\u0DF2\\u0DF3\\u0E01-\\u0E3A\\u0E40-\\u0E4E\\u0E50-\\u0E59\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB9\\u0EBB-\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EC8-\\u0ECD\\u0ED0-\\u0ED9\\u0EDC-\\u0EDF\\u0F00\\u0F18\\u0F19\\u0F20-\\u0F29\\u0F35\\u0F37\\u0F39\\u0F3E-\\u0F47\\u0F49-\\u0F6C\\u0F71-\\u0F84\\u0F86-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u1000-\\u1049\\u1050-\\u109D\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u135D-\\u135F\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1714\\u1720-\\u1734\\u1740-\\u1753\\u1760-\\u176C\\u176E-\\u1770\\u1772\\u1773\\u1780-\\u17D3\\u17D7\\u17DC\\u17DD\\u17E0-\\u17E9\\u180B-\\u180D\\u1810-\\u1819\\u1820-\\u1877\\u1880-\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1920-\\u192B\\u1930-\\u193B\\u1946-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u19D0-\\u19D9\\u1A00-\\u1A1B\\u1A20-\\u1A5E\\u1A60-\\u1A7C\\u1A7F-\\u1A89\\u1A90-\\u1A99\\u1AA7\\u1AB0-\\u1ABD\\u1B00-\\u1B4B\\u1B50-\\u1B59\\u1B6B-\\u1B73\\u1B80-\\u1BF3\\u1C00-\\u1C37\\u1C40-\\u1C49\\u1C4D-\\u1C7D\\u1CD0-\\u1CD2\\u1CD4-\\u1CF6\\u1CF8\\u1CF9\\u1D00-\\u1DF5\\u1DFC-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u200C\\u200D\\u203F\\u2040\\u2054\\u2071\\u207F\\u2090-\\u209C\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D7F-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2DE0-\\u2DFF\\u2E2F\\u3005-\\u3007\\u3021-\\u302F\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u3099\\u309A\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA62B\\uA640-\\uA66F\\uA674-\\uA67D\\uA67F-\\uA69D\\uA69F-\\uA6F1\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA7AD\\uA7B0\\uA7B1\\uA7F7-\\uA827\\uA840-\\uA873\\uA880-\\uA8C4\\uA8D0-\\uA8D9\\uA8E0-\\uA8F7\\uA8FB\\uA900-\\uA92D\\uA930-\\uA953\\uA960-\\uA97C\\uA980-\\uA9C0\\uA9CF-\\uA9D9\\uA9E0-\\uA9FE\\uAA00-\\uAA36\\uAA40-\\uAA4D\\uAA50-\\uAA59\\uAA60-\\uAA76\\uAA7A-\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEF\\uAAF2-\\uAAF6\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB5F\\uAB64\\uAB65\\uABC0-\\uABEA\\uABEC\\uABED\\uABF0-\\uABF9\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE00-\\uFE0F\\uFE20-\\uFE2D\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF10-\\uFF19\\uFF21-\\uFF3A\\uFF3F\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]");function Ah(t,e){if(!t)throw new Error("ASSERT: "+e)}function gr(t){return t>=48&&t<=57}function By(t){return "0123456789abcdefABCDEF".indexOf(t)>=0}function xo(t){return "01234567".indexOf(t)>=0}function jY(t){return t===32||t===9||t===11||t===12||t===160||t>=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(t)>=0}function Xo(t){return t===10||t===13||t===8232||t===8233}function $s(t){return t===36||t===95||t>=65&&t<=90||t>=97&&t<=122||t===92||t>=128&&UY.test(String.fromCharCode(t))}function Wf(t){return t===36||t===95||t>=65&&t<=90||t>=97&&t<=122||t>=48&&t<=57||t===92||t>=128&&qY.test(String.fromCharCode(t))}const WY={if:1,in:1,do:1,var:1,for:1,new:1,try:1,let:1,this:1,else:1,case:1,void:1,with:1,enum:1,while:1,break:1,catch:1,throw:1,const:1,yield:1,class:1,super:1,return:1,typeof:1,delete:1,switch:1,export:1,import:1,public:1,static:1,default:1,finally:1,extends:1,package:1,private:1,function:1,continue:1,debugger:1,interface:1,protected:1,instanceof:1,implements:1};function T5(){for(;T1114111||t!=="}")&&ht({},Gt,Zt),e<=65535?String.fromCharCode(e):(n=(e-65536>>10)+55296,r=(e-65536&1023)+56320,String.fromCharCode(n,r))}function R5(){var t,e;for(t=j.charCodeAt(T++),e=String.fromCharCode(t),t===92&&(j.charCodeAt(T)!==117&&ht({},Gt,Zt),++T,t=A1("u"),(!t||t==="\\"||!$s(t.charCodeAt(0)))&&ht({},Gt,Zt),e=t);T>>=")return T+=4,{type:Oe,value:u,start:t,end:T};if(a=u.substr(0,3),a===">>>"||a==="<<="||a===">>=")return T+=3,{type:Oe,value:a,start:t,end:T};if(i=a.substr(0,2),r===i[1]&&"+-<>&|".indexOf(r)>=0||i==="=>")return T+=2,{type:Oe,value:i,start:t,end:T};if(i==="//"&&ht({},Gt,Zt),"<>=!+-*%&|^/".indexOf(r)>=0)return ++T,{type:Oe,value:r,start:t,end:T};ht({},Gt,Zt);}function XY(t){let e="";for(;T=0&&T=0&&(n=n.replace(/\\u\{([0-9a-fA-F]+)\}/g,(r,i)=>{if(parseInt(i,16)<=1114111)return "x";ht({},b1);}).replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"x"));try{new RegExp(n);}catch{ht({},b1);}try{return new RegExp(t,e)}catch{return null}}function ZY(){var t,e,n,r,i;for(t=j[T],Ah(t==="/","Regular expression literal must start with a slash"),e=j[T++],n=!1,r=!1;T=0&&ht({},b1,n),{value:n,literal:e}}function tH(){var t,e,n,r;return yt=null,T5(),t=T,e=ZY(),n=JY(),r=QY(e.value,n.value),{literal:e.literal+n.literal,value:r,regex:{pattern:e.value,flags:n.value},start:t,end:T}}function eH(t){return t.type===Qi||t.type===pi||t.type===vh||t.type===bh}function O5(){if(T5(),T>=he)return {type:Ms,start:T,end:T};const t=j.charCodeAt(T);return $s(t)?GY():t===40||t===41||t===59?$0():t===39||t===34?KY():t===46?gr(j.charCodeAt(T+1))?_b():$0():gr(t)?_b():$0()}function ze(){const t=yt;return T=t.end,yt=O5(),T=t.end,t}function N5(){const t=T;yt=O5(),T=t;}function nH(t){const e=new Ln(CY);return e.elements=t,e}function Cb(t,e,n){const r=new Ln(t==="||"||t==="&&"?$Y:DY);return r.operator=t,r.left=e,r.right=n,r}function rH(t,e){const n=new Ln(FY);return n.callee=t,n.arguments=e,n}function iH(t,e,n){const r=new Ln(MY);return r.test=t,r.consequent=e,r.alternate=n,r}function Ty(t){const e=new Ln(S5);return e.name=t,e}function ao(t){const e=new Ln(kY);return e.value=t.value,e.raw=j.slice(t.start,t.end),t.regex&&(e.raw==="//"&&(e.raw="/(?:)/"),e.regex=t.regex),e}function Db(t,e,n){const r=new Ln(SY);return r.computed=t==="[",r.object=e,r.property=n,r.computed||(n.member=!0),r}function aH(t){const e=new Ln(BY);return e.properties=t,e}function Fb(t,e,n){const r=new Ln(TY);return r.key=e,r.value=n,r.kind=t,r}function uH(t,e){const n=new Ln(RY);return n.operator=t,n.argument=e,n.prefix=!0,n}function ht(t,e){var n,r=Array.prototype.slice.call(arguments,2),i=e.replace(/%(\d)/g,(a,u)=>(Ah(u":case"<=":case">=":case"instanceof":case"in":e=7;break;case"<<":case">>":case">>>":e=8;break;case"+":case"-":e=9;break;case"*":case"/":case"%":e=11;break}return e}function xH(){var t,e,n,r,i,a,u,o,s,l;if(t=yt,s=kl(),r=yt,i=$b(r),i===0)return s;for(r.prec=i,ze(),e=[t,yt],u=kl(),a=[s,r,u];(i=$b(yt))>0;){for(;a.length>2&&i<=a[a.length-2].prec;)u=a.pop(),o=a.pop().value,s=a.pop(),e.pop(),n=Cb(o,s,u),a.push(n);r=ze(),r.prec=i,a.push(r),e.push(yt),n=kl(),a.push(n);}for(l=a.length-1,n=a[l],e.pop();l>1;)e.pop(),n=Cb(a[l-1].value,a[l-2],n),l-=2;return n}function Zi(){var t,e,n;return t=xH(),_t("?")&&(ze(),e=Zi(),de(":"),n=Zi(),t=iH(t,e,n)),t}function Ry(){const t=Zi();if(_t(","))throw new Error(Go);return t}function vH(t){j=t,T=0,he=j.length,yt=null,N5();const e=Ry();if(yt.type!==Ms)throw new Error("Unexpect token after expression.");return e}var bH={NaN:"NaN",E:"Math.E",LN2:"Math.LN2",LN10:"Math.LN10",LOG2E:"Math.LOG2E",LOG10E:"Math.LOG10E",PI:"Math.PI",SQRT1_2:"Math.SQRT1_2",SQRT2:"Math.SQRT2",MIN_VALUE:"Number.MIN_VALUE",MAX_VALUE:"Number.MAX_VALUE"};function AH(t){function e(u,o,s,l){let f=t(o[0]);return s&&(f=s+"("+f+")",s.lastIndexOf("new ",0)===0&&(f="("+f+")")),f+"."+u+(l<0?"":l===0?"()":"("+o.slice(1).map(t).join(",")+")")}function n(u,o,s){return l=>e(u,l,o,s)}const r="new Date",i="String",a="RegExp";return {isNaN:"Number.isNaN",isFinite:"Number.isFinite",abs:"Math.abs",acos:"Math.acos",asin:"Math.asin",atan:"Math.atan",atan2:"Math.atan2",ceil:"Math.ceil",cos:"Math.cos",exp:"Math.exp",floor:"Math.floor",log:"Math.log",max:"Math.max",min:"Math.min",pow:"Math.pow",random:"Math.random",round:"Math.round",sin:"Math.sin",sqrt:"Math.sqrt",tan:"Math.tan",clamp:function(u){u.length<3&&$("Missing arguments to clamp function."),u.length>3&&$("Too many arguments to clamp function.");const o=u.map(t);return "Math.max("+o[1]+", Math.min("+o[2]+","+o[0]+"))"},now:"Date.now",utc:"Date.UTC",datetime:r,date:n("getDate",r,0),day:n("getDay",r,0),year:n("getFullYear",r,0),month:n("getMonth",r,0),hours:n("getHours",r,0),minutes:n("getMinutes",r,0),seconds:n("getSeconds",r,0),milliseconds:n("getMilliseconds",r,0),time:n("getTime",r,0),timezoneoffset:n("getTimezoneOffset",r,0),utcdate:n("getUTCDate",r,0),utcday:n("getUTCDay",r,0),utcyear:n("getUTCFullYear",r,0),utcmonth:n("getUTCMonth",r,0),utchours:n("getUTCHours",r,0),utcminutes:n("getUTCMinutes",r,0),utcseconds:n("getUTCSeconds",r,0),utcmilliseconds:n("getUTCMilliseconds",r,0),length:n("length",null,-1),parseFloat:"parseFloat",parseInt:"parseInt",upper:n("toUpperCase",i,0),lower:n("toLowerCase",i,0),substring:n("substring",i),split:n("split",i),trim:n("trim",i,0),regexp:a,test:n("test",a),if:function(u){u.length<3&&$("Missing arguments to if function."),u.length>3&&$("Too many arguments to if function.");const o=u.map(t);return "("+o[0]+"?"+o[1]+":"+o[2]+")"}}}function wH(t){const e=t&&t.length-1;return e&&(t[0]==='"'&&t[e]==='"'||t[0]==="'"&&t[e]==="'")?t.slice(1,-1):t}function EH(t){t=t||{};const e=t.allowed?nn(t.allowed):{},n=t.forbidden?nn(t.forbidden):{},r=t.constants||bH,i=(t.functions||AH)(c),a=t.globalvar,u=t.fieldvar,o=tt(a)?a:g=>`${a}["${g}"]`;let s={},l={},f=0;function c(g){if(xt(g))return g;const p=h[g.type];return p==null&&$("Unsupported type: "+g.type),p(g)}const h={Literal:g=>g.raw,Identifier:g=>{const p=g.name;return f>0?p:X(n,p)?$("Illegal identifier: "+p):X(r,p)?r[p]:X(e,p)?p:(s[p]=1,o(p))},MemberExpression:g=>{const p=!g.computed,m=c(g.object);p&&(f+=1);const y=c(g.property);return m===u&&(l[wH(y)]=1),p&&(f-=1),m+(p?"."+y:"["+y+"]")},CallExpression:g=>{g.callee.type!=="Identifier"&&$("Illegal callee type: "+g.callee.type);const p=g.callee.name,m=g.arguments,y=X(i,p)&&i[p];return y||$("Unrecognized function: "+p),tt(y)?y(m):y+"("+m.map(c).join(",")+")"},ArrayExpression:g=>"["+g.elements.map(c).join(",")+"]",BinaryExpression:g=>"("+c(g.left)+" "+g.operator+" "+c(g.right)+")",UnaryExpression:g=>"("+g.operator+c(g.argument)+")",ConditionalExpression:g=>"("+c(g.test)+"?"+c(g.consequent)+":"+c(g.alternate)+")",LogicalExpression:g=>"("+c(g.left)+g.operator+c(g.right)+")",ObjectExpression:g=>"{"+g.properties.map(c).join(",")+"}",Property:g=>{f+=1;const p=c(g.key);return f-=1,p+":"+c(g.value)}};function d(g){const p={code:c(g),globals:Object.keys(s),fields:Object.keys(l)};return s={},l={},p}return d.functions=i,d.constants=r,d}var _H="5.23.0";nt(qa,uS,KR,MO,aN,hN,zN,xN,UN,YN,eL,sL);const LH=Object.freeze(Object.defineProperty({__proto__:null,Bounds:St,CanvasHandler:bs,CanvasRenderer:$f,DATE:He,DAY:oe,DAYOFYEAR:Jn,Dataflow:ka,Debug:y3,Error:lg,EventStream:Dc,Gradient:Op,GroupItem:Hc,HOURS:rn,Handler:oi,Info:m3,Item:Yc,MILLISECONDS:Bn,MINUTES:an,MONTH:le,Marks:on,MultiPulse:Wg,None:g3,Operator:At,Parameters:Cc,Pulse:Qr,QUARTER:Ye,RenderType:Hr,Renderer:ir,ResourceLoader:zp,SECONDS:yn,SVGHandler:rm,SVGRenderer:lm,SVGStringRenderer:fm,Scenegraph:em,TIME_UNITS:Fg,Transform:S,View:PD,WEEK:Nt,Warn:p3,YEAR:Jt,accessor:Ge,accessorFields:se,accessorName:$t,array:H,ascending:yc,bandwidthNRD:Xg,bin:oE,bootstrapCI:sE,boundClip:oC,boundContext:ms,boundItem:Pd,boundMark:T_,boundStroke:$r,changeset:ra,clampRange:yg,codegenExpression:EH,compare:xg,constant:pe,cumulativeLogNormal:$c,cumulativeNormal:is,cumulativeUniform:Rc,dayofyear:Sg,debounce:vg,defaultLocale:zg,definition:iE,densityLogNormal:kc,densityNormal:Fc,densityUniform:Tc,domChild:Le,domClear:Cn,domCreate:Wr,domFind:nm,dotbin:lE,error:$,expressionFunction:Rt,extend:nt,extent:Sn,extentIndex:_3,falsy:Rr,fastmap:iu,field:en,flush:bg,font:Qc,fontFamily:vs,fontSize:rr,format:fl,formatLocale:vf,formats:qg,hasOwnProperty:X,id:ns,identity:ge,inferType:G3,inferTypes:X3,ingest:gt,inherits:L,inrange:Bi,interpolate:$p,interpolateColors:jc,interpolateRange:n_,intersect:cm,intersectBoxLine:Ea,intersectPath:Ip,intersectPoint:Up,intersectRule:w_,isArray:U,isBoolean:Ag,isDate:Cr,isFunction:tt,isIterable:C3,isNumber:Mr,isObject:et,isRegExp:wg,isString:xt,isTuple:su,key:Eg,lerp:_g,lineHeight:ai,loader:wc,locale:Y3,logger:x3,lruCache:D3,markup:sm,merge:F3,mergeConfig:v3,multiLineOffset:Zp,one:ru,pad:Cg,panLinear:cg,panLog:hg,panPow:dg,panSymlog:gg,parse:fY,parseExpression:vH,parseSelector:t5,path:Vf,pathCurves:Np,pathEqual:sC,pathParse:Gi,pathRectangle:y_,pathRender:Ha,pathSymbols:m_,pathTrail:x_,peek:ut,point:Jc,projection:Em,quantileLogNormal:Sc,quantileNormal:as,quantileUniform:Oc,quantiles:Hg,quantizeInterpolator:r_,quarter:pg,quartiles:Gg,get random(){return un},randomInteger:f$,randomKDE:Kg,randomLCG:l$,randomLogNormal:cE,randomMixture:hE,randomNormal:Vg,randomUniform:dE,read:Q3,regressionExp:pE,regressionLinear:Qg,regressionLoess:xE,regressionLog:gE,regressionPoly:yE,regressionPow:mE,regressionQuad:Zg,renderModule:th,repeat:Xu,resetDefaultLocale:u7,resetSVGClipId:b_,resetSVGDefIds:gR,responseType:K3,runtimeContext:CD,sampleCurve:Lc,sampleLogNormal:Mc,sampleNormal:rs,sampleUniform:Bc,scale:ft,sceneEqual:hm,sceneFromJSON:O_,scenePickVisit:_f,sceneToJSON:R_,sceneVisit:Tn,sceneZOrder:qp,scheme:Sp,serializeXML:K_,setRandom:o$,span:au,splitAccessPath:cc,stringValue:Y,textMetrics:kn,timeBin:P3,timeFloor:B3,timeFormatLocale:To,timeInterval:uu,timeOffset:Og,timeSequence:Lg,timeUnitSpecifier:kg,timeUnits:Mg,toBoolean:xc,toDate:vc,toNumber:Kt,toSet:nn,toString:bc,transform:aE,transforms:qa,truncate:Dg,truthy:We,tupleid:K,typeParsers:Md,utcFloor:T3,utcInterval:ou,utcOffset:Ng,utcSequence:Pg,utcdayofyear:Tg,utcquarter:mg,utcweek:Rg,version:_H,visitArray:Lr,week:Bg,writeConfig:fg,zero:Ir,zoomLinear:gc,zoomLog:pc,zoomPow:Bo,zoomSymlog:mc},Symbol.toStringTag,{value:"Module"}));function CH(t,e,n){let r;e.x2&&(e.x?(n&&t.x>t.x2&&(r=t.x,t.x=t.x2,t.x2=r),t.width=t.x2-t.x):t.x=t.x2-(t.width||0)),e.xc&&(t.x=t.xc-(t.width||0)/2),e.y2&&(e.y?(n&&t.y>t.y2&&(r=t.y,t.y=t.y2,t.y2=r),t.height=t.y2-t.y):t.y=t.y2-(t.height||0)),e.yc&&(t.y=t.yc-(t.height||0)/2);}var DH={NaN:NaN,E:Math.E,LN2:Math.LN2,LN10:Math.LN10,LOG2E:Math.LOG2E,LOG10E:Math.LOG10E,PI:Math.PI,SQRT1_2:Math.SQRT1_2,SQRT2:Math.SQRT2,MIN_VALUE:Number.MIN_VALUE,MAX_VALUE:Number.MAX_VALUE},FH={"*":(t,e)=>t*e,"+":(t,e)=>t+e,"-":(t,e)=>t-e,"/":(t,e)=>t/e,"%":(t,e)=>t%e,">":(t,e)=>t>e,"<":(t,e)=>tt<=e,">=":(t,e)=>t>=e,"==":(t,e)=>t==e,"!=":(t,e)=>t!=e,"===":(t,e)=>t===e,"!==":(t,e)=>t!==e,"&":(t,e)=>t&e,"|":(t,e)=>t|e,"^":(t,e)=>t^e,"<<":(t,e)=>t<>":(t,e)=>t>>e,">>>":(t,e)=>t>>>e},MH={"+":t=>+t,"-":t=>-t,"~":t=>~t,"!":t=>!t};const kH=Array.prototype.slice,bi=(t,e,n)=>{const r=n?n(e[0]):e[0];return r[t].apply(r,kH.call(e,1))},$H=(t,e,n,r,i,a,u)=>new Date(t,e||0,n??1,r||0,i||0,a||0,u||0);var SH={isNaN:Number.isNaN,isFinite:Number.isFinite,abs:Math.abs,acos:Math.acos,asin:Math.asin,atan:Math.atan,atan2:Math.atan2,ceil:Math.ceil,cos:Math.cos,exp:Math.exp,floor:Math.floor,log:Math.log,max:Math.max,min:Math.min,pow:Math.pow,random:Math.random,round:Math.round,sin:Math.sin,sqrt:Math.sqrt,tan:Math.tan,clamp:(t,e,n)=>Math.max(e,Math.min(n,t)),now:Date.now,utc:Date.UTC,datetime:$H,date:t=>new Date(t).getDate(),day:t=>new Date(t).getDay(),year:t=>new Date(t).getFullYear(),month:t=>new Date(t).getMonth(),hours:t=>new Date(t).getHours(),minutes:t=>new Date(t).getMinutes(),seconds:t=>new Date(t).getSeconds(),milliseconds:t=>new Date(t).getMilliseconds(),time:t=>new Date(t).getTime(),timezoneoffset:t=>new Date(t).getTimezoneOffset(),utcdate:t=>new Date(t).getUTCDate(),utcday:t=>new Date(t).getUTCDay(),utcyear:t=>new Date(t).getUTCFullYear(),utcmonth:t=>new Date(t).getUTCMonth(),utchours:t=>new Date(t).getUTCHours(),utcminutes:t=>new Date(t).getUTCMinutes(),utcseconds:t=>new Date(t).getUTCSeconds(),utcmilliseconds:t=>new Date(t).getUTCMilliseconds(),length:t=>t.length,join:function(){return bi("join",arguments)},indexof:function(){return bi("indexOf",arguments)},lastindexof:function(){return bi("lastIndexOf",arguments)},slice:function(){return bi("slice",arguments)},reverse:t=>t.slice().reverse(),parseFloat,parseInt,upper:t=>String(t).toUpperCase(),lower:t=>String(t).toLowerCase(),substring:function(){return bi("substring",arguments,String)},split:function(){return bi("split",arguments,String)},replace:function(){return bi("replace",arguments,String)},trim:t=>String(t).trim(),regexp:RegExp,test:(t,e)=>RegExp(t).test(e)};const BH=["view","item","group","xy","x","y"],w1=new Set([Function,eval,setTimeout,setInterval]);typeof setImmediate=="function"&&w1.add(setImmediate);const TH={Literal:(t,e)=>e.value,Identifier:(t,e)=>{const n=e.name;return t.memberDepth>0?n:n==="datum"?t.datum:n==="event"?t.event:n==="item"?t.item:DH[n]||t.params["$"+n]},MemberExpression:(t,e)=>{const n=!e.computed,r=t(e.object);n&&(t.memberDepth+=1);const i=t(e.property);if(n&&(t.memberDepth-=1),w1.has(r[i])){console.error(`Prevented interpretation of member "${i}" which could lead to insecure code execution`);return}return r[i]},CallExpression:(t,e)=>{const n=e.arguments;let r=e.callee.name;return r.startsWith("_")&&(r=r.slice(1)),r==="if"?t(n[0])?t(n[1]):t(n[2]):(t.fn[r]||SH[r]).apply(t.fn,n.map(t))},ArrayExpression:(t,e)=>e.elements.map(t),BinaryExpression:(t,e)=>FH[e.operator](t(e.left),t(e.right)),UnaryExpression:(t,e)=>MH[e.operator](t(e.argument)),ConditionalExpression:(t,e)=>t(e.test)?t(e.consequent):t(e.alternate),LogicalExpression:(t,e)=>e.operator==="&&"?t(e.left)&&t(e.right):t(e.left)||t(e.right),ObjectExpression:(t,e)=>e.properties.reduce((n,r)=>{t.memberDepth+=1;const i=t(r.key);return t.memberDepth-=1,w1.has(t(r.value))?console.error(`Prevented interpretation of property "${i}" which could lead to insecure code execution`):n[i]=t(r.value),n},{})};function Pu(t,e,n,r,i,a){const u=o=>TH[o.type](u,o);return u.memberDepth=0,u.fn=Object.create(e),u.params=n,u.datum=r,u.event=i,u.item=a,BH.forEach(o=>u.fn[o]=function(){return i.vega[o](...arguments)}),u(t)}var PH={operator(t,e){const n=e.ast,r=t.functions;return i=>Pu(n,r,i)},parameter(t,e){const n=e.ast,r=t.functions;return (i,a)=>Pu(n,r,a,i)},event(t,e){const n=e.ast,r=t.functions;return i=>Pu(n,r,void 0,void 0,i)},handler(t,e){const n=e.ast,r=t.functions;return (i,a)=>{const u=a.item&&a.item.datum;return Pu(n,r,i,u,a)}},encode(t,e){const{marktype:n,channels:r}=e,i=t.functions,a=n==="group"||n==="image"||n==="rect";return (u,o)=>{const s=u.datum;let l=0,f;for(const c in r)f=Pu(r[c].ast,i,o,s,void 0,u),u[c]!==f&&(u[c]=f,l=1);return n!=="rule"&&CH(u,r,a),l}}}; + +export { Ag as A, H, LH as L, Mr as M, PH as P, U, X, Y, x3 as a, pP as b, cc as c, tt as d, et as e, fg as f, ge as g, p3 as p, t5 as t, ug as u, v3 as v, xt as x }; +//# sourceMappingURL=vega-interpreter.module-D8ONVnUK.js.map diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/vega-interpreter.module-D8ONVnUK.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/vega-interpreter.module-D8ONVnUK.js.map new file mode 100644 index 0000000000000000000000000000000000000000..fbf8a17ab20472889176a4a469ef86476e5fb816 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/vega-interpreter.module-D8ONVnUK.js.map @@ -0,0 +1 @@ +{"version":3,"file":"vega-interpreter.module-D8ONVnUK.js","sources":["../../../../../../js/app/.svelte-kit/adapter-node/chunks/vega-interpreter.module.js"],"sourcesContent":["import{d as L5}from\"./dispatch.js\";var Ny={},Eh={},_h=34,vu=10,Ch=13;function Sb(t){return new Function(\"d\",\"return {\"+t.map(function(e,n){return JSON.stringify(e)+\": d[\"+n+'] || \"\"'}).join(\",\")+\"}\")}function P5(t,e){var n=Sb(t);return function(r,i){return e(n(r),i,t)}}function Ly(t){var e=Object.create(null),n=[];return t.forEach(function(r){for(var i in r)i in e||n.push(e[i]=i)}),n}function Te(t,e){var n=t+\"\",r=n.length;return r9999?\"+\"+Te(t,6):Te(t,4)}function I5(t){var e=t.getUTCHours(),n=t.getUTCMinutes(),r=t.getUTCSeconds(),i=t.getUTCMilliseconds();return isNaN(t)?\"Invalid Date\":z5(t.getUTCFullYear())+\"-\"+Te(t.getUTCMonth()+1,2)+\"-\"+Te(t.getUTCDate(),2)+(i?\"T\"+Te(e,2)+\":\"+Te(n,2)+\":\"+Te(r,2)+\".\"+Te(i,3)+\"Z\":r?\"T\"+Te(e,2)+\":\"+Te(n,2)+\":\"+Te(r,2)+\"Z\":n||e?\"T\"+Te(e,2)+\":\"+Te(n,2)+\"Z\":\"\")}function U5(t){var e=new RegExp('[\"'+t+`\n\\r]`),n=t.charCodeAt(0);function r(c,h){var d,g,p=i(c,function(m,y){if(d)return d(m,y-1);g=m,d=h?P5(m,h):Sb(m)});return p.columns=g||[],p}function i(c,h){var d=[],g=c.length,p=0,m=0,y,x=g<=0,v=!1;c.charCodeAt(g-1)===vu&&--g,c.charCodeAt(g-1)===Ch&&--g;function b(){if(x)return Eh;if(v)return v=!1,Ny;var E,A=p,_;if(c.charCodeAt(A)===_h){for(;p++=g?x=!0:(_=c.charCodeAt(p++))===vu?v=!0:_===Ch&&(v=!0,c.charCodeAt(p)===vu&&++p),c.slice(A+1,E-1).replace(/\"\"/g,'\"')}for(;pe?1:t>=e?0:NaN}function q5(t,e){return t==null||e==null?NaN:et?1:e>=t?0:NaN}function Za(t){let e,n,r;t.length!==2?(e=wr,n=(o,s)=>wr(t(o),s),r=(o,s)=>t(o)-s):(e=t===wr||t===q5?t:j5,n=t,r=t);function i(o,s,l=0,f=o.length){if(l>>1;n(o[c],s)<0?l=c+1:f=c}while(l>>1;n(o[c],s)<=0?l=c+1:f=c}while(ll&&r(o[c-1],s)>-r(o[c],s)?c-1:c}return{left:i,center:u,right:a}}function j5(){return 0}function Bb(t){return t===null?NaN:+t}function*W5(t,e){if(e===void 0)for(let n of t)n!=null&&(n=+n)>=n&&(yield n);else{let n=-1;for(let r of t)(r=e(r,++n,t))!=null&&(r=+r)>=r&&(yield r)}}const Tb=Za(wr),ti=Tb.right,Y5=Tb.left;Za(Bb).center;function H5(t,e){let n=0,r,i=0,a=0;if(e===void 0)for(let u of t)u!=null&&(u=+u)>=u&&(r=u-i,i+=r/++n,a+=r*(u-i));else{let u=-1;for(let o of t)(o=e(o,++u,t))!=null&&(o=+o)>=o&&(r=o-i,i+=r/++n,a+=r*(o-i))}if(n>1)return a/(n-1)}function G5(t,e){const n=H5(t,e);return n&&Math.sqrt(n)}class De{constructor(){this._partials=new Float64Array(32),this._n=0}add(e){const n=this._partials;let r=0;for(let i=0;i0){for(u=e[--n];n>0&&(r=u,i=e[--n],u=r+i,a=i-(u-r),!a););n>0&&(a<0&&e[n-1]<0||a>0&&e[n-1]>0)&&(i=a*2,r=u+i,i==r-u&&(u=r))}return u}}class Py extends Map{constructor(e,n=Nb){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:n}}),e!=null)for(const[r,i]of e)this.set(r,i)}get(e){return super.get(B0(this,e))}has(e){return super.has(B0(this,e))}set(e,n){return super.set(Rb(this,e),n)}delete(e){return super.delete(Ob(this,e))}}class $l extends Set{constructor(e,n=Nb){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:n}}),e!=null)for(const r of e)this.add(r)}has(e){return super.has(B0(this,e))}add(e){return super.add(Rb(this,e))}delete(e){return super.delete(Ob(this,e))}}function B0({_intern:t,_key:e},n){const r=e(n);return t.has(r)?t.get(r):n}function Rb({_intern:t,_key:e},n){const r=e(n);return t.has(r)?t.get(r):(t.set(r,n),n)}function Ob({_intern:t,_key:e},n){const r=e(n);return t.has(r)&&(n=t.get(r),t.delete(r)),n}function Nb(t){return t!==null&&typeof t==\"object\"?t.valueOf():t}function X5(t,e){return Array.from(e,n=>t[n])}function V5(t=wr){if(t===wr)return Lb;if(typeof t!=\"function\")throw new TypeError(\"compare is not a function\");return(e,n)=>{const r=t(e,n);return r||r===0?r:(t(n,n)===0)-(t(e,e)===0)}}function Lb(t,e){return(t==null||!(t>=t))-(e==null||!(e>=e))||(te?1:0)}const K5=Math.sqrt(50),Q5=Math.sqrt(10),Z5=Math.sqrt(2);function Sl(t,e,n){const r=(e-t)/Math.max(0,n),i=Math.floor(Math.log10(r)),a=r/Math.pow(10,i),u=a>=K5?10:a>=Q5?5:a>=Z5?2:1;let o,s,l;return i<0?(l=Math.pow(10,-i)/u,o=Math.round(t*l),s=Math.round(e*l),o/le&&--s,l=-l):(l=Math.pow(10,i)*u,o=Math.round(t/l),s=Math.round(e/l),o*le&&--s),s0))return[];if(t===e)return[t];const r=e=i))return[];const o=a-i+1,s=new Array(o);if(r)if(u<0)for(let l=0;l=r)&&(n=r);else{let r=-1;for(let i of t)(i=e(i,++r,t))!=null&&(n=i)&&(n=i)}return n}function O0(t,e){let n;if(e===void 0)for(const r of t)r!=null&&(n>r||n===void 0&&r>=r)&&(n=r);else{let r=-1;for(let i of t)(i=e(i,++r,t))!=null&&(n>i||n===void 0&&i>=i)&&(n=i)}return n}function Pb(t,e,n=0,r=1/0,i){if(e=Math.floor(e),n=Math.floor(Math.max(0,n)),r=Math.floor(Math.min(t.length-1,r)),!(n<=e&&e<=r))return t;for(i=i===void 0?Lb:V5(i);r>n;){if(r-n>600){const s=r-n+1,l=e-n+1,f=Math.log(s),c=.5*Math.exp(2*f/3),h=.5*Math.sqrt(f*c*(s-c)/s)*(l-s/2<0?-1:1),d=Math.max(n,Math.floor(e-l*c/s+h)),g=Math.min(r,Math.floor(e+(s-l)*c/s+h));Pb(t,e,d,g,i)}const a=t[e];let u=n,o=r;for(bu(t,n,e),i(t[r],a)>0&&bu(t,n,r);u0;)--o}i(t[n],a)===0?bu(t,n,o):(++o,bu(t,o,r)),o<=e&&(n=o+1),e<=o&&(r=o-1)}return t}function bu(t,e,n){const r=t[e];t[e]=t[n],t[n]=r}function N0(t,e,n){if(t=Float64Array.from(W5(t,n)),!(!(r=t.length)||isNaN(e=+e))){if(e<=0||r<2)return O0(t);if(e>=1)return Ri(t);var r,i=(r-1)*e,a=Math.floor(i),u=Ri(Pb(t,a).subarray(0,a+1)),o=O0(t.subarray(a+1));return u+(o-u)*(i-a)}}function zb(t,e,n=Bb){if(!(!(r=t.length)||isNaN(e=+e))){if(e<=0||r<2)return+n(t[0],0,t);if(e>=1)return+n(t[r-1],r-1,t);var r,i=(r-1)*e,a=Math.floor(i),u=+n(t[a],a,t),o=+n(t[a+1],a+1,t);return u+(o-u)*(i-a)}}function J5(t,e){let n=0,r=0;if(e===void 0)for(let i of t)i!=null&&(i=+i)>=i&&(++n,r+=i);else{let i=-1;for(let a of t)(a=e(a,++i,t))!=null&&(a=+a)>=a&&(++n,r+=a)}if(n)return r/n}function Ib(t,e){return N0(t,.5,e)}function*tF(t){for(const e of t)yield*e}function Ub(t){return Array.from(tF(t))}function Ie(t,e,n){t=+t,e=+e,n=(i=arguments.length)<2?(e=t,t=0,1):i<3?1:+n;for(var r=-1,i=Math.max(0,Math.ceil((e-t)/n))|0,a=new Array(i);++r>8&15|e>>4&240,e>>4&15|e&240,(e&15)<<4|e&15,1):n===8?Ss(e>>24&255,e>>16&255,e>>8&255,(e&255)/255):n===4?Ss(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|e&240,((e&15)<<4|e&15)/255):null):(e=aF.exec(t))?new qt(e[1],e[2],e[3],1):(e=uF.exec(t))?new qt(e[1]*255/100,e[2]*255/100,e[3]*255/100,1):(e=oF.exec(t))?Ss(e[1],e[2],e[3],e[4]):(e=sF.exec(t))?Ss(e[1]*255/100,e[2]*255/100,e[3]*255/100,e[4]):(e=lF.exec(t))?Yy(e[1],e[2]/100,e[3]/100,1):(e=fF.exec(t))?Yy(e[1],e[2]/100,e[3]/100,e[4]):zy.hasOwnProperty(t)?qy(zy[t]):t===\"transparent\"?new qt(NaN,NaN,NaN,0):null}function qy(t){return new qt(t>>16&255,t>>8&255,t&255,1)}function Ss(t,e,n,r){return r<=0&&(t=e=n=NaN),new qt(t,e,n,r)}function E1(t){return t instanceof fi||(t=bo(t)),t?(t=t.rgb(),new qt(t.r,t.g,t.b,t.opacity)):new qt}function Vn(t,e,n,r){return arguments.length===1?E1(t):new qt(t,e,n,r??1)}function qt(t,e,n,r){this.r=+t,this.g=+e,this.b=+n,this.opacity=+r}Ja(qt,Vn,Vo(fi,{brighter(t){return t=t==null?Sa:Math.pow(Sa,t),new qt(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=t==null?Ii:Math.pow(Ii,t),new qt(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new qt(Oi(this.r),Oi(this.g),Oi(this.b),Bl(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:jy,formatHex:jy,formatHex8:dF,formatRgb:Wy,toString:Wy}));function jy(){return`#${ki(this.r)}${ki(this.g)}${ki(this.b)}`}function dF(){return`#${ki(this.r)}${ki(this.g)}${ki(this.b)}${ki((isNaN(this.opacity)?1:this.opacity)*255)}`}function Wy(){const t=Bl(this.opacity);return`${t===1?\"rgb(\":\"rgba(\"}${Oi(this.r)}, ${Oi(this.g)}, ${Oi(this.b)}${t===1?\")\":`, ${t})`}`}function Bl(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function Oi(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function ki(t){return t=Oi(t),(t<16?\"0\":\"\")+t.toString(16)}function Yy(t,e,n,r){return r<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=NaN),new _n(t,e,n,r)}function jb(t){if(t instanceof _n)return new _n(t.h,t.s,t.l,t.opacity);if(t instanceof fi||(t=bo(t)),!t)return new _n;if(t instanceof _n)return t;t=t.rgb();var e=t.r/255,n=t.g/255,r=t.b/255,i=Math.min(e,n,r),a=Math.max(e,n,r),u=NaN,o=a-i,s=(a+i)/2;return o?(e===a?u=(n-r)/o+(n0&&s<1?0:u,new _n(u,o,s,t.opacity)}function Ao(t,e,n,r){return arguments.length===1?jb(t):new _n(t,e,n,r??1)}function _n(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r}Ja(_n,Ao,Vo(fi,{brighter(t){return t=t==null?Sa:Math.pow(Sa,t),new _n(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=t==null?Ii:Math.pow(Ii,t),new _n(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+(this.h<0)*360,e=isNaN(t)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*e,i=2*n-r;return new qt(Dh(t>=240?t-240:t+120,i,r),Dh(t,i,r),Dh(t<120?t+240:t-120,i,r),this.opacity)},clamp(){return new _n(Hy(this.h),Bs(this.s),Bs(this.l),Bl(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=Bl(this.opacity);return`${t===1?\"hsl(\":\"hsla(\"}${Hy(this.h)}, ${Bs(this.s)*100}%, ${Bs(this.l)*100}%${t===1?\")\":`, ${t})`}`}}));function Hy(t){return t=(t||0)%360,t<0?t+360:t}function Bs(t){return Math.max(0,Math.min(1,t||0))}function Dh(t,e,n){return(t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t)/60:e)*255}const Wb=Math.PI/180,Yb=180/Math.PI,Tl=18,Hb=.96422,Gb=1,Xb=.82521,Vb=4/29,Fa=6/29,Kb=3*Fa*Fa,gF=Fa*Fa*Fa;function Qb(t){if(t instanceof Gn)return new Gn(t.l,t.a,t.b,t.opacity);if(t instanceof yr)return Zb(t);t instanceof qt||(t=E1(t));var e=$h(t.r),n=$h(t.g),r=$h(t.b),i=Fh((.2225045*e+.7168786*n+.0606169*r)/Gb),a,u;return e===n&&n===r?a=u=i:(a=Fh((.4360747*e+.3850649*n+.1430804*r)/Hb),u=Fh((.0139322*e+.0971045*n+.7141733*r)/Xb)),new Gn(116*i-16,500*(a-i),200*(i-u),t.opacity)}function wo(t,e,n,r){return arguments.length===1?Qb(t):new Gn(t,e,n,r??1)}function Gn(t,e,n,r){this.l=+t,this.a=+e,this.b=+n,this.opacity=+r}Ja(Gn,wo,Vo(fi,{brighter(t){return new Gn(this.l+Tl*(t??1),this.a,this.b,this.opacity)},darker(t){return new Gn(this.l-Tl*(t??1),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,n=isNaN(this.b)?t:t-this.b/200;return e=Hb*Mh(e),t=Gb*Mh(t),n=Xb*Mh(n),new qt(kh(3.1338561*e-1.6168667*t-.4906146*n),kh(-.9787684*e+1.9161415*t+.033454*n),kh(.0719453*e-.2289914*t+1.4052427*n),this.opacity)}}));function Fh(t){return t>gF?Math.pow(t,1/3):t/Kb+Vb}function Mh(t){return t>Fa?t*t*t:Kb*(t-Vb)}function kh(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function $h(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function pF(t){if(t instanceof yr)return new yr(t.h,t.c,t.l,t.opacity);if(t instanceof Gn||(t=Qb(t)),t.a===0&&t.b===0)return new yr(NaN,0=1?(n=1,e-1):Math.floor(n*e),i=t[r],a=t[r+1],u=r>0?t[r-1]:2*i-a,o=r()=>t;function rA(t,e){return function(n){return t+n*e}}function yF(t,e,n){return t=Math.pow(t,n),e=Math.pow(e,n)-t,n=1/n,function(r){return Math.pow(t+r*e,n)}}function Gf(t,e){var n=e-t;return n?rA(t,n>180||n<-180?n-360*Math.round(n/360):n):Hf(isNaN(t)?e:t)}function xF(t){return(t=+t)==1?jt:function(e,n){return n-e?yF(e,n,t):Hf(isNaN(e)?n:e)}}function jt(t,e){var n=e-t;return n?rA(t,n):Hf(isNaN(t)?e:t)}const P0=function t(e){var n=xF(e);function r(i,a){var u=n((i=Vn(i)).r,(a=Vn(a)).r),o=n(i.g,a.g),s=n(i.b,a.b),l=jt(i.opacity,a.opacity);return function(f){return i.r=u(f),i.g=o(f),i.b=s(f),i.opacity=l(f),i+\"\"}}return r.gamma=t,r}(1);function iA(t){return function(e){var n=e.length,r=new Array(n),i=new Array(n),a=new Array(n),u,o;for(u=0;un&&(a=e.slice(n,a),o[u]?o[u]+=a:o[++u]=a),(r=r[0])===(i=i[0])?o[u]?o[u]+=i:o[++u]=i:(o[++u]=null,s.push({i:u,x:wn(r,i)})),n=Sh.lastIndex;return n180?f+=360:f-l>180&&(l+=360),h.push({i:c.push(i(c)+\"rotate(\",null,r)-2,x:wn(l,f)})):f&&c.push(i(c)+\"rotate(\"+f+r)}function o(l,f,c,h){l!==f?h.push({i:c.push(i(c)+\"skewX(\",null,r)-2,x:wn(l,f)}):f&&c.push(i(c)+\"skewX(\"+f+r)}function s(l,f,c,h,d,g){if(l!==c||f!==h){var p=d.push(i(d)+\"scale(\",null,\",\",null,\")\");g.push({i:p-4,x:wn(l,c)},{i:p-2,x:wn(f,h)})}else(c!==1||h!==1)&&d.push(i(d)+\"scale(\"+c+\",\"+h+\")\")}return function(l,f){var c=[],h=[];return l=t(l),f=t(f),a(l.translateX,l.translateY,f.translateX,f.translateY,c,h),u(l.rotate,f.rotate,c,h),o(l.skewX,f.skewX,c,h),s(l.scaleX,l.scaleY,f.scaleX,f.scaleY,c,h),l=f=null,function(d){for(var g=-1,p=h.length,m;++g=0&&t._call.call(void 0,e),t=t._next;--Ba}function Zy(){Ui=(Ol=Co.now())+Xf,Ba=zu=0;try{WF()}finally{Ba=0,HF(),Ui=0}}function YF(){var t=Co.now(),e=t-Ol;e>pA&&(Xf-=e,Ol=t)}function HF(){for(var t,e=Rl,n,r=1/0;e;)e._call?(r>e._time&&(r=e._time),t=e,e=e._next):(n=e._next,e._next=null,e=t?t._next=n:Rl=n);Iu=t,U0(r)}function U0(t){if(!Ba){zu&&(zu=clearTimeout(zu));var e=t-Ui;e>24?(t<1/0&&(zu=setTimeout(Zy,t-Co.now()-Xf)),Au&&(Au=clearInterval(Au))):(Au||(Ol=Co.now(),Au=setInterval(YF,pA)),Ba=1,mA(Zy))}}function GF(t,e,n){var r=new Nl,i=e;return e==null?(r.restart(t,e,n),r):(r._restart=r.restart,r.restart=function(a,u,o){u=+u,o=o==null?M1():+o,r._restart(function s(l){l+=i,r._restart(s,i+=u,o),a(l)},u,o)},r.restart(t,e,n),r)}const q0=Math.PI,j0=2*q0,Ai=1e-6,XF=j0-Ai;function xA(t){this._+=t[0];for(let e=1,n=t.length;e=0))throw new Error(`invalid digits: ${t}`);if(e>15)return xA;const n=10**e;return function(r){this._+=r[0];for(let i=1,a=r.length;iAi)if(!(Math.abs(c*s-l*f)>Ai)||!a)this._append`L${this._x1=e},${this._y1=n}`;else{let d=r-u,g=i-o,p=s*s+l*l,m=d*d+g*g,y=Math.sqrt(p),x=Math.sqrt(h),v=a*Math.tan((q0-Math.acos((p+h-m)/(2*y*x)))/2),b=v/x,w=v/y;Math.abs(b-1)>Ai&&this._append`L${e+b*f},${n+b*c}`,this._append`A${a},${a},0,0,${+(c*d>f*g)},${this._x1=e+w*s},${this._y1=n+w*l}`}}arc(e,n,r,i,a,u){if(e=+e,n=+n,r=+r,u=!!u,r<0)throw new Error(`negative radius: ${r}`);let o=r*Math.cos(i),s=r*Math.sin(i),l=e+o,f=n+s,c=1^u,h=u?i-a:a-i;this._x1===null?this._append`M${l},${f}`:(Math.abs(this._x1-l)>Ai||Math.abs(this._y1-f)>Ai)&&this._append`L${l},${f}`,r&&(h<0&&(h=h%j0+j0),h>XF?this._append`A${r},${r},0,1,${c},${e-o},${n-s}A${r},${r},0,1,${c},${this._x1=l},${this._y1=f}`:h>Ai&&this._append`A${r},${r},0,${+(h>=q0)},${c},${this._x1=e+r*Math.cos(a)},${this._y1=n+r*Math.sin(a)}`)}rect(e,n,r,i){this._append`M${this._x0=this._x1=+e},${this._y0=this._y1=+n}h${r=+r}v${+i}h${-r}Z`}toString(){return this._}};function Vf(){return new k1}Vf.prototype=k1.prototype;const Er=11102230246251565e-32,ne=134217729,KF=(3+8*Er)*Er;function Bh(t,e,n,r,i){let a,u,o,s,l=e[0],f=r[0],c=0,h=0;f>l==f>-l?(a=l,l=e[++c]):(a=f,f=r[++h]);let d=0;if(cl==f>-l?(u=l+a,o=a-(u-l),l=e[++c]):(u=f+a,o=a-(u-f),f=r[++h]),a=u,o!==0&&(i[d++]=o);cl==f>-l?(u=a+l,s=u-a,o=a-(u-s)+(l-s),l=e[++c]):(u=a+f,s=u-a,o=a-(u-s)+(f-s),f=r[++h]),a=u,o!==0&&(i[d++]=o);for(;c=N||-k>=N||(c=t-C,o=t-(C+c)+(c-i),c=n-F,l=n-(F+c)+(c-i),c=e-D,s=e-(D+c)+(c-a),c=r-R,f=r-(R+c)+(c-a),o===0&&s===0&&l===0&&f===0)||(N=tM*u+KF*Math.abs(k),k+=C*f+R*o-(D*l+F*s),k>=N||-k>=N))return k;b=o*R,h=ne*o,d=h-(h-o),g=o-d,h=ne*R,p=h-(h-R),m=R-p,w=g*m-(b-d*p-g*p-d*m),E=s*F,h=ne*s,d=h-(h-s),g=s-d,h=ne*F,p=h-(h-F),m=F-p,A=g*m-(E-d*p-g*p-d*m),y=w-A,c=w-y,ye[0]=w-(y+c)+(c-A),x=b+y,c=x-b,v=b-(x-c)+(y-c),y=v-E,c=v-y,ye[1]=v-(y+c)+(c-E),_=x+y,c=_-x,ye[2]=x-(_-c)+(y-c),ye[3]=_;const M=Bh(4,la,4,ye,Jy);b=C*f,h=ne*C,d=h-(h-C),g=C-d,h=ne*f,p=h-(h-f),m=f-p,w=g*m-(b-d*p-g*p-d*m),E=D*l,h=ne*D,d=h-(h-D),g=D-d,h=ne*l,p=h-(h-l),m=l-p,A=g*m-(E-d*p-g*p-d*m),y=w-A,c=w-y,ye[0]=w-(y+c)+(c-A),x=b+y,c=x-b,v=b-(x-c)+(y-c),y=v-E,c=v-y,ye[1]=v-(y+c)+(c-E),_=x+y,c=_-x,ye[2]=x-(_-c)+(y-c),ye[3]=_;const O=Bh(M,Jy,4,ye,t2);b=o*f,h=ne*o,d=h-(h-o),g=o-d,h=ne*f,p=h-(h-f),m=f-p,w=g*m-(b-d*p-g*p-d*m),E=s*l,h=ne*s,d=h-(h-s),g=s-d,h=ne*l,p=h-(h-l),m=l-p,A=g*m-(E-d*p-g*p-d*m),y=w-A,c=w-y,ye[0]=w-(y+c)+(c-A),x=b+y,c=x-b,v=b-(x-c)+(y-c),y=v-E,c=v-y,ye[1]=v-(y+c)+(c-E),_=x+y,c=_-x,ye[2]=x-(_-c)+(y-c),ye[3]=_;const z=Bh(O,t2,4,ye,e2);return e2[z-1]}function Rs(t,e,n,r,i,a){const u=(e-a)*(n-i),o=(t-i)*(r-a),s=u-o,l=Math.abs(u+o);return Math.abs(s)>=ZF*l?s:-eM(t,e,n,r,i,a,l)}const n2=Math.pow(2,-52),Os=new Uint32Array(512);class Ll{static from(e,n=uM,r=oM){const i=e.length,a=new Float64Array(i*2);for(let u=0;u>1;if(n>0&&typeof e[0]!=\"number\")throw new Error(\"Expected coords to contain numbers.\");this.coords=e;const r=Math.max(2*n-5,0);this._triangles=new Uint32Array(r*3),this._halfedges=new Int32Array(r*3),this._hashSize=Math.ceil(Math.sqrt(n)),this._hullPrev=new Uint32Array(n),this._hullNext=new Uint32Array(n),this._hullTri=new Uint32Array(n),this._hullHash=new Int32Array(this._hashSize),this._ids=new Uint32Array(n),this._dists=new Float64Array(n),this.update()}update(){const{coords:e,_hullPrev:n,_hullNext:r,_hullTri:i,_hullHash:a}=this,u=e.length>>1;let o=1/0,s=1/0,l=-1/0,f=-1/0;for(let C=0;Cl&&(l=F),D>f&&(f=D),this._ids[C]=C}const c=(o+l)/2,h=(s+f)/2;let d,g,p;for(let C=0,F=1/0;C0&&(g=C,F=D)}let x=e[2*g],v=e[2*g+1],b=1/0;for(let C=0;CR&&(C[F++]=k,R=N)}this.hull=C.subarray(0,F),this.triangles=new Uint32Array(0),this.halfedges=new Uint32Array(0);return}if(Rs(m,y,x,v,w,E)<0){const C=g,F=x,D=v;g=p,x=w,v=E,p=C,w=F,E=D}const A=aM(m,y,x,v,w,E);this._cx=A.x,this._cy=A.y;for(let C=0;C0&&Math.abs(k-F)<=n2&&Math.abs(N-D)<=n2||(F=k,D=N,R===d||R===g||R===p))continue;let M=0;for(let bt=0,It=this._hashKey(k,N);bt=0;)if(O=z,O===M){O=-1;break}if(O===-1)continue;let G=this._addTriangle(O,R,r[O],-1,-1,i[O]);i[R]=this._legalize(G+2),i[O]=G,_++;let W=r[O];for(;z=r[W],Rs(k,N,e[2*W],e[2*W+1],e[2*z],e[2*z+1])<0;)G=this._addTriangle(W,R,z,i[R],-1,i[W]),i[R]=this._legalize(G+2),r[W]=W,_--,W=z;if(O===M)for(;z=n[O],Rs(k,N,e[2*z],e[2*z+1],e[2*O],e[2*O+1])<0;)G=this._addTriangle(z,R,O,-1,i[O],i[z]),this._legalize(G+2),i[z]=G,r[O]=O,_--,O=z;this._hullStart=n[R]=O,r[O]=n[W]=R,r[R]=W,a[this._hashKey(k,N)]=R,a[this._hashKey(e[2*O],e[2*O+1])]=O}this.hull=new Uint32Array(_);for(let C=0,F=this._hullStart;C<_;C++)this.hull[C]=F,F=r[F];this.triangles=this._triangles.subarray(0,this.trianglesLen),this.halfedges=this._halfedges.subarray(0,this.trianglesLen)}_hashKey(e,n){return Math.floor(nM(e-this._cx,n-this._cy)*this._hashSize)%this._hashSize}_legalize(e){const{_triangles:n,_halfedges:r,coords:i}=this;let a=0,u=0;for(;;){const o=r[e],s=e-e%3;if(u=s+(e+2)%3,o===-1){if(a===0)break;e=Os[--a];continue}const l=o-o%3,f=s+(e+1)%3,c=l+(o+2)%3,h=n[u],d=n[e],g=n[f],p=n[c];if(rM(i[2*h],i[2*h+1],i[2*d],i[2*d+1],i[2*g],i[2*g+1],i[2*p],i[2*p+1])){n[e]=p,n[o]=h;const y=r[c];if(y===-1){let v=this._hullStart;do{if(this._hullTri[v]===c){this._hullTri[v]=e;break}v=this._hullPrev[v]}while(v!==this._hullStart)}this._link(e,y),this._link(o,r[u]),this._link(u,c);const x=l+(o+1)%3;a0?3-n:1+n)/4}function Th(t,e,n,r){const i=t-n,a=e-r;return i*i+a*a}function rM(t,e,n,r,i,a,u,o){const s=t-u,l=e-o,f=n-u,c=r-o,h=i-u,d=a-o,g=s*s+l*l,p=f*f+c*c,m=h*h+d*d;return s*(c*m-p*d)-l*(f*m-p*h)+g*(f*d-c*h)<0}function iM(t,e,n,r,i,a){const u=n-t,o=r-e,s=i-t,l=a-e,f=u*u+o*o,c=s*s+l*l,h=.5/(u*l-o*s),d=(l*f-o*c)*h,g=(u*c-s*f)*h;return d*d+g*g}function aM(t,e,n,r,i,a){const u=n-t,o=r-e,s=i-t,l=a-e,f=u*u+o*o,c=s*s+l*l,h=.5/(u*l-o*s),d=t+(l*f-o*c)*h,g=e+(u*c-s*f)*h;return{x:d,y:g}}function ba(t,e,n,r){if(r-n<=20)for(let i=n+1;i<=r;i++){const a=t[i],u=e[a];let o=i-1;for(;o>=n&&e[t[o]]>u;)t[o+1]=t[o--];t[o+1]=a}else{const i=n+r>>1;let a=n+1,u=r;wu(t,i,a),e[t[n]]>e[t[r]]&&wu(t,n,r),e[t[a]]>e[t[r]]&&wu(t,a,r),e[t[n]]>e[t[a]]&&wu(t,n,a);const o=t[a],s=e[o];for(;;){do a++;while(e[t[a]]s);if(u=u-n?(ba(t,e,a,r),ba(t,e,n,u-1)):(ba(t,e,n,u-1),ba(t,e,a,r))}}function wu(t,e,n){const r=t[e];t[e]=t[n],t[n]=r}function uM(t){return t[0]}function oM(t){return t[1]}const r2=1e-6;class $i{constructor(){this._x0=this._y0=this._x1=this._y1=null,this._=\"\"}moveTo(e,n){this._+=`M${this._x0=this._x1=+e},${this._y0=this._y1=+n}`}closePath(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._+=\"Z\")}lineTo(e,n){this._+=`L${this._x1=+e},${this._y1=+n}`}arc(e,n,r){e=+e,n=+n,r=+r;const i=e+r,a=n;if(r<0)throw new Error(\"negative radius\");this._x1===null?this._+=`M${i},${a}`:(Math.abs(this._x1-i)>r2||Math.abs(this._y1-a)>r2)&&(this._+=\"L\"+i+\",\"+a),r&&(this._+=`A${r},${r},0,1,1,${e-r},${n}A${r},${r},0,1,1,${this._x1=i},${this._y1=a}`)}rect(e,n,r,i){this._+=`M${this._x0=this._x1=+e},${this._y0=this._y1=+n}h${+r}v${+i}h${-r}Z`}value(){return this._||null}}class W0{constructor(){this._=[]}moveTo(e,n){this._.push([e,n])}closePath(){this._.push(this._[0].slice())}lineTo(e,n){this._.push([e,n])}value(){return this._.length?this._:null}}let sM=class{constructor(e,[n,r,i,a]=[0,0,960,500]){if(!((i=+i)>=(n=+n))||!((a=+a)>=(r=+r)))throw new Error(\"invalid bounds\");this.delaunay=e,this._circumcenters=new Float64Array(e.points.length*2),this.vectors=new Float64Array(e.points.length*2),this.xmax=i,this.xmin=n,this.ymax=a,this.ymin=r,this._init()}update(){return this.delaunay.update(),this._init(),this}_init(){const{delaunay:{points:e,hull:n,triangles:r},vectors:i}=this;let a,u;const o=this.circumcenters=this._circumcenters.subarray(0,r.length/3*2);for(let p=0,m=0,y=r.length,x,v;p1;)a-=2;for(let u=2;u0){if(n>=this.ymax)return null;(u=(this.ymax-n)/i)0){if(e>=this.xmax)return null;(u=(this.xmax-e)/r)this.xmax?2:0)|(nthis.ymax?8:0)}_simplify(e){if(e&&e.length>4){for(let n=0;n1e-10)return!1}return!0}function dM(t,e,n){return[t+Math.sin(t+e)*n,e+Math.cos(t-e)*n]}class $1{static from(e,n=fM,r=cM,i){return new $1(\"length\"in e?gM(e,n,r,i):Float64Array.from(pM(e,n,r,i)))}constructor(e){this._delaunator=new Ll(e),this.inedges=new Int32Array(e.length/2),this._hullIndex=new Int32Array(e.length/2),this.points=this._delaunator.coords,this._init()}update(){return this._delaunator.update(),this._init(),this}_init(){const e=this._delaunator,n=this.points;if(e.hull&&e.hull.length>2&&hM(e)){this.collinear=Int32Array.from({length:n.length/2},(h,d)=>d).sort((h,d)=>n[2*h]-n[2*d]||n[2*h+1]-n[2*d+1]);const s=this.collinear[0],l=this.collinear[this.collinear.length-1],f=[n[2*s],n[2*s+1],n[2*l],n[2*l+1]],c=1e-8*Math.hypot(f[3]-f[1],f[2]-f[0]);for(let h=0,d=n.length/2;h0&&(this.triangles=new Int32Array(3).fill(-1),this.halfedges=new Int32Array(3).fill(-1),this.triangles[0]=i[0],u[i[0]]=1,i.length===2&&(u[i[1]]=0,this.triangles[1]=i[1],this.triangles[2]=i[1]))}voronoi(e){return new sM(this,e)}*neighbors(e){const{inedges:n,hull:r,_hullIndex:i,halfedges:a,triangles:u,collinear:o}=this;if(o){const c=o.indexOf(e);c>0&&(yield o[c-1]),c=0&&a!==r&&a!==i;)r=a;return a}_step(e,n,r){const{inedges:i,hull:a,_hullIndex:u,halfedges:o,triangles:s,points:l}=this;if(i[e]===-1||!l.length)return(e+1)%(l.length>>1);let f=e,c=fa(n-l[e*2],2)+fa(r-l[e*2+1],2);const h=i[e];let d=h;do{let g=s[d];const p=fa(n-l[g*2],2)+fa(r-l[g*2+1],2);if(p=(c=(o+l)/2))?o=c:l=c,(m=n>=(h=(s+f)/2))?s=h:f=h,i=a,!(a=a[y=m<<1|p]))return i[y]=u,t;if(d=+t._x.call(null,a.data),g=+t._y.call(null,a.data),e===d&&n===g)return u.next=a,i?i[y]=u:t._root=u,t;do i=i?i[y]=new Array(4):t._root=new Array(4),(p=e>=(c=(o+l)/2))?o=c:l=c,(m=n>=(h=(s+f)/2))?s=h:f=h;while((y=m<<1|p)===(x=(g>=h)<<1|d>=c));return i[x]=a,i[y]=u,t}function xM(t){var e,n,r=t.length,i,a,u=new Array(r),o=new Array(r),s=1/0,l=1/0,f=-1/0,c=-1/0;for(n=0;nf&&(f=i),ac&&(c=a));if(s>f||l>c)return this;for(this.cover(s,l).cover(f,c),n=0;nt||t>=i||r>e||e>=a;)switch(l=(ef||(o=g.y0)>c||(s=g.x1)=y)<<1|t>=m)&&(g=h[h.length-1],h[h.length-1]=h[h.length-1-p],h[h.length-1-p]=g)}else{var x=t-+this._x.call(null,d.data),v=e-+this._y.call(null,d.data),b=x*x+v*v;if(b=(h=(u+s)/2))?u=h:s=h,(p=c>=(d=(o+l)/2))?o=d:l=d,e=n,!(n=n[m=p<<1|g]))return this;if(!n.length)break;(e[m+1&3]||e[m+2&3]||e[m+3&3])&&(r=e,y=m)}for(;n.data!==t;)if(i=n,!(n=n.next))return this;return(a=n.next)&&delete n.next,i?(a?i.next=a:delete i.next,this):e?(a?e[m]=a:delete e[m],(n=e[0]||e[1]||e[2]||e[3])&&n===(e[3]||e[2]||e[1]||e[0])&&!n.length&&(r?r[y]=n:this._root=n),this):(this._root=a,this)}function _M(t){for(var e=0,n=t.length;eh.index){var D=d-_.x-_.vx,R=g-_.y-_.vy,k=D*D+R*R;kd+F||Eg+F||Al.r&&(l.r=l[f].r)}function s(){if(e){var l,f=e.length,c;for(n=new Array(f),l=0;l[e(w,E,u),w])),b;for(m=0,o=new Array(y);m(t=(PM*t+zM)%u2)/u2}function UM(t){return t.x}function qM(t){return t.y}var jM=10,WM=Math.PI*(3-Math.sqrt(5));function YM(t){var e,n=1,r=.001,i=1-Math.pow(r,1/300),a=0,u=.6,o=new Map,s=yA(c),l=L5(\"tick\",\"end\"),f=IM();t==null&&(t=[]);function c(){h(),l.call(\"tick\",e),n1?(m==null?o.delete(p):o.set(p,g(m)),e):o.get(p)},find:function(p,m,y){var x=0,v=t.length,b,w,E,A,_;for(y==null?y=1/0:y*=y,x=0;x1?(l.on(p,m),e):l.on(p)}}}function HM(){var t,e,n,r,i=Ce(-30),a,u=1,o=1/0,s=.81;function l(d){var g,p=t.length,m=S1(t,UM,qM).visitAfter(c);for(r=d,g=0;g=o)return;(d.data!==e||d.next)&&(y===0&&(y=Ur(n),b+=y*y),x===0&&(x=Ur(n),b+=x*x),b=1e21?t.toLocaleString(\"en\").replace(/,/g,\"\"):t.toString(10)}function Pl(t,e){if((n=(t=e?t.toExponential(e-1):t.toExponential()).indexOf(\"e\"))<0)return null;var n,r=t.slice(0,n);return[r.length>1?r[0]+r.slice(2):r,+t.slice(n+1)]}function Ta(t){return t=Pl(Math.abs(t)),t?t[1]:NaN}function KM(t,e){return function(n,r){for(var i=n.length,a=[],u=0,o=t[0],s=0;i>0&&o>0&&(s+o+1>r&&(o=Math.max(1,r-s)),a.push(n.substring(i-=o,i+o)),!((s+=o+1)>r));)o=t[u=(u+1)%t.length];return a.reverse().join(e)}}function QM(t){return function(e){return e.replace(/[0-9]/g,function(n){return t[+n]})}}var ZM=/^(?:(.)?([<>=^]))?([+\\-( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?(~)?([a-z%])?$/i;function qi(t){if(!(e=ZM.exec(t)))throw new Error(\"invalid format: \"+t);var e;return new T1({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}qi.prototype=T1.prototype;function T1(t){this.fill=t.fill===void 0?\" \":t.fill+\"\",this.align=t.align===void 0?\">\":t.align+\"\",this.sign=t.sign===void 0?\"-\":t.sign+\"\",this.symbol=t.symbol===void 0?\"\":t.symbol+\"\",this.zero=!!t.zero,this.width=t.width===void 0?void 0:+t.width,this.comma=!!t.comma,this.precision=t.precision===void 0?void 0:+t.precision,this.trim=!!t.trim,this.type=t.type===void 0?\"\":t.type+\"\"}T1.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?\"0\":\"\")+(this.width===void 0?\"\":Math.max(1,this.width|0))+(this.comma?\",\":\"\")+(this.precision===void 0?\"\":\".\"+Math.max(0,this.precision|0))+(this.trim?\"~\":\"\")+this.type};function JM(t){t:for(var e=t.length,n=1,r=-1,i;n0&&(r=0);break}return r>0?t.slice(0,r)+t.slice(i+1):t}var bA;function t6(t,e){var n=Pl(t,e);if(!n)return t+\"\";var r=n[0],i=n[1],a=i-(bA=Math.max(-8,Math.min(8,Math.floor(i/3)))*3)+1,u=r.length;return a===u?r:a>u?r+new Array(a-u+1).join(\"0\"):a>0?r.slice(0,a)+\".\"+r.slice(a):\"0.\"+new Array(1-a).join(\"0\")+Pl(t,Math.max(0,e+a-1))[0]}function o2(t,e){var n=Pl(t,e);if(!n)return t+\"\";var r=n[0],i=n[1];return i<0?\"0.\"+new Array(-i).join(\"0\")+r:r.length>i+1?r.slice(0,i+1)+\".\"+r.slice(i+1):r+new Array(i-r.length+2).join(\"0\")}const s2={\"%\":(t,e)=>(t*100).toFixed(e),b:t=>Math.round(t).toString(2),c:t=>t+\"\",d:VM,e:(t,e)=>t.toExponential(e),f:(t,e)=>t.toFixed(e),g:(t,e)=>t.toPrecision(e),o:t=>Math.round(t).toString(8),p:(t,e)=>o2(t*100,e),r:o2,s:t6,X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function l2(t){return t}var f2=Array.prototype.map,c2=[\"y\",\"z\",\"a\",\"f\",\"p\",\"n\",\"µ\",\"m\",\"\",\"k\",\"M\",\"G\",\"T\",\"P\",\"E\",\"Z\",\"Y\"];function AA(t){var e=t.grouping===void 0||t.thousands===void 0?l2:KM(f2.call(t.grouping,Number),t.thousands+\"\"),n=t.currency===void 0?\"\":t.currency[0]+\"\",r=t.currency===void 0?\"\":t.currency[1]+\"\",i=t.decimal===void 0?\".\":t.decimal+\"\",a=t.numerals===void 0?l2:QM(f2.call(t.numerals,String)),u=t.percent===void 0?\"%\":t.percent+\"\",o=t.minus===void 0?\"−\":t.minus+\"\",s=t.nan===void 0?\"NaN\":t.nan+\"\";function l(c){c=qi(c);var h=c.fill,d=c.align,g=c.sign,p=c.symbol,m=c.zero,y=c.width,x=c.comma,v=c.precision,b=c.trim,w=c.type;w===\"n\"?(x=!0,w=\"g\"):s2[w]||(v===void 0&&(v=12),b=!0,w=\"g\"),(m||h===\"0\"&&d===\"=\")&&(m=!0,h=\"0\",d=\"=\");var E=p===\"$\"?n:p===\"#\"&&/[boxX]/.test(w)?\"0\"+w.toLowerCase():\"\",A=p===\"$\"?r:/[%p]/.test(w)?u:\"\",_=s2[w],C=/[defgprs%]/.test(w);v=v===void 0?6:/[gprs]/.test(w)?Math.max(1,Math.min(21,v)):Math.max(0,Math.min(20,v));function F(D){var R=E,k=A,N,M,O;if(w===\"c\")k=_(D)+k,D=\"\";else{D=+D;var z=D<0||1/D<0;if(D=isNaN(D)?s:_(Math.abs(D),v),b&&(D=JM(D)),z&&+D==0&&g!==\"+\"&&(z=!1),R=(z?g===\"(\"?g:o:g===\"-\"||g===\"(\"?\"\":g)+R,k=(w===\"s\"?c2[8+bA/3]:\"\")+k+(z&&g===\"(\"?\")\":\"\"),C){for(N=-1,M=D.length;++NO||O>57){k=(O===46?i+D.slice(N+1):D.slice(N))+k,D=D.slice(0,N);break}}}x&&!m&&(D=e(D,1/0));var G=R.length+D.length+k.length,W=G>1)+R+D+k+W.slice(G);break;default:D=W+R+D+k;break}return a(D)}return F.toString=function(){return c+\"\"},F}function f(c,h){var d=l((c=qi(c),c.type=\"f\",c)),g=Math.max(-8,Math.min(8,Math.floor(Ta(h)/3)))*3,p=Math.pow(10,-g),m=c2[8+g/3];return function(y){return d(p*y)+m}}return{format:l,formatPrefix:f}}var Ns,Kf,R1;e6({thousands:\",\",grouping:[3],currency:[\"$\",\"\"]});function e6(t){return Ns=AA(t),Kf=Ns.format,R1=Ns.formatPrefix,Ns}function wA(t){return Math.max(0,-Ta(Math.abs(t)))}function EA(t,e){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(Ta(e)/3)))*3-Ta(Math.abs(t)))}function _A(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,Ta(e)-Ta(t))+1}var Z=1e-6,zl=1e-12,at=Math.PI,kt=at/2,Il=at/4,Me=at*2,Bt=180/at,it=at/180,st=Math.abs,tu=Math.atan,mn=Math.atan2,J=Math.cos,Ls=Math.ceil,CA=Math.exp,Y0=Math.hypot,Ul=Math.log,Rh=Math.pow,Q=Math.sin,cn=Math.sign||function(t){return t>0?1:t<0?-1:0},ke=Math.sqrt,O1=Math.tan;function DA(t){return t>1?0:t<-1?at:Math.acos(t)}function je(t){return t>1?kt:t<-1?-kt:Math.asin(t)}function Vt(){}function ql(t,e){t&&d2.hasOwnProperty(t.type)&&d2[t.type](t,e)}var h2={Feature:function(t,e){ql(t.geometry,e)},FeatureCollection:function(t,e){for(var n=t.features,r=-1,i=n.length;++r=0?1:-1,i=r*n,a=J(e),u=Q(e),o=V0*u,s=X0*a+o*J(i),l=o*r*Q(i);jl.add(mn(l,s)),G0=t,X0=a,V0=u}function $A(t){return Wl=new De,pr(t,Kn),Wl*2}function Yl(t){return[mn(t[1],t[0]),je(t[2])]}function ji(t){var e=t[0],n=t[1],r=J(n);return[r*J(e),r*Q(e),Q(n)]}function Ps(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function Ra(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function Oh(t,e){t[0]+=e[0],t[1]+=e[1],t[2]+=e[2]}function zs(t,e){return[t[0]*e,t[1]*e,t[2]*e]}function Hl(t){var e=ke(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=e,t[1]/=e,t[2]/=e}var Dt,Ne,Ft,Ze,wi,SA,BA,Ma,uo,Nr,Dr,hr={point:K0,lineStart:p2,lineEnd:m2,polygonStart:function(){hr.point=RA,hr.lineStart=a6,hr.lineEnd=u6,uo=new De,Kn.polygonStart()},polygonEnd:function(){Kn.polygonEnd(),hr.point=K0,hr.lineStart=p2,hr.lineEnd=m2,jl<0?(Dt=-(Ft=180),Ne=-(Ze=90)):uo>Z?Ze=90:uo<-Z&&(Ne=-90),Dr[0]=Dt,Dr[1]=Ft},sphere:function(){Dt=-(Ft=180),Ne=-(Ze=90)}};function K0(t,e){Nr.push(Dr=[Dt=t,Ft=t]),eZe&&(Ze=e)}function TA(t,e){var n=ji([t*it,e*it]);if(Ma){var r=Ra(Ma,n),i=[r[1],-r[0],0],a=Ra(i,r);Hl(a),a=Yl(a);var u=t-wi,o=u>0?1:-1,s=a[0]*Bt*o,l,f=st(u)>180;f^(o*wiZe&&(Ze=l)):(s=(s+360)%360-180,f^(o*wiZe&&(Ze=e))),f?tQe(Dt,Ft)&&(Ft=t):Qe(t,Ft)>Qe(Dt,Ft)&&(Dt=t):Ft>=Dt?(tFt&&(Ft=t)):t>wi?Qe(Dt,t)>Qe(Dt,Ft)&&(Ft=t):Qe(t,Ft)>Qe(Dt,Ft)&&(Dt=t)}else Nr.push(Dr=[Dt=t,Ft=t]);eZe&&(Ze=e),Ma=n,wi=t}function p2(){hr.point=TA}function m2(){Dr[0]=Dt,Dr[1]=Ft,hr.point=K0,Ma=null}function RA(t,e){if(Ma){var n=t-wi;uo.add(st(n)>180?n+(n>0?360:-360):n)}else SA=t,BA=e;Kn.point(t,e),TA(t,e)}function a6(){Kn.lineStart()}function u6(){RA(SA,BA),Kn.lineEnd(),st(uo)>Z&&(Dt=-(Ft=180)),Dr[0]=Dt,Dr[1]=Ft,Ma=null}function Qe(t,e){return(e-=t)<0?e+360:e}function o6(t,e){return t[0]-e[0]}function y2(t,e){return t[0]<=t[1]?t[0]<=e&&e<=t[1]:eQe(r[0],r[1])&&(r[1]=i[1]),Qe(i[0],r[1])>Qe(r[0],r[1])&&(r[0]=i[0])):a.push(r=i);for(u=-1/0,n=a.length-1,e=0,r=a[n];e<=n;r=i,++e)i=a[e],(o=Qe(r[1],i[0]))>u&&(u=o,Dt=i[0],Ft=r[1])}return Nr=Dr=null,Dt===1/0||Ne===1/0?[[NaN,NaN],[NaN,NaN]]:[[Dt,Ne],[Ft,Ze]]}var Uu,Gl,Xl,Vl,Kl,Ql,Zl,Jl,Q0,Z0,J0,NA,LA,Ae,we,Ee,Fn={sphere:Vt,point:N1,lineStart:x2,lineEnd:v2,polygonStart:function(){Fn.lineStart=f6,Fn.lineEnd=c6},polygonEnd:function(){Fn.lineStart=x2,Fn.lineEnd=v2}};function N1(t,e){t*=it,e*=it;var n=J(e);Zo(n*J(t),n*Q(t),Q(e))}function Zo(t,e,n){++Uu,Xl+=(t-Xl)/Uu,Vl+=(e-Vl)/Uu,Kl+=(n-Kl)/Uu}function x2(){Fn.point=s6}function s6(t,e){t*=it,e*=it;var n=J(e);Ae=n*J(t),we=n*Q(t),Ee=Q(e),Fn.point=l6,Zo(Ae,we,Ee)}function l6(t,e){t*=it,e*=it;var n=J(e),r=n*J(t),i=n*Q(t),a=Q(e),u=mn(ke((u=we*a-Ee*i)*u+(u=Ee*r-Ae*a)*u+(u=Ae*i-we*r)*u),Ae*r+we*i+Ee*a);Gl+=u,Ql+=u*(Ae+(Ae=r)),Zl+=u*(we+(we=i)),Jl+=u*(Ee+(Ee=a)),Zo(Ae,we,Ee)}function v2(){Fn.point=N1}function f6(){Fn.point=h6}function c6(){PA(NA,LA),Fn.point=N1}function h6(t,e){NA=t,LA=e,t*=it,e*=it,Fn.point=PA;var n=J(e);Ae=n*J(t),we=n*Q(t),Ee=Q(e),Zo(Ae,we,Ee)}function PA(t,e){t*=it,e*=it;var n=J(e),r=n*J(t),i=n*Q(t),a=Q(e),u=we*a-Ee*i,o=Ee*r-Ae*a,s=Ae*i-we*r,l=Y0(u,o,s),f=je(l),c=l&&-f/l;Q0.add(c*u),Z0.add(c*o),J0.add(c*s),Gl+=f,Ql+=f*(Ae+(Ae=r)),Zl+=f*(we+(we=i)),Jl+=f*(Ee+(Ee=a)),Zo(Ae,we,Ee)}function zA(t){Uu=Gl=Xl=Vl=Kl=Ql=Zl=Jl=0,Q0=new De,Z0=new De,J0=new De,pr(t,Fn);var e=+Q0,n=+Z0,r=+J0,i=Y0(e,n,r);return iat&&(t-=Math.round(t/Me)*Me),[t,e]}ed.invert=ed;function IA(t,e,n){return(t%=Me)?e||n?td(A2(t),w2(e,n)):A2(t):e||n?w2(e,n):ed}function b2(t){return function(e,n){return e+=t,st(e)>at&&(e-=Math.round(e/Me)*Me),[e,n]}}function A2(t){var e=b2(t);return e.invert=b2(-t),e}function w2(t,e){var n=J(t),r=Q(t),i=J(e),a=Q(e);function u(o,s){var l=J(s),f=J(o)*l,c=Q(o)*l,h=Q(s),d=h*n+f*r;return[mn(c*i-d*a,f*n-h*r),je(d*i+c*a)]}return u.invert=function(o,s){var l=J(s),f=J(o)*l,c=Q(o)*l,h=Q(s),d=h*i-c*a;return[mn(c*i+h*a,f*n+d*r),je(d*n-f*r)]},u}function d6(t){t=IA(t[0]*it,t[1]*it,t.length>2?t[2]*it:0);function e(n){return n=t(n[0]*it,n[1]*it),n[0]*=Bt,n[1]*=Bt,n}return e.invert=function(n){return n=t.invert(n[0]*it,n[1]*it),n[0]*=Bt,n[1]*=Bt,n},e}function g6(t,e,n,r,i,a){if(n){var u=J(e),o=Q(e),s=r*n;i==null?(i=e+r*Me,a=e-s/2):(i=E2(u,i),a=E2(u,a),(r>0?ia)&&(i+=r*Me));for(var l,f=i;r>0?f>a:f1&&t.push(t.pop().concat(t.shift()))},result:function(){var n=t;return t=[],e=null,n}}}function ol(t,e){return st(t[0]-e[0])=0;--o)i.point((c=f[o])[0],c[1]);else r(h.x,h.p.x,-1,i);h=h.p}h=h.o,f=h.z,d=!d}while(!h.v);i.lineEnd()}}}function _2(t){if(e=t.length){for(var e,n=0,r=t[0],i;++n=0?1:-1,F=C*_,D=F>at,R=m*E;if(s.add(mn(R*C*Q(F),y*A+R*J(F))),u+=D?_+C*Me:_,D^g>=n^b>=n){var k=Ra(ji(d),ji(v));Hl(k);var N=Ra(a,k);Hl(N);var M=(D^_>=0?-1:1)*je(N[2]);(r>M||r===M&&(k[0]||k[1]))&&(o+=D^_>=0?1:-1)}}return(u<-Z||u0){for(s||(i.polygonStart(),s=!0),i.lineStart(),E=0;E<_;++E)i.point((F=C[E])[0],F[1]);i.lineEnd()}return}A>1&&b&2&&w.push(w.pop().concat(w.shift())),f.push(w.filter(m6))}}return h}}function m6(t){return t.length>1}function y6(t,e){return((t=t.x)[0]<0?t[1]-kt-Z:kt-t[1])-((e=e.x)[0]<0?e[1]-kt-Z:kt-e[1])}const C2=jA(function(){return!0},x6,b6,[-at,-kt]);function x6(t){var e=NaN,n=NaN,r=NaN,i;return{lineStart:function(){t.lineStart(),i=1},point:function(a,u){var o=a>0?at:-at,s=st(a-e);st(s-at)0?kt:-kt),t.point(r,n),t.lineEnd(),t.lineStart(),t.point(o,n),t.point(a,n),i=0):r!==o&&s>=at&&(st(e-r)Z?tu((Q(e)*(a=J(r))*Q(n)-Q(r)*(i=J(e))*Q(t))/(i*a*u)):(e+r)/2}function b6(t,e,n,r){var i;if(t==null)i=n*kt,r.point(-at,i),r.point(0,i),r.point(at,i),r.point(at,0),r.point(at,-i),r.point(0,-i),r.point(-at,-i),r.point(-at,0),r.point(-at,i);else if(st(t[0]-e[0])>Z){var a=t[0]0,i=st(e)>Z;function a(f,c,h,d){g6(d,t,n,h,f,c)}function u(f,c){return J(f)*J(c)>e}function o(f){var c,h,d,g,p;return{lineStart:function(){g=d=!1,p=1},point:function(m,y){var x=[m,y],v,b=u(m,y),w=r?b?0:l(m,y):b?l(m+(m<0?at:-at),y):0;if(!c&&(g=d=b)&&f.lineStart(),b!==d&&(v=s(c,x),(!v||ol(c,v)||ol(x,v))&&(x[2]=1)),b!==d)p=0,b?(f.lineStart(),v=s(x,c),f.point(v[0],v[1])):(v=s(c,x),f.point(v[0],v[1],2),f.lineEnd()),c=v;else if(i&&c&&r^b){var E;!(w&h)&&(E=s(x,c,!0))&&(p=0,r?(f.lineStart(),f.point(E[0][0],E[0][1]),f.point(E[1][0],E[1][1]),f.lineEnd()):(f.point(E[1][0],E[1][1]),f.lineEnd(),f.lineStart(),f.point(E[0][0],E[0][1],3)))}b&&(!c||!ol(c,x))&&f.point(x[0],x[1]),c=x,d=b,h=w},lineEnd:function(){d&&f.lineEnd(),c=null},clean:function(){return p|(g&&d)<<1}}}function s(f,c,h){var d=ji(f),g=ji(c),p=[1,0,0],m=Ra(d,g),y=Ps(m,m),x=m[0],v=y-x*x;if(!v)return!h&&f;var b=e*y/v,w=-e*x/v,E=Ra(p,m),A=zs(p,b),_=zs(m,w);Oh(A,_);var C=E,F=Ps(A,C),D=Ps(C,C),R=F*F-D*(Ps(A,A)-1);if(!(R<0)){var k=ke(R),N=zs(C,(-F-k)/D);if(Oh(N,A),N=Yl(N),!h)return N;var M=f[0],O=c[0],z=f[1],G=c[1],W;O0^N[1]<(st(N[0]-M)at^(M<=N[0]&&N[0]<=O)){var me=zs(C,(-F+k)/D);return Oh(me,A),[N,Yl(me)]}}}function l(f,c){var h=r?t:at-t,d=0;return f<-h?d|=1:f>h&&(d|=2),c<-h?d|=4:c>h&&(d|=8),d}return jA(u,o,a,r?[0,-t]:[-at,t-at])}function w6(t,e,n,r,i,a){var u=t[0],o=t[1],s=e[0],l=e[1],f=0,c=1,h=s-u,d=l-o,g;if(g=n-u,!(!h&&g>0)){if(g/=h,h<0){if(g0){if(g>c)return;g>f&&(f=g)}if(g=i-u,!(!h&&g<0)){if(g/=h,h<0){if(g>c)return;g>f&&(f=g)}else if(h>0){if(g0)){if(g/=d,d<0){if(g0){if(g>c)return;g>f&&(f=g)}if(g=a-o,!(!d&&g<0)){if(g/=d,d<0){if(g>c)return;g>f&&(f=g)}else if(d>0){if(g0&&(t[0]=u+f*h,t[1]=o+f*d),c<1&&(e[0]=u+c*h,e[1]=o+c*d),!0}}}}}var qu=1e9,Us=-qu;function WA(t,e,n,r){function i(l,f){return t<=l&&l<=n&&e<=f&&f<=r}function a(l,f,c,h){var d=0,g=0;if(l==null||(d=u(l,c))!==(g=u(f,c))||s(l,f)<0^c>0)do h.point(d===0||d===3?t:n,d>1?r:e);while((d=(d+c+4)%4)!==g);else h.point(f[0],f[1])}function u(l,f){return st(l[0]-t)0?0:3:st(l[0]-n)0?2:1:st(l[1]-e)0?1:0:f>0?3:2}function o(l,f){return s(l.x,f.x)}function s(l,f){var c=u(l,1),h=u(f,1);return c!==h?c-h:c===0?f[1]-l[1]:c===1?l[0]-f[0]:c===2?l[1]-f[1]:f[0]-l[0]}return function(l){var f=l,c=UA(),h,d,g,p,m,y,x,v,b,w,E,A={point:_,lineStart:R,lineEnd:k,polygonStart:F,polygonEnd:D};function _(M,O){i(M,O)&&f.point(M,O)}function C(){for(var M=0,O=0,z=d.length;Or&&(Pn-Se)*(r-me)>(Ut-me)*(t-Se)&&++M:Ut<=r&&(Pn-Se)*(r-me)<(Ut-me)*(t-Se)&&--M;return M}function F(){f=c,h=[],d=[],E=!0}function D(){var M=C(),O=E&&M,z=(h=Ub(h)).length;(O||z)&&(l.polygonStart(),O&&(l.lineStart(),a(null,null,1,l),l.lineEnd()),z&&qA(h,o,M,a,l),l.polygonEnd()),f=l,h=d=g=null}function R(){A.point=N,d&&d.push(g=[]),w=!0,b=!1,x=v=NaN}function k(){h&&(N(p,m),y&&b&&c.rejoin(),h.push(c.result())),A.point=_,b&&f.lineEnd()}function N(M,O){var z=i(M,O);if(d&&g.push([M,O]),w)p=M,m=O,y=z,w=!1,z&&(f.lineStart(),f.point(M,O));else if(z&&b)f.point(M,O);else{var G=[x=Math.max(Us,Math.min(qu,x)),v=Math.max(Us,Math.min(qu,v))],W=[M=Math.max(Us,Math.min(qu,M)),O=Math.max(Us,Math.min(qu,O))];w6(G,W,t,e,n,r)?(b||(f.lineStart(),f.point(G[0],G[1])),f.point(W[0],W[1]),z||f.lineEnd(),E=!1):z&&(f.lineStart(),f.point(M,O),E=!1)}x=M,v=O,b=z}return A}}function D2(t,e,n){var r=Ie(t,e-Z,n).concat(e);return function(i){return r.map(function(a){return[i,a]})}}function F2(t,e,n){var r=Ie(t,e-Z,n).concat(e);return function(i){return r.map(function(a){return[a,i]})}}function E6(){var t,e,n,r,i,a,u,o,s=10,l=s,f=90,c=360,h,d,g,p,m=2.5;function y(){return{type:\"MultiLineString\",coordinates:x()}}function x(){return Ie(Ls(r/f)*f,n,f).map(g).concat(Ie(Ls(o/c)*c,u,c).map(p)).concat(Ie(Ls(e/s)*s,t,s).filter(function(v){return st(v%f)>Z}).map(h)).concat(Ie(Ls(a/l)*l,i,l).filter(function(v){return st(v%c)>Z}).map(d))}return y.lines=function(){return x().map(function(v){return{type:\"LineString\",coordinates:v}})},y.outline=function(){return{type:\"Polygon\",coordinates:[g(r).concat(p(u).slice(1),g(n).reverse().slice(1),p(o).reverse().slice(1))]}},y.extent=function(v){return arguments.length?y.extentMajor(v).extentMinor(v):y.extentMinor()},y.extentMajor=function(v){return arguments.length?(r=+v[0][0],n=+v[1][0],o=+v[0][1],u=+v[1][1],r>n&&(v=r,r=n,n=v),o>u&&(v=o,o=u,u=v),y.precision(m)):[[r,o],[n,u]]},y.extentMinor=function(v){return arguments.length?(e=+v[0][0],t=+v[1][0],a=+v[0][1],i=+v[1][1],e>t&&(v=e,e=t,t=v),a>i&&(v=a,a=i,i=v),y.precision(m)):[[e,a],[t,i]]},y.step=function(v){return arguments.length?y.stepMajor(v).stepMinor(v):y.stepMinor()},y.stepMajor=function(v){return arguments.length?(f=+v[0],c=+v[1],y):[f,c]},y.stepMinor=function(v){return arguments.length?(s=+v[0],l=+v[1],y):[s,l]},y.precision=function(v){return arguments.length?(m=+v,h=D2(a,i,90),d=F2(e,t,m),g=D2(o,u,90),p=F2(r,n,m),y):m},y.extentMajor([[-180,-90+Z],[180,90-Z]]).extentMinor([[-180,-80-Z],[180,80+Z]])}const Do=t=>t;var Lh=new De,nd=new De,YA,HA,rd,id,mr={point:Vt,lineStart:Vt,lineEnd:Vt,polygonStart:function(){mr.lineStart=_6,mr.lineEnd=D6},polygonEnd:function(){mr.lineStart=mr.lineEnd=mr.point=Vt,Lh.add(st(nd)),nd=new De},result:function(){var t=Lh/2;return Lh=new De,t}};function _6(){mr.point=C6}function C6(t,e){mr.point=GA,YA=rd=t,HA=id=e}function GA(t,e){nd.add(id*t-rd*e),rd=t,id=e}function D6(){GA(YA,HA)}var Oa=1/0,tf=Oa,Fo=-Oa,ef=Fo,nf={point:F6,lineStart:Vt,lineEnd:Vt,polygonStart:Vt,polygonEnd:Vt,result:function(){var t=[[Oa,tf],[Fo,ef]];return Fo=ef=-(tf=Oa=1/0),t}};function F6(t,e){tFo&&(Fo=t),eef&&(ef=e)}var ad=0,ud=0,ju=0,rf=0,af=0,Aa=0,od=0,sd=0,Wu=0,XA,VA,jn,Wn,fn={point:Wi,lineStart:M2,lineEnd:k2,polygonStart:function(){fn.lineStart=$6,fn.lineEnd=S6},polygonEnd:function(){fn.point=Wi,fn.lineStart=M2,fn.lineEnd=k2},result:function(){var t=Wu?[od/Wu,sd/Wu]:Aa?[rf/Aa,af/Aa]:ju?[ad/ju,ud/ju]:[NaN,NaN];return ad=ud=ju=rf=af=Aa=od=sd=Wu=0,t}};function Wi(t,e){ad+=t,ud+=e,++ju}function M2(){fn.point=M6}function M6(t,e){fn.point=k6,Wi(jn=t,Wn=e)}function k6(t,e){var n=t-jn,r=e-Wn,i=ke(n*n+r*r);rf+=i*(jn+t)/2,af+=i*(Wn+e)/2,Aa+=i,Wi(jn=t,Wn=e)}function k2(){fn.point=Wi}function $6(){fn.point=B6}function S6(){KA(XA,VA)}function B6(t,e){fn.point=KA,Wi(XA=jn=t,VA=Wn=e)}function KA(t,e){var n=t-jn,r=e-Wn,i=ke(n*n+r*r);rf+=i*(jn+t)/2,af+=i*(Wn+e)/2,Aa+=i,i=Wn*t-jn*e,od+=i*(jn+t),sd+=i*(Wn+e),Wu+=i*3,Wi(jn=t,Wn=e)}function QA(t){this._context=t}QA.prototype={_radius:4.5,pointRadius:function(t){return this._radius=t,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){this._line===0&&this._context.closePath(),this._point=NaN},point:function(t,e){switch(this._point){case 0:{this._context.moveTo(t,e),this._point=1;break}case 1:{this._context.lineTo(t,e);break}default:{this._context.moveTo(t+this._radius,e),this._context.arc(t,e,this._radius,0,Me);break}}},result:Vt};var ld=new De,Ph,ZA,JA,Yu,Hu,Mo={point:Vt,lineStart:function(){Mo.point=T6},lineEnd:function(){Ph&&tw(ZA,JA),Mo.point=Vt},polygonStart:function(){Ph=!0},polygonEnd:function(){Ph=null},result:function(){var t=+ld;return ld=new De,t}};function T6(t,e){Mo.point=tw,ZA=Yu=t,JA=Hu=e}function tw(t,e){Yu-=t,Hu-=e,ld.add(ke(Yu*Yu+Hu*Hu)),Yu=t,Hu=e}let $2,uf,S2,B2;class T2{constructor(e){this._append=e==null?ew:R6(e),this._radius=4.5,this._=\"\"}pointRadius(e){return this._radius=+e,this}polygonStart(){this._line=0}polygonEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){this._line===0&&(this._+=\"Z\"),this._point=NaN}point(e,n){switch(this._point){case 0:{this._append`M${e},${n}`,this._point=1;break}case 1:{this._append`L${e},${n}`;break}default:{if(this._append`M${e},${n}`,this._radius!==S2||this._append!==uf){const r=this._radius,i=this._;this._=\"\",this._append`m0,${r}a${r},${r} 0 1,1 0,${-2*r}a${r},${r} 0 1,1 0,${2*r}z`,S2=r,uf=this._append,B2=this._,this._=i}this._+=B2;break}}}result(){const e=this._;return this._=\"\",e.length?e:null}}function ew(t){let e=1;this._+=t[0];for(const n=t.length;e=0))throw new RangeError(`invalid digits: ${t}`);if(e>15)return ew;if(e!==$2){const n=10**e;$2=e,uf=function(i){let a=1;this._+=i[0];for(const u=i.length;a=0))throw new RangeError(`invalid digits: ${o}`);n=s}return e===null&&(a=new T2(n)),u},u.projection(t).digits(n).context(e)}function Qf(t){return function(e){var n=new fd;for(var r in t)n[r]=t[r];return n.stream=e,n}}function fd(){}fd.prototype={constructor:fd,point:function(t,e){this.stream.point(t,e)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};function L1(t,e,n){var r=t.clipExtent&&t.clipExtent();return t.scale(150).translate([0,0]),r!=null&&t.clipExtent(null),pr(n,t.stream(nf)),e(nf.result()),r!=null&&t.clipExtent(r),t}function Zf(t,e,n){return L1(t,function(r){var i=e[1][0]-e[0][0],a=e[1][1]-e[0][1],u=Math.min(i/(r[1][0]-r[0][0]),a/(r[1][1]-r[0][1])),o=+e[0][0]+(i-u*(r[1][0]+r[0][0]))/2,s=+e[0][1]+(a-u*(r[1][1]+r[0][1]))/2;t.scale(150*u).translate([o,s])},n)}function P1(t,e,n){return Zf(t,[[0,0],e],n)}function z1(t,e,n){return L1(t,function(r){var i=+e,a=i/(r[1][0]-r[0][0]),u=(i-a*(r[1][0]+r[0][0]))/2,o=-a*r[0][1];t.scale(150*a).translate([u,o])},n)}function I1(t,e,n){return L1(t,function(r){var i=+e,a=i/(r[1][1]-r[0][1]),u=-a*r[0][0],o=(i-a*(r[1][1]+r[0][1]))/2;t.scale(150*a).translate([u,o])},n)}var R2=16,O6=J(30*it);function O2(t,e){return+e?L6(t,e):N6(t)}function N6(t){return Qf({point:function(e,n){e=t(e,n),this.stream.point(e[0],e[1])}})}function L6(t,e){function n(r,i,a,u,o,s,l,f,c,h,d,g,p,m){var y=l-r,x=f-i,v=y*y+x*x;if(v>4*e&&p--){var b=u+h,w=o+d,E=s+g,A=ke(b*b+w*w+E*E),_=je(E/=A),C=st(st(E)-1)e||st((y*k+x*N)/v-.5)>.3||u*h+o*d+s*g2?M[2]%360*it:0,k()):[o*Bt,s*Bt,l*Bt]},D.angle=function(M){return arguments.length?(c=M%360*it,k()):c*Bt},D.reflectX=function(M){return arguments.length?(h=M?-1:1,k()):h<0},D.reflectY=function(M){return arguments.length?(d=M?-1:1,k()):d<0},D.precision=function(M){return arguments.length?(E=O2(A,w=M*M),N()):ke(w)},D.fitExtent=function(M,O){return Zf(D,M,O)},D.fitSize=function(M,O){return P1(D,M,O)},D.fitWidth=function(M,O){return z1(D,M,O)},D.fitHeight=function(M,O){return I1(D,M,O)};function k(){var M=N2(n,0,0,h,d,c).apply(null,e(a,u)),O=N2(n,r-M[0],i-M[1],h,d,c);return f=IA(o,s,l),A=td(e,O),_=td(f,A),E=O2(A,w),N()}function N(){return C=F=null,D}return function(){return e=t.apply(this,arguments),D.invert=e.invert&&R,k()}}function U1(t){var e=0,n=at/3,r=rw(t),i=r(e,n);return i.parallels=function(a){return arguments.length?r(e=a[0]*it,n=a[1]*it):[e*Bt,n*Bt]},i}function U6(t){var e=J(t);function n(r,i){return[r*e,Q(i)/e]}return n.invert=function(r,i){return[r/e,je(i*e)]},n}function q6(t,e){var n=Q(t),r=(n+Q(e))/2;if(st(r)=.12&&m<.234&&p>=-.425&&p<-.214?i:m>=.166&&m<.234&&p>=-.214&&p<-.115?u:n).invert(h)},f.stream=function(h){return t&&e===h?t:t=j6([n.stream(e=h),i.stream(h),u.stream(h)])},f.precision=function(h){return arguments.length?(n.precision(h),i.precision(h),u.precision(h),c()):n.precision()},f.scale=function(h){return arguments.length?(n.scale(h),i.scale(h*.35),u.scale(h),f.translate(n.translate())):n.scale()},f.translate=function(h){if(!arguments.length)return n.translate();var d=n.scale(),g=+h[0],p=+h[1];return r=n.translate(h).clipExtent([[g-.455*d,p-.238*d],[g+.455*d,p+.238*d]]).stream(l),a=i.translate([g-.307*d,p+.201*d]).clipExtent([[g-.425*d+Z,p+.12*d+Z],[g-.214*d-Z,p+.234*d-Z]]).stream(l),o=u.translate([g-.205*d,p+.212*d]).clipExtent([[g-.214*d+Z,p+.166*d+Z],[g-.115*d-Z,p+.234*d-Z]]).stream(l),c()},f.fitExtent=function(h,d){return Zf(f,h,d)},f.fitSize=function(h,d){return P1(f,h,d)},f.fitWidth=function(h,d){return z1(f,h,d)},f.fitHeight=function(h,d){return I1(f,h,d)};function c(){return t=e=null,f}return f.scale(1070)}function aw(t){return function(e,n){var r=J(e),i=J(n),a=t(r*i);return a===1/0?[2,0]:[a*i*Q(e),a*Q(n)]}}function Jo(t){return function(e,n){var r=ke(e*e+n*n),i=t(r),a=Q(i),u=J(i);return[mn(e*a,r*u),je(r&&n*a/r)]}}var uw=aw(function(t){return ke(2/(1+t))});uw.invert=Jo(function(t){return 2*je(t/2)});function Y6(){return er(uw).scale(124.75).clipAngle(180-.001)}var ow=aw(function(t){return(t=DA(t))&&t/Q(t)});ow.invert=Jo(function(t){return t});function H6(){return er(ow).scale(79.4188).clipAngle(180-.001)}function Jf(t,e){return[t,Ul(O1((kt+e)/2))]}Jf.invert=function(t,e){return[t,2*tu(CA(e))-kt]};function G6(){return sw(Jf).scale(961/Me)}function sw(t){var e=er(t),n=e.center,r=e.scale,i=e.translate,a=e.clipExtent,u=null,o,s,l;e.scale=function(c){return arguments.length?(r(c),f()):r()},e.translate=function(c){return arguments.length?(i(c),f()):i()},e.center=function(c){return arguments.length?(n(c),f()):n()},e.clipExtent=function(c){return arguments.length?(c==null?u=o=s=l=null:(u=+c[0][0],o=+c[0][1],s=+c[1][0],l=+c[1][1]),f()):u==null?null:[[u,o],[s,l]]};function f(){var c=at*r(),h=e(d6(e.rotate()).invert([0,0]));return a(u==null?[[h[0]-c,h[1]-c],[h[0]+c,h[1]+c]]:t===Jf?[[Math.max(h[0]-c,u),o],[Math.min(h[0]+c,s),l]]:[[u,Math.max(h[1]-c,o)],[s,Math.min(h[1]+c,l)]])}return f()}function qs(t){return O1((kt+t)/2)}function X6(t,e){var n=J(t),r=t===e?Q(t):Ul(n/J(e))/Ul(qs(e)/qs(t)),i=n*Rh(qs(t),r)/r;if(!r)return Jf;function a(u,o){i>0?o<-kt+Z&&(o=-kt+Z):o>kt-Z&&(o=kt-Z);var s=i/Rh(qs(o),r);return[s*Q(r*u),i-s*J(r*u)]}return a.invert=function(u,o){var s=i-o,l=cn(r)*ke(u*u+s*s),f=mn(u,st(s))*cn(s);return s*r<0&&(f-=at*cn(u)*cn(s)),[f/r,2*tu(Rh(i/l,1/r))-kt]},a}function V6(){return U1(X6).scale(109.5).parallels([30,30])}function sf(t,e){return[t,e]}sf.invert=sf;function K6(){return er(sf).scale(152.63)}function Q6(t,e){var n=J(t),r=t===e?Q(t):(n-J(e))/(e-t),i=n/r+t;if(st(r)Z&&--r>0);return[t/(.8707+(a=n*n)*(-.131979+a*(-.013791+a*a*a*(.003971-.001529*a)))),n]};function rk(){return er(cw).scale(175.295)}function hw(t,e){return[J(e)*Q(t),Q(e)]}hw.invert=Jo(je);function ik(){return er(hw).scale(249.5).clipAngle(90+Z)}function dw(t,e){var n=J(e),r=1+J(t)*n;return[n*Q(t)/r,Q(e)/r]}dw.invert=Jo(function(t){return 2*tu(t)});function ak(){return er(dw).scale(250).clipAngle(142)}function gw(t,e){return[Ul(O1((kt+e)/2)),-t]}gw.invert=function(t,e){return[-e,2*tu(CA(t))-kt]};function uk(){var t=sw(gw),e=t.center,n=t.rotate;return t.center=function(r){return arguments.length?e([-r[1],r[0]]):(r=e(),[r[1],-r[0]])},t.rotate=function(r){return arguments.length?n([r[0],r[1],r.length>2?r[2]+90:90]):(r=n(),[r[0],r[1],r[2]-90])},n([0,0,90]).scale(159.155)}function ok(t,e){return t.parent===e.parent?1:2}function sk(t){return t.reduce(lk,0)/t.length}function lk(t,e){return t+e.x}function fk(t){return 1+t.reduce(ck,0)}function ck(t,e){return Math.max(t,e.y)}function hk(t){for(var e;e=t.children;)t=e[0];return t}function dk(t){for(var e;e=t.children;)t=e[e.length-1];return t}function gk(){var t=ok,e=1,n=1,r=!1;function i(a){var u,o=0;a.eachAfter(function(h){var d=h.children;d?(h.x=sk(d),h.y=fk(d)):(h.x=u?o+=t(h,u):0,h.y=0,u=h)});var s=hk(a),l=dk(a),f=s.x-t(s,l)/2,c=l.x+t(l,s)/2;return a.eachAfter(r?function(h){h.x=(h.x-a.x)*e,h.y=(a.y-h.y)*n}:function(h){h.x=(h.x-f)/(c-f)*e,h.y=(1-(a.y?h.y/a.y:1))*n})}return i.separation=function(a){return arguments.length?(t=a,i):t},i.size=function(a){return arguments.length?(r=!1,e=+a[0],n=+a[1],i):r?null:[e,n]},i.nodeSize=function(a){return arguments.length?(r=!0,e=+a[0],n=+a[1],i):r?[e,n]:null},i}function pk(t){var e=0,n=t.children,r=n&&n.length;if(!r)e=1;else for(;--r>=0;)e+=n[r].value;t.value=e}function mk(){return this.eachAfter(pk)}function yk(t,e){let n=-1;for(const r of this)t.call(e,r,++n,this);return this}function xk(t,e){for(var n=this,r=[n],i,a,u=-1;n=r.pop();)if(t.call(e,n,++u,this),i=n.children)for(a=i.length-1;a>=0;--a)r.push(i[a]);return this}function vk(t,e){for(var n=this,r=[n],i=[],a,u,o,s=-1;n=r.pop();)if(i.push(n),a=n.children)for(u=0,o=a.length;u=0;)n+=r[i].value;e.value=n})}function wk(t){return this.eachBefore(function(e){e.children&&e.children.sort(t)})}function Ek(t){for(var e=this,n=_k(e,t),r=[e];e!==n;)e=e.parent,r.push(e);for(var i=r.length;t!==n;)r.splice(i,0,t),t=t.parent;return r}function _k(t,e){if(t===e)return t;var n=t.ancestors(),r=e.ancestors(),i=null;for(t=n.pop(),e=r.pop();t===e;)i=t,t=n.pop(),e=r.pop();return i}function Ck(){for(var t=this,e=[t];t=t.parent;)e.push(t);return e}function Dk(){return Array.from(this)}function Fk(){var t=[];return this.eachBefore(function(e){e.children||t.push(e)}),t}function Mk(){var t=this,e=[];return t.each(function(n){n!==t&&e.push({source:n.parent,target:n})}),e}function*kk(){var t=this,e,n=[t],r,i,a;do for(e=n.reverse(),n=[];t=e.pop();)if(yield t,r=t.children)for(i=0,a=r.length;i=0;--o)i.push(a=u[o]=new Na(u[o])),a.parent=r,a.depth=r.depth+1;return n.eachBefore(pw)}function $k(){return q1(this).eachBefore(Tk)}function Sk(t){return t.children}function Bk(t){return Array.isArray(t)?t[1]:null}function Tk(t){t.data.value!==void 0&&(t.value=t.data.value),t.data=t.data.data}function pw(t){var e=0;do t.height=e;while((t=t.parent)&&t.height<++e)}function Na(t){this.data=t,this.depth=this.height=0,this.parent=null}Na.prototype=q1.prototype={constructor:Na,count:mk,each:yk,eachAfter:vk,eachBefore:xk,find:bk,sum:Ak,sort:wk,path:Ek,ancestors:Ck,descendants:Dk,leaves:Fk,links:Mk,copy:$k,[Symbol.iterator]:kk};function sl(t){return t==null?null:mw(t)}function mw(t){if(typeof t!=\"function\")throw new Error;return t}function _i(){return 0}function xa(t){return function(){return t}}const Rk=1664525,Ok=1013904223,L2=4294967296;function Nk(){let t=1;return()=>(t=(Rk*t+Ok)%L2)/L2}function Lk(t){return typeof t==\"object\"&&\"length\"in t?t:Array.from(t)}function Pk(t,e){let n=t.length,r,i;for(;n;)i=e()*n--|0,r=t[n],t[n]=t[i],t[i]=r;return t}function zk(t,e){for(var n=0,r=(t=Pk(Array.from(t),e)).length,i=[],a,u;n0&&n*n>r*r+i*i}function zh(t,e){for(var n=0;n1e-6?(D+Math.sqrt(D*D-4*F*R))/(2*F):R/D);return{x:r+E+A*k,y:i+_+C*k,r:k}}function P2(t,e,n){var r=t.x-e.x,i,a,u=t.y-e.y,o,s,l=r*r+u*u;l?(a=e.r+n.r,a*=a,s=t.r+n.r,s*=s,a>s?(i=(l+s-a)/(2*l),o=Math.sqrt(Math.max(0,s/l-i*i)),n.x=t.x-i*r-o*u,n.y=t.y-i*u+o*r):(i=(l+a-s)/(2*l),o=Math.sqrt(Math.max(0,a/l-i*i)),n.x=e.x+i*r-o*u,n.y=e.y+i*u+o*r)):(n.x=e.x+n.r,n.y=e.y)}function z2(t,e){var n=t.r+e.r-1e-6,r=e.x-t.x,i=e.y-t.y;return n>0&&n*n>r*r+i*i}function I2(t){var e=t._,n=t.next._,r=e.r+n.r,i=(e.x*n.r+n.x*e.r)/r,a=(e.y*n.r+n.y*e.r)/r;return i*i+a*a}function Ws(t){this._=t,this.next=null,this.previous=null}function jk(t,e){if(!(a=(t=Lk(t)).length))return 0;var n,r,i,a,u,o,s,l,f,c,h;if(n=t[0],n.x=0,n.y=0,!(a>1))return n.r;if(r=t[1],n.x=-r.r,r.x=n.r,r.y=0,!(a>2))return n.r+r.r;P2(r,n,i=t[2]),n=new Ws(n),r=new Ws(r),i=new Ws(i),n.next=i.previous=r,r.next=n.previous=i,i.next=r.previous=n;t:for(s=3;sKk(n(b,w,i))),x=y.map(Y2),v=new Set(y).add(\"\");for(const b of x)v.has(b)||(v.add(b),y.push(b),x.push(Y2(b)),a.push(Uh));u=(b,w)=>y[w],o=(b,w)=>x[w]}for(f=0,s=a.length;f=0&&(d=a[y],d.data===Uh);--y)d.data=null}if(c.parent=Gk,c.eachBefore(function(y){y.depth=y.parent.depth+1,--s}).eachBefore(pw),c.parent=null,s>0)throw new Error(\"cycle\");return c}return r.id=function(i){return arguments.length?(t=sl(i),r):t},r.parentId=function(i){return arguments.length?(e=sl(i),r):e},r.path=function(i){return arguments.length?(n=sl(i),r):n},r}function Kk(t){t=`${t}`;let e=t.length;return cd(t,e-1)&&!cd(t,e-2)&&(t=t.slice(0,-1)),t[0]===\"/\"?t:`/${t}`}function Y2(t){let e=t.length;if(e<2)return\"\";for(;--e>1&&!cd(t,e););return t.slice(0,e)}function cd(t,e){if(t[e]===\"/\"){let n=0;for(;e>0&&t[--e]===\"\\\\\";)++n;if(!(n&1))return!0}return!1}function Qk(t,e){return t.parent===e.parent?1:2}function qh(t){var e=t.children;return e?e[0]:t.t}function jh(t){var e=t.children;return e?e[e.length-1]:t.t}function Zk(t,e,n){var r=n/(e.i-t.i);e.c-=r,e.s+=n,t.c+=r,e.z+=n,e.m+=n}function Jk(t){for(var e=0,n=0,r=t.children,i=r.length,a;--i>=0;)a=r[i],a.z+=e,a.m+=e,e+=a.s+(n+=a.c)}function t8(t,e,n){return t.a.parent===e.parent?t.a:n}function ll(t,e){this._=t,this.parent=null,this.children=null,this.A=null,this.a=this,this.z=0,this.m=0,this.c=0,this.s=0,this.t=null,this.i=e}ll.prototype=Object.create(Na.prototype);function e8(t){for(var e=new ll(t,0),n,r=[e],i,a,u,o;n=r.pop();)if(a=n._.children)for(n.children=new Array(o=a.length),u=o-1;u>=0;--u)r.push(i=n.children[u]=new ll(a[u],u)),i.parent=n;return(e.parent=new ll(null,0)).children=[e],e}function n8(){var t=Qk,e=1,n=1,r=null;function i(l){var f=e8(l);if(f.eachAfter(a),f.parent.m=-f.z,f.eachBefore(u),r)l.eachBefore(s);else{var c=l,h=l,d=l;l.eachBefore(function(x){x.xh.x&&(h=x),x.depth>d.depth&&(d=x)});var g=c===h?1:t(c,h)/2,p=g-c.x,m=e/(h.x+g+p),y=n/(d.depth||1);l.eachBefore(function(x){x.x=(x.x+p)*m,x.y=x.depth*y})}return l}function a(l){var f=l.children,c=l.parent.children,h=l.i?c[l.i-1]:null;if(f){Jk(l);var d=(f[0].z+f[f.length-1].z)/2;h?(l.z=h.z+t(l._,h._),l.m=l.z-d):l.z=d}else h&&(l.z=h.z+t(l._,h._));l.parent.A=o(l,h,l.parent.A||c[0])}function u(l){l._.x=l.z+l.parent.m,l.m+=l.parent.m}function o(l,f,c){if(f){for(var h=l,d=l,g=f,p=h.parent.children[0],m=h.m,y=d.m,x=g.m,v=p.m,b;g=jh(g),h=qh(h),g&&h;)p=qh(p),d=jh(d),d.a=l,b=g.z+x-h.z-m+t(g._,h._),b>0&&(Zk(t8(g,l,c),l,b),m+=b,y+=b),x+=g.m,m+=h.m,v+=p.m,y+=d.m;g&&!jh(d)&&(d.t=g,d.m+=x-y),h&&!qh(p)&&(p.t=h,p.m+=m-v,c=l)}return c}function s(l){l.x*=e,l.y=l.depth*n}return i.separation=function(l){return arguments.length?(t=l,i):t},i.size=function(l){return arguments.length?(r=!1,e=+l[0],n=+l[1],i):r?null:[e,n]},i.nodeSize=function(l){return arguments.length?(r=!0,e=+l[0],n=+l[1],i):r?[e,n]:null},i}function tc(t,e,n,r,i){for(var a=t.children,u,o=-1,s=a.length,l=t.value&&(i-n)/t.value;++ox&&(x=l),E=m*m*w,v=Math.max(x/E,E/y),v>b){m-=l;break}b=v}u.push(s={value:m,dice:d1?r:1)},n}(bw);function r8(){var t=ww,e=!1,n=1,r=1,i=[0],a=_i,u=_i,o=_i,s=_i,l=_i;function f(h){return h.x0=h.y0=0,h.x1=n,h.y1=r,h.eachBefore(c),i=[0],e&&h.eachBefore(vw),h}function c(h){var d=i[h.depth],g=h.x0+d,p=h.y0+d,m=h.x1-d,y=h.y1-d;m=h-1){var x=a[c];x.x0=g,x.y0=p,x.x1=m,x.y1=y;return}for(var v=l[c],b=d/2+v,w=c+1,E=h-1;w>>1;l[A]y-p){var F=d?(g*C+m*_)/d:m;f(c,w,_,g,p,F,y),f(w,h,C,F,p,m,y)}else{var D=d?(p*C+y*_)/d:y;f(c,w,_,g,p,m,D),f(w,h,C,g,D,m,y)}}}function a8(t,e,n,r,i){(t.depth&1?tc:ts)(t,e,n,r,i)}const u8=function t(e){function n(r,i,a,u,o){if((s=r._squarify)&&s.ratio===e)for(var s,l,f,c,h=-1,d,g=s.length,p=r.value;++h1?r:1)},n}(bw);function nr(t,e){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(e).domain(t);break}return this}function hi(t,e){switch(arguments.length){case 0:break;case 1:{typeof t==\"function\"?this.interpolator(t):this.range(t);break}default:{this.domain(t),typeof e==\"function\"?this.interpolator(e):this.range(e);break}}return this}const hd=Symbol(\"implicit\");function j1(){var t=new Py,e=[],n=[],r=hd;function i(a){let u=t.get(a);if(u===void 0){if(r!==hd)return r;t.set(a,u=e.push(a)-1)}return n[u%n.length]}return i.domain=function(a){if(!arguments.length)return e.slice();e=[],t=new Py;for(const u of a)t.has(u)||t.set(u,e.push(u)-1);return i},i.range=function(a){return arguments.length?(n=Array.from(a),i):n.slice()},i.unknown=function(a){return arguments.length?(r=a,i):r},i.copy=function(){return j1(e,n).unknown(r)},nr.apply(i,arguments),i}function o8(t){return function(){return t}}function dd(t){return+t}var H2=[0,1];function Ue(t){return t}function gd(t,e){return(e-=t=+t)?function(n){return(n-t)/e}:o8(isNaN(e)?NaN:.5)}function s8(t,e){var n;return t>e&&(n=t,t=e,e=n),function(r){return Math.max(t,Math.min(e,r))}}function l8(t,e,n){var r=t[0],i=t[1],a=e[0],u=e[1];return i2?f8:l8,s=l=null,c}function c(h){return h==null||isNaN(h=+h)?a:(s||(s=o(t.map(r),e,n)))(r(u(h)))}return c.invert=function(h){return u(i((l||(l=o(e,t.map(r),wn)))(h)))},c.domain=function(h){return arguments.length?(t=Array.from(h,dd),f()):t.slice()},c.range=function(h){return arguments.length?(e=Array.from(h),f()):e.slice()},c.rangeRound=function(h){return e=Array.from(h),n=Ko,f()},c.clamp=function(h){return arguments.length?(u=h?!0:Ue,f()):u!==Ue},c.interpolate=function(h){return arguments.length?(n=h,f()):n},c.unknown=function(h){return arguments.length?(a=h,c):a},function(h,d){return r=h,i=d,f()}}function Ew(){return ec()(Ue,Ue)}function _w(t,e,n,r){var i=ei(t,e,n),a;switch(r=qi(r??\",f\"),r.type){case\"s\":{var u=Math.max(Math.abs(t),Math.abs(e));return r.precision==null&&!isNaN(a=EA(i,u))&&(r.precision=a),R1(r,u)}case\"\":case\"e\":case\"g\":case\"p\":case\"r\":{r.precision==null&&!isNaN(a=_A(i,Math.max(Math.abs(t),Math.abs(e))))&&(r.precision=a-(r.type===\"e\"));break}case\"f\":case\"%\":{r.precision==null&&!isNaN(a=wA(i))&&(r.precision=a-(r.type===\"%\")*2);break}}return Kf(r)}function Ji(t){var e=t.domain;return t.ticks=function(n){var r=e();return T0(r[0],r[r.length-1],n??10)},t.tickFormat=function(n,r){var i=e();return _w(i[0],i[i.length-1],n??10,r)},t.nice=function(n){n==null&&(n=10);var r=e(),i=0,a=r.length-1,u=r[i],o=r[a],s,l,f=10;for(o0;){if(l=R0(u,o,n),l===s)return r[i]=u,r[a]=o,e(r);if(l>0)u=Math.floor(u/l)*l,o=Math.ceil(o/l)*l;else if(l<0)u=Math.ceil(u*l)/l,o=Math.floor(o*l)/l;else break;s=l}return t},t}function Cw(){var t=Ew();return t.copy=function(){return es(t,Cw())},nr.apply(t,arguments),Ji(t)}function Dw(t){var e;function n(r){return r==null||isNaN(r=+r)?e:r}return n.invert=n,n.domain=n.range=function(r){return arguments.length?(t=Array.from(r,dd),n):t.slice()},n.unknown=function(r){return arguments.length?(e=r,n):e},n.copy=function(){return Dw(t).unknown(e)},t=arguments.length?Array.from(t,dd):[0,1],Ji(n)}function Fw(t,e){t=t.slice();var n=0,r=t.length-1,i=t[n],a=t[r],u;return aMath.pow(t,e)}function p8(t){return t===Math.E?Math.log:t===10&&Math.log10||t===2&&Math.log2||(t=Math.log(t),e=>Math.log(e)/t)}function V2(t){return(e,n)=>-t(-e,n)}function W1(t){const e=t(G2,X2),n=e.domain;let r=10,i,a;function u(){return i=p8(r),a=g8(r),n()[0]<0?(i=V2(i),a=V2(a),t(c8,h8)):t(G2,X2),e}return e.base=function(o){return arguments.length?(r=+o,u()):r},e.domain=function(o){return arguments.length?(n(o),u()):n()},e.ticks=o=>{const s=n();let l=s[0],f=s[s.length-1];const c=f0){for(;h<=d;++h)for(g=1;gf)break;y.push(p)}}else for(;h<=d;++h)for(g=r-1;g>=1;--g)if(p=h>0?g/a(-h):g*a(h),!(pf)break;y.push(p)}y.length*2{if(o==null&&(o=10),s==null&&(s=r===10?\"s\":\",\"),typeof s!=\"function\"&&(!(r%1)&&(s=qi(s)).precision==null&&(s.trim=!0),s=Kf(s)),o===1/0)return s;const l=Math.max(1,r*o/e.ticks().length);return f=>{let c=f/a(Math.round(i(f)));return c*rn(Fw(n(),{floor:o=>a(Math.floor(i(o))),ceil:o=>a(Math.ceil(i(o)))})),e}function Mw(){const t=W1(ec()).domain([1,10]);return t.copy=()=>es(t,Mw()).base(t.base()),nr.apply(t,arguments),t}function K2(t){return function(e){return Math.sign(e)*Math.log1p(Math.abs(e/t))}}function Q2(t){return function(e){return Math.sign(e)*Math.expm1(Math.abs(e))*t}}function Y1(t){var e=1,n=t(K2(e),Q2(e));return n.constant=function(r){return arguments.length?t(K2(e=+r),Q2(e)):e},Ji(n)}function kw(){var t=Y1(ec());return t.copy=function(){return es(t,kw()).constant(t.constant())},nr.apply(t,arguments)}function Z2(t){return function(e){return e<0?-Math.pow(-e,t):Math.pow(e,t)}}function m8(t){return t<0?-Math.sqrt(-t):Math.sqrt(t)}function y8(t){return t<0?-t*t:t*t}function H1(t){var e=t(Ue,Ue),n=1;function r(){return n===1?t(Ue,Ue):n===.5?t(m8,y8):t(Z2(n),Z2(1/n))}return e.exponent=function(i){return arguments.length?(n=+i,r()):n},Ji(e)}function G1(){var t=H1(ec());return t.copy=function(){return es(t,G1()).exponent(t.exponent())},nr.apply(t,arguments),t}function x8(){return G1.apply(null,arguments).exponent(.5)}function $w(){var t=[],e=[],n=[],r;function i(){var u=0,o=Math.max(1,e.length);for(n=new Array(o-1);++u0?n[o-1]:t[0],o=n?[r[n-1],e]:[r[l-1],r[l]]},u.unknown=function(s){return arguments.length&&(a=s),u},u.thresholds=function(){return r.slice()},u.copy=function(){return Sw().domain([t,e]).range(i).unknown(a)},nr.apply(Ji(u),arguments)}function Bw(){var t=[.5],e=[0,1],n,r=1;function i(a){return a!=null&&a<=a?e[ti(t,a,0,r)]:n}return i.domain=function(a){return arguments.length?(t=Array.from(a),r=Math.min(t.length,e.length-1),i):t.slice()},i.range=function(a){return arguments.length?(e=Array.from(a),r=Math.min(t.length,e.length-1),i):e.slice()},i.invertExtent=function(a){var u=e.indexOf(a);return[t[u-1],t[u]]},i.unknown=function(a){return arguments.length?(n=a,i):n},i.copy=function(){return Bw().domain(t).range(e).unknown(n)},nr.apply(i,arguments)}const Wh=new Date,Yh=new Date;function Pt(t,e,n,r){function i(a){return t(a=arguments.length===0?new Date:new Date(+a)),a}return i.floor=a=>(t(a=new Date(+a)),a),i.ceil=a=>(t(a=new Date(a-1)),e(a,1),t(a),a),i.round=a=>{const u=i(a),o=i.ceil(a);return a-u(e(a=new Date(+a),u==null?1:Math.floor(u)),a),i.range=(a,u,o)=>{const s=[];if(a=i.ceil(a),o=o==null?1:Math.floor(o),!(a0))return s;let l;do s.push(l=new Date(+a)),e(a,o),t(a);while(lPt(u=>{if(u>=u)for(;t(u),!a(u);)u.setTime(u-1)},(u,o)=>{if(u>=u)if(o<0)for(;++o<=0;)for(;e(u,-1),!a(u););else for(;--o>=0;)for(;e(u,1),!a(u););}),n&&(i.count=(a,u)=>(Wh.setTime(+a),Yh.setTime(+u),t(Wh),t(Yh),Math.floor(n(Wh,Yh))),i.every=a=>(a=Math.floor(a),!isFinite(a)||!(a>0)?null:a>1?i.filter(r?u=>r(u)%a===0:u=>i.count(0,u)%a===0):i)),i}const La=Pt(()=>{},(t,e)=>{t.setTime(+t+e)},(t,e)=>e-t);La.every=t=>(t=Math.floor(t),!isFinite(t)||!(t>0)?null:t>1?Pt(e=>{e.setTime(Math.floor(e/t)*t)},(e,n)=>{e.setTime(+e+n*t)},(e,n)=>(n-e)/t):La);La.range;const xr=1e3,hn=xr*60,vr=hn*60,Fr=vr*24,X1=Fr*7,J2=Fr*30,Hh=Fr*365,br=Pt(t=>{t.setTime(t-t.getMilliseconds())},(t,e)=>{t.setTime(+t+e*xr)},(t,e)=>(e-t)/xr,t=>t.getUTCSeconds());br.range;const nc=Pt(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*xr)},(t,e)=>{t.setTime(+t+e*hn)},(t,e)=>(e-t)/hn,t=>t.getMinutes());nc.range;const rc=Pt(t=>{t.setUTCSeconds(0,0)},(t,e)=>{t.setTime(+t+e*hn)},(t,e)=>(e-t)/hn,t=>t.getUTCMinutes());rc.range;const ic=Pt(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*xr-t.getMinutes()*hn)},(t,e)=>{t.setTime(+t+e*vr)},(t,e)=>(e-t)/vr,t=>t.getHours());ic.range;const ac=Pt(t=>{t.setUTCMinutes(0,0,0)},(t,e)=>{t.setTime(+t+e*vr)},(t,e)=>(e-t)/vr,t=>t.getUTCHours());ac.range;const _r=Pt(t=>t.setHours(0,0,0,0),(t,e)=>t.setDate(t.getDate()+e),(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*hn)/Fr,t=>t.getDate()-1);_r.range;const Kr=Pt(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/Fr,t=>t.getUTCDate()-1);Kr.range;const Tw=Pt(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/Fr,t=>Math.floor(t/Fr));Tw.range;function ta(t){return Pt(e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)},(e,n)=>{e.setDate(e.getDate()+n*7)},(e,n)=>(n-e-(n.getTimezoneOffset()-e.getTimezoneOffset())*hn)/X1)}const eu=ta(0),ff=ta(1),v8=ta(2),b8=ta(3),Pa=ta(4),A8=ta(5),w8=ta(6);eu.range;ff.range;v8.range;b8.range;Pa.range;A8.range;w8.range;function ea(t){return Pt(e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)},(e,n)=>{e.setUTCDate(e.getUTCDate()+n*7)},(e,n)=>(n-e)/X1)}const nu=ea(0),cf=ea(1),E8=ea(2),_8=ea(3),za=ea(4),C8=ea(5),D8=ea(6);nu.range;cf.range;E8.range;_8.range;za.range;C8.range;D8.range;const ko=Pt(t=>{t.setDate(1),t.setHours(0,0,0,0)},(t,e)=>{t.setMonth(t.getMonth()+e)},(t,e)=>e.getMonth()-t.getMonth()+(e.getFullYear()-t.getFullYear())*12,t=>t.getMonth());ko.range;const $o=Pt(t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)},(t,e)=>e.getUTCMonth()-t.getUTCMonth()+(e.getUTCFullYear()-t.getUTCFullYear())*12,t=>t.getUTCMonth());$o.range;const Qn=Pt(t=>{t.setMonth(0,1),t.setHours(0,0,0,0)},(t,e)=>{t.setFullYear(t.getFullYear()+e)},(t,e)=>e.getFullYear()-t.getFullYear(),t=>t.getFullYear());Qn.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:Pt(e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)},(e,n)=>{e.setFullYear(e.getFullYear()+n*t)});Qn.range;const Zn=Pt(t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)},(t,e)=>e.getUTCFullYear()-t.getUTCFullYear(),t=>t.getUTCFullYear());Zn.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:Pt(e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},(e,n)=>{e.setUTCFullYear(e.getUTCFullYear()+n*t)});Zn.range;function Rw(t,e,n,r,i,a){const u=[[br,1,xr],[br,5,5*xr],[br,15,15*xr],[br,30,30*xr],[a,1,hn],[a,5,5*hn],[a,15,15*hn],[a,30,30*hn],[i,1,vr],[i,3,3*vr],[i,6,6*vr],[i,12,12*vr],[r,1,Fr],[r,2,2*Fr],[n,1,X1],[e,1,J2],[e,3,3*J2],[t,1,Hh]];function o(l,f,c){const h=fm).right(u,h);if(d===u.length)return t.every(ei(l/Hh,f/Hh,c));if(d===0)return La.every(Math.max(ei(l,f,c),1));const[g,p]=u[h/u[d-1][2]53)return null;\"w\"in P||(P.w=1),\"Z\"in P?(wt=Xh(Eu(P.y,0,1)),Ve=wt.getUTCDay(),wt=Ve>4||Ve===0?cf.ceil(wt):cf(wt),wt=Kr.offset(wt,(P.V-1)*7),P.y=wt.getUTCFullYear(),P.m=wt.getUTCMonth(),P.d=wt.getUTCDate()+(P.w+6)%7):(wt=Gh(Eu(P.y,0,1)),Ve=wt.getDay(),wt=Ve>4||Ve===0?ff.ceil(wt):ff(wt),wt=_r.offset(wt,(P.V-1)*7),P.y=wt.getFullYear(),P.m=wt.getMonth(),P.d=wt.getDate()+(P.w+6)%7)}else(\"W\"in P||\"U\"in P)&&(\"w\"in P||(P.w=\"u\"in P?P.u%7:\"W\"in P?1:0),Ve=\"Z\"in P?Xh(Eu(P.y,0,1)).getUTCDay():Gh(Eu(P.y,0,1)).getDay(),P.m=0,P.d=\"W\"in P?(P.w+6)%7+P.W*7-(Ve+5)%7:P.w+P.U*7-(Ve+6)%7);return\"Z\"in P?(P.H+=P.Z/100|0,P.M+=P.Z%100,Xh(P)):Gh(P)}}function _(I,rt,ot,P){for(var Be=0,wt=rt.length,Ve=ot.length,Ke,mi;Be=Ve)return-1;if(Ke=rt.charCodeAt(Be++),Ke===37){if(Ke=rt.charAt(Be++),mi=w[Ke in tx?rt.charAt(Be++):Ke],!mi||(P=mi(I,ot,P))<0)return-1}else if(Ke!=ot.charCodeAt(P++))return-1}return P}function C(I,rt,ot){var P=l.exec(rt.slice(ot));return P?(I.p=f.get(P[0].toLowerCase()),ot+P[0].length):-1}function F(I,rt,ot){var P=d.exec(rt.slice(ot));return P?(I.w=g.get(P[0].toLowerCase()),ot+P[0].length):-1}function D(I,rt,ot){var P=c.exec(rt.slice(ot));return P?(I.w=h.get(P[0].toLowerCase()),ot+P[0].length):-1}function R(I,rt,ot){var P=y.exec(rt.slice(ot));return P?(I.m=x.get(P[0].toLowerCase()),ot+P[0].length):-1}function k(I,rt,ot){var P=p.exec(rt.slice(ot));return P?(I.m=m.get(P[0].toLowerCase()),ot+P[0].length):-1}function N(I,rt,ot){return _(I,e,rt,ot)}function M(I,rt,ot){return _(I,n,rt,ot)}function O(I,rt,ot){return _(I,r,rt,ot)}function z(I){return u[I.getDay()]}function G(I){return a[I.getDay()]}function W(I){return s[I.getMonth()]}function bt(I){return o[I.getMonth()]}function It(I){return i[+(I.getHours()>=12)]}function Se(I){return 1+~~(I.getMonth()/3)}function me(I){return u[I.getUTCDay()]}function Pn(I){return a[I.getUTCDay()]}function Ut(I){return s[I.getUTCMonth()]}function mu(I){return o[I.getUTCMonth()]}function yu(I){return i[+(I.getUTCHours()>=12)]}function xu(I){return 1+~~(I.getUTCMonth()/3)}return{format:function(I){var rt=E(I+=\"\",v);return rt.toString=function(){return I},rt},parse:function(I){var rt=A(I+=\"\",!1);return rt.toString=function(){return I},rt},utcFormat:function(I){var rt=E(I+=\"\",b);return rt.toString=function(){return I},rt},utcParse:function(I){var rt=A(I+=\"\",!0);return rt.toString=function(){return I},rt}}}var tx={\"-\":\"\",_:\" \",0:\"0\"},Xt=/^\\s*\\d+/,S8=/^%/,B8=/[\\\\^$*+?|[\\]().{}]/g;function dt(t,e,n){var r=t<0?\"-\":\"\",i=(r?-t:t)+\"\",a=i.length;return r+(a[e.toLowerCase(),n]))}function R8(t,e,n){var r=Xt.exec(e.slice(n,n+1));return r?(t.w=+r[0],n+r[0].length):-1}function O8(t,e,n){var r=Xt.exec(e.slice(n,n+1));return r?(t.u=+r[0],n+r[0].length):-1}function N8(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.U=+r[0],n+r[0].length):-1}function L8(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.V=+r[0],n+r[0].length):-1}function P8(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.W=+r[0],n+r[0].length):-1}function ex(t,e,n){var r=Xt.exec(e.slice(n,n+4));return r?(t.y=+r[0],n+r[0].length):-1}function nx(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),n+r[0].length):-1}function z8(t,e,n){var r=/^(Z)|([+-]\\d\\d)(?::?(\\d\\d))?/.exec(e.slice(n,n+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||\"00\")),n+r[0].length):-1}function I8(t,e,n){var r=Xt.exec(e.slice(n,n+1));return r?(t.q=r[0]*3-3,n+r[0].length):-1}function U8(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function rx(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function q8(t,e,n){var r=Xt.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function ix(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function j8(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function W8(t,e,n){var r=Xt.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function Y8(t,e,n){var r=Xt.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function H8(t,e,n){var r=Xt.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function G8(t,e,n){var r=S8.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function X8(t,e,n){var r=Xt.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function V8(t,e,n){var r=Xt.exec(e.slice(n));return r?(t.s=+r[0],n+r[0].length):-1}function ax(t,e){return dt(t.getDate(),e,2)}function K8(t,e){return dt(t.getHours(),e,2)}function Q8(t,e){return dt(t.getHours()%12||12,e,2)}function Z8(t,e){return dt(1+_r.count(Qn(t),t),e,3)}function Nw(t,e){return dt(t.getMilliseconds(),e,3)}function J8(t,e){return Nw(t,e)+\"000\"}function t9(t,e){return dt(t.getMonth()+1,e,2)}function e9(t,e){return dt(t.getMinutes(),e,2)}function n9(t,e){return dt(t.getSeconds(),e,2)}function r9(t){var e=t.getDay();return e===0?7:e}function i9(t,e){return dt(eu.count(Qn(t)-1,t),e,2)}function Lw(t){var e=t.getDay();return e>=4||e===0?Pa(t):Pa.ceil(t)}function a9(t,e){return t=Lw(t),dt(Pa.count(Qn(t),t)+(Qn(t).getDay()===4),e,2)}function u9(t){return t.getDay()}function o9(t,e){return dt(ff.count(Qn(t)-1,t),e,2)}function s9(t,e){return dt(t.getFullYear()%100,e,2)}function l9(t,e){return t=Lw(t),dt(t.getFullYear()%100,e,2)}function f9(t,e){return dt(t.getFullYear()%1e4,e,4)}function c9(t,e){var n=t.getDay();return t=n>=4||n===0?Pa(t):Pa.ceil(t),dt(t.getFullYear()%1e4,e,4)}function h9(t){var e=t.getTimezoneOffset();return(e>0?\"-\":(e*=-1,\"+\"))+dt(e/60|0,\"0\",2)+dt(e%60,\"0\",2)}function ux(t,e){return dt(t.getUTCDate(),e,2)}function d9(t,e){return dt(t.getUTCHours(),e,2)}function g9(t,e){return dt(t.getUTCHours()%12||12,e,2)}function p9(t,e){return dt(1+Kr.count(Zn(t),t),e,3)}function Pw(t,e){return dt(t.getUTCMilliseconds(),e,3)}function m9(t,e){return Pw(t,e)+\"000\"}function y9(t,e){return dt(t.getUTCMonth()+1,e,2)}function x9(t,e){return dt(t.getUTCMinutes(),e,2)}function v9(t,e){return dt(t.getUTCSeconds(),e,2)}function b9(t){var e=t.getUTCDay();return e===0?7:e}function A9(t,e){return dt(nu.count(Zn(t)-1,t),e,2)}function zw(t){var e=t.getUTCDay();return e>=4||e===0?za(t):za.ceil(t)}function w9(t,e){return t=zw(t),dt(za.count(Zn(t),t)+(Zn(t).getUTCDay()===4),e,2)}function E9(t){return t.getUTCDay()}function _9(t,e){return dt(cf.count(Zn(t)-1,t),e,2)}function C9(t,e){return dt(t.getUTCFullYear()%100,e,2)}function D9(t,e){return t=zw(t),dt(t.getUTCFullYear()%100,e,2)}function F9(t,e){return dt(t.getUTCFullYear()%1e4,e,4)}function M9(t,e){var n=t.getUTCDay();return t=n>=4||n===0?za(t):za.ceil(t),dt(t.getUTCFullYear()%1e4,e,4)}function k9(){return\"+0000\"}function ox(){return\"%\"}function sx(t){return+t}function lx(t){return Math.floor(+t/1e3)}var ca,V1,Iw,K1,Uw;$9({dateTime:\"%x, %X\",date:\"%-m/%-d/%Y\",time:\"%-I:%M:%S %p\",periods:[\"AM\",\"PM\"],days:[\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"],shortDays:[\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"],months:[\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"],shortMonths:[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"]});function $9(t){return ca=Ow(t),V1=ca.format,Iw=ca.parse,K1=ca.utcFormat,Uw=ca.utcParse,ca}function S9(t){return new Date(t)}function B9(t){return t instanceof Date?+t:+new Date(+t)}function Q1(t,e,n,r,i,a,u,o,s,l){var f=Ew(),c=f.invert,h=f.domain,d=l(\".%L\"),g=l(\":%S\"),p=l(\"%I:%M\"),m=l(\"%I %p\"),y=l(\"%a %d\"),x=l(\"%b %d\"),v=l(\"%B\"),b=l(\"%Y\");function w(E){return(s(E)1?0:t<-1?Ia:Math.acos(t)}function cx(t){return t>=1?hf:t<=-1?-hf:Math.asin(t)}function sc(t){let e=3;return t.digits=function(n){if(!arguments.length)return e;if(n==null)e=null;else{const r=Math.floor(n);if(!(r>=0))throw new RangeError(`invalid digits: ${n}`);e=r}return t},()=>new k1(e)}function z9(t){return t.innerRadius}function I9(t){return t.outerRadius}function U9(t){return t.startAngle}function q9(t){return t.endAngle}function j9(t){return t&&t.padAngle}function W9(t,e,n,r,i,a,u,o){var s=n-t,l=r-e,f=u-i,c=o-a,h=c*s-f*l;if(!(h*hN*N+M*M&&(_=F,C=D),{cx:_,cy:C,x01:-f,y01:-c,x11:_*(i/w-1),y11:C*(i/w-1)}}function Y9(){var t=z9,e=I9,n=pt(0),r=null,i=U9,a=q9,u=j9,o=null,s=sc(l);function l(){var f,c,h=+t.apply(this,arguments),d=+e.apply(this,arguments),g=i.apply(this,arguments)-hf,p=a.apply(this,arguments)-hf,m=fx(p-g),y=p>g;if(o||(o=f=s()),die))o.moveTo(0,0);else if(m>Gw-ie)o.moveTo(d*yi(g),d*zn(g)),o.arc(0,0,d,g,p,!y),h>ie&&(o.moveTo(h*yi(p),h*zn(p)),o.arc(0,0,h,p,g,y));else{var x=g,v=p,b=g,w=p,E=m,A=m,_=u.apply(this,arguments)/2,C=_>ie&&(r?+r.apply(this,arguments):Si(h*h+d*d)),F=Vh(fx(d-h)/2,+n.apply(this,arguments)),D=F,R=F,k,N;if(C>ie){var M=cx(C/h*zn(_)),O=cx(C/d*zn(_));(E-=M*2)>ie?(M*=y?1:-1,b+=M,w-=M):(E=0,b=w=(g+p)/2),(A-=O*2)>ie?(O*=y?1:-1,x+=O,v-=O):(A=0,x=v=(g+p)/2)}var z=d*yi(x),G=d*zn(x),W=h*yi(w),bt=h*zn(w);if(F>ie){var It=d*yi(v),Se=d*zn(v),me=h*yi(b),Pn=h*zn(b),Ut;if(mie?R>ie?(k=Ys(me,Pn,z,G,d,R,y),N=Ys(It,Se,W,bt,d,R,y),o.moveTo(k.cx+k.x01,k.cy+k.y01),Rie)||!(E>ie)?o.lineTo(W,bt):D>ie?(k=Ys(W,bt,It,Se,h,-D,y),N=Ys(z,G,me,Pn,h,-D,y),o.lineTo(k.cx+k.x01,k.cy+k.y01),D=d;--g)o.point(v[g],b[g]);o.lineEnd(),o.areaEnd()}y&&(v[h]=+t(m,h,c),b[h]=+e(m,h,c),o.point(r?+r(m,h,c):v[h],n?+n(m,h,c):b[h]))}if(x)return o=null,x+\"\"||null}function f(){return Zw().defined(i).curve(u).context(a)}return l.x=function(c){return arguments.length?(t=typeof c==\"function\"?c:pt(+c),r=null,l):t},l.x0=function(c){return arguments.length?(t=typeof c==\"function\"?c:pt(+c),l):t},l.x1=function(c){return arguments.length?(r=c==null?null:typeof c==\"function\"?c:pt(+c),l):r},l.y=function(c){return arguments.length?(e=typeof c==\"function\"?c:pt(+c),n=null,l):e},l.y0=function(c){return arguments.length?(e=typeof c==\"function\"?c:pt(+c),l):e},l.y1=function(c){return arguments.length?(n=c==null?null:typeof c==\"function\"?c:pt(+c),l):n},l.lineX0=l.lineY0=function(){return f().x(t).y(e)},l.lineY1=function(){return f().x(t).y(n)},l.lineX1=function(){return f().x(r).y(e)},l.defined=function(c){return arguments.length?(i=typeof c==\"function\"?c:pt(!!c),l):i},l.curve=function(c){return arguments.length?(u=c,a!=null&&(o=u(a)),l):u},l.context=function(c){return arguments.length?(c==null?a=o=null:o=u(a=c),l):a},l}const H9={draw(t,e){const n=Si(e/Ia);t.moveTo(n,0),t.arc(0,0,n,0,Gw)}};function G9(t,e){let n=null,r=sc(i);t=typeof t==\"function\"?t:pt(t||H9),e=typeof e==\"function\"?e:pt(e===void 0?64:+e);function i(){let a;if(n||(n=a=r()),t.apply(this,arguments).draw(n,+e.apply(this,arguments)),a)return n=null,a+\"\"||null}return i.type=function(a){return arguments.length?(t=typeof a==\"function\"?a:pt(a),i):t},i.size=function(a){return arguments.length?(e=typeof a==\"function\"?a:pt(+a),i):e},i.context=function(a){return arguments.length?(n=a??null,i):n},i}function ni(){}function df(t,e,n){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+n)/6)}function lc(t){this._context=t}lc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:df(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:df(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};function X9(t){return new lc(t)}function t3(t){this._context=t}t3.prototype={areaStart:ni,areaEnd:ni,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x2,this._y2),this._context.closePath();break}case 2:{this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break}case 3:{this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4);break}}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:df(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};function V9(t){return new t3(t)}function e3(t){this._context=t}e3.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var n=(this._x0+4*this._x1+t)/6,r=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(n,r):this._context.moveTo(n,r);break;case 3:this._point=4;default:df(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};function K9(t){return new e3(t)}function n3(t,e){this._basis=new lc(t),this._beta=e}n3.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,e=this._y,n=t.length-1;if(n>0)for(var r=t[0],i=e[0],a=t[n]-r,u=e[n]-i,o=-1,s;++o<=n;)s=o/n,this._basis.point(this._beta*t[o]+(1-this._beta)*(r+s*a),this._beta*e[o]+(1-this._beta)*(i+s*u));this._x=this._y=null,this._basis.lineEnd()},point:function(t,e){this._x.push(+t),this._y.push(+e)}};const Q9=function t(e){function n(r){return e===1?new lc(r):new n3(r,e)}return n.beta=function(r){return t(+r)},n}(.85);function gf(t,e,n){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-n),t._x2,t._y2)}function ng(t,e){this._context=t,this._k=(1-e)/6}ng.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:gf(this,this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:gf(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Z9=function t(e){function n(r){return new ng(r,e)}return n.tension=function(r){return t(+r)},n}(0);function rg(t,e){this._context=t,this._k=(1-e)/6}rg.prototype={areaStart:ni,areaEnd:ni,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:gf(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const J9=function t(e){function n(r){return new rg(r,e)}return n.tension=function(r){return t(+r)},n}(0);function ig(t,e){this._context=t,this._k=(1-e)/6}ig.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:gf(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const t4=function t(e){function n(r){return new ig(r,e)}return n.tension=function(r){return t(+r)},n}(0);function ag(t,e,n){var r=t._x1,i=t._y1,a=t._x2,u=t._y2;if(t._l01_a>ie){var o=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,s=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*o-t._x0*t._l12_2a+t._x2*t._l01_2a)/s,i=(i*o-t._y0*t._l12_2a+t._y2*t._l01_2a)/s}if(t._l23_a>ie){var l=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,f=3*t._l23_a*(t._l23_a+t._l12_a);a=(a*l+t._x1*t._l23_2a-e*t._l12_2a)/f,u=(u*l+t._y1*t._l23_2a-n*t._l12_2a)/f}t._context.bezierCurveTo(r,i,a,u,t._x2,t._y2)}function r3(t,e){this._context=t,this._alpha=e}r3.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:ag(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const e4=function t(e){function n(r){return e?new r3(r,e):new ng(r,0)}return n.alpha=function(r){return t(+r)},n}(.5);function i3(t,e){this._context=t,this._alpha=e}i3.prototype={areaStart:ni,areaEnd:ni,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:ag(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const n4=function t(e){function n(r){return e?new i3(r,e):new rg(r,0)}return n.alpha=function(r){return t(+r)},n}(.5);function a3(t,e){this._context=t,this._alpha=e}a3.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:ag(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const r4=function t(e){function n(r){return e?new a3(r,e):new ig(r,0)}return n.alpha=function(r){return t(+r)},n}(.5);function u3(t){this._context=t}u3.prototype={areaStart:ni,areaEnd:ni,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))}};function i4(t){return new u3(t)}function hx(t){return t<0?-1:1}function dx(t,e,n){var r=t._x1-t._x0,i=e-t._x1,a=(t._y1-t._y0)/(r||i<0&&-0),u=(n-t._y1)/(i||r<0&&-0),o=(a*i+u*r)/(r+i);return(hx(a)+hx(u))*Math.min(Math.abs(a),Math.abs(u),.5*Math.abs(o))||0}function gx(t,e){var n=t._x1-t._x0;return n?(3*(t._y1-t._y0)/n-e)/2:e}function Kh(t,e,n){var r=t._x0,i=t._y0,a=t._x1,u=t._y1,o=(a-r)/3;t._context.bezierCurveTo(r+o,i+o*e,a-o,u-o*n,a,u)}function pf(t){this._context=t}pf.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:Kh(this,this._t0,gx(this,this._t0));break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){var n=NaN;if(t=+t,e=+e,!(t===this._x1&&e===this._y1)){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,Kh(this,gx(this,n=dx(this,t,e)),n);break;default:Kh(this,this._t0,n=dx(this,t,e));break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e,this._t0=n}}};function o3(t){this._context=new s3(t)}(o3.prototype=Object.create(pf.prototype)).point=function(t,e){pf.prototype.point.call(this,e,t)};function s3(t){this._context=t}s3.prototype={moveTo:function(t,e){this._context.moveTo(e,t)},closePath:function(){this._context.closePath()},lineTo:function(t,e){this._context.lineTo(e,t)},bezierCurveTo:function(t,e,n,r,i,a){this._context.bezierCurveTo(e,t,r,n,a,i)}};function a4(t){return new pf(t)}function u4(t){return new o3(t)}function l3(t){this._context=t}l3.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var t=this._x,e=this._y,n=t.length;if(n)if(this._line?this._context.lineTo(t[0],e[0]):this._context.moveTo(t[0],e[0]),n===2)this._context.lineTo(t[1],e[1]);else for(var r=px(t),i=px(e),a=0,u=1;u=0;--e)i[e]=(u[e]-i[e+1])/a[e];for(a[n-1]=(t[n]+i[n-1])/2,e=0;e=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:{if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var n=this._x*(1-this._t)+t*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,e)}break}}this._x=t,this._y=e}};function s4(t){return new fc(t,.5)}function l4(t){return new fc(t,0)}function f4(t){return new fc(t,1)}/*!\n * https://github.com/Starcounter-Jack/JSON-Patch\n * (c) 2017-2022 Joachim Wester\n * MIT licensed\n */var c4=function(){var t=function(e,n){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(r,i){r.__proto__=i}||function(r,i){for(var a in i)i.hasOwnProperty(a)&&(r[a]=i[a])},t(e,n)};return function(e,n){t(e,n);function r(){this.constructor=e}e.prototype=n===null?Object.create(n):(r.prototype=n.prototype,new r)}}(),h4=Object.prototype.hasOwnProperty;function pd(t,e){return h4.call(t,e)}function md(t){if(Array.isArray(t)){for(var e=new Array(t.length),n=0;n=48&&r<=57){e++;continue}return!1}return!0}function Ei(t){return t.indexOf(\"/\")===-1&&t.indexOf(\"~\")===-1?t:t.replace(/~/g,\"~0\").replace(/\\//g,\"~1\")}function f3(t){return t.replace(/~1/g,\"/\").replace(/~0/g,\"~\")}function xd(t){if(t===void 0)return!0;if(t){if(Array.isArray(t)){for(var e=0,n=t.length;e0&&s[f-1]==\"constructor\"))throw new TypeError(\"JSON-Patch: modifying `__proto__` or `constructor/prototype` prop is banned for security reasons, if this was on purpose, please set `banPrototypeModifications` flag false and pass it to this function. More info in fast-json-patch README\");if(n&&h===void 0&&(l[d]===void 0?h=s.slice(0,f).join(\"/\"):f==c-1&&(h=e.path),h!==void 0&&g(e,0,t,h)),f++,Array.isArray(l)){if(d===\"-\")d=l.length;else{if(n&&!yd(d))throw new Mt(\"Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index\",\"OPERATION_PATH_ILLEGAL_ARRAY_INDEX\",a,e,t);yd(d)&&(d=~~d)}if(f>=c){if(n&&e.op===\"add\"&&d>l.length)throw new Mt(\"The specified index MUST NOT be greater than the number of elements in the array\",\"OPERATION_VALUE_OUT_OF_BOUNDS\",a,e,t);var u=g4[e.op].call(e,l,d,t);if(u.test===!1)throw new Mt(\"Test operation failed\",\"TEST_OPERATION_FAILED\",a,e,t);return u}}else if(f>=c){var u=wa[e.op].call(e,l,d,t);if(u.test===!1)throw new Mt(\"Test operation failed\",\"TEST_OPERATION_FAILED\",a,e,t);return u}if(l=l[d],n&&f0)throw new Mt('Operation `path` property must start with \"/\"',\"OPERATION_PATH_INVALID\",e,t,n);if((t.op===\"move\"||t.op===\"copy\")&&typeof t.from!=\"string\")throw new Mt(\"Operation `from` property is not present (applicable in `move` and `copy` operations)\",\"OPERATION_FROM_REQUIRED\",e,t,n);if((t.op===\"add\"||t.op===\"replace\"||t.op===\"test\")&&t.value===void 0)throw new Mt(\"Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)\",\"OPERATION_VALUE_REQUIRED\",e,t,n);if((t.op===\"add\"||t.op===\"replace\"||t.op===\"test\")&&xd(t.value))throw new Mt(\"Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)\",\"OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED\",e,t,n);if(n){if(t.op==\"add\"){var i=t.path.split(\"/\").length,a=r.split(\"/\").length;if(i!==a+1&&i!==a)throw new Mt(\"Cannot perform an `add` operation at the desired path\",\"OPERATION_PATH_CANNOT_ADD\",e,t,n)}else if(t.op===\"replace\"||t.op===\"remove\"||t.op===\"_get\"){if(t.path!==r)throw new Mt(\"Cannot perform the operation at a path that does not exist\",\"OPERATION_PATH_UNRESOLVABLE\",e,t,n)}else if(t.op===\"move\"||t.op===\"copy\"){var u={op:\"_get\",path:t.from,value:void 0},o=h3([u],n);if(o&&o.name===\"OPERATION_PATH_UNRESOLVABLE\")throw new Mt(\"Cannot perform the operation from a path that does not exist\",\"OPERATION_FROM_UNRESOLVABLE\",e,t,n)}}}else throw new Mt(\"Operation `op` property is not one of operations defined in RFC-6902\",\"OPERATION_OP_INVALID\",e,t,n)}function h3(t,e,n){try{if(!Array.isArray(t))throw new Mt(\"Patch sequence must be an array\",\"SEQUENCE_NOT_AN_ARRAY\");if(e)ug(Je(e),Je(t),n||!0);else{n=n||yf;for(var r=0;r0&&(t.patches=[],t.callback&&t.callback(r)),r}function sg(t,e,n,r,i){if(e!==t){typeof e.toJSON==\"function\"&&(e=e.toJSON());for(var a=md(e),u=md(t),o=!1,s=u.length-1;s>=0;s--){var l=u[s],f=t[l];if(pd(e,l)&&!(e[l]===void 0&&f!==void 0&&Array.isArray(e)===!1)){var c=e[l];typeof f==\"object\"&&f!=null&&typeof c==\"object\"&&c!=null&&Array.isArray(f)===Array.isArray(c)?sg(f,c,n,r+\"/\"+Ei(l),i):f!==c&&(i&&n.push({op:\"test\",path:r+\"/\"+Ei(l),value:Je(f)}),n.push({op:\"replace\",path:r+\"/\"+Ei(l),value:Je(c)}))}else Array.isArray(t)===Array.isArray(e)?(i&&n.push({op:\"test\",path:r+\"/\"+Ei(l),value:Je(f)}),n.push({op:\"remove\",path:r+\"/\"+Ei(l)}),o=!0):(i&&n.push({op:\"test\",path:r,value:t}),n.push({op:\"replace\",path:r,value:e}))}if(!(!o&&a.length==u.length))for(var s=0;sfunction(e){return e[t]},F4=t=>{const e=t.length;return function(n){for(let r=0;ru?l():u=o+1:s===\"[\"?(o>u&&l(),i=u=o+1):s===\"]\"&&(i||$(\"Access path missing open bracket: \"+t),i>0&&l(),i=0,u=o+1)}return i&&$(\"Access path missing closing bracket: \"+t),r&&$(\"Access path missing closing quote: \"+t),o>u&&(o++,l()),e}function en(t,e,n){const r=cc(t);return t=r.length===1?r[0]:t,Ge((n&&n.get||d3)(r),[t],e||t)}const ns=en(\"id\"),ge=Ge(t=>t,[],\"identity\"),Ir=Ge(()=>0,[],\"zero\"),ru=Ge(()=>1,[],\"one\"),We=Ge(()=>!0,[],\"true\"),Rr=Ge(()=>!1,[],\"false\");function M4(t,e,n){const r=[e].concat([].slice.call(n));console[t].apply(console,r)}const g3=0,lg=1,p3=2,m3=3,y3=4;function x3(t,e){let n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:M4,r=t||g3;return{level(i){return arguments.length?(r=+i,this):r},error(){return r>=lg&&n(e||\"error\",\"ERROR\",arguments),this},warn(){return r>=p3&&n(e||\"warn\",\"WARN\",arguments),this},info(){return r>=m3&&n(e||\"log\",\"INFO\",arguments),this},debug(){return r>=y3&&n(e||\"log\",\"DEBUG\",arguments),this}}}var U=Array.isArray;function et(t){return t===Object(t)}const yx=t=>t!==\"__proto__\";function v3(){for(var t=arguments.length,e=new Array(t),n=0;n{for(const a in i)if(a===\"signals\")r.signals=k4(r.signals,i.signals);else{const u=a===\"legend\"?{layout:1}:a===\"style\"?!0:null;fg(r,a,i[a],u)}return r},{})}function fg(t,e,n,r){if(!yx(e))return;let i,a;if(et(n)&&!U(n)){a=et(t[e])?t[e]:t[e]={};for(i in n)r&&(r===!0||r[i])?fg(a,i,n[i]):yx(i)&&(a[i]=n[i])}else t[e]=n}function k4(t,e){if(t==null)return e;const n={},r=[];function i(a){n[a.name]||(n[a.name]=1,r.push(a))}return e.forEach(i),t.forEach(i),r}function ut(t){return t[t.length-1]}function Kt(t){return t==null||t===\"\"?null:+t}const b3=t=>e=>t*Math.exp(e),A3=t=>e=>Math.log(t*e),w3=t=>e=>Math.sign(e)*Math.log1p(Math.abs(e/t)),E3=t=>e=>Math.sign(e)*Math.expm1(Math.abs(e))*t,xf=t=>e=>e<0?-Math.pow(-e,t):Math.pow(e,t);function hc(t,e,n,r){const i=n(t[0]),a=n(ut(t)),u=(a-i)*e;return[r(i-u),r(a-u)]}function cg(t,e){return hc(t,e,Kt,ge)}function hg(t,e){var n=Math.sign(t[0]);return hc(t,e,A3(n),b3(n))}function dg(t,e,n){return hc(t,e,xf(n),xf(1/n))}function gg(t,e,n){return hc(t,e,w3(n),E3(n))}function dc(t,e,n,r,i){const a=r(t[0]),u=r(ut(t)),o=e!=null?r(e):(a+u)/2;return[i(o+(a-o)*n),i(o+(u-o)*n)]}function gc(t,e,n){return dc(t,e,n,Kt,ge)}function pc(t,e,n){const r=Math.sign(t[0]);return dc(t,e,n,A3(r),b3(r))}function Bo(t,e,n,r){return dc(t,e,n,xf(r),xf(1/r))}function mc(t,e,n,r){return dc(t,e,n,w3(r),E3(r))}function pg(t){return 1+~~(new Date(t).getMonth()/3)}function mg(t){return 1+~~(new Date(t).getUTCMonth()/3)}function H(t){return t!=null?U(t)?t:[t]:[]}function yg(t,e,n){let r=t[0],i=t[1],a;return i=n-e?[e,n]:[r=Math.min(Math.max(r,e),n-a),r+a]}function tt(t){return typeof t==\"function\"}const $4=\"descending\";function xg(t,e,n){n=n||{},e=H(e)||[];const r=[],i=[],a={},u=n.comparator||S4;return H(t).forEach((o,s)=>{o!=null&&(r.push(e[s]===$4?-1:1),i.push(o=tt(o)?o:en(o,null,n)),(se(o)||[]).forEach(l=>a[l]=1))}),i.length===0?null:Ge(u(i,r),Object.keys(a))}const yc=(t,e)=>(te||e==null)&&t!=null?1:(e=e instanceof Date?+e:e,(t=t instanceof Date?+t:t)!==t&&e===e?-1:e!==e&&t===t?1:0),S4=(t,e)=>t.length===1?B4(t[0],e[0]):T4(t,e,t.length),B4=(t,e)=>function(n,r){return yc(t(n),t(r))*e},T4=(t,e,n)=>(e.push(0),function(r,i){let a,u=0,o=-1;for(;u===0&&++ot}function vg(t,e){let n;return r=>{n&&clearTimeout(n),n=setTimeout(()=>(e(r),n=null),t)}}function nt(t){for(let e,n,r=1,i=arguments.length;ru&&(u=i))}else{for(i=e(t[n]);nu&&(u=i))}return[a,u]}function _3(t,e){const n=t.length;let r=-1,i,a,u,o,s;if(e==null){for(;++r=a){i=u=a;break}if(r===n)return[-1,-1];for(o=s=r;++ra&&(i=a,o=r),u=a){i=u=a;break}if(r===n)return[-1,-1];for(o=s=r;++ra&&(i=a,o=r),u{i.set(a,t[a])}),i}function bg(t,e,n,r,i,a){if(!n&&n!==0)return a;const u=+n;let o=t[0],s=ut(t),l;sa&&(u=i,i=a,a=u),n=n===void 0||n,r=r===void 0||r,(n?i<=t:io.replace(/\\\\(.)/g,\"$1\")):H(t));const r=t&&t.length,i=n&&n.get||d3,a=o=>i(e?[o]:cc(o));let u;if(!r)u=function(){return\"\"};else if(r===1){const o=a(t[0]);u=function(s){return\"\"+o(s)}}else{const o=t.map(a);u=function(s){let l=\"\"+o[0](s),f=0;for(;++f{e={},n={},r=0},a=(u,o)=>(++r>t&&(n=e,e={},r=1),e[u]=o);return i(),{clear:i,has:u=>X(e,u)||X(n,u),get:u=>X(e,u)?e[u]:X(n,u)?a(u,n[u]):void 0,set:(u,o)=>X(e,u)?e[u]=o:a(u,o)}}function F3(t,e,n,r){const i=e.length,a=n.length;if(!a)return e;if(!i)return n;const u=r||new e.constructor(i+a);let o=0,s=0,l=0;for(;o0?n[s++]:e[o++];for(;o=0;)n+=t;return n}function Cg(t,e,n,r){const i=n||\" \",a=t+\"\",u=e-a.length;return u<=0?a:r===\"left\"?Xu(i,u)+a:r===\"center\"?Xu(i,~~(u/2))+a+Xu(i,Math.ceil(u/2)):a+Xu(i,u)}function au(t){return t&&ut(t)-t[0]||0}function Y(t){return U(t)?\"[\"+t.map(Y)+\"]\":et(t)||xt(t)?JSON.stringify(t).replace(\"\\u2028\",\"\\\\u2028\").replace(\"\\u2029\",\"\\\\u2029\"):t}function xc(t){return t==null||t===\"\"?null:!t||t===\"false\"||t===\"0\"?!1:!!t}const N4=t=>Mr(t)||Cr(t)?t:Date.parse(t);function vc(t,e){return e=e||N4,t==null||t===\"\"?null:e(t)}function bc(t){return t==null||t===\"\"?null:t+\"\"}function nn(t){const e={},n=t.length;for(let r=0;r1)r=W4(t,e,n);else for(i=0,r=new Array(a=t.arcs.length);i(t[e]=1+n,t),{});function Mg(t){const e=H(t).slice(),n={};return e.length||$(\"Missing time unit.\"),e.forEach(i=>{X(Qh,i)?n[i]=1:$(`Invalid time unit: ${i}.`)}),(n[Nt]||n[oe]?1:0)+(n[Ye]||n[le]||n[He]?1:0)+(n[Jn]?1:0)>1&&$(`Incompatible time units: ${t}`),e.sort((i,a)=>Qh[i]-Qh[a]),e}const Y4={[Jt]:\"%Y \",[Ye]:\"Q%q \",[le]:\"%b \",[He]:\"%d \",[Nt]:\"W%U \",[oe]:\"%a \",[Jn]:\"%j \",[rn]:\"%H:00\",[an]:\"00:%M\",[yn]:\":%S\",[Bn]:\".%L\",[`${Jt}-${le}`]:\"%Y-%m \",[`${Jt}-${le}-${He}`]:\"%Y-%m-%d \",[`${rn}-${an}`]:\"%H:%M\"};function kg(t,e){const n=nt({},Y4,e),r=Mg(t),i=r.length;let a=\"\",u=0,o,s;for(u=0;uu;--o)if(s=r.slice(u,o).join(\"-\"),n[s]!=null){a+=n[s],u=o;break}return a.trim()}const Ci=new Date;function $g(t){return Ci.setFullYear(t),Ci.setMonth(0),Ci.setDate(1),Ci.setHours(0,0,0,0),Ci}function Sg(t){return k3(new Date(t))}function Bg(t){return bd(new Date(t))}function k3(t){return _r.count($g(t.getFullYear())-1,t)}function bd(t){return eu.count($g(t.getFullYear())-1,t)}function Ad(t){return $g(t).getDay()}function H4(t,e,n,r,i,a,u){if(0<=t&&t<100){const o=new Date(-1,e,n,r,i,a,u);return o.setFullYear(t),o}return new Date(t,e,n,r,i,a,u)}function Tg(t){return $3(new Date(t))}function Rg(t){return wd(new Date(t))}function $3(t){const e=Date.UTC(t.getUTCFullYear(),0,1);return Kr.count(e-1,t)}function wd(t){const e=Date.UTC(t.getUTCFullYear(),0,1);return nu.count(e-1,t)}function Ed(t){return Ci.setTime(Date.UTC(t,0,1)),Ci.getUTCDay()}function G4(t,e,n,r,i,a,u){if(0<=t&&t<100){const o=new Date(Date.UTC(-1,e,n,r,i,a,u));return o.setUTCFullYear(n.y),o}return new Date(Date.UTC(t,e,n,r,i,a,u))}function S3(t,e,n,r,i){const a=e||1,u=ut(t),o=(y,x,v)=>(v=v||y,X4(n[v],r[v],y===u&&a,x)),s=new Date,l=nn(t),f=l[Jt]?o(Jt):pe(2012),c=l[le]?o(le):l[Ye]?o(Ye):Ir,h=l[Nt]&&l[oe]?o(oe,1,Nt+oe):l[Nt]?o(Nt,1):l[oe]?o(oe,1):l[He]?o(He,1):l[Jn]?o(Jn,1):ru,d=l[rn]?o(rn):Ir,g=l[an]?o(an):Ir,p=l[yn]?o(yn):Ir,m=l[Bn]?o(Bn):Ir;return function(y){s.setTime(+y);const x=f(s);return i(x,c(s),h(s,x),d(s),g(s),p(s),m(s))}}function X4(t,e,n,r){const i=n<=1?t:r?(a,u)=>r+n*Math.floor((t(a,u)-r)/n):(a,u)=>n*Math.floor(t(a,u)/n);return e?(a,u)=>e(i(a,u),u):i}function Ua(t,e,n){return e+t*7-(n+6)%7}const V4={[Jt]:t=>t.getFullYear(),[Ye]:t=>Math.floor(t.getMonth()/3),[le]:t=>t.getMonth(),[He]:t=>t.getDate(),[rn]:t=>t.getHours(),[an]:t=>t.getMinutes(),[yn]:t=>t.getSeconds(),[Bn]:t=>t.getMilliseconds(),[Jn]:t=>k3(t),[Nt]:t=>bd(t),[Nt+oe]:(t,e)=>Ua(bd(t),t.getDay(),Ad(e)),[oe]:(t,e)=>Ua(1,t.getDay(),Ad(e))},K4={[Ye]:t=>3*t,[Nt]:(t,e)=>Ua(t,0,Ad(e))};function B3(t,e){return S3(t,e||1,V4,K4,H4)}const Q4={[Jt]:t=>t.getUTCFullYear(),[Ye]:t=>Math.floor(t.getUTCMonth()/3),[le]:t=>t.getUTCMonth(),[He]:t=>t.getUTCDate(),[rn]:t=>t.getUTCHours(),[an]:t=>t.getUTCMinutes(),[yn]:t=>t.getUTCSeconds(),[Bn]:t=>t.getUTCMilliseconds(),[Jn]:t=>$3(t),[Nt]:t=>wd(t),[oe]:(t,e)=>Ua(1,t.getUTCDay(),Ed(e)),[Nt+oe]:(t,e)=>Ua(wd(t),t.getUTCDay(),Ed(e))},Z4={[Ye]:t=>3*t,[Nt]:(t,e)=>Ua(t,0,Ed(e))};function T3(t,e){return S3(t,e||1,Q4,Z4,G4)}const J4={[Jt]:Qn,[Ye]:ko.every(3),[le]:ko,[Nt]:eu,[He]:_r,[oe]:_r,[Jn]:_r,[rn]:ic,[an]:nc,[yn]:br,[Bn]:La},t7={[Jt]:Zn,[Ye]:$o.every(3),[le]:$o,[Nt]:nu,[He]:Kr,[oe]:Kr,[Jn]:Kr,[rn]:ac,[an]:rc,[yn]:br,[Bn]:La};function uu(t){return J4[t]}function ou(t){return t7[t]}function R3(t,e,n){return t?t.offset(e,n):void 0}function Og(t,e,n){return R3(uu(t),e,n)}function Ng(t,e,n){return R3(ou(t),e,n)}function O3(t,e,n,r){return t?t.range(e,n,r):void 0}function Lg(t,e,n,r){return O3(uu(t),e,n,r)}function Pg(t,e,n,r){return O3(ou(t),e,n,r)}const Vu=1e3,Ku=Vu*60,Qu=Ku*60,Ac=Qu*24,e7=Ac*7,vx=Ac*30,_d=Ac*365,N3=[Jt,le,He,rn,an,yn,Bn],Zu=N3.slice(0,-1),Ju=Zu.slice(0,-1),to=Ju.slice(0,-1),n7=to.slice(0,-1),r7=[Jt,Nt],bx=[Jt,le],L3=[Jt],Du=[[Zu,1,Vu],[Zu,5,5*Vu],[Zu,15,15*Vu],[Zu,30,30*Vu],[Ju,1,Ku],[Ju,5,5*Ku],[Ju,15,15*Ku],[Ju,30,30*Ku],[to,1,Qu],[to,3,3*Qu],[to,6,6*Qu],[to,12,12*Qu],[n7,1,Ac],[r7,1,e7],[bx,1,vx],[bx,3,3*vx],[L3,1,_d]];function P3(t){const e=t.extent,n=t.maxbins||40,r=Math.abs(au(e))/n;let i=Za(o=>o[2]).right(Du,r),a,u;return i===Du.length?(a=L3,u=ei(e[0]/_d,e[1]/_d,n)):i?(i=Du[r/Du[i-1][2]e[n]||(e[n]=t(n))}function i7(t,e){return n=>{const r=t(n),i=r.indexOf(e);if(i<0)return r;let a=a7(r,i);const u=ai;)if(r[a]!==\"0\"){++a;break}return r.slice(0,a)+u}}function a7(t,e){let n=t.lastIndexOf(\"e\"),r;if(n>0)return n;for(n=t.length;--n>e;)if(r=t.charCodeAt(n),r>=48&&r<=57)return n+1}function z3(t){const e=eo(t.format),n=t.formatPrefix;return{format:e,formatPrefix:n,formatFloat(r){const i=qi(r||\",\");if(i.precision==null){switch(i.precision=12,i.type){case\"%\":i.precision-=2;break;case\"e\":i.precision-=1;break}return i7(e(i),e(\".1f\")(1)[1])}else return e(i)},formatSpan(r,i,a,u){u=qi(u??\",f\");const o=ei(r,i,a),s=Math.max(Math.abs(r),Math.abs(i));let l;if(u.precision==null)switch(u.type){case\"s\":return isNaN(l=EA(o,s))||(u.precision=l),n(u,s);case\"\":case\"e\":case\"g\":case\"p\":case\"r\":{isNaN(l=_A(o,s))||(u.precision=l-(u.type===\"e\"));break}case\"f\":case\"%\":{isNaN(l=wA(o))||(u.precision=l-(u.type===\"%\")*2);break}}return e(u)}}}let Cd;I3();function I3(){return Cd=z3({format:Kf,formatPrefix:R1})}function U3(t){return z3(AA(t))}function vf(t){return arguments.length?Cd=U3(t):Cd}function Ax(t,e,n){n=n||{},et(n)||$(`Invalid time multi-format specifier: ${n}`);const r=e(yn),i=e(an),a=e(rn),u=e(He),o=e(Nt),s=e(le),l=e(Ye),f=e(Jt),c=t(n[Bn]||\".%L\"),h=t(n[yn]||\":%S\"),d=t(n[an]||\"%I:%M\"),g=t(n[rn]||\"%I %p\"),p=t(n[He]||n[oe]||\"%a %d\"),m=t(n[Nt]||\"%b %d\"),y=t(n[le]||\"%B\"),x=t(n[Ye]||\"%B\"),v=t(n[Jt]||\"%Y\");return b=>(r(b)xt(r)?e(r):Ax(e,uu,r),utcFormat:r=>xt(r)?n(r):Ax(n,ou,r),timeParse:eo(t.parse),utcParse:eo(t.utcParse)}}let Dd;j3();function j3(){return Dd=q3({format:V1,parse:Iw,utcFormat:K1,utcParse:Uw})}function W3(t){return q3(Ow(t))}function To(t){return arguments.length?Dd=W3(t):Dd}const Fd=(t,e)=>nt({},t,e);function Y3(t,e){const n=t?U3(t):vf(),r=e?W3(e):To();return Fd(n,r)}function zg(t,e){const n=arguments.length;return n&&n!==2&&$(\"defaultLocale expects either zero or two arguments.\"),n?Fd(vf(t),To(e)):Fd(vf(),To())}function u7(){return I3(),j3(),zg()}const o7=/^(data:|([A-Za-z]+:)?\\/\\/)/,s7=/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|file|data):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i,l7=/[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205f\\u3000]/g,wx=\"file://\";function f7(t,e){return n=>({options:n||{},sanitize:h7,load:c7,fileAccess:!!e,file:d7(e),http:p7(t)})}async function c7(t,e){const n=await this.sanitize(t,e),r=n.href;return n.localFile?this.file(r):this.http(r,e)}async function h7(t,e){e=nt({},this.options,e);const n=this.fileAccess,r={href:null};let i,a,u;const o=s7.test(t.replace(l7,\"\"));(t==null||typeof t!=\"string\"||!o)&&$(\"Sanitize failure, invalid URI: \"+Y(t));const s=o7.test(t);return(u=e.baseURL)&&!s&&(!t.startsWith(\"/\")&&!u.endsWith(\"/\")&&(t=\"/\"+t),t=u+t),a=(i=t.startsWith(wx))||e.mode===\"file\"||e.mode!==\"http\"&&!s&&n,i?t=t.slice(wx.length):t.startsWith(\"//\")&&(e.defaultProtocol===\"file\"?(t=t.slice(2),a=!0):t=(e.defaultProtocol||\"http\")+\":\"+t),Object.defineProperty(r,\"localFile\",{value:!!a}),r.href=t,e.target&&(r.target=e.target+\"\"),e.rel&&(r.rel=e.rel+\"\"),e.context===\"image\"&&e.crossOrigin&&(r.crossOrigin=e.crossOrigin+\"\"),r}function d7(t){return t?e=>new Promise((n,r)=>{t.readFile(e,(i,a)=>{i?r(i):n(a)})}):g7}async function g7(){$(\"No file system access.\")}function p7(t){return t?async function(e,n){const r=nt({},this.options.http,n),i=n&&n.response,a=await t(e,r);return a.ok?tt(a[i])?a[i]():a.text():$(a.status+\"\"+a.statusText)}:m7}async function m7(){$(\"No HTTP fetch method available.\")}const y7=t=>t!=null&&t===t,x7=t=>t===\"true\"||t===\"false\"||t===!0||t===!1,v7=t=>!Number.isNaN(Date.parse(t)),H3=t=>!Number.isNaN(+t)&&!(t instanceof Date),b7=t=>H3(t)&&Number.isInteger(+t),Md={boolean:xc,integer:Kt,number:Kt,date:vc,string:bc,unknown:ge},Gs=[x7,b7,H3,v7],A7=[\"boolean\",\"integer\",\"number\",\"date\"];function G3(t,e){if(!t||!t.length)return\"unknown\";const n=t.length,r=Gs.length,i=Gs.map((a,u)=>u+1);for(let a=0,u=0,o,s;aa===0?u:a,0)-1]}function X3(t,e){return e.reduce((n,r)=>(n[r]=G3(t,r),n),{})}function Ex(t){const e=function(n,r){const i={delimiter:t};return Ig(n,r?nt(r,i):i)};return e.responseType=\"text\",e}function Ig(t,e){return e.header&&(t=e.header.map(Y).join(e.delimiter)+`\n`+t),U5(e.delimiter).parse(t+\"\")}Ig.responseType=\"text\";function w7(t){return typeof Buffer==\"function\"&&tt(Buffer.isBuffer)?Buffer.isBuffer(t):!1}function Ug(t,e){const n=e&&e.property?en(e.property):ge;return et(t)&&!w7(t)?E7(n(t),e):n(JSON.parse(t))}Ug.responseType=\"json\";function E7(t,e){return!U(t)&&C3(t)&&(t=[...t]),e&&e.copy?JSON.parse(JSON.stringify(t)):t}const _7={interior:(t,e)=>t!==e,exterior:(t,e)=>t===e};function V3(t,e){let n,r,i,a;return t=Ug(t,e),e&&e.feature?(n=I4,i=e.feature):e&&e.mesh?(n=q4,i=e.mesh,a=_7[e.filter]):$(\"Missing TopoJSON feature or mesh parameter.\"),r=(r=t.objects[i])?n(t,r,a):$(\"Invalid TopoJSON object: \"+i),r&&r.features||[r]}V3.responseType=\"json\";const fl={dsv:Ig,csv:Ex(\",\"),tsv:Ex(\"\t\"),json:Ug,topojson:V3};function qg(t,e){return arguments.length>1?(fl[t]=e,this):X(fl,t)?fl[t]:null}function K3(t){const e=qg(t);return e&&e.responseType||\"text\"}function Q3(t,e,n,r){e=e||{};const i=qg(e.type||\"json\");return i||$(\"Unknown data format type: \"+e.type),t=i(t,e),e.parse&&C7(t,e.parse,n,r),X(t,\"columns\")&&delete t.columns,t}function C7(t,e,n,r){if(!t.length)return;const i=To();n=n||i.timeParse,r=r||i.utcParse;let a=t.columns||Object.keys(t[0]),u,o,s,l,f,c;e===\"auto\"&&(e=X3(t,a)),a=Object.keys(e);const h=a.map(d=>{const g=e[d];let p,m;if(g&&(g.startsWith(\"date:\")||g.startsWith(\"utc:\")))return p=g.split(/:(.+)?/,2),m=p[1],(m[0]===\"'\"&&m[m.length-1]===\"'\"||m[0]==='\"'&&m[m.length-1]==='\"')&&(m=m.slice(1,-1)),(p[0]===\"utc\"?r:n)(m);if(!Md[g])throw Error(\"Illegal format pattern: \"+d+\":\"+g);return Md[g]});for(s=0,f=t.length,c=a.length;s{const a=e(i);return r[a]||(r[a]=1,n.push(i)),n},n.remove=i=>{const a=e(i);if(r[a]){r[a]=0;const u=n.indexOf(i);u>=0&&n.splice(u,1)}return n},n}async function cl(t,e){try{await e(t)}catch(n){t.error(n)}}const Z3=Symbol(\"vega_id\");let D7=1;function su(t){return!!(t&&K(t))}function K(t){return t[Z3]}function J3(t,e){return t[Z3]=e,t}function gt(t){const e=t===Object(t)?t:{data:t};return K(e)?e:J3(e,D7++)}function jg(t){return _c(t,gt({}))}function _c(t,e){for(const n in t)e[n]=t[n];return e}function tE(t,e){return J3(e,K(t))}function na(t,e){return t?e?(n,r)=>t(n,r)||K(e(n))-K(e(r)):(n,r)=>t(n,r)||K(n)-K(r):null}function eE(t){return t&&t.constructor===ra}function ra(){const t=[],e=[],n=[],r=[],i=[];let a=null,u=!1;return{constructor:ra,insert(o){const s=H(o),l=s.length;for(let f=0;f{g(x)&&(l[K(x)]=-1)});for(c=0,h=t.length;c0&&(y(p,g,d.value),o.modifies(g));for(c=0,h=i.length;c{g(x)&&l[K(x)]>0&&y(x,d.field,d.value)}),o.modifies(d.field);if(u)o.mod=e.length||r.length?s.filter(x=>l[K(x)]>0):s.slice();else for(m in f)o.mod.push(f[m]);return(a||a==null&&(e.length||r.length))&&o.clean(!0),o}}}const hl=\"_:mod:_\";function Cc(){Object.defineProperty(this,hl,{writable:!0,value:{}})}Cc.prototype={set(t,e,n,r){const i=this,a=i[t],u=i[hl];return e!=null&&e>=0?(a[e]!==n||r)&&(a[e]=n,u[e+\":\"+t]=-1,u[t]=-1):(a!==n||r)&&(i[t]=n,u[t]=U(n)?1+n.length:-1),i},modified(t,e){const n=this[hl];if(arguments.length){if(U(t)){for(let r=0;r=0?e+1{d instanceof At?(d!==this&&(e&&d.targets().add(this),a.push(d)),i.push({op:d,name:c,index:h})):r.set(c,h,d)};for(u in t)if(o=t[u],u===M7)H(o).forEach(c=>{c instanceof At?c!==this&&(c.targets().add(this),a.push(c)):$(\"Pulse parameters must be operator instances.\")}),this.source=o;else if(U(o))for(r.set(u,-1,Array(s=o.length)),l=0;l{const n=Date.now();return n-e>t?(e=n,1):0})},debounce(t){const e=Or();return this.targets().add(Or(null,null,vg(t,n=>{const r=n.dataflow;e.receive(n),r&&r.run&&r.run()}))),e},between(t,e){let n=!1;return t.targets().add(Or(null,null,()=>n=!0)),e.targets().add(Or(null,null,()=>n=!1)),this.filter(()=>n)},detach(){this._filter=We,this._targets=null}};function O7(t,e,n,r){const i=this,a=Or(n,r),u=function(l){l.dataflow=i;try{a.receive(l)}catch(f){i.error(f)}finally{i.run()}};let o;typeof t==\"string\"&&typeof document<\"u\"?o=document.querySelectorAll(t):o=H(t);const s=o.length;for(let l=0;le=r);return n.requests=0,n.done=()=>{--n.requests===0&&(t._pending=null,e(t))},t._pending=n}const U7={skip:!0};function q7(t,e,n,r,i){return(t instanceof At?W7:j7)(this,t,e,n,r,i),this}function j7(t,e,n,r,i,a){const u=nt({},a,U7);let o,s;tt(n)||(n=pe(n)),r===void 0?o=l=>t.touch(n(l)):tt(r)?(s=new At(null,r,i,!1),o=l=>{s.evaluate(l);const f=n(l),c=s.value;eE(c)?t.pulse(f,c,a):t.update(f,c,u)}):o=l=>t.update(n(l),r,u),e.apply(o)}function W7(t,e,n,r,i,a){if(r===void 0)e.targets().add(n);else{const u=a||{},o=new At(null,Y7(n,r),i,!1);o.modified(u.force),o.rank=e.rank,e.targets().add(o),n&&(o.skip(!0),o.value=n.value,o.targets().add(n),t.connect(n,[o]))}}function Y7(t,e){return e=tt(e)?e:pe(e),t?function(n,r){const i=e(n,r);return t.skip()||(t.skip(i!==this.value).value=i),i}:e}function H7(t){t.rank=++this._rank}function G7(t){const e=[t];let n,r,i;for(;e.length;)if(this.rank(n=e.pop()),r=n._targets)for(i=r.length;--i>=0;)e.push(n=r[i]),n===t&&$(\"Cycle detected in dataflow graph.\")}const bf={},Un=1,Pr=2,cr=4,X7=Un|Pr,Cx=Un|cr,ha=Un|Pr|cr,Dx=8,Fu=16,Fx=32,Mx=64;function Qr(t,e,n){this.dataflow=t,this.stamp=e??-1,this.add=[],this.rem=[],this.mod=[],this.fields=null,this.encode=n||null}function Zh(t,e){const n=[];return Lr(t,e,r=>n.push(r)),n}function kx(t,e){const n={};return t.visit(e,r=>{n[K(r)]=1}),r=>n[K(r)]?null:r}function Xs(t,e){return t?(n,r)=>t(n,r)&&e(n,r):e}Qr.prototype={StopPropagation:bf,ADD:Un,REM:Pr,MOD:cr,ADD_REM:X7,ADD_MOD:Cx,ALL:ha,REFLOW:Dx,SOURCE:Fu,NO_SOURCE:Fx,NO_FIELDS:Mx,fork(t){return new Qr(this.dataflow).init(this,t)},clone(){const t=this.fork(ha);return t.add=t.add.slice(),t.rem=t.rem.slice(),t.mod=t.mod.slice(),t.source&&(t.source=t.source.slice()),t.materialize(ha|Fu)},addAll(){let t=this;return!t.source||t.add===t.rem||!t.rem.length&&t.source.length===t.add.length||(t=new Qr(this.dataflow).init(this),t.add=t.source,t.rem=[]),t},init(t,e){const n=this;return n.stamp=t.stamp,n.encode=t.encode,t.fields&&!(e&Mx)&&(n.fields=t.fields),e&Un?(n.addF=t.addF,n.add=t.add):(n.addF=null,n.add=[]),e&Pr?(n.remF=t.remF,n.rem=t.rem):(n.remF=null,n.rem=[]),e&cr?(n.modF=t.modF,n.mod=t.mod):(n.modF=null,n.mod=[]),e&Fx?(n.srcF=null,n.source=null):(n.srcF=t.srcF,n.source=t.source,t.cleans&&(n.cleans=t.cleans)),n},runAfter(t){this.dataflow.runAfter(t)},changed(t){const e=t||ha;return e&Un&&this.add.length||e&Pr&&this.rem.length||e&cr&&this.mod.length},reflow(t){if(t)return this.fork(ha).reflow();const e=this.add.length,n=this.source&&this.source.length;return n&&n!==e&&(this.mod=this.source,e&&this.filter(cr,kx(this,Un))),this},clean(t){return arguments.length?(this.cleans=!!t,this):this.cleans},modifies(t){const e=this.fields||(this.fields={});return U(t)?t.forEach(n=>e[n]=!0):e[t]=!0,this},modified(t,e){const n=this.fields;return(e||this.mod.length)&&n?arguments.length?U(t)?t.some(r=>n[r]):n[t]:!!n:!1},filter(t,e){const n=this;return t&Un&&(n.addF=Xs(n.addF,e)),t&Pr&&(n.remF=Xs(n.remF,e)),t&cr&&(n.modF=Xs(n.modF,e)),t&Fu&&(n.srcF=Xs(n.srcF,e)),n},materialize(t){t=t||ha;const e=this;return t&Un&&e.addF&&(e.add=Zh(e.add,e.addF),e.addF=null),t&Pr&&e.remF&&(e.rem=Zh(e.rem,e.remF),e.remF=null),t&cr&&e.modF&&(e.mod=Zh(e.mod,e.modF),e.modF=null),t&Fu&&e.srcF&&(e.source=e.source.filter(e.srcF),e.srcF=null),e},visit(t,e){const n=this,r=e;if(t&Fu)return Lr(n.source,n.srcF,r),n;t&Un&&Lr(n.add,n.addF,r),t&Pr&&Lr(n.rem,n.remF,r),t&cr&&Lr(n.mod,n.modF,r);const i=n.source;if(t&Dx&&i){const a=n.add.length+n.mod.length;a===i.length||(a?Lr(i,kx(n,Cx),r):Lr(i,n.srcF,r))}return n}};function Wg(t,e,n,r){const i=this;let a=0;this.dataflow=t,this.stamp=e,this.fields=null,this.encode=r||null,this.pulses=n;for(const u of n)if(u.stamp===e){if(u.fields){const o=i.fields||(i.fields={});for(const s in u.fields)o[s]=1}u.changed(i.ADD)&&(a|=i.ADD),u.changed(i.REM)&&(a|=i.REM),u.changed(i.MOD)&&(a|=i.MOD)}this.changes=a}L(Wg,Qr,{fork(t){const e=new Qr(this.dataflow).init(this,t&this.NO_FIELDS);return t!==void 0&&(t&e.ADD&&this.visit(e.ADD,n=>e.add.push(n)),t&e.REM&&this.visit(e.REM,n=>e.rem.push(n)),t&e.MOD&&this.visit(e.MOD,n=>e.mod.push(n))),e},changed(t){return this.changes&t},modified(t){const e=this,n=e.fields;return n&&e.changes&e.MOD?U(t)?t.some(r=>n[r]):n[t]:0},filter(){$(\"MultiPulse does not support filtering.\")},materialize(){$(\"MultiPulse does not support materialization.\")},visit(t,e){const n=this,r=n.pulses,i=r.length;let a=0;if(t&n.SOURCE)for(;ar._enqueue(f,!0)),r._touched=Ec(ns);let u=0,o,s,l;try{for(;r._heap.size()>0;){if(o=r._heap.pop(),o.rank!==o.qrank){r._enqueue(o,!0);continue}s=o.run(r._getPulse(o,t)),s.then?s=await s:s.async&&(i.push(s.async),s=bf),s!==bf&&o._targets&&o._targets.forEach(f=>r._enqueue(f)),++u}}catch(f){r._heap.clear(),l=f}if(r._input={},r._pulse=null,r.debug(`Pulse ${a}: ${u} operators`),l&&(r._postrun=[],r.error(l)),r._postrun.length){const f=r._postrun.sort((c,h)=>h.priority-c.priority);r._postrun=[];for(let c=0;cr.runAsync(null,()=>{f.forEach(c=>{try{c(r)}catch(h){r.error(h)}})})),r}async function K7(t,e,n){for(;this._running;)await this._running;const r=()=>this._running=null;return(this._running=this.evaluate(t,e,n)).then(r,r),this._running}function Q7(t,e,n){return this._pulse?nE(this):(this.evaluate(t,e,n),this)}function Z7(t,e,n){if(this._pulse||e)this._postrun.push({priority:n||0,callback:t});else try{t(this)}catch(r){this.error(r)}}function nE(t){return t.error(\"Dataflow already running. Use runAsync() to chain invocations.\"),t}function J7(t,e){const n=t.stampi.pulse),e):this._input[t.id]||e$(this._pulse,n&&n.pulse)}function e$(t,e){return e&&e.stamp===t.stamp?e:(t=t.fork(),e&&e!==bf&&(t.source=e.source),t)}const Yg={skip:!1,force:!1};function n$(t,e){const n=e||Yg;return this._pulse?this._enqueue(t):this._touched.add(t),n.skip&&t.skip(!0),this}function r$(t,e,n){const r=n||Yg;return(t.set(e)||r.force)&&this.touch(t,r),this}function i$(t,e,n){this.touch(t,n||Yg);const r=new Qr(this,this._clock+(this._pulse?0:1)),i=t.pulse&&t.pulse.source||[];return r.target=t,this._input[t.id]=e.pulse(r,i),this}function a$(t){let e=[];return{clear:()=>e=[],size:()=>e.length,peek:()=>e[0],push:n=>(e.push(n),rE(e,0,e.length-1,t)),pop:()=>{const n=e.pop();let r;return e.length?(r=e[0],e[0]=n,u$(e,0,t)):r=n,r}}}function rE(t,e,n,r){let i,a;const u=t[n];for(;n>e;){if(a=n-1>>1,i=t[a],r(u,i)<0){t[n]=i,n=a;continue}break}return t[n]=u}function u$(t,e,n){const r=e,i=t.length,a=t[e];let u=(e<<1)+1,o;for(;u=0&&(u=o),t[e]=t[u],e=u,u=(e<<1)+1;return t[e]=a,rE(t,r,e,n)}function ka(){this.logger(x3()),this.logLevel(lg),this._clock=0,this._rank=0,this._locale=zg();try{this._loader=wc()}catch{}this._touched=Ec(ns),this._input={},this._pulse=null,this._heap=a$((t,e)=>t.qrank-e.qrank),this._postrun=[]}function Mu(t){return function(){return this._log[t].apply(this,arguments)}}ka.prototype={stamp(){return this._clock},loader(t){return arguments.length?(this._loader=t,this):this._loader},locale(t){return arguments.length?(this._locale=t,this):this._locale},logger(t){return arguments.length?(this._log=t,this):this._log},error:Mu(\"error\"),warn:Mu(\"warn\"),info:Mu(\"info\"),debug:Mu(\"debug\"),logLevel:Mu(\"level\"),cleanThreshold:1e4,add:B7,connect:T7,rank:H7,rerank:G7,pulse:i$,touch:n$,update:r$,changeset:ra,ingest:L7,parse:N7,preload:z7,request:P7,events:O7,on:q7,evaluate:V7,run:Q7,runAsync:K7,runAfter:Z7,_enqueue:J7,_getPulse:t$};function S(t,e){At.call(this,t,null,e)}L(S,At,{run(t){if(t.stampthis.pulse=n):e!==t.StopPropagation&&(this.pulse=e),e},evaluate(t){const e=this.marshall(t.stamp),n=this.transform(e,t);return e.clear(),n},transform(){}});const qa={};function iE(t){const e=aE(t);return e&&e.Definition||null}function aE(t){return t=t&&t.toLowerCase(),X(qa,t)?qa[t]:null}function*uE(t,e){if(e==null)for(let n of t)n!=null&&n!==\"\"&&(n=+n)>=n&&(yield n);else{let n=-1;for(let r of t)r=e(r,++n,t),r!=null&&r!==\"\"&&(r=+r)>=r&&(yield r)}}function Hg(t,e,n){const r=Float64Array.from(uE(t,n));return r.sort(wr),e.map(i=>zb(r,i))}function Gg(t,e){return Hg(t,[.25,.5,.75],e)}function Xg(t,e){const n=t.length,r=G5(t,e),i=Gg(t,e),a=(i[2]-i[0])/1.34;return 1.06*(Math.min(r,a)||r||Math.abs(i[0])||1)*Math.pow(n,-.2)}function oE(t){const e=t.maxbins||20,n=t.base||10,r=Math.log(n),i=t.divide||[5,2];let a=t.extent[0],u=t.extent[1],o,s,l,f,c,h;const d=t.span||u-a||Math.abs(a)||1;if(t.step)o=t.step;else if(t.steps){for(f=d/e,c=0,h=t.steps.length;ce;)o*=n;for(c=0,h=i.length;c=l&&d/f<=e&&(o=f)}f=Math.log(o);const g=f>=0?0:~~(-f/r)+1,p=Math.pow(n,-g-1);return(t.nice||t.nice===void 0)&&(f=Math.floor(a/o+p)*o,a=ah);const i=t.length,a=new Float64Array(i);let u=0,o=1,s=r(t[0]),l=s,f=s+e,c;for(;o=f){for(l=(s+l)/2;u>1);ui;)t[u--]=t[r]}r=i,i=a}return t}function l$(t){return function(){return t=(1103515245*t+12345)%2147483647,t/2147483647}}function f$(t,e){e==null&&(e=t,t=0);let n,r,i;const a={min(u){return arguments.length?(n=u||0,i=r-n,a):n},max(u){return arguments.length?(r=u||0,i=r-n,a):r},sample(){return n+Math.floor(i*un())},pdf(u){return u===Math.floor(u)&&u>=n&&u=r?1:(o-n+1)/i},icdf(u){return u>=0&&u<=1?n-1+Math.floor(u*i):NaN}};return a.min(t).max(e)}const fE=Math.sqrt(2*Math.PI),c$=Math.SQRT2;let ku=NaN;function rs(t,e){t=t||0,e=e??1;let n=0,r=0,i,a;if(ku===ku)n=ku,ku=NaN;else{do n=un()*2-1,r=un()*2-1,i=n*n+r*r;while(i===0||i>1);a=Math.sqrt(-2*Math.log(i)/i),n*=a,ku=r*a}return t+n*e}function Fc(t,e,n){n=n??1;const r=(t-(e||0))/n;return Math.exp(-.5*r*r)/(n*fE)}function is(t,e,n){e=e||0,n=n??1;const r=(t-e)/n,i=Math.abs(r);let a;if(i>37)a=0;else{const u=Math.exp(-i*i/2);let o;i<7.07106781186547?(o=.0352624965998911*i+.700383064443688,o=o*i+6.37396220353165,o=o*i+33.912866078383,o=o*i+112.079291497871,o=o*i+221.213596169931,o=o*i+220.206867912376,a=u*o,o=.0883883476483184*i+1.75566716318264,o=o*i+16.064177579207,o=o*i+86.7807322029461,o=o*i+296.564248779674,o=o*i+637.333633378831,o=o*i+793.826512519948,o=o*i+440.413735824752,a=a/o):(o=i+.65,o=i+4/o,o=i+3/o,o=i+2/o,o=i+1/o,a=u/o/2.506628274631)}return r>0?1-a:a}function as(t,e,n){return t<0||t>1?NaN:(e||0)+(n??1)*c$*h$(2*t-1)}function h$(t){let e=-Math.log((1-t)*(1+t)),n;return e<6.25?(e-=3.125,n=-364441206401782e-35,n=-16850591381820166e-35+n*e,n=128584807152564e-32+n*e,n=11157877678025181e-33+n*e,n=-1333171662854621e-31+n*e,n=20972767875968562e-33+n*e,n=6637638134358324e-30+n*e,n=-4054566272975207e-29+n*e,n=-8151934197605472e-29+n*e,n=26335093153082323e-28+n*e,n=-12975133253453532e-27+n*e,n=-5415412054294628e-26+n*e,n=10512122733215323e-25+n*e,n=-4112633980346984e-24+n*e,n=-29070369957882005e-24+n*e,n=42347877827932404e-23+n*e,n=-13654692000834679e-22+n*e,n=-13882523362786469e-21+n*e,n=.00018673420803405714+n*e,n=-.000740702534166267+n*e,n=-.006033670871430149+n*e,n=.24015818242558962+n*e,n=1.6536545626831027+n*e):e<16?(e=Math.sqrt(e)-3.25,n=22137376921775787e-25,n=9075656193888539e-23+n*e,n=-27517406297064545e-23+n*e,n=18239629214389228e-24+n*e,n=15027403968909828e-22+n*e,n=-4013867526981546e-21+n*e,n=29234449089955446e-22+n*e,n=12475304481671779e-21+n*e,n=-47318229009055734e-21+n*e,n=6828485145957318e-20+n*e,n=24031110387097894e-21+n*e,n=-.0003550375203628475+n*e,n=.0009532893797373805+n*e,n=-.0016882755560235047+n*e,n=.002491442096107851+n*e,n=-.003751208507569241+n*e,n=.005370914553590064+n*e,n=1.0052589676941592+n*e,n=3.0838856104922208+n*e):Number.isFinite(e)?(e=Math.sqrt(e)-5,n=-27109920616438573e-27,n=-2555641816996525e-25+n*e,n=15076572693500548e-25+n*e,n=-3789465440126737e-24+n*e,n=761570120807834e-23+n*e,n=-1496002662714924e-23+n*e,n=2914795345090108e-23+n*e,n=-6771199775845234e-23+n*e,n=22900482228026655e-23+n*e,n=-99298272942317e-20+n*e,n=4526062597223154e-21+n*e,n=-1968177810553167e-20+n*e,n=7599527703001776e-20+n*e,n=-.00021503011930044477+n*e,n=-.00013871931833623122+n*e,n=1.0103004648645344+n*e,n=4.849906401408584+n*e):n=1/0,n*t}function Vg(t,e){let n,r;const i={mean(a){return arguments.length?(n=a||0,i):n},stdev(a){return arguments.length?(r=a??1,i):r},sample:()=>rs(n,r),pdf:a=>Fc(a,n,r),cdf:a=>is(a,n,r),icdf:a=>as(a,n,r)};return i.mean(t).stdev(e)}function Kg(t,e){const n=Vg();let r=0;const i={data(a){return arguments.length?(t=a,r=a?a.length:0,i.bandwidth(e)):t},bandwidth(a){return arguments.length?(e=a,!e&&t&&(e=Xg(t)),i):e},sample(){return t[~~(un()*r)]+e*n.sample()},pdf(a){let u=0,o=0;for(;oMc(n,r),pdf:a=>kc(a,n,r),cdf:a=>$c(a,n,r),icdf:a=>Sc(a,n,r)};return i.mean(t).stdev(e)}function hE(t,e){let n=0,r;function i(u){const o=[];let s=0,l;for(l=0;l=e&&t<=n?1/(n-e):0}function Rc(t,e,n){return n==null&&(n=e??1,e=0),tn?1:(t-e)/(n-e)}function Oc(t,e,n){return n==null&&(n=e??1,e=0),t>=0&&t<=1?e+t*(n-e):NaN}function dE(t,e){let n,r;const i={min(a){return arguments.length?(n=a||0,i):n},max(a){return arguments.length?(r=a??1,i):r},sample:()=>Bc(n,r),pdf:a=>Tc(a,n,r),cdf:a=>Rc(a,n,r),icdf:a=>Oc(a,n,r)};return e==null&&(e=t??1,t=0),i.min(t).max(e)}function us(t,e,n,r){const i=r-t*t,a=Math.abs(i)<1e-24?0:(n-t*e)/i;return[e-a*t,a]}function Nc(t,e,n,r){t=t.filter(d=>{let g=e(d),p=n(d);return g!=null&&(g=+g)>=g&&p!=null&&(p=+p)>=p}),r&&t.sort((d,g)=>e(d)-e(g));const i=t.length,a=new Float64Array(i),u=new Float64Array(i);let o=0,s=0,l=0,f,c,h;for(h of t)a[o]=f=+e(h),u[o]=c=+n(h),++o,s+=(f-s)/o,l+=(c-l)/o;for(o=0;o=a&&u!=null&&(u=+u)>=u&&r(a,u,++i)}function lu(t,e,n,r,i){let a=0,u=0;return os(t,e,n,(o,s)=>{const l=s-i(o),f=s-r;a+=l*l,u+=f*f}),1-a/u}function Qg(t,e,n){let r=0,i=0,a=0,u=0,o=0;os(t,e,n,(f,c)=>{++o,r+=(f-r)/o,i+=(c-i)/o,a+=(f*c-a)/o,u+=(f*f-u)/o});const s=us(r,i,a,u),l=f=>s[0]+s[1]*f;return{coef:s,predict:l,rSquared:lu(t,e,n,i,l)}}function gE(t,e,n){let r=0,i=0,a=0,u=0,o=0;os(t,e,n,(f,c)=>{++o,f=Math.log(f),r+=(f-r)/o,i+=(c-i)/o,a+=(f*c-a)/o,u+=(f*f-u)/o});const s=us(r,i,a,u),l=f=>s[0]+s[1]*Math.log(f);return{coef:s,predict:l,rSquared:lu(t,e,n,i,l)}}function pE(t,e,n){const[r,i,a,u]=Nc(t,e,n);let o=0,s=0,l=0,f=0,c=0,h,d,g;os(t,e,n,(x,v)=>{h=r[c++],d=Math.log(v),g=h*v,o+=(v*d-o)/c,s+=(g-s)/c,l+=(g*d-l)/c,f+=(h*g-f)/c});const[p,m]=us(s/u,o/u,l/u,f/u),y=x=>Math.exp(p+m*(x-a));return{coef:[Math.exp(p-m*a),m],predict:y,rSquared:lu(t,e,n,u,y)}}function mE(t,e,n){let r=0,i=0,a=0,u=0,o=0,s=0;os(t,e,n,(c,h)=>{const d=Math.log(c),g=Math.log(h);++s,r+=(d-r)/s,i+=(g-i)/s,a+=(d*g-a)/s,u+=(d*d-u)/s,o+=(h-o)/s});const l=us(r,i,a,u),f=c=>l[0]*Math.pow(c,l[1]);return l[0]=Math.exp(l[0]),{coef:l,predict:f,rSquared:lu(t,e,n,o,f)}}function Zg(t,e,n){const[r,i,a,u]=Nc(t,e,n),o=r.length;let s=0,l=0,f=0,c=0,h=0,d,g,p,m;for(d=0;d(A=A-a,v*A*A+b*A+w+u);return{coef:[w-b*a+v*a*a+u,b-2*v*a,v],predict:E,rSquared:lu(t,e,n,u,E)}}function yE(t,e,n,r){if(r===1)return Qg(t,e,n);if(r===2)return Zg(t,e,n);const[i,a,u,o]=Nc(t,e,n),s=i.length,l=[],f=[],c=r+1;let h,d,g,p,m;for(h=0;h{v-=u;let b=o+y[0]+y[1]*v+y[2]*v*v;for(h=3;h=0;--a)for(o=e[a],s=1,i[a]+=o,u=1;u<=a;++u)s*=(a+1-u)/u,i[a-u]+=o*Math.pow(n,u)*s;return i[0]+=r,i}function g$(t){const e=t.length-1,n=[];let r,i,a,u,o;for(r=0;rMath.abs(t[r][u])&&(u=i);for(a=r;a=r;a--)t[a][i]-=t[a][r]*t[r][i]/t[r][r]}for(i=e-1;i>=0;--i){for(o=0,a=i+1;ai[v]-y?x:v;let w=0,E=0,A=0,_=0,C=0;const F=1/Math.abs(i[b]-y||1);for(let k=x;k<=v;++k){const N=i[k],M=a[k],O=p$(Math.abs(y-N)*F)*h[k],z=N*O;w+=O,E+=z,A+=M*O,_+=M*z,C+=N*z}const[D,R]=us(E/w,A/w,_/w,C/w);f[m]=D+R*y,c[m]=Math.abs(a[m]-f[m]),m$(i,m+1,g)}if(d===$x)break;const p=Ib(c);if(Math.abs(p)=1?Sx:(x=1-y*y)*x}return y$(i,f,u,o)}function p$(t){return(t=1-t*t*t)*t*t}function m$(t,e,n){const r=t[e];let i=n[0],a=n[1]+1;if(!(a>=t.length))for(;e>i&&t[a]-r<=r-t[i];)n[0]=++i,n[1]=a,++a}function y$(t,e,n,r){const i=t.length,a=[];let u=0,o=0,s=[],l;for(;u[p,t(p)],a=e[0],u=e[1],o=u-a,s=o/r,l=[i(a)],f=[];if(n===r){for(let p=1;p0;)f.push(i(a+p/n*o))}let c=l[0],h=f[f.length-1];const d=1/o,g=v$(c[1],f);for(;h;){const p=i((c[0]+h[0])/2);p[0]-c[0]>=s&&b$(c,p,h,d,g)>x$?f.push(p):(c=h,l.push(h),f.pop()),h=f[f.length-1]}return l}function v$(t,e){let n=t,r=t;const i=e.length;for(let a=0;ar&&(r=u)}return 1/(r-n)}function b$(t,e,n,r,i){const a=Math.atan2(i*(n[1]-t[1]),r*(n[0]-t[0])),u=Math.atan2(i*(e[1]-t[1]),r*(e[0]-t[0]));return Math.abs(a-u)}function A$(t){return e=>{const n=t.length;let r=1,i=String(t[0](e));for(;r{},w$={init:Jh,add:Jh,rem:Jh,idx:0},Ro={values:{init:t=>t.cell.store=!0,value:t=>t.cell.data.values(),idx:-1},count:{value:t=>t.cell.num},__count__:{value:t=>t.missing+t.valid},missing:{value:t=>t.missing},valid:{value:t=>t.valid},sum:{init:t=>t.sum=0,value:t=>t.sum,add:(t,e)=>t.sum+=+e,rem:(t,e)=>t.sum-=e},product:{init:t=>t.product=1,value:t=>t.valid?t.product:void 0,add:(t,e)=>t.product*=e,rem:(t,e)=>t.product/=e},mean:{init:t=>t.mean=0,value:t=>t.valid?t.mean:void 0,add:(t,e)=>(t.mean_d=e-t.mean,t.mean+=t.mean_d/t.valid),rem:(t,e)=>(t.mean_d=e-t.mean,t.mean-=t.valid?t.mean_d/t.valid:t.mean)},average:{value:t=>t.valid?t.mean:void 0,req:[\"mean\"],idx:1},variance:{init:t=>t.dev=0,value:t=>t.valid>1?t.dev/(t.valid-1):void 0,add:(t,e)=>t.dev+=t.mean_d*(e-t.mean),rem:(t,e)=>t.dev-=t.mean_d*(e-t.mean),req:[\"mean\"],idx:1},variancep:{value:t=>t.valid>1?t.dev/t.valid:void 0,req:[\"variance\"],idx:2},stdev:{value:t=>t.valid>1?Math.sqrt(t.dev/(t.valid-1)):void 0,req:[\"variance\"],idx:2},stdevp:{value:t=>t.valid>1?Math.sqrt(t.dev/t.valid):void 0,req:[\"variance\"],idx:2},stderr:{value:t=>t.valid>1?Math.sqrt(t.dev/(t.valid*(t.valid-1))):void 0,req:[\"variance\"],idx:2},distinct:{value:t=>t.cell.data.distinct(t.get),req:[\"values\"],idx:3},ci0:{value:t=>t.cell.data.ci0(t.get),req:[\"values\"],idx:3},ci1:{value:t=>t.cell.data.ci1(t.get),req:[\"values\"],idx:3},median:{value:t=>t.cell.data.q2(t.get),req:[\"values\"],idx:3},q1:{value:t=>t.cell.data.q1(t.get),req:[\"values\"],idx:3},q3:{value:t=>t.cell.data.q3(t.get),req:[\"values\"],idx:3},min:{init:t=>t.min=void 0,value:t=>t.min=Number.isNaN(t.min)?t.cell.data.min(t.get):t.min,add:(t,e)=>{(e{e<=t.min&&(t.min=NaN)},req:[\"values\"],idx:4},max:{init:t=>t.max=void 0,value:t=>t.max=Number.isNaN(t.max)?t.cell.data.max(t.get):t.max,add:(t,e)=>{(e>t.max||t.max===void 0)&&(t.max=e)},rem:(t,e)=>{e>=t.max&&(t.max=NaN)},req:[\"values\"],idx:4},argmin:{init:t=>t.argmin=void 0,value:t=>t.argmin||t.cell.data.argmin(t.get),add:(t,e,n)=>{e{e<=t.min&&(t.argmin=void 0)},req:[\"min\",\"values\"],idx:3},argmax:{init:t=>t.argmax=void 0,value:t=>t.argmax||t.cell.data.argmax(t.get),add:(t,e,n)=>{e>t.max&&(t.argmax=n)},rem:(t,e)=>{e>=t.max&&(t.argmax=void 0)},req:[\"max\",\"values\"],idx:3}},ss=Object.keys(Ro).filter(t=>t!==\"__count__\");function E$(t,e){return n=>nt({name:t,out:n||t},w$,e)}[...ss,\"__count__\"].forEach(t=>{Ro[t]=E$(t,Ro[t])});function bE(t,e){return Ro[t](e)}function AE(t,e){return t.idx-e.idx}function _$(t){const e={};t.forEach(r=>e[r.name]=r);const n=r=>{r.req&&r.req.forEach(i=>{e[i]||n(e[i]=Ro[i]())})};return t.forEach(n),Object.values(e).sort(AE)}function C$(){this.valid=0,this.missing=0,this._ops.forEach(t=>t.init(this))}function D$(t,e){if(t==null||t===\"\"){++this.missing;return}t===t&&(++this.valid,this._ops.forEach(n=>n.add(this,t,e)))}function F$(t,e){if(t==null||t===\"\"){--this.missing;return}t===t&&(--this.valid,this._ops.forEach(n=>n.rem(this,t,e)))}function M$(t){return this._out.forEach(e=>t[e.out]=e.value(this)),t}function wE(t,e){const n=e||ge,r=_$(t),i=t.slice().sort(AE);function a(u){this._ops=r,this._out=i,this.cell=u,this.init()}return a.prototype.init=C$,a.prototype.add=D$,a.prototype.rem=F$,a.prototype.set=M$,a.prototype.get=n,a.fields=t.map(u=>u.out),a}function Jg(t){this._key=t?en(t):K,this.reset()}const ee=Jg.prototype;ee.reset=function(){this._add=[],this._rem=[],this._ext=null,this._get=null,this._q=null};ee.add=function(t){this._add.push(t)};ee.rem=function(t){this._rem.push(t)};ee.values=function(){if(this._get=null,this._rem.length===0)return this._add;const t=this._add,e=this._rem,n=this._key,r=t.length,i=e.length,a=Array(r-i),u={};let o,s,l;for(o=0;o=0;)a=t(e[r])+\"\",X(n,a)||(n[a]=1,++i);return i};ee.extent=function(t){if(this._get!==t||!this._ext){const e=this.values(),n=_3(e,t);this._ext=[e[n[0]],e[n[1]]],this._get=t}return this._ext};ee.argmin=function(t){return this.extent(t)[0]||{}};ee.argmax=function(t){return this.extent(t)[1]||{}};ee.min=function(t){const e=this.extent(t)[0];return e!=null?t(e):void 0};ee.max=function(t){const e=this.extent(t)[1];return e!=null?t(e):void 0};ee.quartile=function(t){return(this._get!==t||!this._q)&&(this._q=Gg(this.values(),t),this._get=t),this._q};ee.q1=function(t){return this.quartile(t)[0]};ee.q2=function(t){return this.quartile(t)[1]};ee.q3=function(t){return this.quartile(t)[2]};ee.ci=function(t){return(this._get!==t||!this._ci)&&(this._ci=sE(this.values(),1e3,.05,t),this._get=t),this._ci};ee.ci0=function(t){return this.ci(t)[0]};ee.ci1=function(t){return this.ci(t)[1]};function ri(t){S.call(this,null,t),this._adds=[],this._mods=[],this._alen=0,this._mlen=0,this._drop=!0,this._cross=!1,this._dims=[],this._dnames=[],this._measures=[],this._countOnly=!1,this._counts=null,this._prev=null,this._inputs=null,this._outputs=null}ri.Definition={type:\"Aggregate\",metadata:{generates:!0,changes:!0},params:[{name:\"groupby\",type:\"field\",array:!0},{name:\"ops\",type:\"enum\",array:!0,values:ss},{name:\"fields\",type:\"field\",null:!0,array:!0},{name:\"as\",type:\"string\",null:!0,array:!0},{name:\"drop\",type:\"boolean\",default:!0},{name:\"cross\",type:\"boolean\",default:!1},{name:\"key\",type:\"field\"}]};L(ri,S,{transform(t,e){const n=this,r=e.fork(e.NO_SOURCE|e.NO_FIELDS),i=t.modified();return n.stamp=r.stamp,n.value&&(i||e.modified(n._inputs,!0))?(n._prev=n.value,n.value=i?n.init(t):Object.create(null),e.visit(e.SOURCE,a=>n.add(a))):(n.value=n.value||n.init(t),e.visit(e.REM,a=>n.rem(a)),e.visit(e.ADD,a=>n.add(a))),r.modifies(n._outputs),n._drop=t.drop!==!1,t.cross&&n._dims.length>1&&(n._drop=!1,n.cross()),e.clean()&&n._drop&&r.clean(!0).runAfter(()=>this.clean()),n.changes(r)},cross(){const t=this,e=t.value,n=t._dnames,r=n.map(()=>({})),i=n.length;function a(o){let s,l,f,c;for(s in o)for(f=o[s].tuple,l=0;l{const y=$t(m);return i(m),n.push(y),y}),this.cellkey=t.key?t.key:kd(this._dims),this._countOnly=!0,this._counts=[],this._measures=[];const a=t.fields||[null],u=t.ops||[\"count\"],o=t.as||[],s=a.length,l={};let f,c,h,d,g,p;for(s!==u.length&&$(\"Unmatched number of fields and aggregate ops.\"),p=0;pwE(m,m.field)),Object.create(null)},cellkey:kd(),cell(t,e){let n=this.value[t];return n?n.num===0&&this._drop&&n.stamp{const c=r(f);f[o]=c,f[s]=c==null?null:i+a*(1+(c-i)/a)}:f=>f[o]=r(f)),e.modifies(n?u:o)},_bins(t){if(this.value&&!t.modified())return this.value;const e=t.field,n=oE(t),r=n.step;let i=n.start,a=i+Math.ceil((n.stop-i)/r)*r,u,o;(u=t.anchor)!=null&&(o=u-(i+r*Math.floor((u-i)/r)),i+=o,a+=o);const s=function(l){let f=Kt(e(l));return f==null?null:fa?1/0:(f=Math.max(i,Math.min(f,a-r)),i+r*Math.floor(k$+(f-i)/r))};return s.start=i,s.stop=n.stop,s.step=r,this.value=Ge(s,se(e),t.name||\"bin_\"+$t(e))}});function EE(t,e,n){const r=t;let i=e||[],a=n||[],u={},o=0;return{add:s=>a.push(s),remove:s=>u[r(s)]=++o,size:()=>i.length,data:(s,l)=>(o&&(i=i.filter(f=>!u[r(f)]),u={},o=0),l&&s&&i.sort(s),a.length&&(i=s?F3(s,i,a.sort(s)):i.concat(a),a=[]),i)}}function ep(t){S.call(this,[],t)}ep.Definition={type:\"Collect\",metadata:{source:!0},params:[{name:\"sort\",type:\"compare\"}]};L(ep,S,{transform(t,e){const n=e.fork(e.ALL),r=EE(K,this.value,n.materialize(n.ADD).add),i=t.sort,a=e.changed()||i&&(t.modified(\"sort\")||e.modified(i.fields));return n.visit(n.REM,r.remove),this.modified(a),this.value=n.source=r.data(na(i),a),e.source&&e.source.root&&(this.value.root=e.source.root),n}});function _E(t){At.call(this,null,$$,t)}L(_E,At);function $$(t){return this.value&&!t.modified()?this.value:xg(t.fields,t.orders)}function np(t){S.call(this,null,t)}np.Definition={type:\"CountPattern\",metadata:{generates:!0,changes:!0},params:[{name:\"field\",type:\"field\",required:!0},{name:\"case\",type:\"enum\",values:[\"upper\",\"lower\",\"mixed\"],default:\"mixed\"},{name:\"pattern\",type:\"string\",default:'[\\\\w\"]+'},{name:\"stopwords\",type:\"string\",default:\"\"},{name:\"as\",type:\"string\",array:!0,length:2,default:[\"text\",\"count\"]}]};function S$(t,e,n){switch(e){case\"upper\":t=t.toUpperCase();break;case\"lower\":t=t.toLowerCase();break}return t.match(n)}L(np,S,{transform(t,e){const n=c=>h=>{for(var d=S$(o(h),t.case,a)||[],g,p=0,m=d.length;pi[c]=1+(i[c]||0)),f=n(c=>i[c]-=1);return r?e.visit(e.SOURCE,l):(e.visit(e.ADD,l),e.visit(e.REM,f)),this._finish(e,s)},_parameterCheck(t,e){let n=!1;return(t.modified(\"stopwords\")||!this._stop)&&(this._stop=new RegExp(\"^\"+(t.stopwords||\"\")+\"$\",\"i\"),n=!0),(t.modified(\"pattern\")||!this._match)&&(this._match=new RegExp(t.pattern||\"[\\\\w']+\",\"g\"),n=!0),(t.modified(\"field\")||e.modified(t.field.fields))&&(n=!0),n&&(this._counts={}),n},_finish(t,e){const n=this._counts,r=this._tuples||(this._tuples={}),i=e[0],a=e[1],u=t.fork(t.NO_SOURCE|t.NO_FIELDS);let o,s,l;for(o in n)s=r[o],l=n[o]||0,!s&&l?(r[o]=s=gt({}),s[i]=o,s[a]=l,u.add.push(s)):l===0?(s&&u.rem.push(s),n[o]=null,r[o]=null):s[a]!==l&&(s[a]=l,u.mod.push(s));return u.modifies(e)}});function rp(t){S.call(this,null,t)}rp.Definition={type:\"Cross\",metadata:{generates:!0},params:[{name:\"filter\",type:\"expr\"},{name:\"as\",type:\"string\",array:!0,length:2,default:[\"a\",\"b\"]}]};L(rp,S,{transform(t,e){const n=e.fork(e.NO_SOURCE),r=t.as||[\"a\",\"b\"],i=r[0],a=r[1],u=!this.value||e.changed(e.ADD_REM)||t.modified(\"as\")||t.modified(\"filter\");let o=this.value;return u?(o&&(n.rem=o),o=e.materialize(e.SOURCE).source,n.add=this.value=B$(o,i,a,t.filter||We)):n.mod=o,n.source=this.value,n.modifies(r)}});function B$(t,e,n,r){for(var i=[],a={},u=t.length,o=0,s,l;oCE(a,e))):typeof r[i]===Tx&&r[i](t[i]);return r}function ip(t){S.call(this,null,t)}const DE=[{key:{function:\"normal\"},params:[{name:\"mean\",type:\"number\",default:0},{name:\"stdev\",type:\"number\",default:1}]},{key:{function:\"lognormal\"},params:[{name:\"mean\",type:\"number\",default:0},{name:\"stdev\",type:\"number\",default:1}]},{key:{function:\"uniform\"},params:[{name:\"min\",type:\"number\",default:0},{name:\"max\",type:\"number\",default:1}]},{key:{function:\"kde\"},params:[{name:\"field\",type:\"field\",required:!0},{name:\"from\",type:\"data\"},{name:\"bandwidth\",type:\"number\",default:0}]}],O$={key:{function:\"mixture\"},params:[{name:\"distributions\",type:\"param\",array:!0,params:DE},{name:\"weights\",type:\"number\",array:!0}]};ip.Definition={type:\"Density\",metadata:{generates:!0},params:[{name:\"extent\",type:\"number\",array:!0,length:2},{name:\"steps\",type:\"number\"},{name:\"minsteps\",type:\"number\",default:25},{name:\"maxsteps\",type:\"number\",default:200},{name:\"method\",type:\"string\",default:\"pdf\",values:[\"pdf\",\"cdf\"]},{name:\"distribution\",type:\"param\",params:DE.concat(O$)},{name:\"as\",type:\"string\",array:!0,default:[\"value\",\"density\"]}]};L(ip,S,{transform(t,e){const n=e.fork(e.NO_SOURCE|e.NO_FIELDS);if(!this.value||e.changed()||t.modified()){const r=CE(t.distribution,N$(e)),i=t.steps||t.minsteps||25,a=t.steps||t.maxsteps||200;let u=t.method||\"pdf\";u!==\"pdf\"&&u!==\"cdf\"&&$(\"Invalid density method: \"+u),!t.extent&&!r.data&&$(\"Missing density extent parameter.\"),u=r[u];const o=t.as||[\"value\",\"density\"],s=t.extent||Sn(r.data()),l=Lc(u,s,i,a).map(f=>{const c={};return c[o[0]]=f[0],c[o[1]]=f[1],gt(c)});this.value&&(n.rem=this.value),this.value=n.add=n.source=l}return n}});function N$(t){return()=>t.materialize(t.SOURCE).source}function FE(t,e){return t?t.map((n,r)=>e[r]||$t(n)):null}function ap(t,e,n){const r=[],i=c=>c(s);let a,u,o,s,l,f;if(e==null)r.push(t.map(n));else for(a={},u=0,o=t.length;uau(Sn(t,e))/30;L(up,S,{transform(t,e){if(this.value&&!(t.modified()||e.changed()))return e;const n=e.materialize(e.SOURCE).source,r=ap(e.source,t.groupby,ge),i=t.smooth||!1,a=t.field,u=t.step||L$(n,a),o=na((g,p)=>a(g)-a(p)),s=t.as||ME,l=r.length;let f=1/0,c=-1/0,h=0,d;for(;hc&&(c=p),g[++d][s]=p}return this.value={start:f,stop:c,step:u},e.reflow(!0).modifies(s)}});function kE(t){At.call(this,null,P$,t),this.modified(!0)}L(kE,At);function P$(t){const e=t.expr;return this.value&&!t.modified(\"expr\")?this.value:Ge(n=>e(n,t),se(e),$t(e))}function op(t){S.call(this,[void 0,void 0],t)}op.Definition={type:\"Extent\",metadata:{},params:[{name:\"field\",type:\"field\",required:!0}]};L(op,S,{transform(t,e){const n=this.value,r=t.field,i=e.changed()||e.modified(r.fields)||t.modified(\"field\");let a=n[0],u=n[1];if((i||a==null)&&(a=1/0,u=-1/0),e.visit(i?e.SOURCE:e.ADD,o=>{const s=Kt(r(o));s!=null&&(su&&(u=s))}),!Number.isFinite(a)||!Number.isFinite(u)){let o=$t(r);o&&(o=` for field \"${o}\"`),e.dataflow.warn(`Infinite extent${o}: [${a}, ${u}]`),a=u=void 0}this.value=[a,u]}});function sp(t,e){At.call(this,t),this.parent=e,this.count=0}L(sp,At,{connect(t){return this.detachSubflow=t.detachSubflow,this.targets().add(t),t.source=this},add(t){this.count+=1,this.value.add.push(t)},rem(t){this.count-=1,this.value.rem.push(t)},mod(t){this.value.mod.push(t)},init(t){this.value.init(t,t.NO_SOURCE)},evaluate(){return this.value}});function Pc(t){S.call(this,{},t),this._keys=iu();const e=this._targets=[];e.active=0,e.forEach=n=>{for(let r=0,i=e.active;rr&&r.count>0);this.initTargets(n)}},initTargets(t){const e=this._targets,n=e.length,r=t?t.length:0;let i=0;for(;ithis.subflow(s,i,e);return this._group=t.group||{},this.initTargets(),e.visit(e.REM,s=>{const l=K(s),f=a.get(l);f!==void 0&&(a.delete(l),o(f).rem(s))}),e.visit(e.ADD,s=>{const l=r(s);a.set(K(s),l),o(l).add(s)}),u||e.modified(r.fields)?e.visit(e.MOD,s=>{const l=K(s),f=a.get(l),c=r(s);f===c?o(c).mod(s):(a.set(l,c),o(f).rem(s),o(c).add(s))}):e.changed(e.MOD)&&e.visit(e.MOD,s=>{o(a.get(K(s))).mod(s)}),u&&e.visit(e.REFLOW,s=>{const l=K(s),f=a.get(l),c=r(s);f!==c&&(a.set(l,c),o(f).rem(s),o(c).add(s))}),e.clean()?n.runAfter(()=>{this.clean(),a.clean()}):a.empty>n.cleanThreshold&&n.runAfter(a.clean),e}});function $E(t){At.call(this,null,z$,t)}L($E,At);function z$(t){return this.value&&!t.modified()?this.value:U(t.name)?H(t.name).map(e=>en(e)):en(t.name,t.as)}function lp(t){S.call(this,iu(),t)}lp.Definition={type:\"Filter\",metadata:{changes:!0},params:[{name:\"expr\",type:\"expr\",required:!0}]};L(lp,S,{transform(t,e){const n=e.dataflow,r=this.value,i=e.fork(),a=i.add,u=i.rem,o=i.mod,s=t.expr;let l=!0;e.visit(e.REM,c=>{const h=K(c);r.has(h)?r.delete(h):u.push(c)}),e.visit(e.ADD,c=>{s(c,t)?a.push(c):r.set(K(c),1)});function f(c){const h=K(c),d=s(c,t),g=r.get(h);d&&g?(r.delete(h),a.push(c)):!d&&!g?(r.set(h,1),u.push(c)):l&&d&&!g&&o.push(c)}return e.visit(e.MOD,f),t.modified()&&(l=!1,e.visit(e.REFLOW,f)),r.empty>n.cleanThreshold&&n.runAfter(r.clean),i}});function fp(t){S.call(this,[],t)}fp.Definition={type:\"Flatten\",metadata:{generates:!0},params:[{name:\"fields\",type:\"field\",array:!0,required:!0},{name:\"index\",type:\"string\"},{name:\"as\",type:\"string\",array:!0}]};L(fp,S,{transform(t,e){const n=e.fork(e.NO_SOURCE),r=t.fields,i=FE(r,t.as||[]),a=t.index||null,u=i.length;return n.rem=this.value,e.visit(e.SOURCE,o=>{const s=r.map(g=>g(o)),l=s.reduce((g,p)=>Math.max(g,p.length),0);let f=0,c,h,d;for(;f{for(let f=0,c;fu[r]=n(u,t))}});function SE(t){S.call(this,[],t)}L(SE,S,{transform(t,e){const n=e.fork(e.ALL),r=t.generator;let i=this.value,a=t.size-i.length,u,o,s;if(a>0){for(u=[];--a>=0;)u.push(s=gt(r(t))),i.push(s);n.add=n.add.length?n.materialize(n.ADD).add.concat(u):u}else o=i.slice(0,-a),n.rem=n.rem.length?n.materialize(n.REM).rem.concat(o):o,i=i.slice(-a);return n.source=this.value=i,n}});const Vs={value:\"value\",median:Ib,mean:J5,min:O0,max:Ri},I$=[];function dp(t){S.call(this,[],t)}dp.Definition={type:\"Impute\",metadata:{changes:!0},params:[{name:\"field\",type:\"field\",required:!0},{name:\"key\",type:\"field\",required:!0},{name:\"keyvals\",array:!0},{name:\"groupby\",type:\"field\",array:!0},{name:\"method\",type:\"enum\",default:\"value\",values:[\"value\",\"mean\",\"median\",\"max\",\"min\"]},{name:\"value\",default:0}]};function U$(t){var e=t.method||Vs.value,n;if(Vs[e]==null)$(\"Unrecognized imputation method: \"+e);else return e===Vs.value?(n=t.value!==void 0?t.value:0,()=>n):Vs[e]}function q$(t){const e=t.field;return n=>n?e(n):NaN}L(dp,S,{transform(t,e){var n=e.fork(e.ALL),r=U$(t),i=q$(t),a=$t(t.field),u=$t(t.key),o=(t.groupby||[]).map($t),s=j$(e.source,t.groupby,t.key,t.keyvals),l=[],f=this.value,c=s.domain.length,h,d,g,p,m,y,x,v,b,w;for(m=0,v=s.length;my(m),a=[],u=r?r.slice():[],o={},s={},l,f,c,h,d,g,p,m;for(u.forEach((y,x)=>o[y]=x+1),h=0,p=t.length;hn.add(a))):(i=n.value=n.value||this.init(t),e.visit(e.REM,a=>n.rem(a)),e.visit(e.ADD,a=>n.add(a))),n.changes(),e.visit(e.SOURCE,a=>{nt(a,i[n.cellkey(a)].tuple)}),e.reflow(r).modifies(this._outputs)},changes(){const t=this._adds,e=this._mods;let n,r;for(n=0,r=this._alen;n{const g=Kg(d,u)[o],p=t.counts?d.length:1,m=f||Sn(d);Lc(g,m,c,h).forEach(y=>{const x={};for(let v=0;v(this._pending=H(i.data),a=>a.touch(this)))}:n.request(t.url,t.format).then(r=>t0(this,e,H(r.data)))}});function Y$(t){return t.modified(\"async\")&&!(t.modified(\"values\")||t.modified(\"url\")||t.modified(\"format\"))}function t0(t,e,n){n.forEach(gt);const r=e.fork(e.NO_FIELDS&e.NO_SOURCE);return r.rem=t.value,t.value=r.source=r.add=n,t._pending=null,r.rem.length&&r.clean(!0),r}function mp(t){S.call(this,{},t)}mp.Definition={type:\"Lookup\",metadata:{modifies:!0},params:[{name:\"index\",type:\"index\",params:[{name:\"from\",type:\"data\",required:!0},{name:\"key\",type:\"field\",required:!0}]},{name:\"values\",type:\"field\",array:!0},{name:\"fields\",type:\"field\",array:!0,required:!0},{name:\"as\",type:\"string\",array:!0},{name:\"default\",default:null}]};L(mp,S,{transform(t,e){const n=t.fields,r=t.index,i=t.values,a=t.default==null?null:t.default,u=t.modified(),o=n.length;let s=u?e.SOURCE:e.ADD,l=e,f=t.as,c,h,d;return i?(h=i.length,o>1&&!f&&$('Multi-field lookup requires explicit \"as\" parameter.'),f&&f.length!==o*h&&$('The \"as\" parameter has too few output field names.'),f=f||i.map($t),c=function(g){for(var p=0,m=0,y,x;pe.modified(g.fields)),s|=d?e.MOD:0),e.visit(s,c),l.modifies(f)}});function RE(t){At.call(this,null,H$,t)}L(RE,At);function H$(t){if(this.value&&!t.modified())return this.value;const e=t.extents,n=e.length;let r=1/0,i=-1/0,a,u;for(a=0;ai&&(i=u[1]);return[r,i]}function OE(t){At.call(this,null,G$,t)}L(OE,At);function G$(t){return this.value&&!t.modified()?this.value:t.values.reduce((e,n)=>e.concat(n),[])}function NE(t){S.call(this,null,t)}L(NE,S,{transform(t,e){return this.modified(t.modified()),this.value=t,e.fork(e.NO_SOURCE|e.NO_FIELDS)}});function yp(t){ri.call(this,t)}yp.Definition={type:\"Pivot\",metadata:{generates:!0,changes:!0},params:[{name:\"groupby\",type:\"field\",array:!0},{name:\"field\",type:\"field\",required:!0},{name:\"value\",type:\"field\",required:!0},{name:\"op\",type:\"enum\",values:ss,default:\"sum\"},{name:\"limit\",type:\"number\",default:0},{name:\"key\",type:\"field\"}]};L(yp,ri,{_transform:ri.prototype.transform,transform(t,e){return this._transform(X$(t,e),e)}});function X$(t,e){const n=t.field,r=t.value,i=(t.op===\"count\"?\"__count__\":t.op)||\"sum\",a=se(n).concat(se(r)),u=K$(n,t.limit||0,e);return e.changed()&&t.set(\"__pivot__\",null,null,!0),{key:t.key,groupby:t.groupby,ops:u.map(()=>i),fields:u.map(o=>V$(o,n,r,a)),as:u.map(o=>o+\"\"),modified:t.modified.bind(t)}}function V$(t,e,n,r){return Ge(i=>e(i)===t?n(i):NaN,r,t+\"\")}function K$(t,e,n){const r={},i=[];return n.visit(n.SOURCE,a=>{const u=t(a);r[u]||(r[u]=1,i.push(u))}),i.sort(yc),e?i.slice(0,e):i}function LE(t){Pc.call(this,t)}L(LE,Pc,{transform(t,e){const n=t.subflow,r=t.field,i=a=>this.subflow(K(a),n,e,a);return(t.modified(\"field\")||r&&e.modified(se(r)))&&$(\"PreFacet does not support field modification.\"),this.initTargets(),r?(e.visit(e.MOD,a=>{const u=i(a);r(a).forEach(o=>u.mod(o))}),e.visit(e.ADD,a=>{const u=i(a);r(a).forEach(o=>u.add(gt(o)))}),e.visit(e.REM,a=>{const u=i(a);r(a).forEach(o=>u.rem(o))})):(e.visit(e.MOD,a=>i(a).mod(a)),e.visit(e.ADD,a=>i(a).add(a)),e.visit(e.REM,a=>i(a).rem(a))),e.clean()&&e.runAfter(()=>this.clean()),e}});function xp(t){S.call(this,null,t)}xp.Definition={type:\"Project\",metadata:{generates:!0,changes:!0},params:[{name:\"fields\",type:\"field\",array:!0},{name:\"as\",type:\"string\",null:!0,array:!0}]};L(xp,S,{transform(t,e){const n=e.fork(e.NO_SOURCE),r=t.fields,i=FE(t.fields,t.as||[]),a=r?(o,s)=>Q$(o,s,r,i):_c;let u;return this.value?u=this.value:(e=e.addAll(),u=this.value={}),e.visit(e.REM,o=>{const s=K(o);n.rem.push(u[s]),u[s]=null}),e.visit(e.ADD,o=>{const s=a(o,gt({}));u[K(o)]=s,n.add.push(s)}),e.visit(e.MOD,o=>{n.mod.push(a(o,u[K(o)]))}),n}});function Q$(t,e,n,r){for(let i=0,a=n.length;i{const h=Hg(c,l);for(let d=0;d{const a=K(i);n.rem.push(r[a]),r[a]=null}),e.visit(e.ADD,i=>{const a=jg(i);r[K(i)]=a,n.add.push(a)}),e.visit(e.MOD,i=>{const a=r[K(i)];for(const u in i)a[u]=i[u],n.modifies(u);n.mod.push(a)})),n}});function bp(t){S.call(this,[],t),this.count=0}bp.Definition={type:\"Sample\",metadata:{},params:[{name:\"size\",type:\"number\",default:1e3}]};L(bp,S,{transform(t,e){const n=e.fork(e.NO_SOURCE),r=t.modified(\"size\"),i=t.size,a=this.value.reduce((f,c)=>(f[K(c)]=1,f),{});let u=this.value,o=this.count,s=0;function l(f){let c,h;u.length=s&&(c=u[h],a[K(c)]&&n.rem.push(c),u[h]=f)),++o}if(e.rem.length&&(e.visit(e.REM,f=>{const c=K(f);a[c]&&(a[c]=-1,n.rem.push(f)),--o}),u=u.filter(f=>a[K(f)]!==-1)),(e.rem.length||r)&&u.length{a[K(f)]||l(f)}),s=-1),r&&u.length>i){const f=u.length-i;for(let c=0;c{a[K(f)]&&n.mod.push(f)}),e.add.length&&e.visit(e.ADD,l),(e.add.length||s<0)&&(n.add=u.filter(f=>!a[K(f)])),this.count=o,this.value=n.source=u,n}});function Ap(t){S.call(this,null,t)}Ap.Definition={type:\"Sequence\",metadata:{generates:!0,changes:!0},params:[{name:\"start\",type:\"number\",required:!0},{name:\"stop\",type:\"number\",required:!0},{name:\"step\",type:\"number\",default:1},{name:\"as\",type:\"string\",default:\"data\"}]};L(Ap,S,{transform(t,e){if(this.value&&!t.modified())return;const n=e.materialize().fork(e.MOD),r=t.as||\"data\";return n.rem=this.value?e.rem.concat(this.value):e.rem,this.value=Ie(t.start,t.stop,t.step||1).map(i=>{const a={};return a[r]=i,gt(a)}),n.add=e.add.concat(this.value),n}});function IE(t){S.call(this,null,t),this.modified(!0)}L(IE,S,{transform(t,e){return this.value=e.source,e.changed()?e.fork(e.NO_SOURCE|e.NO_FIELDS):e.StopPropagation}});function wp(t){S.call(this,null,t)}const UE=[\"unit0\",\"unit1\"];wp.Definition={type:\"TimeUnit\",metadata:{modifies:!0},params:[{name:\"field\",type:\"field\",required:!0},{name:\"interval\",type:\"boolean\",default:!0},{name:\"units\",type:\"enum\",values:Fg,array:!0},{name:\"step\",type:\"number\",default:1},{name:\"maxbins\",type:\"number\",default:40},{name:\"extent\",type:\"date\",array:!0},{name:\"timezone\",type:\"enum\",default:\"local\",values:[\"local\",\"utc\"]},{name:\"as\",type:\"string\",array:!0,length:2,default:UE}]};L(wp,S,{transform(t,e){const n=t.field,r=t.interval!==!1,i=t.timezone===\"utc\",a=this._floor(t,e),u=(i?ou:uu)(a.unit).offset,o=t.as||UE,s=o[0],l=o[1],f=a.step;let c=a.start||1/0,h=a.stop||-1/0,d=e.ADD;return(t.modified()||e.changed(e.REM)||e.modified(se(n)))&&(e=e.reflow(!0),d=e.SOURCE,c=1/0,h=-1/0),e.visit(d,g=>{const p=n(g);let m,y;p==null?(g[s]=null,r&&(g[l]=null)):(g[s]=m=y=a(p),r&&(g[l]=y=u(m,f)),mh&&(h=y))}),a.start=c,a.stop=h,e.modifies(r?o:s)},_floor(t,e){const n=t.timezone===\"utc\",{units:r,step:i}=t.units?{units:t.units,step:t.step||1}:P3({extent:t.extent||Sn(e.materialize(e.SOURCE).source,t.field),maxbins:t.maxbins}),a=Mg(r),u=this.value||{},o=(n?T3:B3)(a,i);return o.unit=ut(a),o.units=a,o.step=i,o.start=u.start,o.stop=u.stop,this.value=o}});function qE(t){S.call(this,iu(),t)}L(qE,S,{transform(t,e){const n=e.dataflow,r=t.field,i=this.value,a=o=>i.set(r(o),o);let u=!0;return t.modified(\"field\")||e.modified(r.fields)?(i.clear(),e.visit(e.SOURCE,a)):e.changed()?(e.visit(e.REM,o=>i.delete(r(o))),e.visit(e.ADD,a)):u=!1,this.modified(u),i.empty>n.cleanThreshold&&n.runAfter(i.clean),e.fork()}});function jE(t){S.call(this,null,t)}L(jE,S,{transform(t,e){(!this.value||t.modified(\"field\")||t.modified(\"sort\")||e.changed()||t.sort&&e.modified(t.sort.fields))&&(this.value=(t.sort?e.source.slice().sort(na(t.sort)):e.source).map(t.field))}});function J$(t,e,n,r){const i=Oo[t](e,n);return{init:i.init||Ir,update:function(a,u){u[r]=i.next(a)}}}const Oo={row_number:function(){return{next:t=>t.index+1}},rank:function(){let t;return{init:()=>t=1,next:e=>{const n=e.index,r=e.data;return n&&e.compare(r[n-1],r[n])?t=n+1:t}}},dense_rank:function(){let t;return{init:()=>t=1,next:e=>{const n=e.index,r=e.data;return n&&e.compare(r[n-1],r[n])?++t:t}}},percent_rank:function(){const t=Oo.rank(),e=t.next;return{init:t.init,next:n=>(e(n)-1)/(n.data.length-1)}},cume_dist:function(){let t;return{init:()=>t=0,next:e=>{const n=e.data,r=e.compare;let i=e.index;if(t0||$(\"ntile num must be greater than zero.\");const n=Oo.cume_dist(),r=n.next;return{init:n.init,next:i=>Math.ceil(e*r(i))}},lag:function(t,e){return e=+e||1,{next:n=>{const r=n.index-e;return r>=0?t(n.data[r]):null}}},lead:function(t,e){return e=+e||1,{next:n=>{const r=n.index+e,i=n.data;return rt(e.data[e.i0])}},last_value:function(t){return{next:e=>t(e.data[e.i1-1])}},nth_value:function(t,e){return e=+e,e>0||$(\"nth_value nth must be greater than zero.\"),{next:n=>{const r=n.i0+(e-1);return re=null,next:n=>{const r=t(n.data[n.index]);return r!=null?e=r:e}}},next_value:function(t){let e,n;return{init:()=>(e=null,n=-1),next:r=>{const i=r.data;return r.index<=n?e:(n=tS(t,i,r.index))<0?(n=i.length,e=null):e=t(i[n])}}}};function tS(t,e,n){for(let r=e.length;no[g]=1)}h(t.sort),e.forEach((d,g)=>{const p=n[g],m=$t(p),y=vE(d,m,i[g]);if(h(p),a.push(y),X(Oo,d))u.push(J$(d,n[g],r[g],y));else{if(p==null&&d!==\"count\"&&$(\"Null aggregate field specified.\"),d===\"count\"){l.push(y);return}c=!1;let x=s[m];x||(x=s[m]=[],x.field=p,f.push(x)),x.push(bE(d,y))}}),(l.length||f.length)&&(this.cell=nS(f,l,c)),this.inputs=Object.keys(o)}const YE=WE.prototype;YE.init=function(){this.windows.forEach(t=>t.init()),this.cell&&this.cell.init()};YE.update=function(t,e){const n=this.cell,r=this.windows,i=t.data,a=r&&r.length;let u;if(n){for(u=t.p0;uwE(s,s.field));const r={num:0,agg:null,store:!1,count:e};if(!n)for(var i=t.length,a=r.agg=Array(i),u=0;uthis.group(i(o));let u=this.state;(!u||n)&&(u=this.state=new WE(t)),n||e.modified(u.inputs)?(this.value={},e.visit(e.SOURCE,o=>a(o).add(o))):(e.visit(e.REM,o=>a(o).remove(o)),e.visit(e.ADD,o=>a(o).add(o)));for(let o=0,s=this._mlen;o0&&!i(a[n],a[n-1])&&(t.i0=e.left(a,a[n])),rtypeof Image<\"u\"?Image:null;let qr;try{qr=require(\"canvas\"),qr&&qr.createCanvas||(qr=null)}catch{}function lS(t,e,n){if(qr)try{return new qr.Canvas(t,e,n)}catch{}return null}const fS=()=>qr&&qr.Image||null;function Zr(t,e,n){return oS(t,e)||lS(t,e,n)||null}function cS(){return sS()||fS()||null}function zc(t,e,n){const r=t-e+n*2;return t?r>0?r:1:0}const hS=\"identity\",ja=\"linear\",kr=\"log\",ls=\"pow\",fs=\"sqrt\",Ic=\"symlog\",Yi=\"time\",Hi=\"utc\",Xn=\"sequential\",fu=\"diverging\",Wa=\"quantile\",Uc=\"quantize\",qc=\"threshold\",_p=\"ordinal\",$d=\"point\",HE=\"band\",Cp=\"bin-ordinal\",zt=\"continuous\",cs=\"discrete\",hs=\"discretizing\",vn=\"interpolating\",Dp=\"temporal\";function dS(t){return function(e){let n=e[0],r=e[1],i;return r=r&&n[s]<=i&&(a<0&&(a=s),u=s);if(!(a<0))return r=t.invertExtent(n[a]),i=t.invertExtent(n[u]),[r[0]===void 0?r[1]:r[0],i[1]===void 0?i[0]:i[1]]}}function Fp(){const t=j1().unknown(void 0),e=t.domain,n=t.range;let r=[0,1],i,a,u=!1,o=0,s=0,l=.5;delete t.unknown;function f(){const c=e().length,h=r[1]p+i*y);return n(h?m.reverse():m)}return t.domain=function(c){return arguments.length?(e(c),f()):e()},t.range=function(c){return arguments.length?(r=[+c[0],+c[1]],f()):r.slice()},t.rangeRound=function(c){return r=[+c[0],+c[1]],u=!0,f()},t.bandwidth=function(){return a},t.step=function(){return i},t.round=function(c){return arguments.length?(u=!!c,f()):u},t.padding=function(c){return arguments.length?(s=Math.max(0,Math.min(1,c)),o=s,f()):o},t.paddingInner=function(c){return arguments.length?(o=Math.max(0,Math.min(1,c)),f()):o},t.paddingOuter=function(c){return arguments.length?(s=Math.max(0,Math.min(1,c)),f()):s},t.align=function(c){return arguments.length?(l=Math.max(0,Math.min(1,c)),f()):l},t.invertRange=function(c){if(c[0]==null||c[1]==null)return;const h=r[1]r[1-h])))return y=Math.max(0,ti(d,p)-1),x=p===m?y:ti(d,m)-1,p-d[y]>a+1e-10&&++y,h&&(v=y,y=g-x,x=g-v),y>x?void 0:e().slice(y,x+1)},t.invert=function(c){const h=t.invertRange([c,c]);return h&&h[0]},t.copy=function(){return Fp().domain(e()).range(r).round(u).paddingInner(o).paddingOuter(s).align(l)},f()}function GE(t){const e=t.copy;return t.padding=t.paddingOuter,delete t.paddingInner,t.copy=function(){return GE(e())},t}function pS(){return GE(Fp().paddingInner(1))}var mS=Array.prototype.map;function yS(t){return mS.call(t,Kt)}const xS=Array.prototype.slice;function XE(){let t=[],e=[];function n(r){return r==null||r!==r?void 0:e[(ti(t,r)-1)%e.length]}return n.domain=function(r){return arguments.length?(t=yS(r),n):t.slice()},n.range=function(r){return arguments.length?(e=xS.call(r),n):e.slice()},n.tickFormat=function(r,i){return _w(t[0],ut(t),r??10,i)},n.copy=function(){return XE().domain(n.domain()).range(n.range())},n}const Af=new Map,VE=Symbol(\"vega_scale\");function KE(t){return t[VE]=!0,t}function QE(t){return t&&t[VE]===!0}function vS(t,e,n){const r=function(){const a=e();return a.invertRange||(a.invertRange=a.invert?dS(a):a.invertExtent?gS(a):void 0),a.type=t,KE(a)};return r.metadata=nn(H(n)),r}function ft(t,e,n){return arguments.length>1?(Af.set(t,vS(t,e,n)),this):ZE(t)?Af.get(t):void 0}ft(hS,Dw);ft(ja,Cw,zt);ft(kr,Mw,[zt,kr]);ft(ls,G1,zt);ft(fs,x8,zt);ft(Ic,kw,zt);ft(Yi,T9,[zt,Dp]);ft(Hi,R9,[zt,Dp]);ft(Xn,Z1,[zt,vn]);ft(`${Xn}-${ja}`,Z1,[zt,vn]);ft(`${Xn}-${kr}`,qw,[zt,vn,kr]);ft(`${Xn}-${ls}`,J1,[zt,vn]);ft(`${Xn}-${fs}`,O9,[zt,vn]);ft(`${Xn}-${Ic}`,jw,[zt,vn]);ft(`${fu}-${ja}`,Ww,[zt,vn]);ft(`${fu}-${kr}`,Yw,[zt,vn,kr]);ft(`${fu}-${ls}`,tg,[zt,vn]);ft(`${fu}-${fs}`,N9,[zt,vn]);ft(`${fu}-${Ic}`,Hw,[zt,vn]);ft(Wa,$w,[hs,Wa]);ft(Uc,Sw,hs);ft(qc,Bw,hs);ft(Cp,XE,[cs,hs]);ft(_p,j1,cs);ft(HE,Fp,cs);ft($d,pS,cs);function ZE(t){return Af.has(t)}function ia(t,e){const n=Af.get(t);return n&&n.metadata[e]}function Mp(t){return ia(t,zt)}function Ya(t){return ia(t,cs)}function Sd(t){return ia(t,hs)}function JE(t){return ia(t,kr)}function bS(t){return ia(t,Dp)}function t_(t){return ia(t,vn)}function e_(t){return ia(t,Wa)}const AS=[\"clamp\",\"base\",\"constant\",\"exponent\"];function n_(t,e){const n=e[0],r=ut(e)-n;return function(i){return t(n+i*r)}}function jc(t,e,n){return F1($p(e||\"rgb\",n),t)}function r_(t,e){const n=new Array(e),r=e+1;for(let i=0;it[o]?u[o](t[o]()):0),u)}function $p(t,e){const n=qF[wS(t)];return e!=null&&n&&n.gamma?n.gamma(e):n}function wS(t){return\"interpolate\"+t.toLowerCase().split(\"-\").map(e=>e[0].toUpperCase()+e.slice(1)).join(\"\")}const ES={blues:\"cfe1f2bed8eca8cee58fc1de74b2d75ba3cf4592c63181bd206fb2125ca40a4a90\",greens:\"d3eecdc0e6baabdda594d3917bc77d60ba6c46ab5e329a512089430e7735036429\",greys:\"e2e2e2d4d4d4c4c4c4b1b1b19d9d9d8888887575756262624d4d4d3535351e1e1e\",oranges:\"fdd8b3fdc998fdb87bfda55efc9244f87f2cf06b18e4580bd14904b93d029f3303\",purples:\"e2e1efd4d4e8c4c5e0b4b3d6a3a0cc928ec3827cb97566ae684ea25c3696501f8c\",reds:\"fdc9b4fcb49afc9e80fc8767fa7051f6573fec3f2fdc2a25c81b1db21218970b13\",blueGreen:\"d5efedc1e8e0a7ddd18bd2be70c6a958ba9144ad77319c5d2089460e7736036429\",bluePurple:\"ccddecbad0e4a8c2dd9ab0d4919cc98d85be8b6db28a55a6873c99822287730f71\",greenBlue:\"d3eecec5e8c3b1e1bb9bd8bb82cec269c2ca51b2cd3c9fc7288abd1675b10b60a1\",orangeRed:\"fddcaffdcf9bfdc18afdad77fb9562f67d53ee6545e24932d32d1ebf130da70403\",purpleBlue:\"dbdaebc8cee4b1c3de97b7d87bacd15b9fc93a90c01e7fb70b70ab056199045281\",purpleBlueGreen:\"dbd8eac8cee4b0c3de93b7d872acd1549fc83892bb1c88a3097f8702736b016353\",purpleRed:\"dcc9e2d3b3d7ce9eccd186c0da6bb2e14da0e23189d91e6fc61159ab07498f023a\",redPurple:\"fccfccfcbec0faa9b8f98faff571a5ec539ddb3695c41b8aa908808d0179700174\",yellowGreen:\"e4f4acd1eca0b9e2949ed68880c97c62bb6e47aa5e3297502083440e723b036034\",yellowOrangeBrown:\"feeaa1fedd84fecc63feb746fca031f68921eb7215db5e0bc54c05ab3d038f3204\",yellowOrangeRed:\"fee087fed16ffebd59fea849fd903efc7335f9522bee3423de1b20ca0b22af0225\",blueOrange:\"134b852f78b35da2cb9dcae1d2e5eff2f0ebfce0bafbbf74e8932fc5690d994a07\",brownBlueGreen:\"704108a0651ac79548e3c78af3e6c6eef1eac9e9e48ed1c74da79e187a72025147\",purpleGreen:\"5b1667834792a67fb6c9aed3e6d6e8eff0efd9efd5aedda971bb75368e490e5e29\",purpleOrange:\"4114696647968f83b7b9b4d6dadbebf3eeeafce0bafbbf74e8932fc5690d994a07\",redBlue:\"8c0d25bf363adf745ef4ae91fbdbc9f2efeed2e5ef9dcae15da2cb2f78b3134b85\",redGrey:\"8c0d25bf363adf745ef4ae91fcdccbfaf4f1e2e2e2c0c0c0969696646464343434\",yellowGreenBlue:\"eff9bddbf1b4bde5b594d5b969c5be45b4c22c9ec02182b82163aa23479c1c3185\",redYellowBlue:\"a50026d4322cf16e43fcac64fedd90faf8c1dcf1ecabd6e875abd04a74b4313695\",redYellowGreen:\"a50026d4322cf16e43fcac63fedd8df9f7aed7ee8ea4d86e64bc6122964f006837\",pinkYellowGreen:\"8e0152c0267edd72adf0b3d6faddedf5f3efe1f2cab6de8780bb474f9125276419\",spectral:\"9e0142d13c4bf0704afcac63fedd8dfbf8b0e0f3a1a9dda269bda94288b55e4fa2\",viridis:\"440154470e61481a6c482575472f7d443a834144873d4e8a39568c35608d31688e2d708e2a788e27818e23888e21918d1f988b1fa08822a8842ab07f35b77943bf7154c56866cc5d7ad1518fd744a5db36bcdf27d2e21be9e51afde725\",magma:\"0000040404130b0924150e3720114b2c11603b0f704a107957157e651a80721f817f24828c29819a2e80a8327db6377ac43c75d1426fde4968e95462f1605df76f5cfa7f5efc8f65fe9f6dfeaf78febf84fece91fddea0fcedaffcfdbf\",inferno:\"0000040403130c0826170c3b240c4f330a5f420a68500d6c5d126e6b176e781c6d86216b932667a12b62ae305cbb3755c73e4cd24644dd513ae65c30ed6925f3771af8850ffb9506fca50afcb519fac62df6d645f2e661f3f484fcffa4\",plasma:\"0d088723069033059742039d5002a25d01a66a00a87801a88405a7900da49c179ea72198b12a90ba3488c33d80cb4779d35171da5a69e16462e76e5bed7953f2834cf68f44fa9a3dfca636fdb32ffec029fcce25f9dc24f5ea27f0f921\",cividis:\"00205100235800265d002961012b65042e670831690d346b11366c16396d1c3c6e213f6e26426e2c456e31476e374a6e3c4d6e42506e47536d4c566d51586e555b6e5a5e6e5e616e62646f66676f6a6a706e6d717270717573727976737c79747f7c75827f758682768985778c8877908b78938e789691789a94789e9778a19b78a59e77a9a177aea575b2a874b6ab73bbaf71c0b26fc5b66dc9b96acebd68d3c065d8c462ddc85fe2cb5ce7cf58ebd355f0d652f3da4ff7de4cfae249fce647\",rainbow:\"6e40aa883eb1a43db3bf3cafd83fa4ee4395fe4b83ff576eff6659ff7847ff8c38f3a130e2b72fcfcc36bee044aff05b8ff4576ff65b52f6673af27828ea8d1ddfa319d0b81cbecb23abd82f96e03d82e14c6edb5a5dd0664dbf6e40aa\",sinebow:\"ff4040fc582af47218e78d0bd5a703bfbf00a7d5038de70b72f41858fc2a40ff402afc5818f4720be78d03d5a700bfbf03a7d50b8de71872f42a58fc4040ff582afc7218f48d0be7a703d5bf00bfd503a7e70b8df41872fc2a58ff4040\",turbo:\"23171b32204a3e2a71453493493eae4b49c54a53d7485ee44569ee4074f53c7ff8378af93295f72e9ff42ba9ef28b3e926bce125c5d925cdcf27d5c629dcbc2de3b232e9a738ee9d3ff39347f68950f9805afc7765fd6e70fe667cfd5e88fc5795fb51a1f84badf545b9f140c5ec3cd0e637dae034e4d931ecd12ef4c92bfac029ffb626ffad24ffa223ff9821ff8d1fff821dff771cfd6c1af76118f05616e84b14df4111d5380fcb2f0dc0260ab61f07ac1805a313029b0f00950c00910b00\",browns:\"eedbbdecca96e9b97ae4a865dc9856d18954c7784cc0673fb85536ad44339f3632\",tealBlues:\"bce4d89dd3d181c3cb65b3c245a2b9368fae347da0306a932c5985\",teals:\"bbdfdfa2d4d58ac9c975bcbb61b0af4da5a43799982b8b8c1e7f7f127273006667\",warmGreys:\"dcd4d0cec5c1c0b8b4b3aaa7a59c9998908c8b827f7e7673726866665c5a59504e\",goldGreen:\"f4d166d5ca60b6c35c98bb597cb25760a6564b9c533f8f4f33834a257740146c36\",goldOrange:\"f4d166f8be5cf8aa4cf5983bf3852aef701be2621fd65322c54923b142239e3a26\",goldRed:\"f4d166f6be59f9aa51fc964ef6834bee734ae56249db5247cf4244c43141b71d3e\",lightGreyRed:\"efe9e6e1dad7d5cbc8c8bdb9bbaea9cd967ddc7b43e15f19df4011dc000b\",lightGreyTeal:\"e4eaead6dcddc8ced2b7c2c7a6b4bc64b0bf22a6c32295c11f85be1876bc\",lightMulti:\"e0f1f2c4e9d0b0de9fd0e181f6e072f6c053f3993ef77440ef4a3c\",lightOrange:\"f2e7daf7d5baf9c499fab184fa9c73f68967ef7860e8645bde515bd43d5b\",lightTealBlue:\"e3e9e0c0dccf9aceca7abfc859afc0389fb9328dad2f7ca0276b95255988\",darkBlue:\"3232322d46681a5c930074af008cbf05a7ce25c0dd38daed50f3faffffff\",darkGold:\"3c3c3c584b37725e348c7631ae8b2bcfa424ecc31ef9de30fff184ffffff\",darkGreen:\"3a3a3a215748006f4d048942489e4276b340a6c63dd2d836ffeb2cffffaa\",darkMulti:\"3737371f5287197d8c29a86995ce3fffe800ffffff\",darkRed:\"3434347036339e3c38cc4037e75d1eec8620eeab29f0ce32ffeb2c\"},_S={category10:\"1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf\",category20:\"1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5\",category20b:\"393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6\",category20c:\"3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9\",tableau10:\"4c78a8f58518e4575672b7b254a24beeca3bb279a2ff9da69d755dbab0ac\",tableau20:\"4c78a89ecae9f58518ffbf7954a24b88d27ab79a20f2cf5b43989483bcb6e45756ff9d9879706ebab0acd67195fcbfd2b279a2d6a5c99e765fd8b5a5\",accent:\"7fc97fbeaed4fdc086ffff99386cb0f0027fbf5b17666666\",dark2:\"1b9e77d95f027570b3e7298a66a61ee6ab02a6761d666666\",paired:\"a6cee31f78b4b2df8a33a02cfb9a99e31a1cfdbf6fff7f00cab2d66a3d9affff99b15928\",pastel1:\"fbb4aeb3cde3ccebc5decbe4fed9a6ffffcce5d8bdfddaecf2f2f2\",pastel2:\"b3e2cdfdcdaccbd5e8f4cae4e6f5c9fff2aef1e2cccccccc\",set1:\"e41a1c377eb84daf4a984ea3ff7f00ffff33a65628f781bf999999\",set2:\"66c2a5fc8d628da0cbe78ac3a6d854ffd92fe5c494b3b3b3\",set3:\"8dd3c7ffffb3bebadafb807280b1d3fdb462b3de69fccde5d9d9d9bc80bdccebc5ffed6f\"};function i_(t){const e=t.length/6|0,n=new Array(e);for(let r=0;rjc(i_(t)));function Sp(t,e){return t=t&&t.toLowerCase(),arguments.length>1?(Rx[t]=e,this):Rx[t]}const dl=\"symbol\",CS=\"discrete\",DS=\"gradient\",FS=t=>U(t)?t.map(e=>String(e)):String(t),MS=(t,e)=>t[1]-e[1],kS=(t,e)=>e[1]-t[1];function Bp(t,e,n){let r;return Mr(e)&&(t.bins&&(e=Math.max(e,t.bins.length)),n!=null&&(e=Math.min(e,Math.floor(au(t.domain())/n||1)+1))),et(e)&&(r=e.step,e=e.interval),xt(e)&&(e=t.type===Yi?uu(e):t.type==Hi?ou(e):$(\"Only time and utc scales accept interval strings.\"),r&&(e=e.every(r))),e}function u_(t,e,n){let r=t.range(),i=r[0],a=ut(r),u=MS;if(i>a&&(r=a,a=i,i=r,u=kS),i=Math.floor(i),a=Math.ceil(a),e=e.map(o=>[o,t(o)]).filter(o=>i<=o[1]&&o[1]<=a).sort(u).map(o=>o[0]),n>0&&e.length>1){const o=[e[0],ut(e)];for(;e.length>n&&e.length>=3;)e=e.filter((s,l)=>!(l%2));e.length<3&&(e=o)}return e}function Tp(t,e){return t.bins?u_(t,t.bins):t.ticks?t.ticks(e):t.domain()}function o_(t,e,n,r,i,a){const u=e.type;let o=FS;if(u===Yi||i===Yi)o=t.timeFormat(r);else if(u===Hi||i===Hi)o=t.utcFormat(r);else if(JE(u)){const s=t.formatFloat(r);if(a||e.bins)o=s;else{const l=s_(e,n,!1);o=f=>l(f)?s(f):\"\"}}else if(e.tickFormat){const s=e.domain();o=t.formatSpan(s[0],s[s.length-1],n,r)}else r&&(o=t.format(r));return o}function s_(t,e,n){const r=Tp(t,e),i=t.base(),a=Math.log(i),u=Math.max(1,i*e/r.length),o=s=>{let l=s/Math.pow(i,Math.round(Math.log(s)/a));return l*i1?r[1]-r[0]:r[0],u;for(u=1;uBd[t.type]||t.bins;function c_(t,e,n,r,i,a,u){const o=l_[e.type]&&a!==Yi&&a!==Hi?$S(t,e,i):o_(t,e,n,i,a,u);return r===dl&&TS(e)?RS(o):r===CS?OS(o):NS(o)}const RS=t=>(e,n,r)=>{const i=Ox(r[n+1],Ox(r.max,1/0)),a=Nx(e,t),u=Nx(i,t);return a&&u?a+\" – \"+u:u?\"< \"+u:\"≥ \"+a},Ox=(t,e)=>t??e,OS=t=>(e,n)=>n?t(e):null,NS=t=>e=>t(e),Nx=(t,e)=>Number.isFinite(t)?e(t):null;function LS(t){const e=t.domain(),n=e.length-1;let r=+e[0],i=+ut(e),a=i-r;if(t.type===qc){const u=n?a/n:.1;r-=u,i+=u,a=i-r}return u=>(u-r)/a}function PS(t,e,n,r){const i=r||e.type;return xt(n)&&bS(i)&&(n=n.replace(/%a/g,\"%A\").replace(/%b/g,\"%B\")),!n&&i===Yi?t.timeFormat(\"%A, %d %B %Y, %X\"):!n&&i===Hi?t.utcFormat(\"%A, %d %B %Y, %X UTC\"):c_(t,e,5,null,n,r,!0)}function h_(t,e,n){n=n||{};const r=Math.max(3,n.maxlen||7),i=PS(t,e,n.format,n.formatType);if(Sd(e.type)){const a=f_(e).slice(1).map(i),u=a.length;return`${u} boundar${u===1?\"y\":\"ies\"}: ${a.join(\", \")}`}else if(Ya(e.type)){const a=e.domain(),u=a.length,o=u>r?a.slice(0,r-2).map(i).join(\", \")+\", ending with \"+a.slice(-1).map(i):a.map(i).join(\", \");return`${u} value${u===1?\"\":\"s\"}: ${o}`}else{const a=e.domain();return`values from ${i(a[0])} to ${i(ut(a))}`}}let d_=0;function zS(){d_=0}const wf=\"p_\";function Rp(t){return t&&t.gradient}function g_(t,e,n){const r=t.gradient;let i=t.id,a=r===\"radial\"?wf:\"\";return i||(i=t.id=\"gradient_\"+d_++,r===\"radial\"?(t.x1=In(t.x1,.5),t.y1=In(t.y1,.5),t.r1=In(t.r1,0),t.x2=In(t.x2,.5),t.y2=In(t.y2,.5),t.r2=In(t.r2,.5),a=wf):(t.x1=In(t.x1,0),t.y1=In(t.y1,0),t.x2=In(t.x2,1),t.y2=In(t.y2,0))),e[i]=t,\"url(\"+(n||\"\")+\"#\"+a+i+\")\"}function In(t,e){return t??e}function Op(t,e){var n=[],r;return r={gradient:\"linear\",x1:t?t[0]:0,y1:t?t[1]:0,x2:e?e[0]:1,y2:e?e[1]:0,stops:n,stop:function(i,a){return n.push({offset:i,color:a}),r}}}const Lx={basis:{curve:X9},\"basis-closed\":{curve:V9},\"basis-open\":{curve:K9},bundle:{curve:Q9,tension:\"beta\",value:.85},cardinal:{curve:Z9,tension:\"tension\",value:0},\"cardinal-open\":{curve:t4,tension:\"tension\",value:0},\"cardinal-closed\":{curve:J9,tension:\"tension\",value:0},\"catmull-rom\":{curve:e4,tension:\"alpha\",value:.5},\"catmull-rom-closed\":{curve:n4,tension:\"alpha\",value:.5},\"catmull-rom-open\":{curve:r4,tension:\"alpha\",value:.5},linear:{curve:eg},\"linear-closed\":{curve:i4},monotone:{horizontal:u4,vertical:a4},natural:{curve:o4},step:{curve:s4},\"step-after\":{curve:f4},\"step-before\":{curve:l4}};function Np(t,e,n){var r=X(Lx,t)&&Lx[t],i=null;return r&&(i=r.curve||r[e||\"vertical\"],r.tension&&n!=null&&(i=i[r.tension](n))),i}const IS={m:2,l:2,h:1,v:1,z:0,c:6,s:4,q:4,t:2,a:7},US=/[mlhvzcsqta]([^mlhvzcsqta]+|$)/gi,qS=/^[+-]?(([0-9]*\\.[0-9]+)|([0-9]+\\.)|([0-9]+))([eE][+-]?[0-9]+)?/,jS=/^((\\s+,?\\s*)|(,\\s*))/,WS=/^[01]/;function Gi(t){const e=[];return(t.match(US)||[]).forEach(r=>{let i=r[0];const a=i.toLowerCase(),u=IS[a],o=YS(a,u,r.slice(1).trim()),s=o.length;if(s1&&(p=Math.sqrt(p),n*=p,r*=p);const m=h/n,y=c/n,x=-c/r,v=h/r,b=m*o+y*s,w=x*o+v*s,E=m*t+y*e,A=x*t+v*e;let C=1/((E-b)*(E-b)+(A-w)*(A-w))-.25;C<0&&(C=0);let F=Math.sqrt(C);a==i&&(F=-F);const D=.5*(b+E)-F*(A-w),R=.5*(w+A)+F*(E-b),k=Math.atan2(w-R,b-D);let M=Math.atan2(A-R,E-D)-k;M<0&&a===1?M+=Yn:M>0&&a===0&&(M-=Yn);const O=Math.ceil(Math.abs(M/(Di+.001))),z=[];for(let G=0;G+t}function Ks(t,e,n){return Math.max(e,Math.min(t,n))}function y_(){var t=QS,e=ZS,n=JS,r=tB,i=sr(0),a=i,u=i,o=i,s=null;function l(f,c,h){var d,g=c??+t.call(this,f),p=h??+e.call(this,f),m=+n.call(this,f),y=+r.call(this,f),x=Math.min(m,y)/2,v=Ks(+i.call(this,f),0,x),b=Ks(+a.call(this,f),0,x),w=Ks(+u.call(this,f),0,x),E=Ks(+o.call(this,f),0,x);if(s||(s=d=Vf()),v<=0&&b<=0&&w<=0&&E<=0)s.rect(g,p,m,y);else{var A=g+m,_=p+y;s.moveTo(g+v,p),s.lineTo(A-b,p),s.bezierCurveTo(A-Tr*b,p,A,p+Tr*b,A,p+b),s.lineTo(A,_-E),s.bezierCurveTo(A,_-Tr*E,A-Tr*E,_,A-E,_),s.lineTo(g+w,_),s.bezierCurveTo(g+Tr*w,_,g,_-Tr*w,g,_-w),s.lineTo(g,p+v),s.bezierCurveTo(g,p+Tr*v,g+Tr*v,p,g+v,p),s.closePath()}if(d)return s=null,d+\"\"||null}return l.x=function(f){return arguments.length?(t=sr(f),l):t},l.y=function(f){return arguments.length?(e=sr(f),l):e},l.width=function(f){return arguments.length?(n=sr(f),l):n},l.height=function(f){return arguments.length?(r=sr(f),l):r},l.cornerRadius=function(f,c,h,d){return arguments.length?(i=sr(f),a=c!=null?sr(c):i,o=h!=null?sr(h):i,u=d!=null?sr(d):a,l):i},l.context=function(f){return arguments.length?(s=f??null,l):s},l}function x_(){var t,e,n,r,i=null,a,u,o,s;function l(c,h,d){const g=d/2;if(a){var p=o-h,m=c-u;if(p||m){var y=Math.sqrt(p*p+m*m),x=(p/=y)*s,v=(m/=y)*s,b=Math.atan2(m,p);i.moveTo(u-x,o-v),i.lineTo(c-p*g,h-m*g),i.arc(c,h,g,b-Math.PI,b),i.lineTo(u+x,o+v),i.arc(u,o,s,b,b+Math.PI)}else i.arc(c,h,g,0,Yn);i.closePath()}else a=1;u=c,o=h,s=g}function f(c){var h,d=c.length,g,p=!1,m;for(i==null&&(i=m=Vf()),h=0;h<=d;++h)!(ht.x||0,ps=t=>t.y||0,eB=t=>t.width||0,nB=t=>t.height||0,rB=t=>(t.x||0)+(t.width||0),iB=t=>(t.y||0)+(t.height||0),aB=t=>t.startAngle||0,uB=t=>t.endAngle||0,oB=t=>t.padAngle||0,sB=t=>t.innerRadius||0,lB=t=>t.outerRadius||0,fB=t=>t.cornerRadius||0,cB=t=>ds(t.cornerRadiusTopLeft,t.cornerRadius)||0,hB=t=>ds(t.cornerRadiusTopRight,t.cornerRadius)||0,dB=t=>ds(t.cornerRadiusBottomRight,t.cornerRadius)||0,gB=t=>ds(t.cornerRadiusBottomLeft,t.cornerRadius)||0,pB=t=>ds(t.size,64),mB=t=>t.size||1,Wc=t=>t.defined!==!1,yB=t=>m_(t.shape||\"circle\"),xB=Y9().startAngle(aB).endAngle(uB).padAngle(oB).innerRadius(sB).outerRadius(lB).cornerRadius(fB),vB=Jw().x(gs).y1(ps).y0(iB).defined(Wc),bB=Jw().y(ps).x1(gs).x0(rB).defined(Wc),AB=Zw().x(gs).y(ps).defined(Wc),wB=y_().x(gs).y(ps).width(eB).height(nB).cornerRadius(cB,hB,dB,gB),EB=G9().type(yB).size(pB),_B=x_().x(gs).y(ps).defined(Wc).size(mB);function Lp(t){return t.cornerRadius||t.cornerRadiusTopLeft||t.cornerRadiusTopRight||t.cornerRadiusBottomRight||t.cornerRadiusBottomLeft}function CB(t,e){return xB.context(t)(e)}function DB(t,e){const n=e[0],r=n.interpolate||\"linear\";return(n.orient===\"horizontal\"?bB:vB).curve(Np(r,n.orient,n.tension)).context(t)(e)}function FB(t,e){const n=e[0],r=n.interpolate||\"linear\";return AB.curve(Np(r,n.orient,n.tension)).context(t)(e)}function cu(t,e,n,r){return wB.context(t)(e,n,r)}function MB(t,e){return(e.mark.shape||e.shape).context(t)(e)}function kB(t,e){return EB.context(t)(e)}function $B(t,e){return _B.context(t)(e)}var v_=1;function b_(){v_=1}function Pp(t,e,n){var r=e.clip,i=t._defs,a=e.clip_id||(e.clip_id=\"clip\"+v_++),u=i.clipping[a]||(i.clipping[a]={id:a});return tt(r)?u.path=r(null):Lp(n)?u.path=cu(null,n,0,0):(u.width=n.width||0,u.height=n.height||0),\"url(#\"+a+\")\"}function St(t){this.clear(),t&&this.union(t)}St.prototype={clone(){return new St(this)},clear(){return this.x1=+Number.MAX_VALUE,this.y1=+Number.MAX_VALUE,this.x2=-Number.MAX_VALUE,this.y2=-Number.MAX_VALUE,this},empty(){return this.x1===+Number.MAX_VALUE&&this.y1===+Number.MAX_VALUE&&this.x2===-Number.MAX_VALUE&&this.y2===-Number.MAX_VALUE},equals(t){return this.x1===t.x1&&this.y1===t.y1&&this.x2===t.x2&&this.y2===t.y2},set(t,e,n,r){return nthis.x2&&(this.x2=t),e>this.y2&&(this.y2=e),this},expand(t){return this.x1-=t,this.y1-=t,this.x2+=t,this.y2+=t,this},round(){return this.x1=Math.floor(this.x1),this.y1=Math.floor(this.y1),this.x2=Math.ceil(this.x2),this.y2=Math.ceil(this.y2),this},scale(t){return this.x1*=t,this.y1*=t,this.x2*=t,this.y2*=t,this},translate(t,e){return this.x1+=t,this.x2+=t,this.y1+=e,this.y2+=e,this},rotate(t,e,n){const r=this.rotatedPoints(t,e,n);return this.clear().add(r[0],r[1]).add(r[2],r[3]).add(r[4],r[5]).add(r[6],r[7])},rotatedPoints(t,e,n){var{x1:r,y1:i,x2:a,y2:u}=this,o=Math.cos(t),s=Math.sin(t),l=e-e*o+n*s,f=n-e*s-n*o;return[o*r-s*i+l,s*r+o*i+f,o*r-s*u+l,s*r+o*u+f,o*a-s*i+l,s*a+o*i+f,o*a-s*u+l,s*a+o*u+f]},union(t){return t.x1this.x2&&(this.x2=t.x2),t.y2>this.y2&&(this.y2=t.y2),this},intersect(t){return t.x1>this.x1&&(this.x1=t.x1),t.y1>this.y1&&(this.y1=t.y1),t.x2=t.x2&&this.y1<=t.y1&&this.y2>=t.y2},alignsWith(t){return t&&(this.x1==t.x1||this.x2==t.x2||this.y1==t.y1||this.y2==t.y2)},intersects(t){return t&&!(this.x2t.x2||this.y2t.y2)},contains(t,e){return!(tthis.x2||ethis.y2)},width(){return this.x2-this.x1},height(){return this.y2-this.y1}};function Yc(t){this.mark=t,this.bounds=this.bounds||new St}function Hc(t){Yc.call(this,t),this.items=this.items||[]}L(Hc,Yc);function zp(t){this._pending=0,this._loader=t||wc()}function Ux(t){t._pending+=1}function $u(t){t._pending-=1}zp.prototype={pending(){return this._pending},sanitizeURL(t){const e=this;return Ux(e),e._loader.sanitize(t,{context:\"href\"}).then(n=>($u(e),n)).catch(()=>($u(e),null))},loadImage(t){const e=this,n=cS();return Ux(e),e._loader.sanitize(t,{context:\"image\"}).then(r=>{const i=r.href;if(!i||!n)throw{url:i};const a=new n,u=X(r,\"crossOrigin\")?r.crossOrigin:\"anonymous\";return u!=null&&(a.crossOrigin=u),a.onload=()=>$u(e),a.onerror=()=>$u(e),a.src=i,a}).catch(r=>($u(e),{complete:!1,width:0,height:0,src:r&&r.url||\"\"}))},ready(){const t=this;return new Promise(e=>{function n(r){t.pending()?setTimeout(()=>{n(!0)},10):e(r)}n(!1)})}};function $r(t,e,n){if(e.stroke&&e.opacity!==0&&e.strokeOpacity!==0){const r=e.strokeWidth!=null?+e.strokeWidth:1;t.expand(r+(n?SB(e,r):0))}return t}function SB(t,e){return t.strokeJoin&&t.strokeJoin!==\"miter\"?0:e}const BB=Yn-1e-8;let Gc,gl,pl,Ti,Td,ml,Rd,Od;const jr=(t,e)=>Gc.add(t,e),yl=(t,e)=>jr(gl=t,pl=e),qx=t=>jr(t,Gc.y1),jx=t=>jr(Gc.x1,t),Fi=(t,e)=>Td*t+Rd*e,Mi=(t,e)=>ml*t+Od*e,i0=(t,e)=>jr(Fi(t,e),Mi(t,e)),a0=(t,e)=>yl(Fi(t,e),Mi(t,e));function ms(t,e){return Gc=t,e?(Ti=e*ii,Td=Od=Math.cos(Ti),ml=Math.sin(Ti),Rd=-ml):(Td=Od=1,Ti=ml=Rd=0),TB}const TB={beginPath(){},closePath(){},moveTo:a0,lineTo:a0,rect(t,e,n,r){Ti?(i0(t+n,e),i0(t+n,e+r),i0(t,e+r),a0(t,e)):(jr(t+n,e+r),yl(t,e))},quadraticCurveTo(t,e,n,r){const i=Fi(t,e),a=Mi(t,e),u=Fi(n,r),o=Mi(n,r);Wx(gl,i,u,qx),Wx(pl,a,o,jx),yl(u,o)},bezierCurveTo(t,e,n,r,i,a){const u=Fi(t,e),o=Mi(t,e),s=Fi(n,r),l=Mi(n,r),f=Fi(i,a),c=Mi(i,a);Yx(gl,u,s,f,qx),Yx(pl,o,l,c,jx),yl(f,c)},arc(t,e,n,r,i,a){if(r+=Ti,i+=Ti,gl=n*Math.cos(i)+t,pl=n*Math.sin(i)+e,Math.abs(i-r)>BB)jr(t-n,e-n),jr(t+n,e+n);else{const u=l=>jr(n*Math.cos(l)+t,n*Math.sin(l)+e);let o,s;if(u(r),u(i),i!==r)if(r=r%Yn,r<0&&(r+=Yn),i=i%Yn,i<0&&(i+=Yn),ii;++s,o-=Di)u(o);else for(o=r-r%Di+Di,s=0;s<4&&oHS?(f=u*u+o*a,f>=0&&(f=Math.sqrt(f),s=(-u+f)/a,l=(-u-f)/a)):s=.5*o/u,0h)return!1;p>c&&(c=p)}else if(d>0){if(p0?(t.globalAlpha=n,t.fillStyle=E_(t,e,e.fill),!0):!1}var OB=[];function Xa(t,e,n){var r=(r=e.strokeWidth)!=null?r:1;return r<=0?!1:(n*=e.strokeOpacity==null?1:e.strokeOpacity,n>0?(t.globalAlpha=n,t.strokeStyle=E_(t,e,e.stroke),t.lineWidth=r,t.lineCap=e.strokeCap||\"butt\",t.lineJoin=e.strokeJoin||\"miter\",t.miterLimit=e.strokeMiterLimit||10,t.setLineDash&&(t.setLineDash(e.strokeDash||OB),t.lineDashOffset=e.strokeDashOffset||0),!0):!1)}function NB(t,e){return t.zindex-e.zindex||t.index-e.index}function qp(t){if(!t.zdirty)return t.zitems;var e=t.items,n=[],r,i,a;for(i=0,a=e.length;i=0;)if(r=e(n[i]))return r;if(n===a){for(n=t.items,i=n.length;--i>=0;)if(!n[i].zindex&&(r=e(n[i])))return r}return null}function jp(t){return function(e,n,r){Tn(n,i=>{(!r||r.intersects(i.bounds))&&__(t,e,i,i)})}}function LB(t){return function(e,n,r){n.items.length&&(!r||r.intersects(n.bounds))&&__(t,e,n.items[0],n.items)}}function __(t,e,n,r){var i=n.opacity==null?1:n.opacity;i!==0&&(t(e,r)||(Ga(e,n),n.fill&&Ef(e,n,i)&&e.fill(),n.stroke&&Xa(e,n,i)&&e.stroke()))}function Xc(t){return t=t||We,function(e,n,r,i,a,u){return r*=e.pixelRatio,i*=e.pixelRatio,_f(n,o=>{const s=o.bounds;if(!(s&&!s.contains(a,u)||!s)&&t(e,o,r,i,a,u))return o})}}function ys(t,e){return function(n,r,i,a){var u=Array.isArray(r)?r[0]:r,o=e??u.fill,s=u.stroke&&n.isPointInStroke,l,f;return s&&(l=u.strokeWidth,f=u.strokeCap,n.lineWidth=l??1,n.lineCap=f??\"butt\"),t(n,r)?!1:o&&n.isPointInPath(i,a)||s&&n.isPointInStroke(i,a)}}function Wp(t){return Xc(ys(t))}function Pi(t,e){return\"translate(\"+t+\",\"+e+\")\"}function Yp(t){return\"rotate(\"+t+\")\"}function PB(t,e){return\"scale(\"+t+\",\"+e+\")\"}function C_(t){return Pi(t.x||0,t.y||0)}function zB(t){return Pi(t.x||0,t.y||0)+(t.angle?\" \"+Yp(t.angle):\"\")}function IB(t){return Pi(t.x||0,t.y||0)+(t.angle?\" \"+Yp(t.angle):\"\")+(t.scaleX||t.scaleY?\" \"+PB(t.scaleX||1,t.scaleY||1):\"\")}function Hp(t,e,n){function r(u,o){u(\"transform\",zB(o)),u(\"d\",e(null,o))}function i(u,o){return e(ms(u,o.angle),o),$r(u,o).translate(o.x||0,o.y||0)}function a(u,o){var s=o.x||0,l=o.y||0,f=o.angle||0;u.translate(s,l),f&&u.rotate(f*=ii),u.beginPath(),e(u,o),f&&u.rotate(-f),u.translate(-s,-l)}return{type:t,tag:\"path\",nested:!1,attr:r,bound:i,draw:jp(a),pick:Wp(a),isect:n||Ip(a)}}var UB=Hp(\"arc\",CB);function qB(t,e){for(var n=t[0].orient===\"horizontal\"?e[1]:e[0],r=t[0].orient===\"horizontal\"?\"y\":\"x\",i=t.length,a=1/0,u,o;--i>=0;)t[i].defined!==!1&&(o=Math.abs(t[i][r]-n),o=0;)if(t[r].defined!==!1&&(i=t[r].x-e[0],a=t[r].y-e[1],u=i*i+a*a,u=0;)if(t[n].defined!==!1&&(r=t[n].x-e[0],i=t[n].y-e[1],a=r*r+i*i,r=t[n].size||1,a.5&&e<1.5?.5-Math.abs(e-1):0}function GB(t,e){t(\"transform\",C_(e))}function M_(t,e){const n=F_(e);t(\"d\",cu(null,e,n,n))}function XB(t,e){t(\"class\",\"background\"),t(\"aria-hidden\",!0),M_(t,e)}function VB(t,e){t(\"class\",\"foreground\"),t(\"aria-hidden\",!0),e.strokeForeground?M_(t,e):t(\"d\",\"\")}function KB(t,e,n){const r=e.clip?Pp(n,e,e):null;t(\"clip-path\",r)}function QB(t,e){if(!e.clip&&e.items){const n=e.items,r=n.length;for(let i=0;i{const i=r.x||0,a=r.y||0,u=r.strokeForeground,o=r.opacity==null?1:r.opacity;(r.stroke||r.fill)&&o&&(No(t,r,i,a),Ga(t,r),r.fill&&Ef(t,r,o)&&t.fill(),r.stroke&&!u&&Xa(t,r,o)&&t.stroke()),t.save(),t.translate(i,a),r.clip&&D_(t,r),n&&n.translate(-i,-a),Tn(r,s=>{this.draw(t,s,n)}),n&&n.translate(i,a),t.restore(),u&&r.stroke&&o&&(No(t,r,i,a),Ga(t,r),Xa(t,r,o)&&t.stroke())})}function nT(t,e,n,r,i,a){if(e.bounds&&!e.bounds.contains(i,a)||!e.items)return null;const u=n*t.pixelRatio,o=r*t.pixelRatio;return _f(e,s=>{let l,f,c;const h=s.bounds;if(h&&!h.contains(i,a))return;f=s.x||0,c=s.y||0;const d=f+(s.width||0),g=c+(s.height||0),p=s.clip;if(p&&(id||ag))return;if(t.save(),t.translate(f,c),f=i-f,c=a-c,p&&Lp(s)&&!tT(t,s,u,o))return t.restore(),null;const m=s.strokeForeground,y=e.interactive!==!1;return y&&m&&s.stroke&&JB(t,s,u,o)?(t.restore(),s):(l=_f(s,x=>rT(x,f,c)?this.pick(x,n,r,f,c):null),!l&&y&&(s.fill||!m&&s.stroke)&&ZB(t,s,u,o)&&(l=s),t.restore(),l||null)})}function rT(t,e,n){return(t.interactive!==!1||t.marktype===\"group\")&&t.bounds&&t.bounds.contains(e,n)}var iT={type:\"group\",tag:\"g\",nested:!1,attr:GB,bound:QB,draw:eT,pick:nT,isect:A_,content:KB,background:XB,foreground:VB},Lo={xmlns:\"http://www.w3.org/2000/svg\",\"xmlns:xlink\":\"http://www.w3.org/1999/xlink\",version:\"1.1\"};function Xp(t,e){var n=t.image;return(!n||t.url&&t.url!==n.url)&&(n={complete:!1,width:0,height:0},e.loadImage(t.url).then(r=>{t.image=r,t.image.url=t.url})),n}function Vp(t,e){return t.width!=null?t.width:!e||!e.width?0:t.aspect!==!1&&t.height?t.height*e.width/e.height:e.width}function Kp(t,e){return t.height!=null?t.height:!e||!e.height?0:t.aspect!==!1&&t.width?t.width*e.height/e.width:e.height}function Vc(t,e){return t===\"center\"?e/2:t===\"right\"?e:0}function Kc(t,e){return t===\"middle\"?e/2:t===\"bottom\"?e:0}function aT(t,e,n){const r=Xp(e,n),i=Vp(e,r),a=Kp(e,r),u=(e.x||0)-Vc(e.align,i),o=(e.y||0)-Kc(e.baseline,a),s=!r.src&&r.toDataURL?r.toDataURL():r.src||\"\";t(\"href\",s,Lo[\"xmlns:xlink\"],\"xlink:href\"),t(\"transform\",Pi(u,o)),t(\"width\",i),t(\"height\",a),t(\"preserveAspectRatio\",e.aspect===!1?\"none\":\"xMidYMid\")}function uT(t,e){const n=e.image,r=Vp(e,n),i=Kp(e,n),a=(e.x||0)-Vc(e.align,r),u=(e.y||0)-Kc(e.baseline,i);return t.set(a,u,a+r,u+i)}function oT(t,e,n){Tn(e,r=>{if(n&&!n.intersects(r.bounds))return;const i=Xp(r,this);let a=Vp(r,i),u=Kp(r,i);if(a===0||u===0)return;let o=(r.x||0)-Vc(r.align,a),s=(r.y||0)-Kc(r.baseline,u),l,f,c,h;r.aspect!==!1&&(f=i.width/i.height,c=r.width/r.height,f===f&&c===c&&f!==c&&(c{if(!(n&&!n.intersects(r.bounds))){var i=r.opacity==null?1:r.opacity;i&&k_(t,r,i)&&(Ga(t,r),t.stroke())}})}function vT(t,e,n,r){return t.isPointInStroke?k_(t,e,1)&&t.isPointInStroke(n,r):!1}var bT={type:\"rule\",tag:\"line\",nested:!1,attr:mT,bound:yT,draw:xT,pick:Xc(vT),isect:w_},AT=Hp(\"shape\",MB),wT=Hp(\"symbol\",kB,Up);const Vx=D3();var kn={height:rr,measureWidth:Qp,estimateWidth:Ld,width:Ld,canvas:$_};$_(!0);function $_(t){kn.width=t&&Jr?Qp:Ld}function Ld(t,e){return S_(ui(t,e),rr(t))}function S_(t,e){return~~(.8*t.length*e)}function Qp(t,e){return rr(t)<=0||!(e=ui(t,e))?0:B_(e,Qc(t))}function B_(t,e){const n=`(${e}) ${t}`;let r=Vx.get(n);return r===void 0&&(Jr.font=e,r=Jr.measureText(t).width,Vx.set(n,r)),r}function rr(t){return t.fontSize!=null?+t.fontSize||0:11}function ai(t){return t.lineHeight!=null?t.lineHeight:rr(t)+2}function ET(t){return U(t)?t.length>1?t:t[0]:t}function xs(t){return ET(t.lineBreak&&t.text&&!U(t.text)?t.text.split(t.lineBreak):t.text)}function Zp(t){const e=xs(t);return(U(e)?e.length-1:0)*ai(t)}function ui(t,e){const n=e==null?\"\":(e+\"\").trim();return t.limit>0&&n.length?CT(t,n):n}function _T(t){if(kn.width===Qp){const e=Qc(t);return n=>B_(n,e)}else{const e=rr(t);return n=>S_(n,e)}}function CT(t,e){var n=+t.limit,r=_T(t);if(r(e)>>1,r(e.slice(s))>n?u=s+1:o=s;return i+e.slice(u)}else{for(;u>>1),r(e.slice(0,s))Math.max(h,kn.width(e,d)),0)):c=kn.width(e,f),i===\"center\"?s-=c/2:i===\"right\"&&(s-=c),t.set(s+=u,l+=o,s+c,l+r),e.angle&&!n)t.rotate(e.angle*ii,u,o);else if(n===2)return t.rotatedPoints(e.angle*ii,u,o);return t}function MT(t,e,n){Tn(e,r=>{var i=r.opacity==null?1:r.opacity,a,u,o,s,l,f,c;if(!(n&&!n.intersects(r.bounds)||i===0||r.fontSize<=0||r.text==null||r.text.length===0)){if(t.font=Qc(r),t.textAlign=r.align||\"left\",a=Zc(r),u=a.x1,o=a.y1,r.angle&&(t.save(),t.translate(u,o),t.rotate(r.angle*ii),u=o=0),u+=r.dx||0,o+=(r.dy||0)+Jp(r),f=xs(r),Ga(t,r),U(f))for(l=ai(r),s=0;se;)t.removeChild(n[--r]);return t}function P_(t){return\"mark-\"+t.marktype+(t.role?\" role-\"+t.role:\"\")+(t.name?\" \"+t.name:\"\")}function Jc(t,e){const n=e.getBoundingClientRect();return[t.clientX-n.left-(e.clientLeft||0),t.clientY-n.top-(e.clientTop||0)]}function RT(t,e,n,r){var i=t&&t.mark,a,u;if(i&&(a=on[i.marktype]).tip){for(u=Jc(e,n),u[0]-=r[0],u[1]-=r[1];t=t.mark.group;)u[0]-=t.x||0,u[1]-=t.y||0;t=a.tip(i.items,u)}return t}function oi(t,e){this._active=null,this._handlers={},this._loader=t||wc(),this._tooltip=e||OT}function OT(t,e,n,r){t.element().setAttribute(\"title\",r||\"\")}oi.prototype={initialize(t,e,n){return this._el=t,this._obj=n||null,this.origin(e)},element(){return this._el},canvas(){return this._el&&this._el.firstChild},origin(t){return arguments.length?(this._origin=t||[0,0],this):this._origin.slice()},scene(t){return arguments.length?(this._scene=t,this):this._scene},on(){},off(){},_handlerIndex(t,e,n){for(let r=t?t.length:0;--r>=0;)if(t[r].type===e&&(!n||t[r].handler===n))return r;return-1},handlers(t){const e=this._handlers,n=[];if(t)n.push(...e[this.eventName(t)]);else for(const r in e)n.push(...e[r]);return n},eventName(t){const e=t.indexOf(\".\");return e<0?t:t.slice(0,e)},handleHref(t,e,n){this._loader.sanitize(n,{context:\"href\"}).then(r=>{const i=new MouseEvent(t.type,t),a=Wr(null,\"a\");for(const u in r)a.setAttribute(u,r[u]);a.dispatchEvent(i)}).catch(()=>{})},handleTooltip(t,e,n){if(e&&e.tooltip!=null){e=RT(e,t,this.canvas(),this._origin);const r=n&&e&&e.tooltip||null;this._tooltip.call(this._obj,this,t,e,r)}},getItemBoundingClientRect(t){const e=this.canvas();if(!e)return;const n=e.getBoundingClientRect(),r=this._origin,i=t.bounds,a=i.width(),u=i.height();let o=i.x1+r[0]+n.left,s=i.y1+r[1]+n.top;for(;t.mark&&(t=t.mark.group);)o+=t.x||0,s+=t.y||0;return{x:o,y:s,width:a,height:u,left:o,top:s,right:o+a,bottom:s+u}}};function ir(t){this._el=null,this._bgcolor=null,this._loader=new zp(t)}ir.prototype={initialize(t,e,n,r,i){return this._el=t,this.resize(e,n,r,i)},element(){return this._el},canvas(){return this._el&&this._el.firstChild},background(t){return arguments.length===0?this._bgcolor:(this._bgcolor=t,this)},resize(t,e,n,r){return this._width=t,this._height=e,this._origin=n||[0,0],this._scale=r||1,this},dirty(){},render(t){const e=this;return e._call=function(){e._render(t)},e._call(),e._call=null,e},_render(){},renderAsync(t){const e=this.render(t);return this._ready?this._ready.then(()=>e):Promise.resolve(e)},_load(t,e){var n=this,r=n._loader[t](e);if(!n._ready){const i=n._call;n._ready=n._loader.ready().then(a=>{a&&i(),n._ready=null})}return r},sanitizeURL(t){return this._load(\"sanitizeURL\",t)},loadImage(t){return this._load(\"loadImage\",t)}};const NT=\"keydown\",LT=\"keypress\",PT=\"keyup\",z_=\"dragenter\",vl=\"dragleave\",I_=\"dragover\",zd=\"mousedown\",zT=\"mouseup\",Cf=\"mousemove\",ho=\"mouseout\",U_=\"mouseover\",Df=\"click\",IT=\"dblclick\",UT=\"wheel\",q_=\"mousewheel\",Ff=\"touchstart\",Mf=\"touchmove\",kf=\"touchend\",qT=[NT,LT,PT,z_,vl,I_,zd,zT,Cf,ho,U_,Df,IT,UT,q_,Ff,Mf,kf],Id=Cf,Po=ho,Ud=Df;function bs(t,e){oi.call(this,t,e),this._down=null,this._touch=null,this._first=!0,this._events={}}const jT=t=>t===Ff||t===Mf||t===kf?[Ff,Mf,kf]:[t];function Qx(t,e){jT(e).forEach(n=>WT(t,n))}function WT(t,e){const n=t.canvas();n&&!t._events[e]&&(t._events[e]=1,n.addEventListener(e,t[e]?r=>t[e](r):r=>t.fire(e,r)))}function Zx(t,e,n){return function(r){const i=this._active,a=this.pickEvent(r);a===i?this.fire(t,r):((!i||!i.exit)&&this.fire(n,r),this._active=a,this.fire(e,r),this.fire(t,r))}}function Jx(t){return function(e){this.fire(t,e),this._active=null}}L(bs,oi,{initialize(t,e,n){return this._canvas=t&&nm(t,\"canvas\"),[Df,zd,Cf,ho,vl].forEach(r=>Qx(this,r)),oi.prototype.initialize.call(this,t,e,n)},canvas(){return this._canvas},context(){return this._canvas.getContext(\"2d\")},events:qT,DOMMouseScroll(t){this.fire(q_,t)},mousemove:Zx(Cf,U_,ho),dragover:Zx(I_,z_,vl),mouseout:Jx(ho),dragleave:Jx(vl),mousedown(t){this._down=this._active,this.fire(zd,t)},click(t){this._down===this._active&&(this.fire(Df,t),this._down=null)},touchstart(t){this._touch=this.pickEvent(t.changedTouches[0]),this._first&&(this._active=this._touch,this._first=!1),this.fire(Ff,t,!0)},touchmove(t){this.fire(Mf,t,!0)},touchend(t){this.fire(kf,t,!0),this._touch=null},fire(t,e,n){const r=n?this._touch:this._active,i=this._handlers[t];if(e.vegaType=t,t===Ud&&r&&r.href?this.handleHref(e,r,r.href):(t===Id||t===Po)&&this.handleTooltip(e,r,t!==Po),i)for(let a=0,u=i.length;a=0&&r.splice(i,1),this},pickEvent(t){const e=Jc(t,this._canvas),n=this._origin;return this.pick(this._scene,e[0],e[1],e[0]-n[0],e[1]-n[1])},pick(t,e,n,r,i){const a=this.context();return on[t.marktype].pick.call(this,a,t,e,n,r,i)}});function YT(){return typeof window<\"u\"&&window.devicePixelRatio||1}var HT=YT();function GT(t,e,n,r,i,a){const u=typeof HTMLElement<\"u\"&&t instanceof HTMLElement&&t.parentNode!=null,o=t.getContext(\"2d\"),s=u?HT:i;t.width=e*s,t.height=n*s;for(const l in a)o[l]=a[l];return u&&s!==1&&(t.style.width=e+\"px\",t.style.height=n+\"px\"),o.pixelRatio=s,o.setTransform(s,0,0,s,s*r[0],s*r[1]),t}function $f(t){ir.call(this,t),this._options={},this._redraw=!1,this._dirty=new St,this._tempb=new St}const tv=ir.prototype,XT=(t,e,n)=>new St().set(0,0,e,n).translate(-t[0],-t[1]);function VT(t,e,n){return e.expand(1).round(),t.pixelRatio%1&&e.scale(t.pixelRatio).round().scale(1/t.pixelRatio),e.translate(-(n[0]%1),-(n[1]%1)),t.beginPath(),t.rect(e.x1,e.y1,e.width(),e.height()),t.clip(),e}L($f,ir,{initialize(t,e,n,r,i,a){return this._options=a||{},this._canvas=this._options.externalContext?null:Zr(1,1,this._options.type),t&&this._canvas&&(Cn(t,0).appendChild(this._canvas),this._canvas.setAttribute(\"class\",\"marks\")),tv.initialize.call(this,t,e,n,r,i)},resize(t,e,n,r){if(tv.resize.call(this,t,e,n,r),this._canvas)GT(this._canvas,this._width,this._height,this._origin,this._scale,this._options.context);else{const i=this._options.externalContext;i||$(\"CanvasRenderer is missing a valid canvas or context\"),i.scale(this._scale,this._scale),i.translate(this._origin[0],this._origin[1])}return this._redraw=!0,this},canvas(){return this._canvas},context(){return this._options.externalContext||(this._canvas?this._canvas.getContext(\"2d\"):null)},dirty(t){const e=this._tempb.clear().union(t.bounds);let n=t.mark.group;for(;n;)e.translate(n.x||0,n.y||0),n=n.mark.group;this._dirty.union(e)},_render(t){const e=this.context(),n=this._origin,r=this._width,i=this._height,a=this._dirty,u=XT(n,r,i);e.save();const o=this._redraw||a.empty()?(this._redraw=!1,u.expand(1)):VT(e,u.intersect(a),n);return this.clear(-n[0],-n[1],r,i),this.draw(e,t,o),e.restore(),a.clear(),this},draw(t,e,n){const r=on[e.marktype];e.clip&&HB(t,e),r.draw.call(this,t,e,n),e.clip&&t.restore()},clear(t,e,n,r){const i=this._options,a=this.context();i.type!==\"pdf\"&&!i.externalContext&&a.clearRect(t,e,n,r),this._bgcolor!=null&&(a.fillStyle=this._bgcolor,a.fillRect(t,e,n,r))}});function rm(t,e){oi.call(this,t,e);const n=this;n._hrefHandler=qd(n,(r,i)=>{i&&i.href&&n.handleHref(r,i,i.href)}),n._tooltipHandler=qd(n,(r,i)=>{n.handleTooltip(r,i,r.type!==Po)})}const qd=(t,e)=>n=>{let r=n.target.__data__;r=Array.isArray(r)?r[0]:r,n.vegaType=n.type,e.call(t._obj,n,r)};L(rm,oi,{initialize(t,e,n){let r=this._svg;return r&&(r.removeEventListener(Ud,this._hrefHandler),r.removeEventListener(Id,this._tooltipHandler),r.removeEventListener(Po,this._tooltipHandler)),this._svg=r=t&&nm(t,\"svg\"),r&&(r.addEventListener(Ud,this._hrefHandler),r.addEventListener(Id,this._tooltipHandler),r.addEventListener(Po,this._tooltipHandler)),oi.prototype.initialize.call(this,t,e,n)},canvas(){return this._svg},on(t,e){const n=this.eventName(t),r=this._handlers;if(this._handlerIndex(r[n],t,e)<0){const a={type:t,handler:e,listener:qd(this,e)};(r[n]||(r[n]=[])).push(a),this._svg&&this._svg.addEventListener(n,a.listener)}return this},off(t,e){const n=this.eventName(t),r=this._handlers[n],i=this._handlerIndex(r,t,e);return i>=0&&(this._svg&&this._svg.removeEventListener(n,r[i].listener),r.splice(i,1)),this}});const j_=\"aria-hidden\",im=\"aria-label\",am=\"role\",um=\"aria-roledescription\",W_=\"graphics-object\",om=\"graphics-symbol\",Y_=(t,e,n)=>({[am]:t,[um]:e,[im]:n||void 0}),KT=nn([\"axis-domain\",\"axis-grid\",\"axis-label\",\"axis-tick\",\"axis-title\",\"legend-band\",\"legend-entry\",\"legend-gradient\",\"legend-label\",\"legend-title\",\"legend-symbol\",\"title\"]),ev={axis:{desc:\"axis\",caption:JT},legend:{desc:\"legend\",caption:tR},\"title-text\":{desc:\"title\",caption:t=>`Title text '${rv(t)}'`},\"title-subtitle\":{desc:\"subtitle\",caption:t=>`Subtitle text '${rv(t)}'`}},nv={ariaRole:am,ariaRoleDescription:um,description:im};function H_(t,e){const n=e.aria===!1;if(t(j_,n||void 0),n||e.description==null)for(const r in nv)t(nv[r],void 0);else{const r=e.mark.marktype;t(im,e.description),t(am,e.ariaRole||(r===\"group\"?W_:om)),t(um,e.ariaRoleDescription||`${r} mark`)}}function G_(t){return t.aria===!1?{[j_]:!0}:KT[t.role]?null:ev[t.role]?ZT(t,ev[t.role]):QT(t)}function QT(t){const e=t.marktype,n=e===\"group\"||e===\"text\"||t.items.some(r=>r.description!=null&&r.aria!==!1);return Y_(n?W_:om,`${e} mark container`,t.description)}function ZT(t,e){try{const n=t.items[0],r=e.caption||(()=>\"\");return Y_(e.role||om,e.desc,n.description||r(n))}catch{return null}}function rv(t){return H(t.text).join(\" \")}function JT(t){const e=t.datum,n=t.orient,r=e.title?X_(t):null,i=t.context,a=i.scales[e.scale].value,u=i.dataflow.locale(),o=a.type;return`${n===\"left\"||n===\"right\"?\"Y\":\"X\"}-axis`+(r?` titled '${r}'`:\"\")+` for a ${Ya(o)?\"discrete\":o} scale with ${h_(u,a,t)}`}function tR(t){const e=t.datum,n=e.title?X_(t):null,r=`${e.type||\"\"} legend`.trim(),i=e.scales,a=Object.keys(i),u=t.context,o=u.scales[i[a[0]]].value,s=u.dataflow.locale();return nR(r)+(n?` titled '${n}'`:\"\")+` for ${eR(a)} with ${h_(s,o,t)}`}function X_(t){try{return H(ut(t.items).items[0].text).join(\" \")}catch{return null}}function eR(t){return t=t.map(e=>e+(e===\"fill\"||e===\"stroke\"?\" color\":\"\")),t.length<2?t[0]:t.slice(0,-1).join(\", \")+\" and \"+ut(t)}function nR(t){return t.length?t[0].toUpperCase()+t.slice(1):t}const V_=t=>(t+\"\").replace(/&/g,\"&\").replace(//g,\">\"),rR=t=>V_(t).replace(/\"/g,\""\").replace(/\\t/g,\" \").replace(/\\n/g,\" \").replace(/\\r/g,\" \");function sm(){let t=\"\",e=\"\",n=\"\";const r=[],i=()=>e=n=\"\",a=s=>{e&&(t+=`${e}>${n}`,i()),r.push(s)},u=(s,l)=>(l!=null&&(e+=` ${s}=\"${rR(l)}\"`),o),o={open(s){a(s),e=\"<\"+s;for(var l=arguments.length,f=new Array(l>1?l-1:0),c=1;c${n}`:\"/>\"):t+=``,i(),o},attr:u,text:s=>(n+=V_(s),o),toString:()=>t};return o}const K_=t=>Q_(sm(),t)+\"\";function Q_(t,e){if(t.open(e.tagName),e.hasAttributes()){const n=e.attributes,r=n.length;for(let i=0;i{l.dirty=e})),!r.zdirty){if(n.exit){a.nested&&r.items.length?(s=r.items[0],s._svg&&this._update(a,s._svg,s)):n._svg&&(s=n._svg.parentNode,s&&s.removeChild(n._svg)),n._svg=null;continue}n=a.nested?r.items[0]:n,n._update!==e&&(!n._svg||!n._svg.ownerSVGElement?(this._dirtyAll=!1,av(n,e)):this._update(a,n._svg,n),n._update=e)}return!this._dirtyAll},mark(t,e,n){if(!this.isDirty(e))return e._svg;const r=this._svg,i=on[e.marktype],a=e.interactive===!1?\"none\":null,u=i.tag===\"g\",o=uv(e,t,n,\"g\",r);o.setAttribute(\"class\",P_(e));const s=G_(e);for(const h in s)ve(o,h,s[h]);u||ve(o,\"pointer-events\",a),ve(o,\"clip-path\",e.clip?Pp(this,e,e.group):null);let l=null,f=0;const c=h=>{const d=this.isDirty(h),g=uv(h,o,l,i.tag,r);d&&(this._update(i,g,h),u&&uR(this,g,h)),l=g,++f};return i.nested?e.items.length&&c(e.items[0]):Tn(e,c),Cn(o,f),o},_update(t,e,n){Ar=e,ue=e.__values__,H_(go,n),t.attr(go,n,this);const r=sR[t.type];r&&r.call(this,t,e,n),Ar&&this.style(Ar,n)},style(t,e){if(e!=null){for(const n in Sf){let r=n===\"font\"?vs(e):e[n];if(r===ue[n])continue;const i=Sf[n];r==null?t.removeAttribute(i):(Rp(r)&&(r=g_(r,this._defs.gradient,J_())),t.setAttribute(i,r+\"\")),ue[n]=r}for(const n in Bf)bl(t,Bf[n],e[n])}},defs(){const t=this._svg,e=this._defs;let n=e.el,r=0;for(const i in e.gradient)n||(e.el=n=Le(t,Su+1,\"defs\",Ot)),r=iR(n,e.gradient[i],r);for(const i in e.clipping)n||(e.el=n=Le(t,Su+1,\"defs\",Ot)),r=aR(n,e.clipping[i],r);n&&(r===0?(t.removeChild(n),e.el=null):Cn(n,r))},_clearDefs(){const t=this._defs;t.gradient={},t.clipping={}}});function av(t,e){for(;t&&t.dirty!==e;t=t.mark.group)if(t.dirty=e,t.mark&&t.mark.dirty!==e)t.mark.dirty=e;else return}function iR(t,e,n){let r,i,a;if(e.gradient===\"radial\"){let u=Le(t,n++,\"pattern\",Ot);Yr(u,{id:wf+e.id,viewBox:\"0,0,1,1\",width:\"100%\",height:\"100%\",preserveAspectRatio:\"xMidYMid slice\"}),u=Le(u,0,\"rect\",Ot),Yr(u,{width:1,height:1,fill:`url(${J_()}#${e.id})`}),t=Le(t,n++,\"radialGradient\",Ot),Yr(t,{id:e.id,fx:e.x1,fy:e.y1,fr:e.r1,cx:e.x2,cy:e.y2,r:e.r2})}else t=Le(t,n++,\"linearGradient\",Ot),Yr(t,{id:e.id,x1:e.x1,x2:e.x2,y1:e.y1,y2:e.y2});for(r=0,i=e.stops.length;r{r=t.mark(e,a,r),++i}),Cn(e,1+i)}function uv(t,e,n,r,i){let a=t._svg,u;if(!a&&(u=e.ownerDocument,a=Wr(u,r,Ot),t._svg=a,t.mark&&(a.__data__=t,a.__values__={fill:\"default\"},r===\"g\"))){const o=Wr(u,\"path\",Ot);a.appendChild(o),o.__data__=t;const s=Wr(u,\"g\",Ot);a.appendChild(s),s.__data__=t;const l=Wr(u,\"path\",Ot);a.appendChild(l),l.__data__=t,l.__values__={fill:\"default\"}}return(a.ownerSVGElement!==i||oR(a,n))&&e.insertBefore(a,n?n.nextSibling:e.firstChild),a}function oR(t,e){return t.parentNode&&t.parentNode.childNodes.length>1&&t.previousSibling!=e}let Ar=null,ue=null;const sR={group(t,e,n){const r=Ar=e.childNodes[2];ue=r.__values__,t.foreground(go,n,this),ue=e.__values__,Ar=e.childNodes[1],t.content(go,n,this);const i=Ar=e.childNodes[0];t.background(go,n,this);const a=n.mark.interactive===!1?\"none\":null;if(a!==ue.events&&(ve(r,\"pointer-events\",a),ve(i,\"pointer-events\",a),ue.events=a),n.strokeForeground&&n.stroke){const u=n.fill;ve(r,\"display\",null),this.style(i,n),ve(i,\"stroke\",null),u&&(n.fill=null),ue=r.__values__,this.style(r,n),u&&(n.fill=u),Ar=null}else ve(r,\"display\",\"none\")},image(t,e,n){n.smooth===!1?(bl(e,\"image-rendering\",\"optimizeSpeed\"),bl(e,\"image-rendering\",\"pixelated\")):bl(e,\"image-rendering\",null)},text(t,e,n){const r=xs(n);let i,a,u,o;U(r)?(a=r.map(s=>ui(n,s)),i=a.join(`\n`),i!==ue.text&&(Cn(e,0),u=e.ownerDocument,o=ai(n),a.forEach((s,l)=>{const f=Wr(u,\"tspan\",Ot);f.__data__=n,f.textContent=s,l&&(f.setAttribute(\"x\",0),f.setAttribute(\"dy\",o)),e.appendChild(f)}),ue.text=i)):(a=ui(n,r),a!==ue.text&&(e.textContent=a,ue.text=a)),ve(e,\"font-family\",vs(n)),ve(e,\"font-size\",rr(n)+\"px\"),ve(e,\"font-style\",n.fontStyle),ve(e,\"font-variant\",n.fontVariant),ve(e,\"font-weight\",n.fontWeight)}};function go(t,e,n){e!==ue[t]&&(n?lR(Ar,t,e,n):ve(Ar,t,e),ue[t]=e)}function bl(t,e,n){n!==ue[e]&&(n==null?t.style.removeProperty(e):t.style.setProperty(e,n+\"\"),ue[e]=n)}function Yr(t,e){for(const n in e)ve(t,n,e[n])}function ve(t,e,n){n!=null?t.setAttribute(e,n):t.removeAttribute(e)}function lR(t,e,n,r){n!=null?t.setAttributeNS(r,e,n):t.removeAttributeNS(r,e)}function J_(){let t;return typeof window>\"u\"?\"\":(t=window.location).hash?t.href.slice(0,-t.hash.length):t.href}function fm(t){ir.call(this,t),this._text=null,this._defs={gradient:{},clipping:{}}}L(fm,ir,{svg(){return this._text},_render(t){const e=sm();e.open(\"svg\",nt({},Lo,{class:\"marks\",width:this._width*this._scale,height:this._height*this._scale,viewBox:`0 0 ${this._width} ${this._height}`}));const n=this._bgcolor;return n&&n!==\"transparent\"&&n!==\"none\"&&e.open(\"rect\",{width:this._width,height:this._height,fill:n}).close(),e.open(\"g\",Z_,{transform:\"translate(\"+this._origin+\")\"}),this.mark(e,t),e.close(),this.defs(e),this._text=e.close()+\"\",this},mark(t,e){const n=on[e.marktype],r=n.tag,i=[H_,n.attr];t.open(\"g\",{class:P_(e),\"clip-path\":e.clip?Pp(this,e,e.group):null},G_(e),{\"pointer-events\":r!==\"g\"&&e.interactive===!1?\"none\":null});const a=u=>{const o=this.href(u);if(o&&t.open(\"a\",o),t.open(r,this.attr(e,u,i,r!==\"g\"?r:null)),r===\"text\"){const s=xs(u);if(U(s)){const l={x:0,dy:ai(u)};for(let f=0;fthis.mark(t,c)),t.close(),s&&f?(l&&(u.fill=null),u.stroke=f,t.open(\"path\",this.attr(e,u,n.foreground,\"bgrect\")).close(),l&&(u.fill=l)):t.open(\"path\",this.attr(e,u,n.foreground,\"bgfore\")).close()}t.close(),o&&t.close()};return n.nested?e.items&&e.items.length&&a(e.items[0]):Tn(e,a),t.close()},href(t){const e=t.href;let n;if(e){if(n=this._hrefs&&this._hrefs[e])return n;this.sanitizeURL(e).then(r=>{r[\"xlink:href\"]=r.href,r.href=null,(this._hrefs||(this._hrefs={}))[e]=r})}return null},attr(t,e,n,r){const i={},a=(u,o,s,l)=>{i[l||u]=o};return Array.isArray(n)?n.forEach(u=>u(a,e,this)):n(a,e,this),r&&fR(i,e,t,r,this._defs),i},defs(t){const e=this._defs.gradient,n=this._defs.clipping;if(Object.keys(e).length+Object.keys(n).length!==0){t.open(\"defs\");for(const i in e){const a=e[i],u=a.stops;a.gradient===\"radial\"?(t.open(\"pattern\",{id:wf+i,viewBox:\"0,0,1,1\",width:\"100%\",height:\"100%\",preserveAspectRatio:\"xMidYMid slice\"}),t.open(\"rect\",{width:\"1\",height:\"1\",fill:\"url(#\"+i+\")\"}).close(),t.close(),t.open(\"radialGradient\",{id:i,fx:a.x1,fy:a.y1,fr:a.r1,cx:a.x2,cy:a.y2,r:a.r2})):t.open(\"linearGradient\",{id:i,x1:a.x1,x2:a.x2,y1:a.y1,y2:a.y2});for(let o=0;o1?(Va[t]=e,this):Va[t]}function cm(t,e,n){const r=[],i=new St().union(e),a=t.marktype;return a?iC(t,i,n,r):a===\"group\"?aC(t,i,n,r):$(\"Intersect scene must be mark node or group item.\")}function iC(t,e,n,r){if(cR(t,e,n)){const i=t.items,a=t.marktype,u=i.length;let o=0;if(a===\"group\")for(;o=0;a--)if(n[a]!=r[a])return!1;for(a=n.length-1;a>=0;a--)if(i=n[a],!hm(t[i],e[i],i))return!1;return typeof t==typeof e}function gR(){b_(),zS()}const Ka=\"top\",Dn=\"left\",Mn=\"right\",si=\"bottom\",pR=\"top-left\",mR=\"top-right\",yR=\"bottom-left\",xR=\"bottom-right\",dm=\"start\",jd=\"middle\",be=\"end\",vR=\"x\",bR=\"y\",eh=\"group\",gm=\"axis\",pm=\"title\",AR=\"frame\",wR=\"scope\",mm=\"legend\",lC=\"row-header\",fC=\"row-footer\",cC=\"row-title\",hC=\"column-header\",dC=\"column-footer\",gC=\"column-title\",ER=\"padding\",_R=\"symbol\",pC=\"fit\",mC=\"fit-x\",yC=\"fit-y\",CR=\"pad\",ym=\"none\",Qs=\"all\",Wd=\"each\",xm=\"flush\",Gr=\"column\",Xr=\"row\";function xC(t){S.call(this,null,t)}L(xC,S,{transform(t,e){const n=e.dataflow,r=t.mark,i=r.marktype,a=on[i],u=a.bound;let o=r.bounds,s;if(a.nested)r.items.length&&n.dirty(r.items[0]),o=Zs(r,u),r.items.forEach(l=>{l.bounds.clear().union(o)});else if(i===eh||t.modified())switch(e.visit(e.MOD,l=>n.dirty(l)),o.clear(),r.items.forEach(l=>o.union(Zs(l,u))),r.role){case gm:case mm:case pm:e.reflow()}else s=e.changed(e.REM),e.visit(e.ADD,l=>{o.union(Zs(l,u))}),e.visit(e.MOD,l=>{s=s||o.alignsWith(l.bounds),n.dirty(l),o.union(Zs(l,u))}),s&&(o.clear(),r.items.forEach(l=>o.union(l.bounds)));return oC(r),e.modifies(\"bounds\")}});function Zs(t,e,n){return e(t.bounds.clear(),t,n)}const ov=\":vega_identifier:\";function vm(t){S.call(this,0,t)}vm.Definition={type:\"Identifier\",metadata:{modifies:!0},params:[{name:\"as\",type:\"string\",required:!0}]};L(vm,S,{transform(t,e){const n=DR(e.dataflow),r=t.as;let i=n.value;return e.visit(e.ADD,a=>a[r]=a[r]||++i),n.set(this.value=i),e}});function DR(t){return t._signals[ov]||(t._signals[ov]=t.add(0))}function vC(t){S.call(this,null,t)}L(vC,S,{transform(t,e){let n=this.value;n||(n=e.dataflow.scenegraph().mark(t.markdef,FR(t),t.index),n.group.context=t.context,t.context.group||(t.context.group=n.group),n.source=this.source,n.clip=t.clip,n.interactive=t.interactive,this.value=n);const r=n.marktype===eh?Hc:Yc;return e.visit(e.ADD,i=>r.call(i,n)),(t.modified(\"clip\")||t.modified(\"interactive\"))&&(n.clip=t.clip,n.interactive=!!t.interactive,n.zdirty=!0,e.reflow()),n.items=e.source,e}});function FR(t){const e=t.groups,n=t.parent;return e&&e.size===1?e.get(Object.keys(e.object)[0]):e&&n?e.lookup(n):null}function bC(t){S.call(this,null,t)}const sv={parity:t=>t.filter((e,n)=>n%2?e.opacity=0:1),greedy:(t,e)=>{let n;return t.filter((r,i)=>!i||!AC(n.bounds,r.bounds,e)?(n=r,1):r.opacity=0)}},AC=(t,e,n)=>n>Math.max(e.x1-t.x2,t.x1-e.x2,e.y1-t.y2,t.y1-e.y2),lv=(t,e)=>{for(var n=1,r=t.length,i=t[0].bounds,a;n{const e=t.bounds;return e.width()>1&&e.height()>1},kR=(t,e,n)=>{var r=t.range(),i=new St;return e===Ka||e===si?i.set(r[0],-1/0,r[1],1/0):i.set(-1/0,r[0],1/0,r[1]),i.expand(n||1),a=>i.encloses(a.bounds)},fv=t=>(t.forEach(e=>e.opacity=1),t),cv=(t,e)=>t.reflow(e.modified()).modifies(\"opacity\");L(bC,S,{transform(t,e){const n=sv[t.method]||sv.parity,r=t.separation||0;let i=e.materialize(e.SOURCE).source,a,u;if(!i||!i.length)return;if(!t.method)return t.modified(\"method\")&&(fv(i),e=cv(e,t)),e;if(i=i.filter(MR),!i.length)return;if(t.sort&&(i=i.slice().sort(t.sort)),a=fv(i),e=cv(e,t),a.length>=3&&lv(a,r)){do a=n(a,r);while(a.length>=3&&lv(a,r));a.length<3&&!ut(i).opacity&&(a.length>1&&(ut(a).opacity=0),ut(i).opacity=1)}t.boundScale&&t.boundTolerance>=0&&(u=kR(t.boundScale,t.boundOrient,+t.boundTolerance),i.forEach(s=>{u(s)||(s.opacity=0)}));const o=a[0].mark.bounds.clear();return i.forEach(s=>{s.opacity&&o.union(s.bounds)}),e}});function wC(t){S.call(this,null,t)}L(wC,S,{transform(t,e){const n=e.dataflow;if(e.visit(e.ALL,r=>n.dirty(r)),e.fields&&e.fields.zindex){const r=e.source&&e.source[0];r&&(r.mark.zdirty=!0)}}});const ae=new St;function _a(t,e,n){return t[e]===n?0:(t[e]=n,1)}function $R(t){var e=t.items[0].orient;return e===Dn||e===Mn}function SR(t){let e=+t.grid;return[t.ticks?e++:-1,t.labels?e++:-1,e+ +t.domain]}function BR(t,e,n,r){var i=e.items[0],a=i.datum,u=i.translate!=null?i.translate:.5,o=i.orient,s=SR(a),l=i.range,f=i.offset,c=i.position,h=i.minExtent,d=i.maxExtent,g=a.title&&i.items[s[2]].items[0],p=i.titlePadding,m=i.bounds,y=g&&Zp(g),x=0,v=0,b,w;switch(ae.clear().union(m),m.clear(),(b=s[0])>-1&&m.union(i.items[b].bounds),(b=s[1])>-1&&m.union(i.items[b].bounds),o){case Ka:x=c||0,v=-f,w=Math.max(h,Math.min(d,-m.y1)),m.add(0,-w).add(l,0),g&&Js(t,g,w,p,y,0,-1,m);break;case Dn:x=-f,v=c||0,w=Math.max(h,Math.min(d,-m.x1)),m.add(-w,0).add(0,l),g&&Js(t,g,w,p,y,1,-1,m);break;case Mn:x=n+f,v=c||0,w=Math.max(h,Math.min(d,m.x2)),m.add(0,0).add(w,l),g&&Js(t,g,w,p,y,1,1,m);break;case si:x=c||0,v=r+f,w=Math.max(h,Math.min(d,m.y2)),m.add(0,0).add(l,w),g&&Js(t,g,w,p,0,0,1,m);break;default:x=i.x,v=i.y}return $r(m.translate(x,v),i),_a(i,\"x\",x+u)|_a(i,\"y\",v+u)&&(i.bounds=ae,t.dirty(i),i.bounds=m,t.dirty(i)),i.mark.bounds.clear().union(m)}function Js(t,e,n,r,i,a,u,o){const s=e.bounds;if(e.auto){const l=u*(n+i+r);let f=0,c=0;t.dirty(e),a?f=(e.x||0)-(e.x=l):c=(e.y||0)-(e.y=l),e.mark.bounds.clear().union(s.translate(-f,-c)),t.dirty(e)}o.union(s)}const hv=(t,e)=>Math.floor(Math.min(t,e)),dv=(t,e)=>Math.ceil(Math.max(t,e));function TR(t){var e=t.items,n=e.length,r=0,i,a;const u={marks:[],rowheaders:[],rowfooters:[],colheaders:[],colfooters:[],rowtitle:null,coltitle:null};for(;r1)for(A=0;A0&&(v[A]+=N/2);if(o&&Ct(n.center,Xr)&&f!==1)for(A=0;A0&&(b[A]+=M/2);for(A=0;Ai&&(t.warn(\"Grid headers exceed limit: \"+i),e=e.slice(0,i)),p+=a,x=0,b=e.length;x=0&&(A=n[v])==null;v-=h);o?(_=d==null?A.x:Math.round(A.bounds.x1+d*A.bounds.width()),C=p):(_=p,C=d==null?A.y:Math.round(A.bounds.y1+d*A.bounds.height())),w.union(E.bounds.translate(_-(E.x||0),C-(E.y||0))),E.x=_,E.y=C,t.dirty(E),m=u(m,w[l])}return m}function pv(t,e,n,r,i,a){if(e){t.dirty(e);var u=n,o=n;r?u=Math.round(i.x1+a*i.width()):o=Math.round(i.y1+a*i.height()),e.bounds.translate(u-(e.x||0),o-(e.y||0)),e.mark.bounds.clear().union(e.bounds),e.x=u,e.y=o,t.dirty(e)}}function zR(t,e){const n=t[e]||{};return(r,i)=>n[r]!=null?n[r]:t[r]!=null?t[r]:i}function IR(t,e){let n=-1/0;return t.forEach(r=>{r.offset!=null&&(n=Math.max(n,r.offset))}),n>-1/0?n:e}function UR(t,e,n,r,i,a,u){const o=zR(n,e),s=IR(t,o(\"offset\",0)),l=o(\"anchor\",dm),f=l===be?1:l===jd?.5:0,c={align:Wd,bounds:o(\"bounds\",xm),columns:o(\"direction\")===\"vertical\"?1:t.length,padding:o(\"margin\",8),center:o(\"center\"),nodirty:!0};switch(e){case Dn:c.anchor={x:Math.floor(r.x1)-s,column:be,y:f*(u||r.height()+2*r.y1),row:l};break;case Mn:c.anchor={x:Math.ceil(r.x2)+s,y:f*(u||r.height()+2*r.y1),row:l};break;case Ka:c.anchor={y:Math.floor(i.y1)-s,row:be,x:f*(a||i.width()+2*i.x1),column:l};break;case si:c.anchor={y:Math.ceil(i.y2)+s,x:f*(a||i.width()+2*i.x1),column:l};break;case pR:c.anchor={x:s,y:s};break;case mR:c.anchor={x:a-s,y:s,column:be};break;case yR:c.anchor={x:s,y:u-s,row:be};break;case xR:c.anchor={x:a-s,y:u-s,column:be,row:be};break}return c}function qR(t,e){var n=e.items[0],r=n.datum,i=n.orient,a=n.bounds,u=n.x,o=n.y,s,l;return n._bounds?n._bounds.clear().union(a):n._bounds=a.clone(),a.clear(),WR(t,n,n.items[0].items[0]),a=jR(n,a),s=2*n.padding,l=2*n.padding,a.empty()||(s=Math.ceil(a.width()+s),l=Math.ceil(a.height()+l)),r.type===_R&&YR(n.items[0].items[0].items[0].items),i!==ym&&(n.x=u=0,n.y=o=0),n.width=s,n.height=l,$r(a.set(u,o,u+s,o+l),n),n.mark.bounds.clear().union(a),n}function jR(t,e){return t.items.forEach(n=>e.union(n.bounds)),e.x1=t.padding,e.y1=t.padding,e}function WR(t,e,n){var r=e.padding,i=r-n.x,a=r-n.y;if(!e.datum.title)(i||a)&&Bu(t,n,i,a);else{var u=e.items[1].items[0],o=u.anchor,s=e.titlePadding||0,l=r-u.x,f=r-u.y;switch(u.orient){case Dn:i+=Math.ceil(u.bounds.width())+s;break;case Mn:case si:break;default:a+=u.bounds.height()+s}switch((i||a)&&Bu(t,n,i,a),u.orient){case Dn:f+=ga(e,n,u,o,1,1);break;case Mn:l+=ga(e,n,u,be,0,0)+s,f+=ga(e,n,u,o,1,1);break;case si:l+=ga(e,n,u,o,0,0),f+=ga(e,n,u,be,-1,0,1)+s;break;default:l+=ga(e,n,u,o,0,0)}(l||f)&&Bu(t,u,l,f),(l=Math.round(u.bounds.x1-r))<0&&(Bu(t,n,-l,0),Bu(t,u,-l,0))}}function ga(t,e,n,r,i,a,u){const o=t.datum.type!==\"symbol\",s=n.datum.vgrad,l=o&&(a||!s)&&!u?e.items[0]:e,f=l.bounds[i?\"y2\":\"x2\"]-t.padding,c=s&&a?f:0,h=s&&a?0:f,d=i<=0?0:Zp(n);return Math.round(r===dm?c:r===be?h-d:.5*(f-d))}function Bu(t,e,n,r){e.x+=n,e.y+=r,e.bounds.translate(n,r),e.mark.bounds.translate(n,r),t.dirty(e)}function YR(t){const e=t.reduce((n,r)=>(n[r.column]=Math.max(r.bounds.x2-r.x,n[r.column]||0),n),{});t.forEach(n=>{n.width=e[n.column],n.height=n.bounds.y2-n.y})}function HR(t,e,n,r,i){var a=e.items[0],u=a.frame,o=a.orient,s=a.anchor,l=a.offset,f=a.padding,c=a.items[0].items[0],h=a.items[1]&&a.items[1].items[0],d=o===Dn||o===Mn?r:n,g=0,p=0,m=0,y=0,x=0,v;if(u!==eh?o===Dn?(g=i.y2,d=i.y1):o===Mn?(g=i.y1,d=i.y2):(g=i.x1,d=i.x2):o===Dn&&(g=r,d=0),v=s===dm?g:s===be?d:(g+d)/2,h&&h.text){switch(o){case Ka:case si:x=c.bounds.height()+f;break;case Dn:y=c.bounds.width()+f;break;case Mn:y=-c.bounds.width()-f;break}ae.clear().union(h.bounds),ae.translate(y-(h.x||0),x-(h.y||0)),_a(h,\"x\",y)|_a(h,\"y\",x)&&(t.dirty(h),h.bounds.clear().union(ae),h.mark.bounds.clear().union(ae),t.dirty(h)),ae.clear().union(h.bounds)}else ae.clear();switch(ae.union(c.bounds),o){case Ka:p=v,m=i.y1-ae.height()-l;break;case Dn:p=i.x1-ae.width()-l,m=v;break;case Mn:p=i.x2+ae.width()+l,m=v;break;case si:p=v,m=i.y2+l;break;default:p=a.x,m=a.y}return _a(a,\"x\",p)|_a(a,\"y\",m)&&(ae.translate(p,m),t.dirty(a),a.bounds.clear().union(ae),e.bounds.clear().union(ae),t.dirty(a)),a.bounds}function _C(t){S.call(this,null,t)}L(_C,S,{transform(t,e){const n=e.dataflow;return t.mark.items.forEach(r=>{t.layout&&NR(n,r,t.layout),XR(n,r,t)}),GR(t.mark.group)?e.reflow():e}});function GR(t){return t&&t.mark.role!==\"legend-entry\"}function XR(t,e,n){var r=e.items,i=Math.max(0,e.width||0),a=Math.max(0,e.height||0),u=new St().set(0,0,i,a),o=u.clone(),s=u.clone(),l=[],f,c,h,d,g,p;for(g=0,p=r.length;g{h=y.orient||Mn,h!==ym&&(m[h]||(m[h]=[])).push(y)});for(const y in m){const x=m[y];EC(t,x,UR(x,y,n.legends,o,s,i,a))}l.forEach(y=>{const x=y.bounds;if(x.equals(y._bounds)||(y.bounds=y._bounds,t.dirty(y),y.bounds=x,t.dirty(y)),n.autosize&&(n.autosize.type===pC||n.autosize.type===mC||n.autosize.type===yC))switch(y.orient){case Dn:case Mn:u.add(x.x1,0).add(x.x2,0);break;case Ka:case si:u.add(0,x.y1).add(0,x.y2)}else u.union(x)})}u.union(o).union(s),f&&u.union(HR(t,f,i,a,u)),e.clip&&u.set(0,0,e.width||0,e.height||0),VR(t,e,u,n)}function VR(t,e,n,r){const i=r.autosize||{},a=i.type;if(t._autosize<1||!a)return;let u=t._width,o=t._height,s=Math.max(0,e.width||0),l=Math.max(0,Math.ceil(-n.x1)),f=Math.max(0,e.height||0),c=Math.max(0,Math.ceil(-n.y1));const h=Math.max(0,Math.ceil(n.x2-s)),d=Math.max(0,Math.ceil(n.y2-f));if(i.contains===ER){const g=t.padding();u-=g.left+g.right,o-=g.top+g.bottom}a===ym?(l=0,c=0,s=u,f=o):a===pC?(s=Math.max(0,u-l-h),f=Math.max(0,o-c-d)):a===mC?(s=Math.max(0,u-l-h),o=f+c+d):a===yC?(u=s+l+h,f=Math.max(0,o-c-d)):a===CR&&(u=s+l+h,o=f+c+d),t._resizeView(u,o,s,f,[l,c],i.resize)}const KR=Object.freeze(Object.defineProperty({__proto__:null,bound:xC,identifier:vm,mark:vC,overlap:bC,render:wC,viewlayout:_C},Symbol.toStringTag,{value:\"Module\"}));function CC(t){S.call(this,null,t)}L(CC,S,{transform(t,e){if(this.value&&!t.modified())return e.StopPropagation;var n=e.dataflow.locale(),r=e.fork(e.NO_SOURCE|e.NO_FIELDS),i=this.value,a=t.scale,u=t.count==null?t.values?t.values.length:10:t.count,o=Bp(a,u,t.minstep),s=t.format||o_(n,a,o,t.formatSpecifier,t.formatType,!!t.values),l=t.values?u_(a,t.values,o):Tp(a,o);return i&&(r.rem=i),i=l.map((f,c)=>gt({index:c/(l.length-1||1),value:f,label:s(f)})),t.extra&&i.length&&i.push(gt({index:-1,extra:{value:i[0].value},label:\"\"})),r.source=i,r.add=i,this.value=i,r}});function DC(t){S.call(this,null,t)}function QR(){return gt({})}function ZR(t){const e=iu().test(n=>n.exit);return e.lookup=n=>e.get(t(n)),e}L(DC,S,{transform(t,e){var n=e.dataflow,r=e.fork(e.NO_SOURCE|e.NO_FIELDS),i=t.item||QR,a=t.key||K,u=this.value;return U(r.encode)&&(r.encode=null),u&&(t.modified(\"key\")||e.modified(a))&&$(\"DataJoin does not support modified key function or fields.\"),u||(e=e.addAll(),this.value=u=ZR(a)),e.visit(e.ADD,o=>{const s=a(o);let l=u.get(s);l?l.exit?(u.empty--,r.add.push(l)):r.mod.push(l):(l=i(o),u.set(s,l),r.add.push(l)),l.datum=o,l.exit=!1}),e.visit(e.MOD,o=>{const s=a(o),l=u.get(s);l&&(l.datum=o,r.mod.push(l))}),e.visit(e.REM,o=>{const s=a(o),l=u.get(s);o===l.datum&&!l.exit&&(r.rem.push(l),l.exit=!0,++u.empty)}),e.changed(e.ADD_MOD)&&r.modifies(\"datum\"),(e.clean()||t.clean&&u.empty>n.cleanThreshold)&&n.runAfter(u.clean),r}});function FC(t){S.call(this,null,t)}L(FC,S,{transform(t,e){var n=e.fork(e.ADD_REM),r=t.mod||!1,i=t.encoders,a=e.encode;if(U(a))if(n.changed()||a.every(c=>i[c]))a=a[0],n.encode=null;else return e.StopPropagation;var u=a===\"enter\",o=i.update||Rr,s=i.enter||Rr,l=i.exit||Rr,f=(a&&!u?i[a]:o)||Rr;if(e.changed(e.ADD)&&(e.visit(e.ADD,c=>{s(c,t),o(c,t)}),n.modifies(s.output),n.modifies(o.output),f!==Rr&&f!==o&&(e.visit(e.ADD,c=>{f(c,t)}),n.modifies(f.output))),e.changed(e.REM)&&l!==Rr&&(e.visit(e.REM,c=>{l(c,t)}),n.modifies(l.output)),u||f!==Rr){const c=e.MOD|(t.modified()?e.REFLOW:0);u?(e.visit(c,h=>{const d=s(h,t)||r;(f(h,t)||d)&&n.mod.push(h)}),n.mod.length&&n.modifies(s.output)):e.visit(c,h=>{(f(h,t)||r)&&n.mod.push(h)}),n.mod.length&&n.modifies(f.output)}return n.changed()?n:e.StopPropagation}});function MC(t){S.call(this,[],t)}L(MC,S,{transform(t,e){if(this.value!=null&&!t.modified())return e.StopPropagation;var n=e.dataflow.locale(),r=e.fork(e.NO_SOURCE|e.NO_FIELDS),i=this.value,a=t.type||dl,u=t.scale,o=+t.limit,s=Bp(u,t.count==null?5:t.count,t.minstep),l=!!t.values||a===dl,f=t.format||c_(n,u,s,a,t.formatSpecifier,t.formatType,l),c=t.values||f_(u,s),h,d,g,p,m;return i&&(r.rem=i),a===dl?(o&&c.length>o?(e.dataflow.warn(\"Symbol legend count exceeds limit, filtering items.\"),i=c.slice(0,o-1),m=!0):i=c,tt(g=t.size)?(!t.values&&u(i[0])===0&&(i=i.slice(1)),p=i.reduce((y,x)=>Math.max(y,g(x,t)),0)):g=pe(p=g||8),i=i.map((y,x)=>gt({index:x,label:f(y,x,i),value:y,offset:p,size:g(y,t)})),m&&(m=c[i.length],i.push(gt({index:i.length,label:`…${c.length-i.length} entries`,value:m,offset:p,size:g(m,t)})))):a===DS?(h=u.domain(),d=kp(u,h[0],ut(h)),c.length<3&&!t.values&&h[0]!==ut(h)&&(c=[h[0],ut(h)]),i=c.map((y,x)=>gt({index:x,label:f(y,x,c),value:y,perc:d(y)}))):(g=c.length-1,d=LS(u),i=c.map((y,x)=>gt({index:x,label:f(y,x,c),value:y,perc:x?d(y):0,perc2:x===g?1:d(c[x+1])}))),r.source=i,r.add=i,this.value=i,r}});const JR=t=>t.source.x,tO=t=>t.source.y,eO=t=>t.target.x,nO=t=>t.target.y;function bm(t){S.call(this,{},t)}bm.Definition={type:\"LinkPath\",metadata:{modifies:!0},params:[{name:\"sourceX\",type:\"field\",default:\"source.x\"},{name:\"sourceY\",type:\"field\",default:\"source.y\"},{name:\"targetX\",type:\"field\",default:\"target.x\"},{name:\"targetY\",type:\"field\",default:\"target.y\"},{name:\"orient\",type:\"enum\",default:\"vertical\",values:[\"horizontal\",\"vertical\",\"radial\"]},{name:\"shape\",type:\"enum\",default:\"line\",values:[\"line\",\"arc\",\"curve\",\"diagonal\",\"orthogonal\"]},{name:\"require\",type:\"signal\"},{name:\"as\",type:\"string\",default:\"path\"}]};L(bm,S,{transform(t,e){var n=t.sourceX||JR,r=t.sourceY||tO,i=t.targetX||eO,a=t.targetY||nO,u=t.as||\"path\",o=t.orient||\"vertical\",s=t.shape||\"line\",l=mv.get(s+\"-\"+o)||mv.get(s);return l||$(\"LinkPath unsupported type: \"+t.shape+(t.orient?\"-\"+t.orient:\"\")),e.visit(e.SOURCE,f=>{f[u]=l(n(f),r(f),i(f),a(f))}),e.reflow(t.modified()).modifies(u)}});const kC=(t,e,n,r)=>\"M\"+t+\",\"+e+\"L\"+n+\",\"+r,rO=(t,e,n,r)=>kC(e*Math.cos(t),e*Math.sin(t),r*Math.cos(n),r*Math.sin(n)),$C=(t,e,n,r)=>{var i=n-t,a=r-e,u=Math.hypot(i,a)/2,o=180*Math.atan2(a,i)/Math.PI;return\"M\"+t+\",\"+e+\"A\"+u+\",\"+u+\" \"+o+\" 0 1 \"+n+\",\"+r},iO=(t,e,n,r)=>$C(e*Math.cos(t),e*Math.sin(t),r*Math.cos(n),r*Math.sin(n)),SC=(t,e,n,r)=>{const i=n-t,a=r-e,u=.2*(i+a),o=.2*(a-i);return\"M\"+t+\",\"+e+\"C\"+(t+u)+\",\"+(e+o)+\" \"+(n+o)+\",\"+(r-u)+\" \"+n+\",\"+r},aO=(t,e,n,r)=>SC(e*Math.cos(t),e*Math.sin(t),r*Math.cos(n),r*Math.sin(n)),uO=(t,e,n,r)=>\"M\"+t+\",\"+e+\"V\"+r+\"H\"+n,oO=(t,e,n,r)=>\"M\"+t+\",\"+e+\"H\"+n+\"V\"+r,sO=(t,e,n,r)=>{const i=Math.cos(t),a=Math.sin(t),u=Math.cos(n),o=Math.sin(n),s=Math.abs(n-t)>Math.PI?n<=t:n>t;return\"M\"+e*i+\",\"+e*a+\"A\"+e+\",\"+e+\" 0 0,\"+(s?1:0)+\" \"+e*u+\",\"+e*o+\"L\"+r*u+\",\"+r*o},lO=(t,e,n,r)=>{const i=(t+n)/2;return\"M\"+t+\",\"+e+\"C\"+i+\",\"+e+\" \"+i+\",\"+r+\" \"+n+\",\"+r},fO=(t,e,n,r)=>{const i=(e+r)/2;return\"M\"+t+\",\"+e+\"C\"+t+\",\"+i+\" \"+n+\",\"+i+\" \"+n+\",\"+r},cO=(t,e,n,r)=>{const i=Math.cos(t),a=Math.sin(t),u=Math.cos(n),o=Math.sin(n),s=(e+r)/2;return\"M\"+e*i+\",\"+e*a+\"C\"+s*i+\",\"+s*a+\" \"+s*u+\",\"+s*o+\" \"+r*u+\",\"+r*o},mv=iu({line:kC,\"line-radial\":rO,arc:$C,\"arc-radial\":iO,curve:SC,\"curve-radial\":aO,\"orthogonal-horizontal\":uO,\"orthogonal-vertical\":oO,\"orthogonal-radial\":sO,\"diagonal-horizontal\":lO,\"diagonal-vertical\":fO,\"diagonal-radial\":cO});function Am(t){S.call(this,null,t)}Am.Definition={type:\"Pie\",metadata:{modifies:!0},params:[{name:\"field\",type:\"field\"},{name:\"startAngle\",type:\"number\",default:0},{name:\"endAngle\",type:\"number\",default:6.283185307179586},{name:\"sort\",type:\"boolean\",default:!1},{name:\"as\",type:\"string\",array:!0,length:2,default:[\"startAngle\",\"endAngle\"]}]};L(Am,S,{transform(t,e){var n=t.as||[\"startAngle\",\"endAngle\"],r=n[0],i=n[1],a=t.field||ru,u=t.startAngle||0,o=t.endAngle!=null?t.endAngle:2*Math.PI,s=e.source,l=s.map(a),f=l.length,c=u,h=(o-u)/qb(l),d=Ie(f),g,p,m;for(t.sort&&d.sort((y,x)=>l[y]-l[x]),g=0;g-1)return r;var i=e.domain,a=t.type,u=e.zero||e.zero===void 0&&dO(t),o,s;if(!i)return 0;if(BC(a)&&e.padding&&i[0]!==ut(i)&&(i=vO(a,i,e.range,e.padding,e.exponent,e.constant)),(u||e.domainMin!=null||e.domainMax!=null||e.domainMid!=null)&&(o=(i=i.slice()).length-1||1,u&&(i[0]>0&&(i[0]=0),i[o]<0&&(i[o]=0)),e.domainMin!=null&&(i[0]=e.domainMin),e.domainMax!=null&&(i[o]=e.domainMax),e.domainMid!=null)){s=e.domainMid;const l=s>i[o]?o+1:si+(a<0?-1:a>0?1:0),0));r!==e.length&&n.warn(\"Log scale domain includes zero: \"+Y(e))}return e}function bO(t,e,n){let r=e.bins;if(r&&!U(r)){const i=t.domain(),a=i[0],u=ut(i),o=r.step;let s=r.start==null?a:r.start,l=r.stop==null?u:r.stop;o||$(\"Scale bins parameter missing step property.\"),su&&(l=o*Math.floor(u/o)),r=Ie(s,l+o/2,o)}return r?t.bins=r:t.bins&&delete t.bins,t.type===Cp&&(r?!e.domain&&!e.domainRaw&&(t.domain(r),n=r.length):t.bins=t.domain()),n}function AO(t,e,n){var r=t.type,i=e.round||!1,a=e.range;if(e.rangeStep!=null)a=wO(r,e,n);else if(e.scheme&&(a=EO(r,e,n),tt(a))){if(t.interpolator)return t.interpolator(a);$(`Scale type ${r} does not support interpolating color schemes.`)}if(a&&t_(r))return t.interpolator(jc(Yd(a,e.reverse),e.interpolate,e.interpolateGamma));a&&e.interpolate&&t.interpolate?t.interpolate($p(e.interpolate,e.interpolateGamma)):tt(t.round)?t.round(i):tt(t.rangeRound)&&t.interpolate(i?Ko:ci),a&&t.range(Yd(a,e.reverse))}function wO(t,e,n){t!==HE&&t!==$d&&$(\"Only band and point scales support rangeStep.\");var r=(e.paddingOuter!=null?e.paddingOuter:e.padding)||0,i=t===$d?1:(e.paddingInner!=null?e.paddingInner:e.padding)||0;return[0,e.rangeStep*zc(n,i,r)]}function EO(t,e,n){var r=e.schemeExtent,i,a;return U(e.scheme)?a=jc(e.scheme,e.interpolate,e.interpolateGamma):(i=e.scheme.toLowerCase(),a=Sp(i),a||$(`Unrecognized scheme name: ${e.scheme}`)),n=t===qc?n+1:t===Cp?n-1:t===Wa||t===Uc?+e.schemeCount||hO:n,t_(t)?yv(a,r,e.reverse):tt(a)?r_(yv(a,r),n):t===_p?a:a.slice(0,n)}function yv(t,e,n){return tt(t)&&(e||n)?n_(t,Yd(e||[0,1],n)):t}function Yd(t,e){return e?t.slice().reverse():t}function OC(t){S.call(this,null,t)}L(OC,S,{transform(t,e){const n=t.modified(\"sort\")||e.changed(e.ADD)||e.modified(t.sort.fields)||e.modified(\"datum\");return n&&e.source.sort(na(t.sort)),this.modified(n),e}});const xv=\"zero\",NC=\"center\",LC=\"normalize\",PC=[\"y0\",\"y1\"];function wm(t){S.call(this,null,t)}wm.Definition={type:\"Stack\",metadata:{modifies:!0},params:[{name:\"field\",type:\"field\"},{name:\"groupby\",type:\"field\",array:!0},{name:\"sort\",type:\"compare\"},{name:\"offset\",type:\"enum\",default:xv,values:[xv,NC,LC]},{name:\"as\",type:\"string\",array:!0,length:2,default:PC}]};L(wm,S,{transform(t,e){var n=t.as||PC,r=n[0],i=n[1],a=na(t.sort),u=t.field||ru,o=t.offset===NC?_O:t.offset===LC?CO:DO,s,l,f,c;for(s=FO(e.source,t.groupby,a,u),l=0,f=s.length,c=s.max;lp(f),u,o,s,l,f,c,h,d,g;if(e==null)i.push(t.slice());else for(u={},o=0,s=t.length;og&&(g=d),n&&h.sort(n)}return i.max=g,i}const MO=Object.freeze(Object.defineProperty({__proto__:null,axisticks:CC,datajoin:DC,encode:FC,legendentries:MC,linkpath:bm,pie:Am,scale:TC,sortitems:OC,stack:wm},Symbol.toStringTag,{value:\"Module\"}));var kO=Math.abs,Hd=Math.cos,Tf=Math.sin,$O=1e-6,zC=Math.PI,Gd=zC/2,vv=SO(2);function bv(t){return t>1?Gd:t<-1?-Gd:Math.asin(t)}function SO(t){return t>0?Math.sqrt(t):0}function BO(t,e){var n=t*Tf(e),r=30,i;do e-=i=(e+Tf(e)-n)/(1+Hd(e));while(kO(i)>$O&&--r>0);return e/2}function TO(t,e,n){function r(i,a){return[t*i*Hd(a=BO(n,a)),e*Tf(a)]}return r.invert=function(i,a){return a=bv(a/e),[i/(t*Hd(a)),bv((2*a+Tf(2*a))/n)]},r}var RO=TO(vv/Gd,vv,zC);function OO(){return er(RO).scale(169.529)}const NO=nw(),Xd=[\"clipAngle\",\"clipExtent\",\"scale\",\"translate\",\"center\",\"rotate\",\"parallels\",\"precision\",\"reflectX\",\"reflectY\",\"coefficient\",\"distance\",\"fraction\",\"lobes\",\"parallel\",\"radius\",\"ratio\",\"spacing\",\"tilt\"];function LO(t,e){return function n(){const r=e();return r.type=t,r.path=nw().projection(r),r.copy=r.copy||function(){const i=n();return Xd.forEach(a=>{r[a]&&i[a](r[a]())}),i.path.pointRadius(r.path.pointRadius()),i},KE(r)}}function Em(t,e){if(!t||typeof t!=\"string\")throw new Error(\"Projection type must be a name string.\");return t=t.toLowerCase(),arguments.length>1?(Rf[t]=LO(t,e),this):Rf[t]||null}function IC(t){return t&&t.path||NO}const Rf={albers:iw,albersusa:W6,azimuthalequalarea:Y6,azimuthalequidistant:H6,conicconformal:V6,conicequalarea:of,conicequidistant:Z6,equalEarth:tk,equirectangular:K6,gnomonic:ek,identity:nk,mercator:G6,mollweide:OO,naturalEarth1:rk,orthographic:ik,stereographic:ak,transversemercator:uk};for(const t in Rf)Em(t,Rf[t]);function PO(){}const lr=[[],[[[1,1.5],[.5,1]]],[[[1.5,1],[1,1.5]]],[[[1.5,1],[.5,1]]],[[[1,.5],[1.5,1]]],[[[1,1.5],[.5,1]],[[1,.5],[1.5,1]]],[[[1,.5],[1,1.5]]],[[[1,.5],[.5,1]]],[[[.5,1],[1,.5]]],[[[1,1.5],[1,.5]]],[[[.5,1],[1,.5]],[[1.5,1],[1,1.5]]],[[[1.5,1],[1,.5]]],[[[.5,1],[1.5,1]]],[[[1,1.5],[1.5,1]]],[[[.5,1],[1,1.5]]],[]];function UC(){var t=1,e=1,n=o;function r(s,l){return l.map(f=>i(s,f))}function i(s,l){var f=[],c=[];return a(s,l,h=>{n(h,s,l),zO(h)>0?f.push([h]):c.push(h)}),c.forEach(h=>{for(var d=0,g=f.length,p;d=l,lr[m<<1].forEach(v);++d=l,lr[p|m<<1].forEach(v);for(lr[m<<0].forEach(v);++g=l,y=s[g*t]>=l,lr[m<<1|y<<2].forEach(v);++d=l,x=y,y=s[g*t+d+1]>=l,lr[p|m<<1|y<<2|x<<3].forEach(v);lr[m|y<<3].forEach(v)}for(d=-1,y=s[g*t]>=l,lr[y<<2].forEach(v);++d=l,lr[y<<2|x<<3].forEach(v);lr[y<<3].forEach(v);function v(b){var w=[b[0][0]+d,b[0][1]+g],E=[b[1][0]+d,b[1][1]+g],A=u(w),_=u(E),C,F;(C=h[A])?(F=c[_])?(delete h[C.end],delete c[F.start],C===F?(C.ring.push(E),f(C.ring)):c[C.start]=h[F.end]={start:C.start,end:F.end,ring:C.ring.concat(F.ring)}):(delete h[C.end],C.ring.push(E),h[C.end=_]=C):(C=c[_])?(F=h[A])?(delete c[C.start],delete h[F.end],C===F?(C.ring.push(E),f(C.ring)):c[F.start]=h[C.end]={start:F.start,end:C.end,ring:F.ring.concat(C.ring)}):(delete c[C.start],C.ring.unshift(w),c[C.start=A]=C):c[A]=h[_]={start:A,end:_,ring:[w,E]}}}function u(s){return s[0]*2+s[1]*(t+1)*4}function o(s,l,f){s.forEach(c=>{var h=c[0],d=c[1],g=h|0,p=d|0,m,y=l[p*t+g];h>0&&h0&&d=0&&f>=0||$(\"invalid size\"),t=l,e=f,r},r.smooth=function(s){return arguments.length?(n=s?o:PO,r):n===o},r}function zO(t){for(var e=0,n=t.length,r=t[n-1][1]*t[0][0]-t[n-1][0]*t[0][1];++er!=d>r&&n<(h-l)*(r-f)/(d-f)+l&&(i=-i)}return i}function qO(t,e,n){var r;return jO(t,e,n)&&WO(t[r=+(t[0]===e[0])],n[r],e[r])}function jO(t,e,n){return(e[0]-t[0])*(n[1]-t[1])===(n[0]-t[0])*(e[1]-t[1])}function WO(t,e,n){return t<=e&&e<=n||n<=e&&e<=t}function qC(t,e,n){return function(r){var i=Sn(r),a=n?Math.min(i[0],0):i[0],u=i[1],o=u-a,s=e?ei(a,u,t):o/(t+1);return Ie(a+s,u,s)}}function _m(t){S.call(this,null,t)}_m.Definition={type:\"Isocontour\",metadata:{generates:!0},params:[{name:\"field\",type:\"field\"},{name:\"thresholds\",type:\"number\",array:!0},{name:\"levels\",type:\"number\"},{name:\"nice\",type:\"boolean\",default:!1},{name:\"resolve\",type:\"enum\",values:[\"shared\",\"independent\"],default:\"independent\"},{name:\"zero\",type:\"boolean\",default:!0},{name:\"smooth\",type:\"boolean\",default:!0},{name:\"scale\",type:\"number\",expr:!0},{name:\"translate\",type:\"number\",array:!0,expr:!0},{name:\"as\",type:\"string\",null:!0,default:\"contour\"}]};L(_m,S,{transform(t,e){if(this.value&&!e.changed()&&!t.modified())return e.StopPropagation;var n=e.fork(e.NO_SOURCE|e.NO_FIELDS),r=e.materialize(e.SOURCE).source,i=t.field||ge,a=UC().smooth(t.smooth!==!1),u=t.thresholds||YO(r,i,t),o=t.as===null?null:t.as||\"contour\",s=[];return r.forEach(l=>{const f=i(l),c=a.size([f.width,f.height])(f.values,U(u)?u:u(f.values));HO(c,f,l,t),c.forEach(h=>{s.push(_c(l,gt(o!=null?{[o]:h}:h)))})}),this.value&&(n.rem=this.value),this.value=n.source=n.add=s,n}});function YO(t,e,n){const r=qC(n.levels||10,n.nice,n.zero!==!1);return n.resolve!==\"shared\"?r:r(t.map(i=>Ri(e(i).values)))}function HO(t,e,n,r){let i=r.scale||e.scale,a=r.translate||e.translate;if(tt(i)&&(i=i(n,r)),tt(a)&&(a=a(n,r)),(i===1||i==null)&&!a)return;const u=(Mr(i)?i:i[0])||1,o=(Mr(i)?i:i[1])||1,s=a&&a[0]||0,l=a&&a[1]||0;t.forEach(jC(e,u,o,s,l))}function jC(t,e,n,r,i){const a=t.x1||0,u=t.y1||0,o=e*n<0;function s(c){c.forEach(l)}function l(c){o&&c.reverse(),c.forEach(f)}function f(c){c[0]=(c[0]-a)*e+r,c[1]=(c[1]-u)*n+i}return function(c){return c.coordinates.forEach(s),c}}function Av(t,e,n){const r=t>=0?t:Xg(e,n);return Math.round((Math.sqrt(4*r*r+1)-1)/2)}function s0(t){return tt(t)?t:pe(+t)}function WC(){var t=s=>s[0],e=s=>s[1],n=ru,r=[-1,-1],i=960,a=500,u=2;function o(s,l){const f=Av(r[0],s,t)>>u,c=Av(r[1],s,e)>>u,h=f?f+2:0,d=c?c+2:0,g=2*h+(i>>u),p=2*d+(a>>u),m=new Float32Array(g*p),y=new Float32Array(g*p);let x=m;s.forEach(b=>{const w=h+(+t(b)>>u),E=d+(+e(b)>>u);w>=0&&w=0&&E0&&c>0?(pa(g,p,m,y,f),ma(g,p,y,m,c),pa(g,p,m,y,f),ma(g,p,y,m,c),pa(g,p,m,y,f),ma(g,p,y,m,c)):f>0?(pa(g,p,m,y,f),pa(g,p,y,m,f),pa(g,p,m,y,f),x=y):c>0&&(ma(g,p,m,y,c),ma(g,p,y,m,c),ma(g,p,m,y,c),x=y);const v=l?Math.pow(2,-2*u):1/qb(x);for(let b=0,w=g*p;b>u),y2:d+(a>>u)}}return o.x=function(s){return arguments.length?(t=s0(s),o):t},o.y=function(s){return arguments.length?(e=s0(s),o):e},o.weight=function(s){return arguments.length?(n=s0(s),o):n},o.size=function(s){if(!arguments.length)return[i,a];var l=+s[0],f=+s[1];return l>=0&&f>=0||$(\"invalid size\"),i=l,a=f,o},o.cellSize=function(s){return arguments.length?((s=+s)>=1||$(\"invalid cell size\"),u=Math.floor(Math.log(s)/Math.LN2),o):1<=i&&(o>=a&&(s-=n[o-a+u*t]),r[o-i+u*t]=s/Math.min(o+1,t-1+a-o,a))}function ma(t,e,n,r,i){const a=(i<<1)+1;for(let u=0;u=i&&(o>=a&&(s-=n[u+(o-a)*t]),r[u+(o-i)*t]=s/Math.min(o+1,e-1+a-o,a))}function Cm(t){S.call(this,null,t)}Cm.Definition={type:\"KDE2D\",metadata:{generates:!0},params:[{name:\"size\",type:\"number\",array:!0,length:2,required:!0},{name:\"x\",type:\"field\",required:!0},{name:\"y\",type:\"field\",required:!0},{name:\"weight\",type:\"field\"},{name:\"groupby\",type:\"field\",array:!0},{name:\"cellSize\",type:\"number\"},{name:\"bandwidth\",type:\"number\",array:!0,length:2},{name:\"counts\",type:\"boolean\",default:!1},{name:\"as\",type:\"string\",default:\"grid\"}]};const GO=[\"x\",\"y\",\"weight\",\"size\",\"cellSize\",\"bandwidth\"];function YC(t,e){return GO.forEach(n=>e[n]!=null?t[n](e[n]):0),t}L(Cm,S,{transform(t,e){if(this.value&&!e.changed()&&!t.modified())return e.StopPropagation;var n=e.fork(e.NO_SOURCE|e.NO_FIELDS),r=e.materialize(e.SOURCE).source,i=XO(r,t.groupby),a=(t.groupby||[]).map($t),u=YC(WC(),t),o=t.as||\"grid\",s=[];function l(f,c){for(let h=0;hgt(l({[o]:u(f,t.counts)},f.dims))),this.value&&(n.rem=this.value),this.value=n.source=n.add=s,n}});function XO(t,e){var n=[],r=f=>f(o),i,a,u,o,s,l;if(e==null)n.push(t);else for(i={},a=0,u=t.length;an.push(o(f))),a&&u&&(e.visit(s,f=>{var c=a(f),h=u(f);c!=null&&h!=null&&(c=+c)===c&&(h=+h)===h&&r.push([c,h])}),n=n.concat({type:Vd,geometry:{type:VO,coordinates:r}})),this.value={type:Fm,features:n}}});function km(t){S.call(this,null,t)}km.Definition={type:\"GeoPath\",metadata:{modifies:!0},params:[{name:\"projection\",type:\"projection\"},{name:\"field\",type:\"field\"},{name:\"pointRadius\",type:\"number\",expr:!0},{name:\"as\",type:\"string\",default:\"path\"}]};L(km,S,{transform(t,e){var n=e.fork(e.ALL),r=this.value,i=t.field||ge,a=t.as||\"path\",u=n.SOURCE;!r||t.modified()?(this.value=r=IC(t.projection),n.materialize().reflow()):u=i===ge||e.modified(i.fields)?n.ADD_MOD:n.ADD;const o=KO(r,t.pointRadius);return n.visit(u,s=>s[a]=r(i(s))),r.pointRadius(o),n.modifies(a)}});function KO(t,e){const n=t.pointRadius();return t.context(null),e!=null&&t.pointRadius(e),n}function $m(t){S.call(this,null,t)}$m.Definition={type:\"GeoPoint\",metadata:{modifies:!0},params:[{name:\"projection\",type:\"projection\",required:!0},{name:\"fields\",type:\"field\",array:!0,required:!0,length:2},{name:\"as\",type:\"string\",array:!0,length:2,default:[\"x\",\"y\"]}]};L($m,S,{transform(t,e){var n=t.projection,r=t.fields[0],i=t.fields[1],a=t.as||[\"x\",\"y\"],u=a[0],o=a[1],s;function l(f){const c=n([r(f),i(f)]);c?(f[u]=c[0],f[o]=c[1]):(f[u]=void 0,f[o]=void 0)}return t.modified()?e=e.materialize().reflow(!0).visit(e.SOURCE,l):(s=e.modified(r.fields)||e.modified(i.fields),e.visit(s?e.ADD_MOD:e.ADD,l)),e.modifies(a)}});function Sm(t){S.call(this,null,t)}Sm.Definition={type:\"GeoShape\",metadata:{modifies:!0,nomod:!0},params:[{name:\"projection\",type:\"projection\"},{name:\"field\",type:\"field\",default:\"datum\"},{name:\"pointRadius\",type:\"number\",expr:!0},{name:\"as\",type:\"string\",default:\"shape\"}]};L(Sm,S,{transform(t,e){var n=e.fork(e.ALL),r=this.value,i=t.as||\"shape\",a=n.ADD;return(!r||t.modified())&&(this.value=r=QO(IC(t.projection),t.field||en(\"datum\"),t.pointRadius),n.materialize().reflow(),a=n.SOURCE),n.visit(a,u=>u[i]=r),n.modifies(i)}});function QO(t,e,n){const r=n==null?i=>t(e(i)):i=>{var a=t.pointRadius(),u=t.pointRadius(n)(e(i));return t.pointRadius(a),u};return r.context=i=>(t.context(i),r),r}function Bm(t){S.call(this,[],t),this.generator=E6()}Bm.Definition={type:\"Graticule\",metadata:{changes:!0,generates:!0},params:[{name:\"extent\",type:\"array\",array:!0,length:2,content:{type:\"number\",array:!0,length:2}},{name:\"extentMajor\",type:\"array\",array:!0,length:2,content:{type:\"number\",array:!0,length:2}},{name:\"extentMinor\",type:\"array\",array:!0,length:2,content:{type:\"number\",array:!0,length:2}},{name:\"step\",type:\"number\",array:!0,length:2},{name:\"stepMajor\",type:\"number\",array:!0,length:2,default:[90,360]},{name:\"stepMinor\",type:\"number\",array:!0,length:2,default:[10,10]},{name:\"precision\",type:\"number\",default:2.5}]};L(Bm,S,{transform(t,e){var n=this.value,r=this.generator,i;if(!n.length||t.modified())for(const a in t)tt(r[a])&&r[a](t[a]);return i=r(),n.length?e.mod.push(tE(n[0],i)):e.add.push(gt(i)),n[0]=i,e}});function Tm(t){S.call(this,null,t)}Tm.Definition={type:\"heatmap\",metadata:{modifies:!0},params:[{name:\"field\",type:\"field\"},{name:\"color\",type:\"string\",expr:!0},{name:\"opacity\",type:\"number\",expr:!0},{name:\"resolve\",type:\"enum\",values:[\"shared\",\"independent\"],default:\"independent\"},{name:\"as\",type:\"string\",default:\"image\"}]};L(Tm,S,{transform(t,e){if(!e.changed()&&!t.modified())return e.StopPropagation;var n=e.materialize(e.SOURCE).source,r=t.resolve===\"shared\",i=t.field||ge,a=JO(t.opacity,t),u=ZO(t.color,t),o=t.as||\"image\",s={$x:0,$y:0,$value:0,$max:r?Ri(n.map(l=>Ri(i(l).values))):0};return n.forEach(l=>{const f=i(l),c=nt({},l,s);r||(c.$max=Ri(f.values||[])),l[o]=tN(f,c,u.dep?u:pe(u(c)),a.dep?a:pe(a(c)))}),e.reflow(!0).modifies(o)}});function ZO(t,e){let n;return tt(t)?(n=r=>Vn(t(r,e)),n.dep=HC(t)):n=pe(Vn(t||\"#888\")),n}function JO(t,e){let n;return tt(t)?(n=r=>t(r,e),n.dep=HC(t)):t?n=pe(t):(n=r=>r.$value/r.$max||0,n.dep=!0),n}function HC(t){if(!tt(t))return!1;const e=nn(se(t));return e.$x||e.$y||e.$value||e.$max}function tN(t,e,n,r){const i=t.width,a=t.height,u=t.x1||0,o=t.y1||0,s=t.x2||i,l=t.y2||a,f=t.values,c=f?m=>f[m]:Ir,h=Zr(s-u,l-o),d=h.getContext(\"2d\"),g=d.getImageData(0,0,s-u,l-o),p=g.data;for(let m=o,y=0;m{t[r]!=null&&wv(n,r,t[r])})):Xd.forEach(r=>{t.modified(r)&&wv(n,r,t[r])}),t.pointRadius!=null&&n.path.pointRadius(t.pointRadius),t.fit&&eN(n,t),e.fork(e.NO_SOURCE|e.NO_FIELDS)}});function eN(t,e){const n=rN(e.fit);e.extent?t.fitExtent(e.extent,n):e.size&&t.fitSize(e.size,n)}function nN(t){const e=Em((t||\"mercator\").toLowerCase());return e||$(\"Unrecognized projection type: \"+t),e()}function wv(t,e,n){tt(t[e])&&t[e](n)}function rN(t){return t=H(t),t.length===1?t[0]:{type:Fm,features:t.reduce((e,n)=>e.concat(iN(n)),[])}}function iN(t){return t.type===Fm?t.features:H(t).filter(e=>e!=null).map(e=>e.type===Vd?e:{type:Vd,geometry:e})}const aN=Object.freeze(Object.defineProperty({__proto__:null,contour:Dm,geojson:Mm,geopath:km,geopoint:$m,geoshape:Sm,graticule:Bm,heatmap:Tm,isocontour:_m,kde2d:Cm,projection:GC},Symbol.toStringTag,{value:\"Module\"})),Ev={center:mM,collide:OM,nbody:HM,link:LM,x:GM,y:XM},no=\"forces\",Kd=[\"alpha\",\"alphaMin\",\"alphaTarget\",\"velocityDecay\",\"forces\"],uN=[\"static\",\"iterations\"],XC=[\"x\",\"y\",\"vx\",\"vy\"];function Rm(t){S.call(this,null,t)}Rm.Definition={type:\"Force\",metadata:{modifies:!0},params:[{name:\"static\",type:\"boolean\",default:!1},{name:\"restart\",type:\"boolean\",default:!1},{name:\"iterations\",type:\"number\",default:300},{name:\"alpha\",type:\"number\",default:1},{name:\"alphaMin\",type:\"number\",default:.001},{name:\"alphaTarget\",type:\"number\",default:0},{name:\"velocityDecay\",type:\"number\",default:.4},{name:\"forces\",type:\"param\",array:!0,params:[{key:{force:\"center\"},params:[{name:\"x\",type:\"number\",default:0},{name:\"y\",type:\"number\",default:0}]},{key:{force:\"collide\"},params:[{name:\"radius\",type:\"number\",expr:!0},{name:\"strength\",type:\"number\",default:.7},{name:\"iterations\",type:\"number\",default:1}]},{key:{force:\"nbody\"},params:[{name:\"strength\",type:\"number\",default:-30},{name:\"theta\",type:\"number\",default:.9},{name:\"distanceMin\",type:\"number\",default:1},{name:\"distanceMax\",type:\"number\"}]},{key:{force:\"link\"},params:[{name:\"links\",type:\"data\"},{name:\"id\",type:\"field\"},{name:\"distance\",type:\"number\",default:30,expr:!0},{name:\"strength\",type:\"number\",expr:!0},{name:\"iterations\",type:\"number\",default:1}]},{key:{force:\"x\"},params:[{name:\"strength\",type:\"number\",default:.1},{name:\"x\",type:\"field\"}]},{key:{force:\"y\"},params:[{name:\"strength\",type:\"number\",default:.1},{name:\"y\",type:\"field\"}]}]},{name:\"as\",type:\"string\",array:!0,modify:!1,default:XC}]};L(Rm,S,{transform(t,e){var n=this.value,r=e.changed(e.ADD_REM),i=t.modified(Kd),a=t.iterations||300;if(n?(r&&(e.modifies(\"index\"),n.nodes(e.source)),(i||e.changed(e.MOD))&&VC(n,t,0,e)):(this.value=n=sN(e.source,t),n.on(\"tick\",oN(e.dataflow,this)),t.static||(r=!0,n.tick()),e.modifies(\"index\")),i||r||t.modified(uN)||e.changed()&&t.restart){if(n.alpha(Math.max(n.alpha(),t.alpha||1)).alphaDecay(1-Math.pow(n.alphaMin(),1/a)),t.static)for(n.stop();--a>=0;)n.tick();else if(n.stopped()&&n.restart(),!r)return e.StopPropagation}return this.finish(t,e)},finish(t,e){const n=e.dataflow;for(let o=this._argops,s=0,l=o.length,f;st.touch(e).run()}function sN(t,e){const n=YM(t),r=n.stop,i=n.restart;let a=!1;return n.stopped=()=>a,n.restart=()=>(a=!1,i()),n.stop=()=>(a=!0,r()),VC(n,e,!0).on(\"end\",()=>a=!0)}function VC(t,e,n,r){var i=H(e.forces),a,u,o,s;for(a=0,u=Kd.length;ae(r,n):e)}const hN=Object.freeze(Object.defineProperty({__proto__:null,force:Rm},Symbol.toStringTag,{value:\"Module\"}));function Qd(t,e,n){const r={};return t.each(i=>{const a=i.data;n(a)&&(r[e(a)]=i)}),t.lookup=r,t}function Om(t){S.call(this,null,t)}Om.Definition={type:\"Nest\",metadata:{treesource:!0,changes:!0},params:[{name:\"keys\",type:\"field\",array:!0},{name:\"generate\",type:\"boolean\"}]};const dN=t=>t.values;L(Om,S,{transform(t,e){e.source||$(\"Nest transform requires an upstream data source.\");var n=t.generate,r=t.modified(),i=e.clone(),a=this.value;return(!a||r||e.changed())&&(a&&a.each(u=>{u.children&&su(u.data)&&i.rem.push(u.data)}),this.value=a=q1({values:H(t.keys).reduce((u,o)=>(u.key(o),u),gN()).entries(i.source)},dN),n&&a.each(u=>{u.children&&(u=gt(u.data),i.add.push(u),i.source.push(u))}),Qd(a,K,K)),i.source.root=a,i}});function gN(){const t=[],e={entries:i=>r(n(i,0),0),key:i=>(t.push(i),e)};function n(i,a){if(a>=t.length)return i;const u=i.length,o=t[a++],s={},l={};let f=-1,c,h,d;for(;++ft.length)return i;const u=[];for(const o in i)u.push({key:o,values:r(i[o],a)});return u}return e}function Sr(t){S.call(this,null,t)}const pN=(t,e)=>t.parent===e.parent?1:2;L(Sr,S,{transform(t,e){(!e.source||!e.source.root)&&$(this.constructor.name+\" transform requires a backing tree data source.\");const n=this.layout(t.method),r=this.fields,i=e.source.root,a=t.as||r;t.field?i.sum(t.field):i.count(),t.sort&&i.sort(na(t.sort,u=>u.data)),mN(n,this.params,t),n.separation&&n.separation(t.separation!==!1?pN:ru);try{this.value=n(i)}catch(u){$(u)}return i.each(u=>yN(u,r,a)),e.reflow(t.modified()).modifies(a).modifies(\"leaf\")}});function mN(t,e,n){for(let r,i=0,a=e.length;ia[K(u)]=1),r.each(u=>{const o=u.data,s=u.parent&&u.parent.data;s&&a[K(o)]&&a[K(s)]&&i.add.push(gt({source:s,target:o}))}),this.value=i.add):e.changed(e.MOD)&&(e.visit(e.MOD,u=>a[K(u)]=1),n.forEach(u=>{(a[K(u.source)]||a[K(u.target)])&&i.mod.push(u)})),i}});const Cv={binary:i8,dice:ts,slice:tc,slicedice:a8,squarify:ww,resquarify:u8},e1=[\"x0\",\"y0\",\"x1\",\"y1\",\"depth\",\"children\"];function Um(t){Sr.call(this,t)}Um.Definition={type:\"Treemap\",metadata:{tree:!0,modifies:!0},params:[{name:\"field\",type:\"field\"},{name:\"sort\",type:\"compare\"},{name:\"method\",type:\"enum\",default:\"squarify\",values:[\"squarify\",\"resquarify\",\"binary\",\"dice\",\"slice\",\"slicedice\"]},{name:\"padding\",type:\"number\",default:0},{name:\"paddingInner\",type:\"number\",default:0},{name:\"paddingOuter\",type:\"number\",default:0},{name:\"paddingTop\",type:\"number\",default:0},{name:\"paddingRight\",type:\"number\",default:0},{name:\"paddingBottom\",type:\"number\",default:0},{name:\"paddingLeft\",type:\"number\",default:0},{name:\"ratio\",type:\"number\",default:1.618033988749895},{name:\"round\",type:\"boolean\",default:!1},{name:\"size\",type:\"number\",array:!0,length:2},{name:\"as\",type:\"string\",array:!0,length:e1.length,default:e1}]};L(Um,Sr,{layout(){const t=r8();return t.ratio=e=>{const n=t.tile();n.ratio&&t.tile(n.ratio(e))},t.method=e=>{X(Cv,e)?t.tile(Cv[e]):$(\"Unrecognized Treemap layout method: \"+e)},t},params:[\"method\",\"ratio\",\"size\",\"round\",\"padding\",\"paddingInner\",\"paddingOuter\",\"paddingTop\",\"paddingRight\",\"paddingBottom\",\"paddingLeft\"],fields:e1});const xN=Object.freeze(Object.defineProperty({__proto__:null,nest:Om,pack:Nm,partition:Lm,stratify:Pm,tree:zm,treelinks:Im,treemap:Um},Symbol.toStringTag,{value:\"Module\"})),l0=4278190080;function vN(t,e){const n=t.bitmap();return(e||[]).forEach(r=>n.set(t(r.boundary[0]),t(r.boundary[3]))),[n,void 0]}function bN(t,e,n,r,i){const a=t.width,u=t.height,o=r||i,s=Zr(a,u).getContext(\"2d\"),l=Zr(a,u).getContext(\"2d\"),f=o&&Zr(a,u).getContext(\"2d\");n.forEach(_=>Al(s,_,!1)),Al(l,e,!1),o&&Al(f,e,!0);const c=f0(s,a,u),h=f0(l,a,u),d=o&&f0(f,a,u),g=t.bitmap(),p=o&&t.bitmap();let m,y,x,v,b,w,E,A;for(y=0;y{i.items.forEach(a=>Al(t,a.items,n))}):on[r].draw(t,{items:n?e.map(AN):e})}function AN(t){const e=_c(t,{});return e.stroke&&e.strokeOpacity!==0||e.fill&&e.fillOpacity!==0?{...e,strokeOpacity:1,stroke:\"#000\",fillOpacity:0}:e}const fr=5,xe=31,zo=32,zr=new Uint32Array(zo+1),En=new Uint32Array(zo+1);En[0]=0;zr[0]=~En[0];for(let t=1;t<=zo;++t)En[t]=En[t-1]<<1|1,zr[t]=~En[t];function wN(t,e){const n=new Uint32Array(~~((t*e+zo)/zo));function r(a,u){n[a]|=u}function i(a,u){n[a]&=u}return{array:n,get:(a,u)=>{const o=u*t+a;return n[o>>>fr]&1<<(o&xe)},set:(a,u)=>{const o=u*t+a;r(o>>>fr,1<<(o&xe))},clear:(a,u)=>{const o=u*t+a;i(o>>>fr,~(1<<(o&xe)))},getRange:(a,u,o,s)=>{let l=s,f,c,h,d;for(;l>=u;--l)if(f=l*t+a,c=l*t+o,h=f>>>fr,d=c>>>fr,h===d){if(n[h]&zr[f&xe]&En[(c&xe)+1])return!0}else{if(n[h]&zr[f&xe]||n[d]&En[(c&xe)+1])return!0;for(let g=h+1;g{let l,f,c,h,d;for(;u<=s;++u)if(l=u*t+a,f=u*t+o,c=l>>>fr,h=f>>>fr,c===h)r(c,zr[l&xe]&En[(f&xe)+1]);else for(r(c,zr[l&xe]),r(h,En[(f&xe)+1]),d=c+1;d{let l,f,c,h,d;for(;u<=s;++u)if(l=u*t+a,f=u*t+o,c=l>>>fr,h=f>>>fr,c===h)i(c,En[l&xe]|zr[(f&xe)+1]);else for(i(c,En[l&xe]),i(h,zr[(f&xe)+1]),d=c+1;da<0||u<0||s>=e||o>=t}}function EN(t,e,n){const r=Math.max(1,Math.sqrt(t*e/1e6)),i=~~((t+2*n+r)/r),a=~~((e+2*n+r)/r),u=o=>~~((o+n)/r);return u.invert=o=>o*r-n,u.bitmap=()=>wN(i,a),u.ratio=r,u.padding=n,u.width=t,u.height=e,u}function _N(t,e,n,r){const i=t.width,a=t.height;return function(u){const o=u.datum.datum.items[r].items,s=o.length,l=u.datum.fontSize,f=kn.width(u.datum,u.datum.text);let c=0,h,d,g,p,m,y,x;for(let v=0;v=c&&(c=x,u.x=m,u.y=y);return m=f/2,y=l/2,h=u.x-m,d=u.x+m,g=u.y-y,p=u.y+y,u.align=\"center\",h<0&&d<=i?u.align=\"left\":0<=h&&ii||e-(u=r/2)<0||e+u>a}function Vr(t,e,n,r,i,a,u,o){const s=i*a/(r*2),l=t(e-s),f=t(e+s),c=t(n-(a=a/2)),h=t(n+a);return u.outOfBounds(l,c,f,h)||u.getRange(l,c,f,h)||o&&o.getRange(l,c,f,h)}function CN(t,e,n,r){const i=t.width,a=t.height,u=e[0],o=e[1];function s(l,f,c,h,d){const g=t.invert(l),p=t.invert(f);let m=c,y=a,x;if(!Of(g,p,h,d,i,a)&&!Vr(t,g,p,d,h,m,u,o)&&!Vr(t,g,p,d,h,d,u,null)){for(;y-m>=1;)x=(m+y)/2,Vr(t,g,p,d,h,x,u,o)?y=x:m=x;if(m>c)return[g,p,m,!0]}}return function(l){const f=l.datum.datum.items[r].items,c=f.length,h=l.datum.fontSize,d=kn.width(l.datum,l.datum.text);let g=n?h:0,p=!1,m=!1,y=0,x,v,b,w,E,A,_,C,F,D,R,k,N,M,O,z,G;for(let W=0;Wv&&(G=x,x=v,v=G),b>w&&(G=b,b=w,w=G),F=t(x),R=t(v),D=~~((F+R)/2),k=t(b),M=t(w),N=~~((k+M)/2),_=D;_>=F;--_)for(C=N;C>=k;--C)z=s(_,C,g,d,h),z&&([l.x,l.y,g,p]=z);for(_=D;_<=R;++_)for(C=N;C<=M;++C)z=s(_,C,g,d,h),z&&([l.x,l.y,g,p]=z);!p&&!n&&(O=Math.abs(v-x+w-b),E=(x+v)/2,A=(b+w)/2,O>=y&&!Of(E,A,d,h,i,a)&&!Vr(t,E,A,h,d,h,u,null)&&(y=O,l.x=E,l.y=A,m=!0))}return p||m?(E=d/2,A=h/2,u.setRange(t(l.x-E),t(l.y-A),t(l.x+E),t(l.y+A)),l.align=\"center\",l.baseline=\"middle\",!0):!1}}const DN=[-1,-1,1,1],FN=[-1,1,-1,1];function MN(t,e,n,r){const i=t.width,a=t.height,u=e[0],o=e[1],s=t.bitmap();return function(l){const f=l.datum.datum.items[r].items,c=f.length,h=l.datum.fontSize,d=kn.width(l.datum,l.datum.text),g=[];let p=n?h:0,m=!1,y=!1,x=0,v,b,w,E,A,_,C,F,D,R,k,N;for(let M=0;M=1;)k=(D+R)/2,Vr(t,A,_,h,d,k,u,o)?R=k:D=k;D>p&&(l.x=A,l.y=_,p=D,m=!0)}}!m&&!n&&(N=Math.abs(b-v+E-w),A=(v+b)/2,_=(w+E)/2,N>=x&&!Of(A,_,d,h,i,a)&&!Vr(t,A,_,h,d,h,u,null)&&(x=N,l.x=A,l.y=_,y=!0))}return m||y?(A=d/2,_=h/2,u.setRange(t(l.x-A),t(l.y-_),t(l.x+A),t(l.y+_)),l.align=\"center\",l.baseline=\"middle\",!0):!1}}const kN=[\"right\",\"center\",\"left\"],$N=[\"bottom\",\"middle\",\"top\"];function SN(t,e,n,r){const i=t.width,a=t.height,u=e[0],o=e[1],s=r.length;return function(l){const f=l.boundary,c=l.datum.fontSize;if(f[2]<0||f[5]<0||f[0]>i||f[3]>a)return!1;let h=l.textWidth??0,d,g,p,m,y,x,v,b,w,E,A,_,C,F,D;for(let R=0;R>>2&3)-1,p=d===0&&g===0||r[R]<0,m=d&&g?Math.SQRT1_2:1,y=r[R]<0?-1:1,x=f[1+d]+r[R]*d*m,A=f[4+g]+y*c*g/2+r[R]*g*m,b=A-c/2,w=A+c/2,_=t(x),F=t(b),D=t(w),!h)if(Dv(_,_,F,D,u,o,x,x,b,w,f,p))h=kn.width(l.datum,l.datum.text);else continue;if(E=x+y*h*d/2,x=E-h/2,v=E+h/2,_=t(x),C=t(v),Dv(_,C,F,D,u,o,x,v,b,w,f,p))return l.x=d?d*y<0?v:x:E,l.y=g?g*y<0?w:b:A,l.align=kN[d*y+1],l.baseline=$N[g*y+1],u.setRange(_,F,C,D),!0}return!1}}function Dv(t,e,n,r,i,a,u,o,s,l,f,c){return!(i.outOfBounds(t,n,e,r)||(c&&a||i).getRange(t,n,e,r))}const c0=0,h0=4,d0=8,g0=0,p0=1,m0=2,BN={\"top-left\":c0+g0,top:c0+p0,\"top-right\":c0+m0,left:h0+g0,middle:h0+p0,right:h0+m0,\"bottom-left\":d0+g0,bottom:d0+p0,\"bottom-right\":d0+m0},TN={naive:_N,\"reduced-search\":CN,floodfill:MN};function RN(t,e,n,r,i,a,u,o,s,l,f){if(!t.length)return t;const c=Math.max(r.length,i.length),h=ON(r,c),d=NN(i,c),g=LN(t[0].datum),p=g===\"group\"&&t[0].datum.items[s].marktype,m=p===\"area\",y=PN(g,p,o,s),x=l===null||l===1/0,v=m&&f===\"naive\";let b=-1,w=-1;const E=t.map(F=>{const D=x?kn.width(F,F.text):void 0;return b=Math.max(b,D),w=Math.max(w,F.fontSize),{datum:F,opacity:0,x:void 0,y:void 0,align:void 0,baseline:void 0,boundary:y(F),textWidth:D}});l=l===null||l===1/0?Math.max(b,w)+Math.max(...r):l;const A=EN(e[0],e[1],l);let _;if(!v){n&&E.sort((R,k)=>n(R.datum,k.datum));let F=!1;for(let R=0;RR.datum);_=a.length||D?bN(A,D||[],a,F,m):vN(A,u&&E)}const C=m?TN[f](A,_,u,s):SN(A,_,d,h);return E.forEach(F=>F.opacity=+C(F)),E}function ON(t,e){const n=new Float64Array(e),r=t.length;for(let i=0;i[a.x,a.x,a.x,a.y,a.y,a.y];return t?t===\"line\"||t===\"area\"?a=>i(a.datum):e===\"line\"?a=>{const u=a.datum.items[r].items;return i(u.length?u[n===\"start\"?0:u.length-1]:{x:NaN,y:NaN})}:a=>{const u=a.datum.bounds;return[u.x1,(u.x1+u.x2)/2,u.x2,u.y1,(u.y1+u.y2)/2,u.y2]}:i}const n1=[\"x\",\"y\",\"opacity\",\"align\",\"baseline\"],KC=[\"top-left\",\"left\",\"bottom-left\",\"top\",\"bottom\",\"top-right\",\"right\",\"bottom-right\"];function qm(t){S.call(this,null,t)}qm.Definition={type:\"Label\",metadata:{modifies:!0},params:[{name:\"size\",type:\"number\",array:!0,length:2,required:!0},{name:\"sort\",type:\"compare\"},{name:\"anchor\",type:\"string\",array:!0,default:KC},{name:\"offset\",type:\"number\",array:!0,default:[1]},{name:\"padding\",type:\"number\",default:0,null:!0},{name:\"lineAnchor\",type:\"string\",values:[\"start\",\"end\"],default:\"end\"},{name:\"markIndex\",type:\"number\",default:0},{name:\"avoidBaseMark\",type:\"boolean\",default:!0},{name:\"avoidMarks\",type:\"data\",array:!0},{name:\"method\",type:\"string\",default:\"naive\"},{name:\"as\",type:\"string\",array:!0,length:n1.length,default:n1}]};L(qm,S,{transform(t,e){function n(a){const u=t[a];return tt(u)&&e.modified(u.fields)}const r=t.modified();if(!(r||e.changed(e.ADD_REM)||n(\"sort\")))return;(!t.size||t.size.length!==2)&&$(\"Size parameter should be specified as a [width, height] array.\");const i=t.as||n1;return RN(e.materialize(e.SOURCE).source||[],t.size,t.sort,H(t.offset==null?1:t.offset),H(t.anchor||KC),t.avoidMarks||[],t.avoidBaseMark!==!1,t.lineAnchor||\"end\",t.markIndex||0,t.padding===void 0?0:t.padding,t.method||\"naive\").forEach(a=>{const u=a.datum;u[i[0]]=a.x,u[i[1]]=a.y,u[i[2]]=a.opacity,u[i[3]]=a.align,u[i[4]]=a.baseline}),e.reflow(r).modifies(i)}});const zN=Object.freeze(Object.defineProperty({__proto__:null,label:qm},Symbol.toStringTag,{value:\"Module\"}));function QC(t,e){var n=[],r=function(f){return f(o)},i,a,u,o,s,l;if(e==null)n.push(t);else for(i={},a=0,u=t.length;a{xE(l,t.x,t.y,t.bandwidth||.3).forEach(f=>{const c={};for(let h=0;ht===\"poly\"?e:t===\"quad\"?2:1;function Wm(t){S.call(this,null,t)}Wm.Definition={type:\"Regression\",metadata:{generates:!0},params:[{name:\"x\",type:\"field\",required:!0},{name:\"y\",type:\"field\",required:!0},{name:\"groupby\",type:\"field\",array:!0},{name:\"method\",type:\"string\",default:\"linear\",values:Object.keys(r1)},{name:\"order\",type:\"number\",default:3},{name:\"extent\",type:\"number\",array:!0,length:2},{name:\"params\",type:\"boolean\",default:!1},{name:\"as\",type:\"string\",array:!0}]};L(Wm,S,{transform(t,e){const n=e.fork(e.NO_SOURCE|e.NO_FIELDS);if(!this.value||e.changed()||t.modified()){const r=e.materialize(e.SOURCE).source,i=QC(r,t.groupby),a=(t.groupby||[]).map($t),u=t.method||\"linear\",o=t.order||3,s=IN(u,o),l=t.as||[$t(t.x),$t(t.y)],f=r1[u],c=[];let h=t.extent;X(r1,u)||$(\"Invalid regression method: \"+u),h!=null&&u===\"log\"&&h[0]<=0&&(e.dataflow.warn(\"Ignoring extent with values <= 0 for log regression.\"),h=null),i.forEach(d=>{if(d.length<=s){e.dataflow.warn(\"Skipping regression with more parameters than data points.\");return}const p=f(d,t.x,t.y,o);if(t.params){c.push(gt({keys:d.dims,coef:p.coef,rSquared:p.rSquared}));return}const m=h||Sn(d,t.x),y=x=>{const v={};for(let b=0;by([x,p.predict(x)])):Lc(p.predict,m,25,200).forEach(y)}),this.value&&(n.rem=this.value),this.value=n.add=n.source=c}return n}});const UN=Object.freeze(Object.defineProperty({__proto__:null,loess:jm,regression:Wm},Symbol.toStringTag,{value:\"Module\"}));function Ym(t){S.call(this,null,t)}Ym.Definition={type:\"Voronoi\",metadata:{modifies:!0},params:[{name:\"x\",type:\"field\",required:!0},{name:\"y\",type:\"field\",required:!0},{name:\"size\",type:\"number\",array:!0,length:2},{name:\"extent\",type:\"array\",array:!0,length:2,default:[[-1e5,-1e5],[1e5,1e5]],content:{type:\"number\",array:!0,length:2}},{name:\"as\",type:\"string\",default:\"path\"}]};const qN=[-1e5,-1e5,1e5,1e5];L(Ym,S,{transform(t,e){const n=t.as||\"path\",r=e.source;if(!r||!r.length)return e;let i=t.size;i=i?[0,0,i[0],i[1]]:(i=t.extent)?[i[0][0],i[0][1],i[1][0],i[1][1]]:qN;const a=this.value=$1.from(r,t.x,t.y).voronoi(i);for(let u=0,o=r.length;u>5)*t[1]),m=null,y=l.length,x=-1,v=[],b=l.map(E=>({text:e(E),font:n(E),style:i(E),weight:a(E),rotate:u(E),size:~~(r(E)+1e-14),padding:o(E),xoff:0,yoff:0,x1:0,y1:0,x0:0,y0:0,hasText:!1,sprite:null,datum:E})).sort((E,A)=>A.size-E.size);++x>1,w.y=t[1]*(f()+.5)>>1,GN(g,w,b,x),w.hasText&&d(p,w,m)&&(v.push(w),m?VN(m,w):m=[{x:w.x+w.x0,y:w.y+w.y0},{x:w.x+w.x1,y:w.y+w.y1}],w.x-=t[0]>>1,w.y-=t[1]>>1)}return v};function h(g){g.width=g.height=1;var p=Math.sqrt(g.getContext(\"2d\").getImageData(0,0,1,1).data.length>>2);g.width=(ro<<5)/p,g.height=wl/p;var m=g.getContext(\"2d\");return m.fillStyle=m.strokeStyle=\"red\",m.textAlign=\"center\",{context:m,ratio:p}}function d(g,p,m){for(var y=p.x,x=p.y,v=Math.sqrt(t[0]*t[0]+t[1]*t[1]),b=s(t),w=f()<.5?1:-1,E=-w,A,_,C;(A=b(E+=w))&&(_=~~A[0],C=~~A[1],!(Math.min(Math.abs(_),Math.abs(C))>=v));)if(p.x=y+_,p.y=x+C,!(p.x+p.x0<0||p.y+p.y0<0||p.x+p.x1>t[0]||p.y+p.y1>t[1])&&(!m||!XN(p,g,t[0]))&&(!m||KN(p,m))){for(var F=p.sprite,D=p.width>>5,R=t[0]>>5,k=p.x-(D<<4),N=k&127,M=32-N,O=p.y1-p.y0,z=(p.y+p.y0)*R+(k>>5),G,W=0;W>>N:0);z+=R}return p.sprite=null,!0}return!1}return c.words=function(g){return arguments.length?(l=g,c):l},c.size=function(g){return arguments.length?(t=[+g[0],+g[1]],c):t},c.font=function(g){return arguments.length?(n=xi(g),c):n},c.fontStyle=function(g){return arguments.length?(i=xi(g),c):i},c.fontWeight=function(g){return arguments.length?(a=xi(g),c):a},c.rotate=function(g){return arguments.length?(u=xi(g),c):u},c.text=function(g){return arguments.length?(e=xi(g),c):e},c.spiral=function(g){return arguments.length?(s=JN[g]||g,c):s},c.fontSize=function(g){return arguments.length?(r=xi(g),c):r},c.padding=function(g){return arguments.length?(o=xi(g),c):o},c.random=function(g){return arguments.length?(f=g,c):f},c}function GN(t,e,n,r){if(!e.sprite){var i=t.context,a=t.ratio;i.clearRect(0,0,(ro<<5)/a,wl/a);var u=0,o=0,s=0,l=n.length,f,c,h,d,g;for(--r;++r>5<<5,h=~~Math.max(Math.abs(x+v),Math.abs(x-v))}else f=f+31>>5<<5;if(h>s&&(s=h),u+f>=ro<<5&&(u=0,o+=s,s=0),o+h>=wl)break;i.translate((u+(f>>1))/a,(o+(h>>1))/a),e.rotate&&i.rotate(e.rotate*y0),i.fillText(e.text,0,0),e.padding&&(i.lineWidth=2*e.padding,i.strokeText(e.text,0,0)),i.restore(),e.width=f,e.height=h,e.xoff=u,e.yoff=o,e.x1=f>>1,e.y1=h>>1,e.x0=-e.x1,e.y0=-e.y1,e.hasText=!0,u+=f}for(var w=i.getImageData(0,0,(ro<<5)/a,wl/a).data,E=[];--r>=0;)if(e=n[r],!!e.hasText){for(f=e.width,c=f>>5,h=e.y1-e.y0,d=0;d>5),F=w[(o+g)*(ro<<5)+(u+d)<<2]?1<<31-d%32:0;E[C]|=F,A|=F}A?_=g:(e.y0++,h--,g--,o++)}e.y1=e.y0+_,e.sprite=E.slice(0,(e.y1-e.y0)*c)}}}function XN(t,e,n){n>>=5;for(var r=t.sprite,i=t.width>>5,a=t.x-(i<<4),u=a&127,o=32-u,s=t.y1-t.y0,l=(t.y+t.y0)*n+(a>>5),f,c=0;c>>u:0))&e[l+h])return!0;l+=n}return!1}function VN(t,e){var n=t[0],r=t[1];e.x+e.x0r.x&&(r.x=e.x+e.x1),e.y+e.y1>r.y&&(r.y=e.y+e.y1)}function KN(t,e){return t.x+t.x1>e[0].x&&t.x+t.x0e[0].y&&t.y+t.y0p(g(m))}i.forEach(g=>{g[u[0]]=NaN,g[u[1]]=NaN,g[u[3]]=0});const l=a.words(i).text(t.text).size(t.size||[500,500]).padding(t.padding||1).spiral(t.spiral||\"archimedean\").rotate(t.rotate||0).font(t.font||\"sans-serif\").fontStyle(t.fontStyle||\"normal\").fontWeight(t.fontWeight||\"normal\").fontSize(o).random(un).layout(),f=a.size(),c=f[0]>>1,h=f[1]>>1,d=l.length;for(let g=0,p,m;gnew Uint8Array(t),rL=t=>new Uint16Array(t),po=t=>new Uint32Array(t);function iL(){let t=8,e=[],n=po(0),r=el(0,t),i=el(0,t);return{data:()=>e,seen:()=>n=aL(n,e.length),add(a){for(let u=0,o=e.length,s=a.length,l;ue.length,curr:()=>r,prev:()=>i,reset:a=>i[a]=r[a],all:()=>t<257?255:t<65537?65535:4294967295,set(a,u){r[a]|=u},clear(a,u){r[a]&=~u},resize(a,u){const o=r.length;(a>o||u>t)&&(t=Math.max(u,t),r=el(a,t,r),i=el(a,t))}}}function aL(t,e,n){return t.length>=e?t:(n=n||new t.constructor(e),n.set(t),n)}function el(t,e,n){const r=(e<257?nL:e<65537?rL:po)(t);return n&&r.set(n),r}function Fv(t,e,n){const r=1<0)for(m=0;mt,size:()=>n}}function uL(t,e){return t.sort.call(e,(n,r)=>{const i=t[n],a=t[r];return ia?1:0}),X5(t,e)}function oL(t,e,n,r,i,a,u,o,s){let l=0,f=0,c;for(c=0;le.modified(r.fields));return n?this.reinit(t,e):this.eval(t,e)}else return this.init(t,e)},init(t,e){const n=t.fields,r=t.query,i=this._indices={},a=this._dims=[],u=r.length;let o=0,s,l;for(;o{const a=i.remove(e,n);for(const u in r)r[u].reindex(a)})},update(t,e,n){const r=this._dims,i=t.query,a=e.stamp,u=r.length;let o=0,s,l;for(n.filters=0,l=0;ld)for(m=d,y=Math.min(c,g);mg)for(m=Math.max(c,g),y=h;mc)for(g=c,p=Math.min(l,h);gh)for(g=Math.max(l,h),p=f;go[f]&n?null:u[f];return a.filter(a.MOD,l),i&i-1?(a.filter(a.ADD,f=>{const c=o[f]&n;return!c&&c^s[f]&n?u[f]:null}),a.filter(a.REM,f=>{const c=o[f]&n;return c&&!(c^(c^s[f]&n))?u[f]:null})):(a.filter(a.ADD,l),a.filter(a.REM,f=>(o[f]&n)===i?u[f]:null)),a.filter(a.SOURCE,f=>l(f._index))}});const sL=Object.freeze(Object.defineProperty({__proto__:null,crossfilter:Gm,resolvefilter:Xm},Symbol.toStringTag,{value:\"Module\"})),lL=\"RawCode\",xn=\"Literal\",fL=\"Property\",cL=\"Identifier\",hL=\"ArrayExpression\",dL=\"BinaryExpression\",tD=\"CallExpression\",gL=\"ConditionalExpression\",pL=\"LogicalExpression\",mL=\"MemberExpression\",yL=\"ObjectExpression\",xL=\"UnaryExpression\";function Rn(t){this.type=t}Rn.prototype.visit=function(t){let e,n,r;if(t(this))return 1;for(e=vL(this),n=0,r=e.length;n\";ar[Xi]=\"Identifier\";ar[gi]=\"Keyword\";ar[rh]=\"Null\";ar[aa]=\"Numeric\";ar[Re]=\"Punctuator\";ar[ws]=\"String\";ar[bL]=\"RegularExpression\";var AL=\"ArrayExpression\",wL=\"BinaryExpression\",EL=\"CallExpression\",_L=\"ConditionalExpression\",eD=\"Identifier\",CL=\"Literal\",DL=\"LogicalExpression\",FL=\"MemberExpression\",ML=\"ObjectExpression\",kL=\"Property\",$L=\"UnaryExpression\",Wt=\"Unexpected token %0\",SL=\"Unexpected number\",BL=\"Unexpected string\",TL=\"Unexpected identifier\",RL=\"Unexpected reserved word\",OL=\"Unexpected end of input\",i1=\"Invalid regular expression\",x0=\"Invalid regular expression: missing /\",nD=\"Octal literals are not allowed in strict mode.\",NL=\"Duplicate data property in object literal not allowed in strict mode\",Qt=\"ILLEGAL\",Io=\"Disabled.\",LL=new RegExp(\"[\\\\xAA\\\\xB5\\\\xBA\\\\xC0-\\\\xD6\\\\xD8-\\\\xF6\\\\xF8-\\\\u02C1\\\\u02C6-\\\\u02D1\\\\u02E0-\\\\u02E4\\\\u02EC\\\\u02EE\\\\u0370-\\\\u0374\\\\u0376\\\\u0377\\\\u037A-\\\\u037D\\\\u037F\\\\u0386\\\\u0388-\\\\u038A\\\\u038C\\\\u038E-\\\\u03A1\\\\u03A3-\\\\u03F5\\\\u03F7-\\\\u0481\\\\u048A-\\\\u052F\\\\u0531-\\\\u0556\\\\u0559\\\\u0561-\\\\u0587\\\\u05D0-\\\\u05EA\\\\u05F0-\\\\u05F2\\\\u0620-\\\\u064A\\\\u066E\\\\u066F\\\\u0671-\\\\u06D3\\\\u06D5\\\\u06E5\\\\u06E6\\\\u06EE\\\\u06EF\\\\u06FA-\\\\u06FC\\\\u06FF\\\\u0710\\\\u0712-\\\\u072F\\\\u074D-\\\\u07A5\\\\u07B1\\\\u07CA-\\\\u07EA\\\\u07F4\\\\u07F5\\\\u07FA\\\\u0800-\\\\u0815\\\\u081A\\\\u0824\\\\u0828\\\\u0840-\\\\u0858\\\\u08A0-\\\\u08B2\\\\u0904-\\\\u0939\\\\u093D\\\\u0950\\\\u0958-\\\\u0961\\\\u0971-\\\\u0980\\\\u0985-\\\\u098C\\\\u098F\\\\u0990\\\\u0993-\\\\u09A8\\\\u09AA-\\\\u09B0\\\\u09B2\\\\u09B6-\\\\u09B9\\\\u09BD\\\\u09CE\\\\u09DC\\\\u09DD\\\\u09DF-\\\\u09E1\\\\u09F0\\\\u09F1\\\\u0A05-\\\\u0A0A\\\\u0A0F\\\\u0A10\\\\u0A13-\\\\u0A28\\\\u0A2A-\\\\u0A30\\\\u0A32\\\\u0A33\\\\u0A35\\\\u0A36\\\\u0A38\\\\u0A39\\\\u0A59-\\\\u0A5C\\\\u0A5E\\\\u0A72-\\\\u0A74\\\\u0A85-\\\\u0A8D\\\\u0A8F-\\\\u0A91\\\\u0A93-\\\\u0AA8\\\\u0AAA-\\\\u0AB0\\\\u0AB2\\\\u0AB3\\\\u0AB5-\\\\u0AB9\\\\u0ABD\\\\u0AD0\\\\u0AE0\\\\u0AE1\\\\u0B05-\\\\u0B0C\\\\u0B0F\\\\u0B10\\\\u0B13-\\\\u0B28\\\\u0B2A-\\\\u0B30\\\\u0B32\\\\u0B33\\\\u0B35-\\\\u0B39\\\\u0B3D\\\\u0B5C\\\\u0B5D\\\\u0B5F-\\\\u0B61\\\\u0B71\\\\u0B83\\\\u0B85-\\\\u0B8A\\\\u0B8E-\\\\u0B90\\\\u0B92-\\\\u0B95\\\\u0B99\\\\u0B9A\\\\u0B9C\\\\u0B9E\\\\u0B9F\\\\u0BA3\\\\u0BA4\\\\u0BA8-\\\\u0BAA\\\\u0BAE-\\\\u0BB9\\\\u0BD0\\\\u0C05-\\\\u0C0C\\\\u0C0E-\\\\u0C10\\\\u0C12-\\\\u0C28\\\\u0C2A-\\\\u0C39\\\\u0C3D\\\\u0C58\\\\u0C59\\\\u0C60\\\\u0C61\\\\u0C85-\\\\u0C8C\\\\u0C8E-\\\\u0C90\\\\u0C92-\\\\u0CA8\\\\u0CAA-\\\\u0CB3\\\\u0CB5-\\\\u0CB9\\\\u0CBD\\\\u0CDE\\\\u0CE0\\\\u0CE1\\\\u0CF1\\\\u0CF2\\\\u0D05-\\\\u0D0C\\\\u0D0E-\\\\u0D10\\\\u0D12-\\\\u0D3A\\\\u0D3D\\\\u0D4E\\\\u0D60\\\\u0D61\\\\u0D7A-\\\\u0D7F\\\\u0D85-\\\\u0D96\\\\u0D9A-\\\\u0DB1\\\\u0DB3-\\\\u0DBB\\\\u0DBD\\\\u0DC0-\\\\u0DC6\\\\u0E01-\\\\u0E30\\\\u0E32\\\\u0E33\\\\u0E40-\\\\u0E46\\\\u0E81\\\\u0E82\\\\u0E84\\\\u0E87\\\\u0E88\\\\u0E8A\\\\u0E8D\\\\u0E94-\\\\u0E97\\\\u0E99-\\\\u0E9F\\\\u0EA1-\\\\u0EA3\\\\u0EA5\\\\u0EA7\\\\u0EAA\\\\u0EAB\\\\u0EAD-\\\\u0EB0\\\\u0EB2\\\\u0EB3\\\\u0EBD\\\\u0EC0-\\\\u0EC4\\\\u0EC6\\\\u0EDC-\\\\u0EDF\\\\u0F00\\\\u0F40-\\\\u0F47\\\\u0F49-\\\\u0F6C\\\\u0F88-\\\\u0F8C\\\\u1000-\\\\u102A\\\\u103F\\\\u1050-\\\\u1055\\\\u105A-\\\\u105D\\\\u1061\\\\u1065\\\\u1066\\\\u106E-\\\\u1070\\\\u1075-\\\\u1081\\\\u108E\\\\u10A0-\\\\u10C5\\\\u10C7\\\\u10CD\\\\u10D0-\\\\u10FA\\\\u10FC-\\\\u1248\\\\u124A-\\\\u124D\\\\u1250-\\\\u1256\\\\u1258\\\\u125A-\\\\u125D\\\\u1260-\\\\u1288\\\\u128A-\\\\u128D\\\\u1290-\\\\u12B0\\\\u12B2-\\\\u12B5\\\\u12B8-\\\\u12BE\\\\u12C0\\\\u12C2-\\\\u12C5\\\\u12C8-\\\\u12D6\\\\u12D8-\\\\u1310\\\\u1312-\\\\u1315\\\\u1318-\\\\u135A\\\\u1380-\\\\u138F\\\\u13A0-\\\\u13F4\\\\u1401-\\\\u166C\\\\u166F-\\\\u167F\\\\u1681-\\\\u169A\\\\u16A0-\\\\u16EA\\\\u16EE-\\\\u16F8\\\\u1700-\\\\u170C\\\\u170E-\\\\u1711\\\\u1720-\\\\u1731\\\\u1740-\\\\u1751\\\\u1760-\\\\u176C\\\\u176E-\\\\u1770\\\\u1780-\\\\u17B3\\\\u17D7\\\\u17DC\\\\u1820-\\\\u1877\\\\u1880-\\\\u18A8\\\\u18AA\\\\u18B0-\\\\u18F5\\\\u1900-\\\\u191E\\\\u1950-\\\\u196D\\\\u1970-\\\\u1974\\\\u1980-\\\\u19AB\\\\u19C1-\\\\u19C7\\\\u1A00-\\\\u1A16\\\\u1A20-\\\\u1A54\\\\u1AA7\\\\u1B05-\\\\u1B33\\\\u1B45-\\\\u1B4B\\\\u1B83-\\\\u1BA0\\\\u1BAE\\\\u1BAF\\\\u1BBA-\\\\u1BE5\\\\u1C00-\\\\u1C23\\\\u1C4D-\\\\u1C4F\\\\u1C5A-\\\\u1C7D\\\\u1CE9-\\\\u1CEC\\\\u1CEE-\\\\u1CF1\\\\u1CF5\\\\u1CF6\\\\u1D00-\\\\u1DBF\\\\u1E00-\\\\u1F15\\\\u1F18-\\\\u1F1D\\\\u1F20-\\\\u1F45\\\\u1F48-\\\\u1F4D\\\\u1F50-\\\\u1F57\\\\u1F59\\\\u1F5B\\\\u1F5D\\\\u1F5F-\\\\u1F7D\\\\u1F80-\\\\u1FB4\\\\u1FB6-\\\\u1FBC\\\\u1FBE\\\\u1FC2-\\\\u1FC4\\\\u1FC6-\\\\u1FCC\\\\u1FD0-\\\\u1FD3\\\\u1FD6-\\\\u1FDB\\\\u1FE0-\\\\u1FEC\\\\u1FF2-\\\\u1FF4\\\\u1FF6-\\\\u1FFC\\\\u2071\\\\u207F\\\\u2090-\\\\u209C\\\\u2102\\\\u2107\\\\u210A-\\\\u2113\\\\u2115\\\\u2119-\\\\u211D\\\\u2124\\\\u2126\\\\u2128\\\\u212A-\\\\u212D\\\\u212F-\\\\u2139\\\\u213C-\\\\u213F\\\\u2145-\\\\u2149\\\\u214E\\\\u2160-\\\\u2188\\\\u2C00-\\\\u2C2E\\\\u2C30-\\\\u2C5E\\\\u2C60-\\\\u2CE4\\\\u2CEB-\\\\u2CEE\\\\u2CF2\\\\u2CF3\\\\u2D00-\\\\u2D25\\\\u2D27\\\\u2D2D\\\\u2D30-\\\\u2D67\\\\u2D6F\\\\u2D80-\\\\u2D96\\\\u2DA0-\\\\u2DA6\\\\u2DA8-\\\\u2DAE\\\\u2DB0-\\\\u2DB6\\\\u2DB8-\\\\u2DBE\\\\u2DC0-\\\\u2DC6\\\\u2DC8-\\\\u2DCE\\\\u2DD0-\\\\u2DD6\\\\u2DD8-\\\\u2DDE\\\\u2E2F\\\\u3005-\\\\u3007\\\\u3021-\\\\u3029\\\\u3031-\\\\u3035\\\\u3038-\\\\u303C\\\\u3041-\\\\u3096\\\\u309D-\\\\u309F\\\\u30A1-\\\\u30FA\\\\u30FC-\\\\u30FF\\\\u3105-\\\\u312D\\\\u3131-\\\\u318E\\\\u31A0-\\\\u31BA\\\\u31F0-\\\\u31FF\\\\u3400-\\\\u4DB5\\\\u4E00-\\\\u9FCC\\\\uA000-\\\\uA48C\\\\uA4D0-\\\\uA4FD\\\\uA500-\\\\uA60C\\\\uA610-\\\\uA61F\\\\uA62A\\\\uA62B\\\\uA640-\\\\uA66E\\\\uA67F-\\\\uA69D\\\\uA6A0-\\\\uA6EF\\\\uA717-\\\\uA71F\\\\uA722-\\\\uA788\\\\uA78B-\\\\uA78E\\\\uA790-\\\\uA7AD\\\\uA7B0\\\\uA7B1\\\\uA7F7-\\\\uA801\\\\uA803-\\\\uA805\\\\uA807-\\\\uA80A\\\\uA80C-\\\\uA822\\\\uA840-\\\\uA873\\\\uA882-\\\\uA8B3\\\\uA8F2-\\\\uA8F7\\\\uA8FB\\\\uA90A-\\\\uA925\\\\uA930-\\\\uA946\\\\uA960-\\\\uA97C\\\\uA984-\\\\uA9B2\\\\uA9CF\\\\uA9E0-\\\\uA9E4\\\\uA9E6-\\\\uA9EF\\\\uA9FA-\\\\uA9FE\\\\uAA00-\\\\uAA28\\\\uAA40-\\\\uAA42\\\\uAA44-\\\\uAA4B\\\\uAA60-\\\\uAA76\\\\uAA7A\\\\uAA7E-\\\\uAAAF\\\\uAAB1\\\\uAAB5\\\\uAAB6\\\\uAAB9-\\\\uAABD\\\\uAAC0\\\\uAAC2\\\\uAADB-\\\\uAADD\\\\uAAE0-\\\\uAAEA\\\\uAAF2-\\\\uAAF4\\\\uAB01-\\\\uAB06\\\\uAB09-\\\\uAB0E\\\\uAB11-\\\\uAB16\\\\uAB20-\\\\uAB26\\\\uAB28-\\\\uAB2E\\\\uAB30-\\\\uAB5A\\\\uAB5C-\\\\uAB5F\\\\uAB64\\\\uAB65\\\\uABC0-\\\\uABE2\\\\uAC00-\\\\uD7A3\\\\uD7B0-\\\\uD7C6\\\\uD7CB-\\\\uD7FB\\\\uF900-\\\\uFA6D\\\\uFA70-\\\\uFAD9\\\\uFB00-\\\\uFB06\\\\uFB13-\\\\uFB17\\\\uFB1D\\\\uFB1F-\\\\uFB28\\\\uFB2A-\\\\uFB36\\\\uFB38-\\\\uFB3C\\\\uFB3E\\\\uFB40\\\\uFB41\\\\uFB43\\\\uFB44\\\\uFB46-\\\\uFBB1\\\\uFBD3-\\\\uFD3D\\\\uFD50-\\\\uFD8F\\\\uFD92-\\\\uFDC7\\\\uFDF0-\\\\uFDFB\\\\uFE70-\\\\uFE74\\\\uFE76-\\\\uFEFC\\\\uFF21-\\\\uFF3A\\\\uFF41-\\\\uFF5A\\\\uFF66-\\\\uFFBE\\\\uFFC2-\\\\uFFC7\\\\uFFCA-\\\\uFFCF\\\\uFFD2-\\\\uFFD7\\\\uFFDA-\\\\uFFDC]\"),PL=new RegExp(\"[\\\\xAA\\\\xB5\\\\xBA\\\\xC0-\\\\xD6\\\\xD8-\\\\xF6\\\\xF8-\\\\u02C1\\\\u02C6-\\\\u02D1\\\\u02E0-\\\\u02E4\\\\u02EC\\\\u02EE\\\\u0300-\\\\u0374\\\\u0376\\\\u0377\\\\u037A-\\\\u037D\\\\u037F\\\\u0386\\\\u0388-\\\\u038A\\\\u038C\\\\u038E-\\\\u03A1\\\\u03A3-\\\\u03F5\\\\u03F7-\\\\u0481\\\\u0483-\\\\u0487\\\\u048A-\\\\u052F\\\\u0531-\\\\u0556\\\\u0559\\\\u0561-\\\\u0587\\\\u0591-\\\\u05BD\\\\u05BF\\\\u05C1\\\\u05C2\\\\u05C4\\\\u05C5\\\\u05C7\\\\u05D0-\\\\u05EA\\\\u05F0-\\\\u05F2\\\\u0610-\\\\u061A\\\\u0620-\\\\u0669\\\\u066E-\\\\u06D3\\\\u06D5-\\\\u06DC\\\\u06DF-\\\\u06E8\\\\u06EA-\\\\u06FC\\\\u06FF\\\\u0710-\\\\u074A\\\\u074D-\\\\u07B1\\\\u07C0-\\\\u07F5\\\\u07FA\\\\u0800-\\\\u082D\\\\u0840-\\\\u085B\\\\u08A0-\\\\u08B2\\\\u08E4-\\\\u0963\\\\u0966-\\\\u096F\\\\u0971-\\\\u0983\\\\u0985-\\\\u098C\\\\u098F\\\\u0990\\\\u0993-\\\\u09A8\\\\u09AA-\\\\u09B0\\\\u09B2\\\\u09B6-\\\\u09B9\\\\u09BC-\\\\u09C4\\\\u09C7\\\\u09C8\\\\u09CB-\\\\u09CE\\\\u09D7\\\\u09DC\\\\u09DD\\\\u09DF-\\\\u09E3\\\\u09E6-\\\\u09F1\\\\u0A01-\\\\u0A03\\\\u0A05-\\\\u0A0A\\\\u0A0F\\\\u0A10\\\\u0A13-\\\\u0A28\\\\u0A2A-\\\\u0A30\\\\u0A32\\\\u0A33\\\\u0A35\\\\u0A36\\\\u0A38\\\\u0A39\\\\u0A3C\\\\u0A3E-\\\\u0A42\\\\u0A47\\\\u0A48\\\\u0A4B-\\\\u0A4D\\\\u0A51\\\\u0A59-\\\\u0A5C\\\\u0A5E\\\\u0A66-\\\\u0A75\\\\u0A81-\\\\u0A83\\\\u0A85-\\\\u0A8D\\\\u0A8F-\\\\u0A91\\\\u0A93-\\\\u0AA8\\\\u0AAA-\\\\u0AB0\\\\u0AB2\\\\u0AB3\\\\u0AB5-\\\\u0AB9\\\\u0ABC-\\\\u0AC5\\\\u0AC7-\\\\u0AC9\\\\u0ACB-\\\\u0ACD\\\\u0AD0\\\\u0AE0-\\\\u0AE3\\\\u0AE6-\\\\u0AEF\\\\u0B01-\\\\u0B03\\\\u0B05-\\\\u0B0C\\\\u0B0F\\\\u0B10\\\\u0B13-\\\\u0B28\\\\u0B2A-\\\\u0B30\\\\u0B32\\\\u0B33\\\\u0B35-\\\\u0B39\\\\u0B3C-\\\\u0B44\\\\u0B47\\\\u0B48\\\\u0B4B-\\\\u0B4D\\\\u0B56\\\\u0B57\\\\u0B5C\\\\u0B5D\\\\u0B5F-\\\\u0B63\\\\u0B66-\\\\u0B6F\\\\u0B71\\\\u0B82\\\\u0B83\\\\u0B85-\\\\u0B8A\\\\u0B8E-\\\\u0B90\\\\u0B92-\\\\u0B95\\\\u0B99\\\\u0B9A\\\\u0B9C\\\\u0B9E\\\\u0B9F\\\\u0BA3\\\\u0BA4\\\\u0BA8-\\\\u0BAA\\\\u0BAE-\\\\u0BB9\\\\u0BBE-\\\\u0BC2\\\\u0BC6-\\\\u0BC8\\\\u0BCA-\\\\u0BCD\\\\u0BD0\\\\u0BD7\\\\u0BE6-\\\\u0BEF\\\\u0C00-\\\\u0C03\\\\u0C05-\\\\u0C0C\\\\u0C0E-\\\\u0C10\\\\u0C12-\\\\u0C28\\\\u0C2A-\\\\u0C39\\\\u0C3D-\\\\u0C44\\\\u0C46-\\\\u0C48\\\\u0C4A-\\\\u0C4D\\\\u0C55\\\\u0C56\\\\u0C58\\\\u0C59\\\\u0C60-\\\\u0C63\\\\u0C66-\\\\u0C6F\\\\u0C81-\\\\u0C83\\\\u0C85-\\\\u0C8C\\\\u0C8E-\\\\u0C90\\\\u0C92-\\\\u0CA8\\\\u0CAA-\\\\u0CB3\\\\u0CB5-\\\\u0CB9\\\\u0CBC-\\\\u0CC4\\\\u0CC6-\\\\u0CC8\\\\u0CCA-\\\\u0CCD\\\\u0CD5\\\\u0CD6\\\\u0CDE\\\\u0CE0-\\\\u0CE3\\\\u0CE6-\\\\u0CEF\\\\u0CF1\\\\u0CF2\\\\u0D01-\\\\u0D03\\\\u0D05-\\\\u0D0C\\\\u0D0E-\\\\u0D10\\\\u0D12-\\\\u0D3A\\\\u0D3D-\\\\u0D44\\\\u0D46-\\\\u0D48\\\\u0D4A-\\\\u0D4E\\\\u0D57\\\\u0D60-\\\\u0D63\\\\u0D66-\\\\u0D6F\\\\u0D7A-\\\\u0D7F\\\\u0D82\\\\u0D83\\\\u0D85-\\\\u0D96\\\\u0D9A-\\\\u0DB1\\\\u0DB3-\\\\u0DBB\\\\u0DBD\\\\u0DC0-\\\\u0DC6\\\\u0DCA\\\\u0DCF-\\\\u0DD4\\\\u0DD6\\\\u0DD8-\\\\u0DDF\\\\u0DE6-\\\\u0DEF\\\\u0DF2\\\\u0DF3\\\\u0E01-\\\\u0E3A\\\\u0E40-\\\\u0E4E\\\\u0E50-\\\\u0E59\\\\u0E81\\\\u0E82\\\\u0E84\\\\u0E87\\\\u0E88\\\\u0E8A\\\\u0E8D\\\\u0E94-\\\\u0E97\\\\u0E99-\\\\u0E9F\\\\u0EA1-\\\\u0EA3\\\\u0EA5\\\\u0EA7\\\\u0EAA\\\\u0EAB\\\\u0EAD-\\\\u0EB9\\\\u0EBB-\\\\u0EBD\\\\u0EC0-\\\\u0EC4\\\\u0EC6\\\\u0EC8-\\\\u0ECD\\\\u0ED0-\\\\u0ED9\\\\u0EDC-\\\\u0EDF\\\\u0F00\\\\u0F18\\\\u0F19\\\\u0F20-\\\\u0F29\\\\u0F35\\\\u0F37\\\\u0F39\\\\u0F3E-\\\\u0F47\\\\u0F49-\\\\u0F6C\\\\u0F71-\\\\u0F84\\\\u0F86-\\\\u0F97\\\\u0F99-\\\\u0FBC\\\\u0FC6\\\\u1000-\\\\u1049\\\\u1050-\\\\u109D\\\\u10A0-\\\\u10C5\\\\u10C7\\\\u10CD\\\\u10D0-\\\\u10FA\\\\u10FC-\\\\u1248\\\\u124A-\\\\u124D\\\\u1250-\\\\u1256\\\\u1258\\\\u125A-\\\\u125D\\\\u1260-\\\\u1288\\\\u128A-\\\\u128D\\\\u1290-\\\\u12B0\\\\u12B2-\\\\u12B5\\\\u12B8-\\\\u12BE\\\\u12C0\\\\u12C2-\\\\u12C5\\\\u12C8-\\\\u12D6\\\\u12D8-\\\\u1310\\\\u1312-\\\\u1315\\\\u1318-\\\\u135A\\\\u135D-\\\\u135F\\\\u1380-\\\\u138F\\\\u13A0-\\\\u13F4\\\\u1401-\\\\u166C\\\\u166F-\\\\u167F\\\\u1681-\\\\u169A\\\\u16A0-\\\\u16EA\\\\u16EE-\\\\u16F8\\\\u1700-\\\\u170C\\\\u170E-\\\\u1714\\\\u1720-\\\\u1734\\\\u1740-\\\\u1753\\\\u1760-\\\\u176C\\\\u176E-\\\\u1770\\\\u1772\\\\u1773\\\\u1780-\\\\u17D3\\\\u17D7\\\\u17DC\\\\u17DD\\\\u17E0-\\\\u17E9\\\\u180B-\\\\u180D\\\\u1810-\\\\u1819\\\\u1820-\\\\u1877\\\\u1880-\\\\u18AA\\\\u18B0-\\\\u18F5\\\\u1900-\\\\u191E\\\\u1920-\\\\u192B\\\\u1930-\\\\u193B\\\\u1946-\\\\u196D\\\\u1970-\\\\u1974\\\\u1980-\\\\u19AB\\\\u19B0-\\\\u19C9\\\\u19D0-\\\\u19D9\\\\u1A00-\\\\u1A1B\\\\u1A20-\\\\u1A5E\\\\u1A60-\\\\u1A7C\\\\u1A7F-\\\\u1A89\\\\u1A90-\\\\u1A99\\\\u1AA7\\\\u1AB0-\\\\u1ABD\\\\u1B00-\\\\u1B4B\\\\u1B50-\\\\u1B59\\\\u1B6B-\\\\u1B73\\\\u1B80-\\\\u1BF3\\\\u1C00-\\\\u1C37\\\\u1C40-\\\\u1C49\\\\u1C4D-\\\\u1C7D\\\\u1CD0-\\\\u1CD2\\\\u1CD4-\\\\u1CF6\\\\u1CF8\\\\u1CF9\\\\u1D00-\\\\u1DF5\\\\u1DFC-\\\\u1F15\\\\u1F18-\\\\u1F1D\\\\u1F20-\\\\u1F45\\\\u1F48-\\\\u1F4D\\\\u1F50-\\\\u1F57\\\\u1F59\\\\u1F5B\\\\u1F5D\\\\u1F5F-\\\\u1F7D\\\\u1F80-\\\\u1FB4\\\\u1FB6-\\\\u1FBC\\\\u1FBE\\\\u1FC2-\\\\u1FC4\\\\u1FC6-\\\\u1FCC\\\\u1FD0-\\\\u1FD3\\\\u1FD6-\\\\u1FDB\\\\u1FE0-\\\\u1FEC\\\\u1FF2-\\\\u1FF4\\\\u1FF6-\\\\u1FFC\\\\u200C\\\\u200D\\\\u203F\\\\u2040\\\\u2054\\\\u2071\\\\u207F\\\\u2090-\\\\u209C\\\\u20D0-\\\\u20DC\\\\u20E1\\\\u20E5-\\\\u20F0\\\\u2102\\\\u2107\\\\u210A-\\\\u2113\\\\u2115\\\\u2119-\\\\u211D\\\\u2124\\\\u2126\\\\u2128\\\\u212A-\\\\u212D\\\\u212F-\\\\u2139\\\\u213C-\\\\u213F\\\\u2145-\\\\u2149\\\\u214E\\\\u2160-\\\\u2188\\\\u2C00-\\\\u2C2E\\\\u2C30-\\\\u2C5E\\\\u2C60-\\\\u2CE4\\\\u2CEB-\\\\u2CF3\\\\u2D00-\\\\u2D25\\\\u2D27\\\\u2D2D\\\\u2D30-\\\\u2D67\\\\u2D6F\\\\u2D7F-\\\\u2D96\\\\u2DA0-\\\\u2DA6\\\\u2DA8-\\\\u2DAE\\\\u2DB0-\\\\u2DB6\\\\u2DB8-\\\\u2DBE\\\\u2DC0-\\\\u2DC6\\\\u2DC8-\\\\u2DCE\\\\u2DD0-\\\\u2DD6\\\\u2DD8-\\\\u2DDE\\\\u2DE0-\\\\u2DFF\\\\u2E2F\\\\u3005-\\\\u3007\\\\u3021-\\\\u302F\\\\u3031-\\\\u3035\\\\u3038-\\\\u303C\\\\u3041-\\\\u3096\\\\u3099\\\\u309A\\\\u309D-\\\\u309F\\\\u30A1-\\\\u30FA\\\\u30FC-\\\\u30FF\\\\u3105-\\\\u312D\\\\u3131-\\\\u318E\\\\u31A0-\\\\u31BA\\\\u31F0-\\\\u31FF\\\\u3400-\\\\u4DB5\\\\u4E00-\\\\u9FCC\\\\uA000-\\\\uA48C\\\\uA4D0-\\\\uA4FD\\\\uA500-\\\\uA60C\\\\uA610-\\\\uA62B\\\\uA640-\\\\uA66F\\\\uA674-\\\\uA67D\\\\uA67F-\\\\uA69D\\\\uA69F-\\\\uA6F1\\\\uA717-\\\\uA71F\\\\uA722-\\\\uA788\\\\uA78B-\\\\uA78E\\\\uA790-\\\\uA7AD\\\\uA7B0\\\\uA7B1\\\\uA7F7-\\\\uA827\\\\uA840-\\\\uA873\\\\uA880-\\\\uA8C4\\\\uA8D0-\\\\uA8D9\\\\uA8E0-\\\\uA8F7\\\\uA8FB\\\\uA900-\\\\uA92D\\\\uA930-\\\\uA953\\\\uA960-\\\\uA97C\\\\uA980-\\\\uA9C0\\\\uA9CF-\\\\uA9D9\\\\uA9E0-\\\\uA9FE\\\\uAA00-\\\\uAA36\\\\uAA40-\\\\uAA4D\\\\uAA50-\\\\uAA59\\\\uAA60-\\\\uAA76\\\\uAA7A-\\\\uAAC2\\\\uAADB-\\\\uAADD\\\\uAAE0-\\\\uAAEF\\\\uAAF2-\\\\uAAF6\\\\uAB01-\\\\uAB06\\\\uAB09-\\\\uAB0E\\\\uAB11-\\\\uAB16\\\\uAB20-\\\\uAB26\\\\uAB28-\\\\uAB2E\\\\uAB30-\\\\uAB5A\\\\uAB5C-\\\\uAB5F\\\\uAB64\\\\uAB65\\\\uABC0-\\\\uABEA\\\\uABEC\\\\uABED\\\\uABF0-\\\\uABF9\\\\uAC00-\\\\uD7A3\\\\uD7B0-\\\\uD7C6\\\\uD7CB-\\\\uD7FB\\\\uF900-\\\\uFA6D\\\\uFA70-\\\\uFAD9\\\\uFB00-\\\\uFB06\\\\uFB13-\\\\uFB17\\\\uFB1D-\\\\uFB28\\\\uFB2A-\\\\uFB36\\\\uFB38-\\\\uFB3C\\\\uFB3E\\\\uFB40\\\\uFB41\\\\uFB43\\\\uFB44\\\\uFB46-\\\\uFBB1\\\\uFBD3-\\\\uFD3D\\\\uFD50-\\\\uFD8F\\\\uFD92-\\\\uFDC7\\\\uFDF0-\\\\uFDFB\\\\uFE00-\\\\uFE0F\\\\uFE20-\\\\uFE2D\\\\uFE33\\\\uFE34\\\\uFE4D-\\\\uFE4F\\\\uFE70-\\\\uFE74\\\\uFE76-\\\\uFEFC\\\\uFF10-\\\\uFF19\\\\uFF21-\\\\uFF3A\\\\uFF3F\\\\uFF41-\\\\uFF5A\\\\uFF66-\\\\uFFBE\\\\uFFC2-\\\\uFFC7\\\\uFFCA-\\\\uFFCF\\\\uFFD2-\\\\uFFD7\\\\uFFDA-\\\\uFFDC]\");function ih(t,e){if(!t)throw new Error(\"ASSERT: \"+e)}function dr(t){return t>=48&&t<=57}function Vm(t){return\"0123456789abcdefABCDEF\".indexOf(t)>=0}function mo(t){return\"01234567\".indexOf(t)>=0}function zL(t){return t===32||t===9||t===11||t===12||t===160||t>=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(t)>=0}function Uo(t){return t===10||t===13||t===8232||t===8233}function Es(t){return t===36||t===95||t>=65&&t<=90||t>=97&&t<=122||t===92||t>=128&&LL.test(String.fromCharCode(t))}function Nf(t){return t===36||t===95||t>=65&&t<=90||t>=97&&t<=122||t>=48&&t<=57||t===92||t>=128&&PL.test(String.fromCharCode(t))}const IL={if:1,in:1,do:1,var:1,for:1,new:1,try:1,let:1,this:1,else:1,case:1,void:1,with:1,enum:1,while:1,break:1,catch:1,throw:1,const:1,yield:1,class:1,super:1,return:1,typeof:1,delete:1,switch:1,export:1,import:1,public:1,static:1,default:1,finally:1,extends:1,package:1,private:1,function:1,continue:1,debugger:1,interface:1,protected:1,instanceof:1,implements:1};function rD(){for(;B1114111||t!==\"}\")&&ct({},Wt,Qt),e<=65535?String.fromCharCode(e):(n=(e-65536>>10)+55296,r=(e-65536&1023)+56320,String.fromCharCode(n,r))}function iD(){var t,e;for(t=q.charCodeAt(B++),e=String.fromCharCode(t),t===92&&(q.charCodeAt(B)!==117&&ct({},Wt,Qt),++B,t=a1(\"u\"),(!t||t===\"\\\\\"||!Es(t.charCodeAt(0)))&&ct({},Wt,Qt),e=t);B>>=\")return B+=4,{type:Re,value:u,start:t,end:B};if(a=u.substr(0,3),a===\">>>\"||a===\"<<=\"||a===\">>=\")return B+=3,{type:Re,value:a,start:t,end:B};if(i=a.substr(0,2),r===i[1]&&\"+-<>&|\".indexOf(r)>=0||i===\"=>\")return B+=2,{type:Re,value:i,start:t,end:B};if(i===\"//\"&&ct({},Wt,Qt),\"<>=!+-*%&|^/\".indexOf(r)>=0)return++B,{type:Re,value:r,start:t,end:B};ct({},Wt,Qt)}function WL(t){let e=\"\";for(;B=0&&B=0&&(n=n.replace(/\\\\u\\{([0-9a-fA-F]+)\\}/g,(r,i)=>{if(parseInt(i,16)<=1114111)return\"x\";ct({},i1)}).replace(/[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g,\"x\"));try{new RegExp(n)}catch{ct({},i1)}try{return new RegExp(t,e)}catch{return null}}function XL(){var t,e,n,r,i;for(t=q[B],ih(t===\"/\",\"Regular expression literal must start with a slash\"),e=q[B++],n=!1,r=!1;B=0&&ct({},i1,n),{value:n,literal:e}}function KL(){var t,e,n,r;return mt=null,rD(),t=B,e=XL(),n=VL(),r=GL(e.value,n.value),{literal:e.literal+n.literal,value:r,regex:{pattern:e.value,flags:n.value},start:t,end:B}}function QL(t){return t.type===Xi||t.type===gi||t.type===nh||t.type===rh}function aD(){if(rD(),B>=fe)return{type:As,start:B,end:B};const t=q.charCodeAt(B);return Es(t)?jL():t===40||t===41||t===59?v0():t===39||t===34?HL():t===46?dr(q.charCodeAt(B+1))?kv():v0():dr(t)?kv():v0()}function Pe(){const t=mt;return B=t.end,mt=aD(),B=t.end,t}function uD(){const t=B;mt=aD(),B=t}function ZL(t){const e=new Rn(AL);return e.elements=t,e}function $v(t,e,n){const r=new Rn(t===\"||\"||t===\"&&\"?DL:wL);return r.operator=t,r.left=e,r.right=n,r}function JL(t,e){const n=new Rn(EL);return n.callee=t,n.arguments=e,n}function tP(t,e,n){const r=new Rn(_L);return r.test=t,r.consequent=e,r.alternate=n,r}function Km(t){const e=new Rn(eD);return e.name=t,e}function io(t){const e=new Rn(CL);return e.value=t.value,e.raw=q.slice(t.start,t.end),t.regex&&(e.raw===\"//\"&&(e.raw=\"/(?:)/\"),e.regex=t.regex),e}function Sv(t,e,n){const r=new Rn(FL);return r.computed=t===\"[\",r.object=e,r.property=n,r.computed||(n.member=!0),r}function eP(t){const e=new Rn(ML);return e.properties=t,e}function Bv(t,e,n){const r=new Rn(kL);return r.key=e,r.value=n,r.kind=t,r}function nP(t,e){const n=new Rn($L);return n.operator=t,n.argument=e,n.prefix=!0,n}function ct(t,e){var n,r=Array.prototype.slice.call(arguments,2),i=e.replace(/%(\\d)/g,(a,u)=>(ih(u\":case\"<=\":case\">=\":case\"instanceof\":case\"in\":e=7;break;case\"<<\":case\">>\":case\">>>\":e=8;break;case\"+\":case\"-\":e=9;break;case\"*\":case\"/\":case\"%\":e=11;break}return e}function gP(){var t,e,n,r,i,a,u,o,s,l;if(t=mt,s=El(),r=mt,i=Ov(r),i===0)return s;for(r.prec=i,Pe(),e=[t,mt],u=El(),a=[s,r,u];(i=Ov(mt))>0;){for(;a.length>2&&i<=a[a.length-2].prec;)u=a.pop(),o=a.pop().value,s=a.pop(),e.pop(),n=$v(o,s,u),a.push(n);r=Pe(),r.prec=i,a.push(r),e.push(mt),n=El(),a.push(n)}for(l=a.length-1,n=a[l],e.pop();l>1;)e.pop(),n=$v(a[l-1].value,a[l-2],n),l-=2;return n}function Vi(){var t,e,n;return t=gP(),Et(\"?\")&&(Pe(),e=Vi(),ce(\":\"),n=Vi(),t=tP(t,e,n)),t}function Qm(){const t=Vi();if(Et(\",\"))throw new Error(Io);return t}function pP(t){q=t,B=0,fe=q.length,mt=null,uD();const e=Qm();if(mt.type!==As)throw new Error(\"Unexpect token after expression.\");return e}var Zm={NaN:\"NaN\",E:\"Math.E\",LN2:\"Math.LN2\",LN10:\"Math.LN10\",LOG2E:\"Math.LOG2E\",LOG10E:\"Math.LOG10E\",PI:\"Math.PI\",SQRT1_2:\"Math.SQRT1_2\",SQRT2:\"Math.SQRT2\",MIN_VALUE:\"Number.MIN_VALUE\",MAX_VALUE:\"Number.MAX_VALUE\"};function Jm(t){function e(u,o,s,l){let f=t(o[0]);return s&&(f=s+\"(\"+f+\")\",s.lastIndexOf(\"new \",0)===0&&(f=\"(\"+f+\")\")),f+\".\"+u+(l<0?\"\":l===0?\"()\":\"(\"+o.slice(1).map(t).join(\",\")+\")\")}function n(u,o,s){return l=>e(u,l,o,s)}const r=\"new Date\",i=\"String\",a=\"RegExp\";return{isNaN:\"Number.isNaN\",isFinite:\"Number.isFinite\",abs:\"Math.abs\",acos:\"Math.acos\",asin:\"Math.asin\",atan:\"Math.atan\",atan2:\"Math.atan2\",ceil:\"Math.ceil\",cos:\"Math.cos\",exp:\"Math.exp\",floor:\"Math.floor\",hypot:\"Math.hypot\",log:\"Math.log\",max:\"Math.max\",min:\"Math.min\",pow:\"Math.pow\",random:\"Math.random\",round:\"Math.round\",sin:\"Math.sin\",sqrt:\"Math.sqrt\",tan:\"Math.tan\",clamp:function(u){u.length<3&&$(\"Missing arguments to clamp function.\"),u.length>3&&$(\"Too many arguments to clamp function.\");const o=u.map(t);return\"Math.max(\"+o[1]+\", Math.min(\"+o[2]+\",\"+o[0]+\"))\"},now:\"Date.now\",utc:\"Date.UTC\",datetime:r,date:n(\"getDate\",r,0),day:n(\"getDay\",r,0),year:n(\"getFullYear\",r,0),month:n(\"getMonth\",r,0),hours:n(\"getHours\",r,0),minutes:n(\"getMinutes\",r,0),seconds:n(\"getSeconds\",r,0),milliseconds:n(\"getMilliseconds\",r,0),time:n(\"getTime\",r,0),timezoneoffset:n(\"getTimezoneOffset\",r,0),utcdate:n(\"getUTCDate\",r,0),utcday:n(\"getUTCDay\",r,0),utcyear:n(\"getUTCFullYear\",r,0),utcmonth:n(\"getUTCMonth\",r,0),utchours:n(\"getUTCHours\",r,0),utcminutes:n(\"getUTCMinutes\",r,0),utcseconds:n(\"getUTCSeconds\",r,0),utcmilliseconds:n(\"getUTCMilliseconds\",r,0),length:n(\"length\",null,-1),parseFloat:\"parseFloat\",parseInt:\"parseInt\",upper:n(\"toUpperCase\",i,0),lower:n(\"toLowerCase\",i,0),substring:n(\"substring\",i),split:n(\"split\",i),trim:n(\"trim\",i,0),regexp:a,test:n(\"test\",a),if:function(u){u.length<3&&$(\"Missing arguments to if function.\"),u.length>3&&$(\"Too many arguments to if function.\");const o=u.map(t);return\"(\"+o[0]+\"?\"+o[1]+\":\"+o[2]+\")\"}}}function mP(t){const e=t&&t.length-1;return e&&(t[0]==='\"'&&t[e]==='\"'||t[0]===\"'\"&&t[e]===\"'\")?t.slice(1,-1):t}function oD(t){t=t||{};const e=t.allowed?nn(t.allowed):{},n=t.forbidden?nn(t.forbidden):{},r=t.constants||Zm,i=(t.functions||Jm)(c),a=t.globalvar,u=t.fieldvar,o=tt(a)?a:g=>`${a}[\"${g}\"]`;let s={},l={},f=0;function c(g){if(xt(g))return g;const p=h[g.type];return p==null&&$(\"Unsupported type: \"+g.type),p(g)}const h={Literal:g=>g.raw,Identifier:g=>{const p=g.name;return f>0?p:X(n,p)?$(\"Illegal identifier: \"+p):X(r,p)?r[p]:X(e,p)?p:(s[p]=1,o(p))},MemberExpression:g=>{const p=!g.computed,m=c(g.object);p&&(f+=1);const y=c(g.property);return m===u&&(l[mP(y)]=1),p&&(f-=1),m+(p?\".\"+y:\"[\"+y+\"]\")},CallExpression:g=>{g.callee.type!==\"Identifier\"&&$(\"Illegal callee type: \"+g.callee.type);const p=g.callee.name,m=g.arguments,y=X(i,p)&&i[p];return y||$(\"Unrecognized function: \"+p),tt(y)?y(m):y+\"(\"+m.map(c).join(\",\")+\")\"},ArrayExpression:g=>\"[\"+g.elements.map(c).join(\",\")+\"]\",BinaryExpression:g=>\"(\"+c(g.left)+\" \"+g.operator+\" \"+c(g.right)+\")\",UnaryExpression:g=>\"(\"+g.operator+c(g.argument)+\")\",ConditionalExpression:g=>\"(\"+c(g.test)+\"?\"+c(g.consequent)+\":\"+c(g.alternate)+\")\",LogicalExpression:g=>\"(\"+c(g.left)+g.operator+c(g.right)+\")\",ObjectExpression:g=>\"{\"+g.properties.map(c).join(\",\")+\"}\",Property:g=>{f+=1;const p=c(g.key);return f-=1,p+\":\"+c(g.value)}};function d(g){const p={code:c(g),globals:Object.keys(s),fields:Object.keys(l)};return s={},l={},p}return d.functions=i,d.constants=r,d}const Nv=Symbol(\"vega_selection_getter\");function sD(t){return(!t.getter||!t.getter[Nv])&&(t.getter=en(t.field),t.getter[Nv]=!0),t.getter}const ty=\"intersect\",Lv=\"union\",yP=\"vlMulti\",xP=\"vlPoint\",Pv=\"or\",vP=\"and\",qn=\"_vgsid_\",qo=en(qn),bP=\"E\",AP=\"R\",wP=\"R-E\",EP=\"R-LE\",_P=\"R-RE\",Lf=\"index:unit\";function zv(t,e){for(var n=e.fields,r=e.values,i=n.length,a=0,u,o;ant(e.fields?{values:e.fields.map(r=>sD(r)(n.datum))}:{[qn]:qo(n.datum)},e))}function dD(t,e,n,r){for(var i=this.context.data[t],a=i?i.values.value:[],u={},o={},s={},l,f,c,h,d,g,p,m,y,x,v=a.length,b=0,w,E;b(A[f[C].field]=_,A),{})))}else d=qn,g=qo(l),p=u[d]||(u[d]={}),m=p[h]||(p[h]=[]),m.push(g),n&&(m=o[h]||(o[h]=[]),m.push({[qn]:g}));if(e=e||Lv,u[qn]?u[qn]=A0[`${qn}_${e}`](...Object.values(u[qn])):Object.keys(u).forEach(A=>{u[A]=Object.keys(u[A]).map(_=>u[A][_]).reduce((_,C)=>_===void 0?C:A0[`${s[A]}_${e}`](_,C))}),a=Object.keys(o),n&&a.length){const A=r?xP:yP;u[A]=e===Lv?{[Pv]:a.reduce((_,C)=>(_.push(...o[C]),_),[])}:{[vP]:a.map(_=>({[Pv]:o[_]}))}}return u}var A0={[`${qn}_union`]:rF,[`${qn}_intersect`]:eF,E_union:function(t,e){if(!t.length)return e;for(var n=0,r=e.length;ne.indexOf(n)>=0):e},R_union:function(t,e){var n=Kt(e[0]),r=Kt(e[1]);return n>r&&(n=e[1],r=e[0]),t.length?(t[0]>n&&(t[0]=n),t[1]r&&(n=e[1],r=e[0]),t.length?rr&&(t[1]=r),t):[n,r]}};const FP=\":\",MP=\"@\";function hu(t,e,n,r){e[0].type!==xn&&$(\"First argument to selection functions must be a string literal.\");const i=e[0].value,a=e.length>=2&&ut(e).value,u=\"unit\",o=MP+u,s=FP+i;a===ty&&!X(r,o)&&(r[o]=n.getData(i).indataRef(n,u)),X(r,s)||(r[s]=n.getData(i).tuplesRef())}function gD(t){const e=this.context.data[t];return e?e.values.value:[]}function kP(t,e,n){const r=this.context.data[t][\"index:\"+e],i=r?r.value.get(n):void 0;return i&&i.count}function $P(t,e){const n=this.context.dataflow,r=this.context.data[t],i=r.input;return n.pulse(i,n.changeset().remove(We).insert(e)),1}function SP(t,e,n){if(t){const r=this.context.dataflow,i=t.mark.source;r.pulse(i,r.changeset().encode(t,e))}return n!==void 0?n:t}const _s=t=>function(e,n){return this.context.dataflow.locale()[t](n)(e)},BP=_s(\"format\"),pD=_s(\"timeFormat\"),TP=_s(\"utcFormat\"),RP=_s(\"timeParse\"),OP=_s(\"utcParse\"),nl=new Date(2e3,0,1);function uh(t,e,n){return!Number.isInteger(t)||!Number.isInteger(e)?\"\":(nl.setYear(2e3),nl.setMonth(t),nl.setDate(e),pD.call(this,nl,n))}function NP(t){return uh.call(this,t,1,\"%B\")}function LP(t){return uh.call(this,t,1,\"%b\")}function PP(t){return uh.call(this,0,2+t,\"%A\")}function zP(t){return uh.call(this,0,2+t,\"%a\")}const IP=\":\",UP=\"@\",u1=\"%\",mD=\"$\";function ey(t,e,n,r){e[0].type!==xn&&$(\"First argument to data functions must be a string literal.\");const i=e[0].value,a=IP+i;if(!X(a,r))try{r[a]=n.getData(i).tuplesRef()}catch{}}function qP(t,e,n,r){e[0].type!==xn&&$(\"First argument to indata must be a string literal.\"),e[1].type!==xn&&$(\"Second argument to indata must be a string literal.\");const i=e[0].value,a=e[1].value,u=UP+a;X(u,r)||(r[u]=n.getData(i).indataRef(n,a))}function Fe(t,e,n,r){if(e[0].type===xn)Iv(n,r,e[0].value);else for(t in n.scales)Iv(n,r,t)}function Iv(t,e,n){const r=u1+n;if(!X(e,r))try{e[r]=t.scaleRef(n)}catch{}}function ur(t,e){if(tt(t))return t;if(xt(t)){const n=e.scales[t];return n&&QE(n.value)?n.value:void 0}}function jP(t,e,n){e.__bandwidth=i=>i&&i.bandwidth?i.bandwidth():0,n._bandwidth=Fe,n._range=Fe,n._scale=Fe;const r=i=>\"_[\"+(i.type===xn?Y(u1+i.value):Y(u1)+\"+\"+t(i))+\"]\";return{_bandwidth:i=>`this.__bandwidth(${r(i[0])})`,_range:i=>`${r(i[0])}.range()`,_scale:i=>`${r(i[0])}(${t(i[1])})`}}function ny(t,e){return function(n,r,i){if(n){const a=ur(n,(i||this).context);return a&&a.path[t](r)}else return e(r)}}const WP=ny(\"area\",$A),YP=ny(\"bounds\",OA),HP=ny(\"centroid\",zA);function GP(t,e){const n=ur(t,(e||this).context);return n&&n.scale()}function XP(t){const e=this.context.group;let n=!1;if(e)for(;t;){if(t===e){n=!0;break}t=t.mark.group}return n}function ry(t,e,n){try{t[e].apply(t,[\"EXPRESSION\"].concat([].slice.call(n)))}catch(r){t.warn(r)}return n[n.length-1]}function VP(){return ry(this.context.dataflow,\"warn\",arguments)}function KP(){return ry(this.context.dataflow,\"info\",arguments)}function QP(){return ry(this.context.dataflow,\"debug\",arguments)}function w0(t){const e=t/255;return e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4)}function o1(t){const e=Vn(t),n=w0(e.r),r=w0(e.g),i=w0(e.b);return .2126*n+.7152*r+.0722*i}function ZP(t,e){const n=o1(t),r=o1(e),i=Math.max(n,r),a=Math.min(n,r);return(i+.05)/(a+.05)}function JP(){const t=[].slice.call(arguments);return t.unshift({}),nt(...t)}function yD(t,e){return t===e||t!==t&&e!==e?!0:U(t)?U(e)&&t.length===e.length?tz(t,e):!1:et(t)&&et(e)?xD(t,e):!1}function tz(t,e){for(let n=0,r=t.length;nxD(t,e)}function ez(t,e,n,r,i,a){const u=this.context.dataflow,o=this.context.data[t],s=o.input,l=u.stamp();let f=o.changes,c,h;if(u._trigger===!1||!(s.value.length||e||r))return 0;if((!f||f.stamp{o.modified=!0,u.pulse(s,f).run()},!0,1)),n&&(c=n===!0?We:U(n)||su(n)?n:Uv(n),f.remove(c)),e&&f.insert(e),r&&(c=Uv(r),s.value.some(c)?f.remove(c):f.insert(r)),i)for(h in a)f.modify(i,h,a[h]);return 1}function nz(t){const e=t.touches,n=e[0].clientX-e[1].clientX,r=e[0].clientY-e[1].clientY;return Math.hypot(n,r)}function rz(t){const e=t.touches;return Math.atan2(e[0].clientY-e[1].clientY,e[0].clientX-e[1].clientX)}const qv={};function iz(t,e){const n=qv[e]||(qv[e]=en(e));return U(t)?t.map(n):n(t)}function iy(t){return U(t)||ArrayBuffer.isView(t)?t:null}function ay(t){return iy(t)||(xt(t)?t:null)}function az(t){for(var e=arguments.length,n=new Array(e>1?e-1:0),r=1;r1?e-1:0),r=1;r1?e-1:0),r=1;r1?e-1:0),r=1;ra.stop(l(f),t(f))),a}function vz(t,e,n){const r=ur(t,(n||this).context);return function(i){return r?r.path.context(i)(e):\"\"}}function bz(t){let e=null;return function(n){return n?Ha(n,e=e||Gi(t)):t}}const vD=t=>t.data;function bD(t,e){const n=gD.call(e,t);return n.root&&n.root.lookup||{}}function Az(t,e,n){const r=bD(t,this),i=r[e],a=r[n];return i&&a?i.path(a).map(vD):void 0}function wz(t,e){const n=bD(t,this)[e];return n?n.ancestors().map(vD):void 0}const AD=()=>typeof window<\"u\"&&window||null;function Ez(){const t=AD();return t?t.screen:{}}function _z(){const t=AD();return t?[t.innerWidth,t.innerHeight]:[void 0,void 0]}function Cz(){const t=this.context.dataflow,e=t.container&&t.container();return e?[e.clientWidth,e.clientHeight]:[void 0,void 0]}function wD(t,e,n){if(!t)return[];const[r,i]=t,a=new St().set(r[0],r[1],i[0],i[1]),u=n||this.context.dataflow.scenegraph().root;return cm(u,a,Dz(e))}function Dz(t){let e=null;if(t){const n=H(t.marktype),r=H(t.markname);e=i=>(!n.length||n.some(a=>i.marktype===a))&&(!r.length||r.some(a=>i.name===a))}return e}function Fz(t,e,n){let r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:5;t=H(t);const i=t[t.length-1];return i===void 0||Math.hypot(i[0]-e,i[1]-n)>r?[...t,[e,n]]:t}function Mz(t){return H(t).reduce((e,n,r)=>{let[i,a]=n;return e+=r==0?`M ${i},${a} `:r===t.length-1?\" Z\":`L ${i},${a} `},\"\")}function kz(t,e,n){const{x:r,y:i,mark:a}=n,u=new St().set(Number.MAX_SAFE_INTEGER,Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER,Number.MIN_SAFE_INTEGER);for(const[s,l]of e)su.x2&&(u.x2=s),lu.y2&&(u.y2=l);return u.translate(r,i),wD([[u.x1,u.y1],[u.x2,u.y2]],t,a).filter(s=>$z(s.x,s.y,e))}function $z(t,e,n){let r=0;for(let i=0,a=n.length-1;ie!=o>e&&t<(u-s)*(e-l)/(o-l)+s&&r++}return r&1}const jo={random(){return un()},cumulativeNormal:is,cumulativeLogNormal:$c,cumulativeUniform:Rc,densityNormal:Fc,densityLogNormal:kc,densityUniform:Tc,quantileNormal:as,quantileLogNormal:Sc,quantileUniform:Oc,sampleNormal:rs,sampleLogNormal:Mc,sampleUniform:Bc,isArray:U,isBoolean:Ag,isDate:Cr,isDefined(t){return t!==void 0},isNumber:Mr,isObject:et,isRegExp:wg,isString:xt,isTuple:su,isValid(t){return t!=null&&t===t},toBoolean:xc,toDate(t){return vc(t)},toNumber:Kt,toString:bc,indexof:uz,join:az,lastindexof:oz,replace:lz,reverse:fz,slice:sz,flush:bg,lerp:_g,merge:JP,pad:Cg,peek:ut,pluck:iz,span:au,inrange:Bi,truncate:Dg,rgb:Vn,lab:wo,hcl:Eo,hsl:Ao,luminance:o1,contrast:ZP,sequence:Ie,format:BP,utcFormat:TP,utcParse:OP,utcOffset:Ng,utcSequence:Pg,timeFormat:pD,timeParse:RP,timeOffset:Og,timeSequence:Lg,timeUnitSpecifier:kg,monthFormat:NP,monthAbbrevFormat:LP,dayFormat:PP,dayAbbrevFormat:zP,quarter:pg,utcquarter:mg,week:Bg,utcweek:Rg,dayofyear:Sg,utcdayofyear:Tg,warn:VP,info:KP,debug:QP,extent(t){return Sn(t)},inScope:XP,intersect:wD,clampRange:yg,pinchDistance:nz,pinchAngle:rz,screen:Ez,containerSize:Cz,windowSize:_z,bandspace:cz,setdata:$P,pathShape:bz,panLinear:cg,panLog:hg,panPow:dg,panSymlog:gg,zoomLinear:gc,zoomLog:pc,zoomPow:Bo,zoomSymlog:mc,encode:SP,modify:ez,lassoAppend:Fz,lassoPath:Mz,intersectLasso:kz},Sz=[\"view\",\"item\",\"group\",\"xy\",\"x\",\"y\"],Bz=\"event.vega.\",ED=\"this.\",uy={},_D={forbidden:[\"_\"],allowed:[\"datum\",\"event\",\"item\"],fieldvar:\"datum\",globalvar:t=>`_[${Y(mD+t)}]`,functions:Tz,constants:Zm,visitors:uy},s1=oD(_D);function Tz(t){const e=Jm(t);Sz.forEach(n=>e[n]=Bz+n);for(const n in jo)e[n]=ED+n;return nt(e,jP(t,jo,uy)),e}function Tt(t,e,n){return arguments.length===1?jo[t]:(jo[t]=e,n&&(uy[t]=n),s1&&(s1.functions[t]=ED+t),this)}Tt(\"bandwidth\",hz,Fe);Tt(\"copy\",dz,Fe);Tt(\"domain\",gz,Fe);Tt(\"range\",mz,Fe);Tt(\"invert\",pz,Fe);Tt(\"scale\",yz,Fe);Tt(\"gradient\",xz,Fe);Tt(\"geoArea\",WP,Fe);Tt(\"geoBounds\",YP,Fe);Tt(\"geoCentroid\",HP,Fe);Tt(\"geoShape\",vz,Fe);Tt(\"geoScale\",GP,Fe);Tt(\"indata\",kP,qP);Tt(\"data\",gD,ey);Tt(\"treePath\",Az,ey);Tt(\"treeAncestors\",wz,ey);Tt(\"vlSelectionTest\",lD,hu);Tt(\"vlSelectionIdTest\",cD,hu);Tt(\"vlSelectionResolve\",dD,hu);Tt(\"vlSelectionTuples\",hD);function tr(t,e){const n={};let r;try{t=xt(t)?t:Y(t)+\"\",r=pP(t)}catch{$(\"Expression parse error: \"+t)}r.visit(a=>{if(a.type!==tD)return;const u=a.callee.name,o=_D.visitors[u];o&&o(u,a.arguments,e,n)});const i=s1(r);return i.globals.forEach(a=>{const u=mD+a;!X(n,u)&&e.getSignal(a)&&(n[u]=e.signalRef(a))}),{$expr:nt({code:i.code},e.options.ast?{ast:r}:null),$fields:i.fields,$params:n}}function Rz(t){const e=this,n=t.operators||[];return t.background&&(e.background=t.background),t.eventConfig&&(e.eventConfig=t.eventConfig),t.locale&&(e.locale=t.locale),n.forEach(r=>e.parseOperator(r)),n.forEach(r=>e.parseOperatorParameters(r)),(t.streams||[]).forEach(r=>e.parseStream(r)),(t.updates||[]).forEach(r=>e.parseUpdate(r)),e.resolve()}const Oz=nn([\"rule\"]),jv=nn([\"group\",\"image\",\"rect\"]);function Nz(t,e){let n=\"\";return Oz[e]||(t.x2&&(t.x?(jv[e]&&(n+=\"if(o.x>o.x2)$=o.x,o.x=o.x2,o.x2=$;\"),n+=\"o.width=o.x2-o.x;\"):n+=\"o.x=o.x2-(o.width||0);\"),t.xc&&(n+=\"o.x=o.xc-(o.width||0)/2;\"),t.y2&&(t.y?(jv[e]&&(n+=\"if(o.y>o.y2)$=o.y,o.y=o.y2,o.y2=$;\"),n+=\"o.height=o.y2-o.y;\"):n+=\"o.y=o.y2-(o.height||0);\"),t.yc&&(n+=\"o.y=o.yc-(o.height||0)/2;\")),n}function oy(t){return(t+\"\").toLowerCase()}function Lz(t){return oy(t)===\"operator\"}function Pz(t){return oy(t)===\"collect\"}function Tu(t,e,n){n.endsWith(\";\")||(n=\"return(\"+n+\");\");const r=Function(...e.concat(n));return t&&t.functions?r.bind(t.functions):r}function zz(t,e,n,r){return`((u = ${t}) < (v = ${e}) || u == null) && v != null ? ${n}\n : (u > v || v == null) && u != null ? ${r}\n : ((v = v instanceof Date ? +v : v), (u = u instanceof Date ? +u : u)) !== u && v === v ? ${n}\n : v !== v && u === u ? ${r} : `}var Iz={operator:(t,e)=>Tu(t,[\"_\"],e.code),parameter:(t,e)=>Tu(t,[\"datum\",\"_\"],e.code),event:(t,e)=>Tu(t,[\"event\"],e.code),handler:(t,e)=>{const n=`var datum=event.item&&event.item.datum;return ${e.code};`;return Tu(t,[\"_\",\"event\"],n)},encode:(t,e)=>{const{marktype:n,channels:r}=e;let i=\"var o=item,datum=o.datum,m=0,$;\";for(const a in r){const u=\"o[\"+Y(a)+\"]\";i+=`$=${r[a].code};if(${u}!==$)${u}=$,m=1;`}return i+=Nz(r,n),i+=\"return m;\",Tu(t,[\"item\",\"_\"],i)},codegen:{get(t){const e=`[${t.map(Y).join(\"][\")}]`,n=Function(\"_\",`return _${e};`);return n.path=e,n},comparator(t,e){let n;const r=(a,u)=>{const o=e[u];let s,l;return a.path?(s=`a${a.path}`,l=`b${a.path}`):((n=n||{})[\"f\"+u]=a,s=`this.f${u}(a)`,l=`this.f${u}(b)`),zz(s,l,-o,o)},i=Function(\"a\",\"b\",\"var u, v; return \"+t.map(r).join(\"\")+\"0;\");return n?i.bind(n):i}}};function Uz(t){const e=this;Lz(t.type)||!t.type?e.operator(t,t.update?e.operatorExpression(t.update):null):e.transform(t,t.type)}function qz(t){const e=this;if(t.params){const n=e.get(t.id);n||$(\"Invalid operator id: \"+t.id),e.dataflow.connect(n,n.parameters(e.parseParameters(t.params),t.react,t.initonly))}}function jz(t,e){e=e||{};const n=this;for(const r in t){const i=t[r];e[r]=U(i)?i.map(a=>Wv(a,n,e)):Wv(i,n,e)}return e}function Wv(t,e,n){if(!t||!et(t))return t;for(let r=0,i=Yv.length,a;ri&&i.$tupleid?K:i);return e.fn[n]||(e.fn[n]=xg(r,t.$order,e.expr.codegen))}function Vz(t,e){const n=t.$encode,r={};for(const i in n){const a=n[i];r[i]=Ge(e.encodeExpression(a.$expr),a.$fields),r[i].output=a.$output}return r}function Kz(t,e){return e}function Qz(t,e){const n=t.$subflow;return function(r,i,a){const u=e.fork().parse(n),o=u.get(n.operators[0].id),s=u.signals.parent;return s&&s.set(a),o.detachSubflow=()=>e.detach(u),o}}function Zz(){return K}function Jz(t){var e=this,n=t.filter!=null?e.eventExpression(t.filter):void 0,r=t.stream!=null?e.get(t.stream):void 0,i;t.source?r=e.events(t.source,t.type,n):t.merge&&(i=t.merge.map(a=>e.get(a)),r=i[0].merge.apply(i[0],i.slice(1))),t.between&&(i=t.between.map(a=>e.get(a)),r=r.between(i[0],i[1])),t.filter&&(r=r.filter(n)),t.throttle!=null&&(r=r.throttle(+t.throttle)),t.debounce!=null&&(r=r.debounce(+t.debounce)),r==null&&$(\"Invalid stream definition: \"+JSON.stringify(t)),t.consume&&r.consume(!0),e.stream(t,r)}function tI(t){var e=this,n=et(n=t.source)?n.$ref:n,r=e.get(n),i=null,a=t.update,u=void 0;r||$(\"Source not defined: \"+t.source),i=t.target&&t.target.$expr?e.eventExpression(t.target.$expr):e.get(t.target),a&&a.$expr&&(a.$params&&(u=e.parseParameters(a.$params)),a=e.handlerExpression(a.$expr)),e.update(t,r,i,a,u)}const eI={skip:!0};function nI(t){var e=this,n={};if(t.signals){var r=n.signals={};Object.keys(e.signals).forEach(a=>{const u=e.signals[a];t.signals(a,u)&&(r[a]=u.value)})}if(t.data){var i=n.data={};Object.keys(e.data).forEach(a=>{const u=e.data[a];t.data(a,u)&&(i[a]=u.input.value)})}return e.subcontext&&t.recurse!==!1&&(n.subcontext=e.subcontext.map(a=>a.getState(t))),n}function rI(t){var e=this,n=e.dataflow,r=t.data,i=t.signals;Object.keys(i||{}).forEach(a=>{n.update(e.signals[a],i[a],eI)}),Object.keys(r||{}).forEach(a=>{n.pulse(e.data[a].input,n.changeset().remove(We).insert(r[a]))}),(t.subcontext||[]).forEach((a,u)=>{const o=e.subcontext[u];o&&o.setState(a)})}function CD(t,e,n,r){return new DD(t,e,n,r)}function DD(t,e,n,r){this.dataflow=t,this.transforms=e,this.events=t.events.bind(t),this.expr=r||Iz,this.signals={},this.scales={},this.nodes={},this.data={},this.fn={},n&&(this.functions=Object.create(n),this.functions.context=this)}function Hv(t){this.dataflow=t.dataflow,this.transforms=t.transforms,this.events=t.events,this.expr=t.expr,this.signals=Object.create(t.signals),this.scales=Object.create(t.scales),this.nodes=Object.create(t.nodes),this.data=Object.create(t.data),this.fn=Object.create(t.fn),t.functions&&(this.functions=Object.create(t.functions),this.functions.context=this)}DD.prototype=Hv.prototype={fork(){const t=new Hv(this);return(this.subcontext||(this.subcontext=[])).push(t),t},detach(t){this.subcontext=this.subcontext.filter(n=>n!==t);const e=Object.keys(t.nodes);for(const n of e)t.nodes[n]._targets=null;for(const n of e)t.nodes[n].detach();t.nodes=null},get(t){return this.nodes[t]},set(t,e){return this.nodes[t]=e},add(t,e){const n=this,r=n.dataflow,i=t.value;if(n.set(t.id,e),Pz(t.type)&&i&&(i.$ingest?r.ingest(e,i.$ingest,i.$format):i.$request?r.preload(e,i.$request,i.$format):r.pulse(e,r.changeset().insert(i))),t.root&&(n.root=e),t.parent){let a=n.get(t.parent.$ref);a?(r.connect(a,[e]),e.targets().add(a)):(n.unresolved=n.unresolved||[]).push(()=>{a=n.get(t.parent.$ref),r.connect(a,[e]),e.targets().add(a)})}if(t.signal&&(n.signals[t.signal]=e),t.scale&&(n.scales[t.scale]=e),t.data)for(const a in t.data){const u=n.data[a]||(n.data[a]={});t.data[a].forEach(o=>u[o]=e)}},resolve(){return(this.unresolved||[]).forEach(t=>t()),delete this.unresolved,this},operator(t,e){this.add(t,this.dataflow.add(t.value,e))},transform(t,e){this.add(t,this.dataflow.add(this.transforms[oy(e)]))},stream(t,e){this.set(t.id,e)},update(t,e,n,r,i){this.dataflow.on(e,n,r,i,t.options)},operatorExpression(t){return this.expr.operator(this,t)},parameterExpression(t){return this.expr.parameter(this,t)},eventExpression(t){return this.expr.event(this,t)},handlerExpression(t){return this.expr.handler(this,t)},encodeExpression(t){return this.expr.encode(this,t)},parse:Rz,parseOperator:Uz,parseOperatorParameters:qz,parseParameters:jz,parseStream:Jz,parseUpdate:tI,getState:nI,setState:rI};function iI(t){const e=t.container();e&&(e.setAttribute(\"role\",\"graphics-document\"),e.setAttribute(\"aria-roleDescription\",\"visualization\"),FD(e,t.description()))}function FD(t,e){t&&(e==null?t.removeAttribute(\"aria-label\"):t.setAttribute(\"aria-label\",e))}function aI(t){t.add(null,e=>(t._background=e.bg,t._resize=1,e.bg),{bg:t._signals.background})}const E0=\"default\";function uI(t){const e=t._signals.cursor||(t._signals.cursor=t.add({user:E0,item:null}));t.on(t.events(\"view\",\"mousemove\"),e,(n,r)=>{const i=e.value,a=i?xt(i)?i:i.user:E0,u=r.item&&r.item.cursor||null;return i&&a===i.user&&u==i.item?i:{user:a,item:u}}),t.add(null,function(n){let r=n.cursor,i=this.value;return xt(r)||(i=r.item,r=r.user),l1(t,r&&r!==E0?r:i||r),i},{cursor:e})}function l1(t,e){const n=t.globalCursor()?typeof document<\"u\"&&document.body:t.container();if(n)return e==null?n.style.removeProperty(\"cursor\"):n.style.cursor=e}function Pf(t,e){var n=t._runtime.data;return X(n,e)||$(\"Unrecognized data set: \"+e),n[e]}function oI(t,e){return arguments.length<2?Pf(this,t).values.value:oh.call(this,t,ra().remove(We).insert(e))}function oh(t,e){eE(e)||$(\"Second argument to changes must be a changeset.\");const n=Pf(this,t);return n.modified=!0,this.pulse(n.input,e)}function sI(t,e){return oh.call(this,t,ra().insert(e))}function lI(t,e){return oh.call(this,t,ra().remove(e))}function MD(t){var e=t.padding();return Math.max(0,t._viewWidth+e.left+e.right)}function kD(t){var e=t.padding();return Math.max(0,t._viewHeight+e.top+e.bottom)}function sh(t){var e=t.padding(),n=t._origin;return[e.left+n[0],e.top+n[1]]}function fI(t){var e=sh(t),n=MD(t),r=kD(t);t._renderer.background(t.background()),t._renderer.resize(n,r,e),t._handler.origin(e),t._resizeListeners.forEach(i=>{try{i(n,r)}catch(a){t.error(a)}})}function cI(t,e,n){var r=t._renderer,i=r&&r.canvas(),a,u,o;return i&&(o=sh(t),u=e.changedTouches?e.changedTouches[0]:e,a=Jc(u,i),a[0]-=o[0],a[1]-=o[1]),e.dataflow=t,e.item=n,e.vega=hI(t,n,a),e}function hI(t,e,n){const r=e?e.mark.marktype===\"group\"?e:e.mark.group:null;function i(u){var o=r,s;if(u){for(s=e;s;s=s.mark.group)if(s.mark.name===u){o=s;break}}return o&&o.mark&&o.mark.interactive?o:{}}function a(u){if(!u)return n;xt(u)&&(u=i(u));const o=n.slice();for(;u;)o[0]-=u.x||0,o[1]-=u.y||0,u=u.mark&&u.mark.group;return o}return{view:pe(t),item:pe(e||{}),group:i,xy:a,x:u=>a(u)[0],y:u=>a(u)[1]}}const Gv=\"view\",dI=\"timer\",gI=\"window\",pI={trap:!1};function mI(t){const e=nt({defaults:{}},t),n=(r,i)=>{i.forEach(a=>{U(r[a])&&(r[a]=nn(r[a]))})};return n(e.defaults,[\"prevent\",\"allow\"]),n(e,[\"view\",\"window\",\"selector\"]),e}function $D(t,e,n,r){t._eventListeners.push({type:n,sources:H(e),handler:r})}function yI(t,e){var n=t._eventConfig.defaults,r=n.prevent,i=n.allow;return r===!1||i===!0?!1:r===!0||i===!1?!0:r?r[e]:i?!i[e]:t.preventDefault()}function rl(t,e,n){const r=t._eventConfig&&t._eventConfig[e];return r===!1||et(r)&&!r[n]?(t.warn(`Blocked ${e} ${n} event listener.`),!1):!0}function xI(t,e,n){var r=this,i=new Dc(n),a=function(l,f){r.runAsync(null,()=>{t===Gv&&yI(r,e)&&l.preventDefault(),i.receive(cI(r,l,f))})},u;if(t===dI)rl(r,\"timer\",e)&&r.timer(a,e);else if(t===Gv)rl(r,\"view\",e)&&r.addEventListener(e,a,pI);else if(t===gI?rl(r,\"window\",e)&&typeof window<\"u\"&&(u=[window]):typeof document<\"u\"&&rl(r,\"selector\",e)&&(u=Array.from(document.querySelectorAll(t))),!u)r.warn(\"Can not resolve event source: \"+t);else{for(var o=0,s=u.length;o=0;)e[r].stop();for(r=n.length;--r>=0;)for(a=n[r],i=a.sources.length;--i>=0;)a.sources[i].removeEventListener(a.type,a.handler);return t&&t.call(this,this._handler,null,null,null),this}function tn(t,e,n){const r=document.createElement(t);for(const i in e)r.setAttribute(i,e[i]);return n!=null&&(r.textContent=n),r}const AI=\"vega-bind\",wI=\"vega-bind-name\",EI=\"vega-bind-radio\";function _I(t,e,n){if(!e)return;const r=n.param;let i=n.state;return i||(i=n.state={elements:null,active:!1,set:null,update:u=>{u!=t.signal(r.signal)&&t.runAsync(null,()=>{i.source=!0,t.signal(r.signal,u)})}},r.debounce&&(i.update=vg(r.debounce,i.update))),(r.input==null&&r.element?CI:FI)(i,e,r,t),i.active||(t.on(t._signals[r.signal],null,()=>{i.source?i.source=!1:i.set(t.signal(r.signal))}),i.active=!0),i}function CI(t,e,n,r){const i=n.event||\"input\",a=()=>t.update(e.value);r.signal(n.signal,e.value),e.addEventListener(i,a),$D(r,e,i,a),t.set=u=>{e.value=u,e.dispatchEvent(DI(i))}}function DI(t){return typeof Event<\"u\"?new Event(t):{type:t}}function FI(t,e,n,r){const i=r.signal(n.signal),a=tn(\"div\",{class:AI}),u=n.input===\"radio\"?a:a.appendChild(tn(\"label\"));u.appendChild(tn(\"span\",{class:wI},n.name||n.signal)),e.appendChild(a);let o=MI;switch(n.input){case\"checkbox\":o=kI;break;case\"select\":o=$I;break;case\"radio\":o=SI;break;case\"range\":o=BI;break}o(t,u,n,i)}function MI(t,e,n,r){const i=tn(\"input\");for(const a in n)a!==\"signal\"&&a!==\"element\"&&i.setAttribute(a===\"input\"?\"type\":a,n[a]);i.setAttribute(\"name\",n.signal),i.value=r,e.appendChild(i),i.addEventListener(\"input\",()=>t.update(i.value)),t.elements=[i],t.set=a=>i.value=a}function kI(t,e,n,r){const i={type:\"checkbox\",name:n.signal};r&&(i.checked=!0);const a=tn(\"input\",i);e.appendChild(a),a.addEventListener(\"change\",()=>t.update(a.checked)),t.elements=[a],t.set=u=>a.checked=!!u||null}function $I(t,e,n,r){const i=tn(\"select\",{name:n.signal}),a=n.labels||[];n.options.forEach((u,o)=>{const s={value:u};zf(u,r)&&(s.selected=!0),i.appendChild(tn(\"option\",s,(a[o]||u)+\"\"))}),e.appendChild(i),i.addEventListener(\"change\",()=>{t.update(n.options[i.selectedIndex])}),t.elements=[i],t.set=u=>{for(let o=0,s=n.options.length;o{const s={type:\"radio\",name:n.signal,value:u};zf(u,r)&&(s.checked=!0);const l=tn(\"input\",s);l.addEventListener(\"change\",()=>t.update(u));const f=tn(\"label\",{},(a[o]||u)+\"\");return f.prepend(l),i.appendChild(f),l}),t.set=u=>{const o=t.elements,s=o.length;for(let l=0;l{s.textContent=o.value,t.update(+o.value)};o.addEventListener(\"input\",l),o.addEventListener(\"change\",l),t.elements=[o],t.set=f=>{o.value=f,s.textContent=f}}function zf(t,e){return t===e||t+\"\"==e+\"\"}function SD(t,e,n,r,i,a){return e=e||new r(t.loader()),e.initialize(n,MD(t),kD(t),sh(t),i,a).background(t.background())}function sy(t,e){return e?function(){try{e.apply(this,arguments)}catch(n){t.error(n)}}:null}function TI(t,e,n,r){const i=new r(t.loader(),sy(t,t.tooltip())).scene(t.scenegraph().root).initialize(n,sh(t),t);return e&&e.handlers().forEach(a=>{i.on(a.type,a.handler)}),i}function RI(t,e){const n=this,r=n._renderType,i=n._eventConfig.bind,a=th(r);t=n._el=t?_0(n,t,!0):null,iI(n),a||n.error(\"Unrecognized renderer type: \"+r);const u=a.handler||bs,o=t?a.renderer:a.headless;return n._renderer=o?SD(n,n._renderer,t,o):null,n._handler=TI(n,n._handler,t,u),n._redraw=!0,t&&i!==\"none\"&&(e=e?n._elBind=_0(n,e,!0):t.appendChild(tn(\"form\",{class:\"vega-bindings\"})),n._bind.forEach(s=>{s.param.element&&i!==\"container\"&&(s.element=_0(n,s.param.element,!!s.param.input))}),n._bind.forEach(s=>{_I(n,s.element||e,s)})),n}function _0(t,e,n){if(typeof e==\"string\")if(typeof document<\"u\"){if(e=document.querySelector(e),!e)return t.error(\"Signal bind element not found: \"+e),null}else return t.error(\"DOM document instance not found.\"),null;if(e&&n)try{e.textContent=\"\"}catch(r){e=null,t.error(r)}return e}const Ru=t=>+t||0,OI=t=>({top:t,bottom:t,left:t,right:t});function Qv(t){return et(t)?{top:Ru(t.top),bottom:Ru(t.bottom),left:Ru(t.left),right:Ru(t.right)}:OI(Ru(t))}async function ly(t,e,n,r){const i=th(e),a=i&&i.headless;return a||$(\"Unrecognized renderer type: \"+e),await t.runAsync(),SD(t,null,null,a,n,r).renderAsync(t._scenegraph.root)}async function NI(t,e){t!==Hr.Canvas&&t!==Hr.SVG&&t!==Hr.PNG&&$(\"Unrecognized image type: \"+t);const n=await ly(this,t,e);return t===Hr.SVG?LI(n.svg(),\"image/svg+xml\"):n.canvas().toDataURL(\"image/png\")}function LI(t,e){const n=new Blob([t],{type:e});return window.URL.createObjectURL(n)}async function PI(t,e){return(await ly(this,Hr.Canvas,t,e)).canvas()}async function zI(t){return(await ly(this,Hr.SVG,t)).svg()}function II(t,e,n){return CD(t,qa,jo,n).parse(e)}function UI(t){var e=this._runtime.scales;return X(e,t)||$(\"Unrecognized scale or projection: \"+t),e[t].value}var BD=\"width\",TD=\"height\",fy=\"padding\",Zv={skip:!0};function RD(t,e){var n=t.autosize(),r=t.padding();return e-(n&&n.contains===fy?r.left+r.right:0)}function OD(t,e){var n=t.autosize(),r=t.padding();return e-(n&&n.contains===fy?r.top+r.bottom:0)}function qI(t){var e=t._signals,n=e[BD],r=e[TD],i=e[fy];function a(){t._autosize=t._resize=1}t._resizeWidth=t.add(null,o=>{t._width=o.size,t._viewWidth=RD(t,o.size),a()},{size:n}),t._resizeHeight=t.add(null,o=>{t._height=o.size,t._viewHeight=OD(t,o.size),a()},{size:r});const u=t.add(null,a,{pad:i});t._resizeWidth.rank=n.rank+1,t._resizeHeight.rank=r.rank+1,u.rank=i.rank+1}function jI(t,e,n,r,i,a){this.runAfter(u=>{let o=0;u._autosize=0,u.width()!==n&&(o=1,u.signal(BD,n,Zv),u._resizeWidth.skip(!0)),u.height()!==r&&(o=1,u.signal(TD,r,Zv),u._resizeHeight.skip(!0)),u._viewWidth!==t&&(u._resize=1,u._viewWidth=t),u._viewHeight!==e&&(u._resize=1,u._viewHeight=e),(u._origin[0]!==i[0]||u._origin[1]!==i[1])&&(u._resize=1,u._origin=i),o&&u.run(\"enter\"),a&&u.runAfter(s=>s.resize())},!1,1)}function WI(t){return this._runtime.getState(t||{data:YI,signals:HI,recurse:!0})}function YI(t,e){return e.modified&&U(e.input.value)&&t.indexOf(\"_:vega:_\")}function HI(t,e){return!(t===\"parent\"||e instanceof qa.proxy)}function GI(t){return this.runAsync(null,e=>{e._trigger=!1,e._runtime.setState(t)},e=>{e._trigger=!0}),this}function XI(t,e){function n(r){t({timestamp:Date.now(),elapsed:r})}this._timers.push(GF(n,e))}function VI(t,e,n,r){const i=t.element();i&&i.setAttribute(\"title\",KI(r))}function KI(t){return t==null?\"\":U(t)?ND(t):et(t)&&!Cr(t)?QI(t):t+\"\"}function QI(t){return Object.keys(t).map(e=>{const n=t[e];return e+\": \"+(U(n)?ND(n):LD(n))}).join(`\n`)}function ND(t){return\"[\"+t.map(LD).join(\", \")+\"]\"}function LD(t){return U(t)?\"[…]\":et(t)&&!Cr(t)?\"{…}\":t}function PD(t,e){const n=this;if(e=e||{},ka.call(n),e.loader&&n.loader(e.loader),e.logger&&n.logger(e.logger),e.logLevel!=null&&n.logLevel(e.logLevel),e.locale||t.locale){const a=nt({},t.locale,e.locale);n.locale(Y3(a.number,a.time))}n._el=null,n._elBind=null,n._renderType=e.renderer||Hr.Canvas,n._scenegraph=new em;const r=n._scenegraph.root;n._renderer=null,n._tooltip=e.tooltip||VI,n._redraw=!0,n._handler=new bs().scene(r),n._globalCursor=!1,n._preventDefault=!1,n._timers=[],n._eventListeners=[],n._resizeListeners=[],n._eventConfig=mI(t.eventConfig),n.globalCursor(n._eventConfig.globalCursor);const i=II(n,t,e.expr);n._runtime=i,n._signals=i.signals,n._bind=(t.bindings||[]).map(a=>({state:null,param:nt({},a)})),i.root&&i.root.set(r),r.source=i.data.root.input,n.pulse(i.data.root.input,n.changeset().insert(r.items)),n._width=n.width(),n._height=n.height(),n._viewWidth=RD(n,n._width),n._viewHeight=OD(n,n._height),n._origin=[0,0],n._resize=0,n._autosize=1,qI(n),aI(n),uI(n),n.description(t.description),e.hover&&n.hover(),e.container&&n.initialize(e.container,e.bind)}function il(t,e){return X(t._signals,e)?t._signals[e]:$(\"Unrecognized signal name: \"+Y(e))}function zD(t,e){const n=(t._targets||[]).filter(r=>r._update&&r._update.handler===e);return n.length?n[0]:null}function Jv(t,e,n,r){let i=zD(n,r);return i||(i=sy(t,()=>r(e,n.value)),i.handler=r,t.on(n,null,i)),t}function tb(t,e,n){const r=zD(e,n);return r&&e._targets.remove(r),t}L(PD,ka,{async evaluate(t,e,n){if(await ka.prototype.evaluate.call(this,t,e),this._redraw||this._resize)try{this._renderer&&(this._resize&&(this._resize=0,fI(this)),await this._renderer.renderAsync(this._scenegraph.root)),this._redraw=!1}catch(r){this.error(r)}return n&&cl(this,n),this},dirty(t){this._redraw=!0,this._renderer&&this._renderer.dirty(t)},description(t){if(arguments.length){const e=t!=null?t+\"\":null;return e!==this._desc&&FD(this._el,this._desc=e),this}return this._desc},container(){return this._el},scenegraph(){return this._scenegraph},origin(){return this._origin.slice()},signal(t,e,n){const r=il(this,t);return arguments.length===1?r.value:this.update(r,e,n)},width(t){return arguments.length?this.signal(\"width\",t):this.signal(\"width\")},height(t){return arguments.length?this.signal(\"height\",t):this.signal(\"height\")},padding(t){return arguments.length?this.signal(\"padding\",Qv(t)):Qv(this.signal(\"padding\"))},autosize(t){return arguments.length?this.signal(\"autosize\",t):this.signal(\"autosize\")},background(t){return arguments.length?this.signal(\"background\",t):this.signal(\"background\")},renderer(t){return arguments.length?(th(t)||$(\"Unrecognized renderer type: \"+t),t!==this._renderType&&(this._renderType=t,this._resetRenderer()),this):this._renderType},tooltip(t){return arguments.length?(t!==this._tooltip&&(this._tooltip=t,this._resetRenderer()),this):this._tooltip},loader(t){return arguments.length?(t!==this._loader&&(ka.prototype.loader.call(this,t),this._resetRenderer()),this):this._loader},resize(){return this._autosize=1,this.touch(il(this,\"autosize\"))},_resetRenderer(){this._renderer&&(this._renderer=null,this.initialize(this._el,this._elBind))},_resizeView:jI,addEventListener(t,e,n){let r=e;return n&&n.trap===!1||(r=sy(this,e),r.raw=e),this._handler.on(t,r),this},removeEventListener(t,e){for(var n=this._handler.handlers(t),r=n.length,i,a;--r>=0;)if(a=n[r].type,i=n[r].handler,t===a&&(e===i||e===i.raw)){this._handler.off(a,i);break}return this},addResizeListener(t){const e=this._resizeListeners;return e.indexOf(t)<0&&e.push(t),this},removeResizeListener(t){var e=this._resizeListeners,n=e.indexOf(t);return n>=0&&e.splice(n,1),this},addSignalListener(t,e){return Jv(this,t,il(this,t),e)},removeSignalListener(t,e){return tb(this,il(this,t),e)},addDataListener(t,e){return Jv(this,t,Pf(this,t).values,e)},removeDataListener(t,e){return tb(this,Pf(this,t).values,e)},globalCursor(t){if(arguments.length){if(this._globalCursor!==!!t){const e=l1(this,null);this._globalCursor=!!t,e&&l1(this,e)}return this}else return this._globalCursor},preventDefault(t){return arguments.length?(this._preventDefault=t,this):this._preventDefault},timer:XI,events:xI,finalize:bI,hover:vI,data:oI,change:oh,insert:sI,remove:lI,scale:UI,initialize:RI,toImageURL:NI,toCanvas:PI,toSVG:zI,getState:WI,setState:GI});function ID(t){const e=this.context.data[t];return e?e.values.value:[]}function ZI(t,e,n){const r=this.context.data[t][\"index:\"+e],i=r?r.value.get(n):void 0;return i&&i.count}function JI(t,e){const n=this.context.dataflow,r=this.context.data[t],i=r.input;return n.pulse(i,n.changeset().remove(We).insert(e)),1}function tU(t,e,n){if(t){const r=this.context.dataflow,i=t.mark.source;r.pulse(i,r.changeset().encode(t,e))}return n!==void 0?n:t}const Cs=t=>function(e,n){return this.context.dataflow.locale()[t](n)(e)},eU=Cs(\"format\"),UD=Cs(\"timeFormat\"),nU=Cs(\"utcFormat\"),rU=Cs(\"timeParse\"),iU=Cs(\"utcParse\"),al=new Date(2e3,0,1);function lh(t,e,n){return!Number.isInteger(t)||!Number.isInteger(e)?\"\":(al.setYear(2e3),al.setMonth(t),al.setDate(e),UD.call(this,al,n))}function aU(t){return lh.call(this,t,1,\"%B\")}function uU(t){return lh.call(this,t,1,\"%b\")}function oU(t){return lh.call(this,0,2+t,\"%A\")}function sU(t){return lh.call(this,0,2+t,\"%a\")}const lU=\":\",fU=\"@\",f1=\"%\",cU=\"$\";function cy(t,e,n,r){e[0].type!==xn&&$(\"First argument to data functions must be a string literal.\");const i=e[0].value,a=lU+i;if(!X(a,r))try{r[a]=n.getData(i).tuplesRef()}catch{}}function hU(t,e,n,r){e[0].type!==xn&&$(\"First argument to indata must be a string literal.\"),e[1].type!==xn&&$(\"Second argument to indata must be a string literal.\");const i=e[0].value,a=e[1].value,u=fU+a;X(u,r)||(r[u]=n.getData(i).indataRef(n,a))}function qe(t,e,n,r){if(e[0].type===xn)eb(n,r,e[0].value);else for(t in n.scales)eb(n,r,t)}function eb(t,e,n){const r=f1+n;if(!X(e,r))try{e[r]=t.scaleRef(n)}catch{}}function Br(t,e){if(tt(t))return t;if(xt(t)){const n=e.scales[t];return n&&QE(n.value)?n.value:void 0}}function dU(t,e,n){e.__bandwidth=i=>i&&i.bandwidth?i.bandwidth():0,n._bandwidth=qe,n._range=qe,n._scale=qe;const r=i=>\"_[\"+(i.type===xn?Y(f1+i.value):Y(f1)+\"+\"+t(i))+\"]\";return{_bandwidth:i=>`this.__bandwidth(${r(i[0])})`,_range:i=>`${r(i[0])}.range()`,_scale:i=>`${r(i[0])}(${t(i[1])})`}}function hy(t,e){return function(n,r,i){if(n){const a=Br(n,(i||this).context);return a&&a.path[t](r)}else return e(r)}}const gU=hy(\"area\",$A),pU=hy(\"bounds\",OA),mU=hy(\"centroid\",zA);function yU(t){const e=this.context.group;let n=!1;if(e)for(;t;){if(t===e){n=!0;break}t=t.mark.group}return n}function dy(t,e,n){try{t[e].apply(t,[\"EXPRESSION\"].concat([].slice.call(n)))}catch(r){t.warn(r)}return n[n.length-1]}function xU(){return dy(this.context.dataflow,\"warn\",arguments)}function vU(){return dy(this.context.dataflow,\"info\",arguments)}function bU(){return dy(this.context.dataflow,\"debug\",arguments)}function C0(t){const e=t/255;return e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4)}function c1(t){const e=Vn(t),n=C0(e.r),r=C0(e.g),i=C0(e.b);return .2126*n+.7152*r+.0722*i}function AU(t,e){const n=c1(t),r=c1(e),i=Math.max(n,r),a=Math.min(n,r);return(i+.05)/(a+.05)}function wU(){const t=[].slice.call(arguments);return t.unshift({}),nt(...t)}function qD(t,e){return t===e||t!==t&&e!==e?!0:U(t)?U(e)&&t.length===e.length?EU(t,e):!1:et(t)&&et(e)?jD(t,e):!1}function EU(t,e){for(let n=0,r=t.length;njD(t,e)}function _U(t,e,n,r,i,a){const u=this.context.dataflow,o=this.context.data[t],s=o.input,l=u.stamp();let f=o.changes,c,h;if(u._trigger===!1||!(s.value.length||e||r))return 0;if((!f||f.stamp{o.modified=!0,u.pulse(s,f).run()},!0,1)),n&&(c=n===!0?We:U(n)||su(n)?n:nb(n),f.remove(c)),e&&f.insert(e),r&&(c=nb(r),s.value.some(c)?f.remove(c):f.insert(r)),i)for(h in a)f.modify(i,h,a[h]);return 1}function CU(t){const e=t.touches,n=e[0].clientX-e[1].clientX,r=e[0].clientY-e[1].clientY;return Math.hypot(n,r)}function DU(t){const e=t.touches;return Math.atan2(e[0].clientY-e[1].clientY,e[0].clientX-e[1].clientX)}const rb={};function FU(t,e){const n=rb[e]||(rb[e]=en(e));return U(t)?t.map(n):n(t)}function gy(t){return U(t)||ArrayBuffer.isView(t)?t:null}function py(t){return gy(t)||(xt(t)?t:null)}function MU(t){for(var e=arguments.length,n=new Array(e>1?e-1:0),r=1;r1?e-1:0),r=1;r1?e-1:0),r=1;r1?e-1:0),r=1;ra.stop(l(f),t(f))),a}function qU(t,e,n){const r=Br(t,(n||this).context);return function(i){return r?r.path.context(i)(e):\"\"}}function jU(t){let e=null;return function(n){return n?Ha(n,e=e||Gi(t)):t}}const WD=t=>t.data;function YD(t,e){const n=ID.call(e,t);return n.root&&n.root.lookup||{}}function WU(t,e,n){const r=YD(t,this),i=r[e],a=r[n];return i&&a?i.path(a).map(WD):void 0}function YU(t,e){const n=YD(t,this)[e];return n?n.ancestors().map(WD):void 0}const HD=()=>typeof window<\"u\"&&window||null;function HU(){const t=HD();return t?t.screen:{}}function GU(){const t=HD();return t?[t.innerWidth,t.innerHeight]:[void 0,void 0]}function XU(){const t=this.context.dataflow,e=t.container&&t.container();return e?[e.clientWidth,e.clientHeight]:[void 0,void 0]}function GD(t,e,n){if(!t)return[];const[r,i]=t,a=new St().set(r[0],r[1],i[0],i[1]),u=n||this.context.dataflow.scenegraph().root;return cm(u,a,VU(e))}function VU(t){let e=null;if(t){const n=H(t.marktype),r=H(t.markname);e=i=>(!n.length||n.some(a=>i.marktype===a))&&(!r.length||r.some(a=>i.name===a))}return e}function KU(t,e,n){let r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:5;t=H(t);const i=t[t.length-1];return i===void 0||Math.hypot(i[0]-e,i[1]-n)>r?[...t,[e,n]]:t}function QU(t){return H(t).reduce((e,n,r)=>{let[i,a]=n;return e+=r==0?`M ${i},${a} `:r===t.length-1?\" Z\":`L ${i},${a} `},\"\")}function ZU(t,e,n){const{x:r,y:i,mark:a}=n,u=new St().set(Number.MAX_SAFE_INTEGER,Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER,Number.MIN_SAFE_INTEGER);for(const[s,l]of e)su.x2&&(u.x2=s),lu.y2&&(u.y2=l);return u.translate(r,i),GD([[u.x1,u.y1],[u.x2,u.y2]],t,a).filter(s=>JU(s.x,s.y,e))}function JU(t,e,n){let r=0;for(let i=0,a=n.length-1;ie!=o>e&&t<(u-s)*(e-l)/(o-l)+s&&r++}return r&1}const If={random(){return un()},cumulativeNormal:is,cumulativeLogNormal:$c,cumulativeUniform:Rc,densityNormal:Fc,densityLogNormal:kc,densityUniform:Tc,quantileNormal:as,quantileLogNormal:Sc,quantileUniform:Oc,sampleNormal:rs,sampleLogNormal:Mc,sampleUniform:Bc,isArray:U,isBoolean:Ag,isDate:Cr,isDefined(t){return t!==void 0},isNumber:Mr,isObject:et,isRegExp:wg,isString:xt,isTuple:su,isValid(t){return t!=null&&t===t},toBoolean:xc,toDate(t){return vc(t)},toNumber:Kt,toString:bc,indexof:kU,join:MU,lastindexof:$U,replace:BU,reverse:TU,slice:SU,flush:bg,lerp:_g,merge:wU,pad:Cg,peek:ut,pluck:FU,span:au,inrange:Bi,truncate:Dg,rgb:Vn,lab:wo,hcl:Eo,hsl:Ao,luminance:c1,contrast:AU,sequence:Ie,format:eU,utcFormat:nU,utcParse:iU,utcOffset:Ng,utcSequence:Pg,timeFormat:UD,timeParse:rU,timeOffset:Og,timeSequence:Lg,timeUnitSpecifier:kg,monthFormat:aU,monthAbbrevFormat:uU,dayFormat:oU,dayAbbrevFormat:sU,quarter:pg,utcquarter:mg,week:Bg,utcweek:Rg,dayofyear:Sg,utcdayofyear:Tg,warn:xU,info:vU,debug:bU,extent(t){return Sn(t)},inScope:yU,intersect:GD,clampRange:yg,pinchDistance:CU,pinchAngle:DU,screen:HU,containerSize:XU,windowSize:GU,bandspace:RU,setdata:JI,pathShape:jU,panLinear:cg,panLog:hg,panPow:dg,panSymlog:gg,zoomLinear:gc,zoomLog:pc,zoomPow:Bo,zoomSymlog:mc,encode:tU,modify:_U,lassoAppend:KU,lassoPath:QU,intersectLasso:ZU},tq=[\"view\",\"item\",\"group\",\"xy\",\"x\",\"y\"],eq=\"event.vega.\",XD=\"this.\",my={},nq={forbidden:[\"_\"],allowed:[\"datum\",\"event\",\"item\"],fieldvar:\"datum\",globalvar:t=>`_[${Y(cU+t)}]`,functions:rq,constants:Zm,visitors:my},ib=oD(nq);function rq(t){const e=Jm(t);tq.forEach(n=>e[n]=eq+n);for(const n in If)e[n]=XD+n;return nt(e,dU(t,If,my)),e}function Rt(t,e,n){return arguments.length===1?If[t]:(If[t]=e,n&&(my[t]=n),ib&&(ib.functions[t]=XD+t),this)}Rt(\"bandwidth\",OU,qe);Rt(\"copy\",NU,qe);Rt(\"domain\",LU,qe);Rt(\"range\",zU,qe);Rt(\"invert\",PU,qe);Rt(\"scale\",IU,qe);Rt(\"gradient\",UU,qe);Rt(\"geoArea\",gU,qe);Rt(\"geoBounds\",pU,qe);Rt(\"geoCentroid\",mU,qe);Rt(\"geoShape\",qU,qe);Rt(\"indata\",ZI,hU);Rt(\"data\",ID,cy);Rt(\"treePath\",WU,cy);Rt(\"treeAncestors\",YU,cy);Rt(\"vlSelectionTest\",lD,hu);Rt(\"vlSelectionIdTest\",cD,hu);Rt(\"vlSelectionResolve\",dD,hu);Rt(\"vlSelectionTuples\",hD);const iq=\"view\",Uf=\"[\",qf=\"]\",VD=\"{\",KD=\"}\",aq=\":\",QD=\",\",uq=\"@\",oq=\">\",sq=/[[\\]{}]/,lq={\"*\":1,arc:1,area:1,group:1,image:1,line:1,path:1,rect:1,rule:1,shape:1,symbol:1,text:1,trail:1};let ZD,JD;function t5(t,e,n){return ZD=e||iq,JD=n||lq,e5(t.trim()).map(h1)}function fq(t){return JD[t]}function yo(t,e,n,r,i){const a=t.length;let u=0,o;for(;e=0?--u:r&&r.indexOf(o)>=0&&++u}return e}function e5(t){const e=[],n=t.length;let r=0,i=0;for(;i' after between selector: \"+t;r=r.map(h1);const i=h1(t.slice(1).trim());return i.between?{between:r,stream:i}:(i.between=r,i)}function hq(t){const e={source:ZD},n=[];let r=[0,0],i=0,a=0,u=t.length,o=0,s,l;if(t[u-1]===KD){if(o=t.lastIndexOf(VD),o>=0){try{r=dq(t.substring(o+1,u-1))}catch{throw\"Invalid throttle specification: \"+t}t=t.slice(0,o).trim(),u=t.length}else throw\"Unmatched right brace: \"+t;o=0}if(!u)throw t;if(t[0]===uq&&(i=++o),s=yo(t,o,aq),s1?(e.type=n[1],i?e.markname=n[0].slice(1):fq(n[0])?e.marktype=n[0]:e.source=n[0]):e.type=n[0],e.type.slice(-1)===\"!\"&&(e.consume=!0,e.type=e.type.slice(0,-1)),l!=null&&(e.filter=l),r[0]&&(e.throttle=r[0]),r[1]&&(e.debounce=r[1]),e}function dq(t){const e=t.split(QD);if(!t.length||e.length>2)throw t;return e.map(n=>{const r=+n;if(r!==r)throw t;return r})}function gq(t){return et(t)?t:{type:t||\"pad\"}}const Ou=t=>+t||0,pq=t=>({top:t,bottom:t,left:t,right:t});function mq(t){return et(t)?t.signal?t:{top:Ou(t.top),bottom:Ou(t.bottom),left:Ou(t.left),right:Ou(t.right)}:pq(Ou(t))}const Yt=t=>et(t)&&!U(t)?nt({},t):{value:t};function ab(t,e,n,r){return n!=null?(et(n)&&!U(n)||U(n)&&n.length&&et(n[0])?t.update[e]=n:t[r||\"enter\"][e]={value:n},1):0}function te(t,e,n){for(const r in e)ab(t,r,e[r]);for(const r in n)ab(t,r,n[r],\"update\")}function du(t,e,n){for(const r in e)n&&X(n,r)||(t[r]=nt(t[r]||{},e[r]));return t}function va(t,e){return e&&(e.enter&&e.enter[t]||e.update&&e.update[t])}const yy=\"mark\",xy=\"frame\",vy=\"scope\",yq=\"axis\",xq=\"axis-domain\",vq=\"axis-grid\",bq=\"axis-label\",Aq=\"axis-tick\",wq=\"axis-title\",Eq=\"legend\",_q=\"legend-band\",Cq=\"legend-entry\",Dq=\"legend-gradient\",n5=\"legend-label\",Fq=\"legend-symbol\",Mq=\"legend-title\",kq=\"title\",$q=\"title-text\",Sq=\"title-subtitle\";function Bq(t,e,n,r,i){const a={},u={};let o,s,l,f;s=\"lineBreak\",e===\"text\"&&i[s]!=null&&!va(s,t)&&D0(a,s,i[s]),(n==\"legend\"||String(n).startsWith(\"axis\"))&&(n=null),f=n===xy?i.group:n===yy?nt({},i.mark,i[e]):null;for(s in f)l=va(s,t)||(s===\"fill\"||s===\"stroke\")&&(va(\"fill\",t)||va(\"stroke\",t)),l||D0(a,s,f[s]);H(r).forEach(c=>{const h=i.style&&i.style[c];for(const d in h)va(d,t)||D0(a,d,h[d])}),t=nt({},t);for(s in a)f=a[s],f.signal?(o=o||{})[s]=f:u[s]=f;return t.enter=nt(u,t.enter),o&&(t.update=nt(o,t.update)),t}function D0(t,e,n){t[e]=n&&n.signal?{signal:n.signal}:{value:n}}const r5=t=>xt(t)?Y(t):t.signal?`(${t.signal})`:i5(t);function fh(t){if(t.gradient!=null)return Rq(t);let e=t.signal?`(${t.signal})`:t.color?Tq(t.color):t.field!=null?i5(t.field):t.value!==void 0?Y(t.value):void 0;return t.scale!=null&&(e=Oq(t,e)),e===void 0&&(e=null),t.exponent!=null&&(e=`pow(${e},${_l(t.exponent)})`),t.mult!=null&&(e+=`*${_l(t.mult)}`),t.offset!=null&&(e+=`+${_l(t.offset)}`),t.round&&(e=`round(${e})`),e}const ul=(t,e,n,r)=>`(${t}(${[e,n,r].map(fh).join(\",\")})+'')`;function Tq(t){return t.c?ul(\"hcl\",t.h,t.c,t.l):t.h||t.s?ul(\"hsl\",t.h,t.s,t.l):t.l||t.a?ul(\"lab\",t.l,t.a,t.b):t.r||t.g||t.b?ul(\"rgb\",t.r,t.g,t.b):null}function Rq(t){const e=[t.start,t.stop,t.count].map(n=>n==null?null:Y(n));for(;e.length&&ut(e)==null;)e.pop();return e.unshift(r5(t.gradient)),`gradient(${e.join(\",\")})`}function _l(t){return et(t)?\"(\"+fh(t)+\")\":t}function i5(t){return a5(et(t)?t:{datum:t})}function a5(t){let e,n,r;if(t.signal)e=\"datum\",r=t.signal;else if(t.group||t.parent){for(n=Math.max(1,t.level||1),e=\"item\";n-- >0;)e+=\".mark.group\";t.parent?(r=t.parent,e+=\".datum\"):r=t.group}else t.datum?(e=\"datum\",r=t.datum):$(\"Invalid field reference: \"+Y(t));return t.signal||(r=xt(r)?cc(r).map(Y).join(\"][\"):a5(r)),e+\"[\"+r+\"]\"}function Oq(t,e){const n=r5(t.scale);return t.range!=null?e=`lerp(_range(${n}), ${+t.range})`:(e!==void 0&&(e=`_scale(${n}, ${e})`),t.band&&(e=(e?e+\"+\":\"\")+`_bandwidth(${n})`+(+t.band==1?\"\":\"*\"+_l(t.band)),t.extra&&(e=`(datum.extra ? _scale(${n}, datum.extra.value) : ${e})`)),e==null&&(e=\"0\")),e}function Nq(t){let e=\"\";return t.forEach(n=>{const r=fh(n);e+=n.test?`(${n.test})?${r}:`:r}),ut(e)===\":\"&&(e+=\"null\"),e}function u5(t,e,n,r,i,a){const u={};a=a||{},a.encoders={$encode:u},t=Bq(t,e,n,r,i.config);for(const o in t)u[o]=Lq(t[o],e,a,i);return a}function Lq(t,e,n,r){const i={},a={};for(const u in t)t[u]!=null&&(i[u]=zq(Pq(t[u]),r,n,a));return{$expr:{marktype:e,channels:i},$fields:Object.keys(a),$output:Object.keys(t)}}function Pq(t){return U(t)?Nq(t):fh(t)}function zq(t,e,n,r){const i=tr(t,e);return i.$fields.forEach(a=>r[a]=1),nt(n,i.$params),i.$expr}const Iq=\"outer\",Uq=[\"value\",\"update\",\"init\",\"react\",\"bind\"];function ub(t,e){$(t+' for \"outer\" push: '+Y(e))}function o5(t,e){const n=t.name;if(t.push===Iq)e.signals[n]||ub(\"No prior signal definition\",n),Uq.forEach(r=>{t[r]!==void 0&&ub(\"Invalid property \",r)});else{const r=e.addSignal(n,t.value);t.react===!1&&(r.react=!1),t.bind&&e.addBinding(n,t.bind)}}function d1(t,e,n,r){this.id=-1,this.type=t,this.value=e,this.params=n,r&&(this.parent=r)}function ch(t,e,n,r){return new d1(t,e,n,r)}function jf(t,e){return ch(\"operator\",t,e)}function V(t){const e={$ref:t.id};return t.id<0&&(t.refs=t.refs||[]).push(e),e}function Wo(t,e){return e?{$field:t,$name:e}:{$field:t}}const g1=Wo(\"key\");function ob(t,e){return{$compare:t,$order:e}}function qq(t,e){const n={$key:t};return e&&(n.$flat=!0),n}const jq=\"ascending\",Wq=\"descending\";function Yq(t){return et(t)?(t.order===Wq?\"-\":\"+\")+hh(t.op,t.field):\"\"}function hh(t,e){return(t&&t.signal?\"$\"+t.signal:t||\"\")+(t&&e?\"_\":\"\")+(e&&e.signal?\"$\"+e.signal:e||\"\")}const by=\"scope\",p1=\"view\";function Lt(t){return t&&t.signal}function Hq(t){return t&&t.expr}function Cl(t){if(Lt(t))return!0;if(et(t)){for(const e in t)if(Cl(t[e]))return!0}return!1}function An(t,e){return t??e}function zi(t){return t&&t.signal||t}const sb=\"timer\";function Yo(t,e){return(t.merge?Xq:t.stream?Vq:t.type?Kq:$(\"Invalid stream specification: \"+Y(t)))(t,e)}function Gq(t){return t===by?p1:t||p1}function Xq(t,e){const n=t.merge.map(i=>Yo(i,e)),r=Ay({merge:n},t,e);return e.addStream(r).id}function Vq(t,e){const n=Yo(t.stream,e),r=Ay({stream:n},t,e);return e.addStream(r).id}function Kq(t,e){let n;t.type===sb?(n=e.event(sb,t.throttle),t={between:t.between,filter:t.filter}):n=e.event(Gq(t.source),t.type);const r=Ay({stream:n},t,e);return Object.keys(r).length===1?n:e.addStream(r).id}function Ay(t,e,n){let r=e.between;return r&&(r.length!==2&&$('Stream \"between\" parameter must have 2 entries: '+Y(e)),t.between=[Yo(r[0],n),Yo(r[1],n)]),r=e.filter?[].concat(e.filter):[],(e.marktype||e.markname||e.markrole)&&r.push(Qq(e.marktype,e.markname,e.markrole)),e.source===by&&r.push(\"inScope(event.item)\"),r.length&&(t.filter=tr(\"(\"+r.join(\")&&(\")+\")\",n).$expr),(r=e.throttle)!=null&&(t.throttle=+r),(r=e.debounce)!=null&&(t.debounce=+r),e.consume&&(t.consume=!0),t}function Qq(t,e,n){const r=\"event.item\";return r+(t&&t!==\"*\"?\"&&\"+r+\".mark.marktype==='\"+t+\"'\":\"\")+(n?\"&&\"+r+\".mark.role==='\"+n+\"'\":\"\")+(e?\"&&\"+r+\".mark.name==='\"+e+\"'\":\"\")}const Zq={code:\"_.$value\",ast:{type:\"Identifier\",value:\"value\"}};function Jq(t,e,n){const r=t.encode,i={target:n};let a=t.events,u=t.update,o=[];a||$(\"Signal update missing events specification.\"),xt(a)&&(a=t5(a,e.isSubscope()?by:p1)),a=H(a).filter(s=>s.signal||s.scale?(o.push(s),0):1),o.length>1&&(o=[ej(o)]),a.length&&o.push(a.length>1?{merge:a}:a[0]),r!=null&&(u&&$(\"Signal encode and update are mutually exclusive.\"),u=\"encode(item(),\"+Y(r)+\")\"),i.update=xt(u)?tr(u,e):u.expr!=null?tr(u.expr,e):u.value!=null?u.value:u.signal!=null?{$expr:Zq,$params:{$value:e.signalRef(u.signal)}}:$(\"Invalid signal update specification.\"),t.force&&(i.options={force:!0}),o.forEach(s=>e.addUpdate(nt(tj(s,e),i)))}function tj(t,e){return{source:t.signal?e.signalRef(t.signal):t.scale?e.scaleRef(t.scale):Yo(t,e)}}function ej(t){return{signal:\"[\"+t.map(e=>e.scale?'scale(\"'+e.scale+'\")':e.signal)+\"]\"}}function nj(t,e){const n=e.getSignal(t.name);let r=t.update;t.init&&(r?$(\"Signals can not include both init and update expressions.\"):(r=t.init,n.initonly=!0)),r&&(r=tr(r,e),n.update=r.$expr,n.params=r.$params),t.on&&t.on.forEach(i=>Jq(i,e,n.id))}const vt=t=>(e,n,r)=>ch(t,n,e||void 0,r),s5=vt(\"aggregate\"),rj=vt(\"axisticks\"),l5=vt(\"bound\"),On=vt(\"collect\"),lb=vt(\"compare\"),ij=vt(\"datajoin\"),f5=vt(\"encode\"),aj=vt(\"expression\"),uj=vt(\"facet\"),oj=vt(\"field\"),sj=vt(\"key\"),lj=vt(\"legendentries\"),fj=vt(\"load\"),cj=vt(\"mark\"),hj=vt(\"multiextent\"),dj=vt(\"multivalues\"),gj=vt(\"overlap\"),pj=vt(\"params\"),c5=vt(\"prefacet\"),mj=vt(\"projection\"),yj=vt(\"proxy\"),xj=vt(\"relay\"),h5=vt(\"render\"),vj=vt(\"scale\"),ua=vt(\"sieve\"),bj=vt(\"sortitems\"),d5=vt(\"viewlayout\"),Aj=vt(\"values\");let wj=0;const g5={min:\"min\",max:\"max\",count:\"sum\"};function Ej(t,e){const n=t.type||\"linear\";ZE(n)||$(\"Unrecognized scale type: \"+Y(n)),e.addScale(t.name,{type:n,domain:void 0})}function _j(t,e){const n=e.getScale(t.name).params;let r;n.domain=p5(t.domain,t,e),t.range!=null&&(n.range=y5(t,e,n)),t.interpolate!=null&&Rj(t.interpolate,n),t.nice!=null&&(n.nice=Tj(t.nice)),t.bins!=null&&(n.bins=Bj(t.bins,e));for(r in t)X(n,r)||r===\"name\"||(n[r]=dn(t[r],e))}function dn(t,e){return et(t)?t.signal?e.signalRef(t.signal):$(\"Unsupported object: \"+Y(t)):t}function Dl(t,e){return t.signal?e.signalRef(t.signal):t.map(n=>dn(n,e))}function dh(t){$(\"Can not find data set: \"+Y(t))}function p5(t,e,n){if(!t){(e.domainMin!=null||e.domainMax!=null)&&$(\"No scale domain defined for domainMin/domainMax to override.\");return}return t.signal?n.signalRef(t.signal):(U(t)?Cj:t.fields?Fj:Dj)(t,e,n)}function Cj(t,e,n){return t.map(r=>dn(r,n))}function Dj(t,e,n){const r=n.getData(t.data);return r||dh(t.data),Ya(e.type)?r.valuesRef(n,t.field,m5(t.sort,!1)):e_(e.type)?r.domainRef(n,t.field):r.extentRef(n,t.field)}function Fj(t,e,n){const r=t.data,i=t.fields.reduce((a,u)=>(u=xt(u)?{data:r,field:u}:U(u)||u.signal?Mj(u,n):u,a.push(u),a),[]);return(Ya(e.type)?kj:e_(e.type)?$j:Sj)(t,n,i)}function Mj(t,e){const n=\"_:vega:_\"+wj++,r=On({});if(U(t))r.value={$ingest:t};else if(t.signal){const i=\"setdata(\"+Y(n)+\",\"+t.signal+\")\";r.params.input=e.signalRef(i)}return e.addDataPipeline(n,[r,ua({})]),{data:n,field:\"data\"}}function kj(t,e,n){const r=m5(t.sort,!0);let i,a;const u=n.map(l=>{const f=e.getData(l.data);return f||dh(l.data),f.countsRef(e,l.field,r)}),o={groupby:g1,pulse:u};r&&(i=r.op||\"count\",a=r.field?hh(i,r.field):\"count\",o.ops=[g5[i]],o.fields=[e.fieldRef(a)],o.as=[a]),i=e.add(s5(o));const s=e.add(On({pulse:V(i)}));return a=e.add(Aj({field:g1,sort:e.sortRef(r),pulse:V(s)})),V(a)}function m5(t,e){return t&&(!t.field&&!t.op?et(t)?t.field=\"key\":t={field:\"key\"}:!t.field&&t.op!==\"count\"?$(\"No field provided for sort aggregate op: \"+t.op):e&&t.field&&t.op&&!g5[t.op]&&$(\"Multiple domain scales can not be sorted using \"+t.op)),t}function $j(t,e,n){const r=n.map(i=>{const a=e.getData(i.data);return a||dh(i.data),a.domainRef(e,i.field)});return V(e.add(dj({values:r})))}function Sj(t,e,n){const r=n.map(i=>{const a=e.getData(i.data);return a||dh(i.data),a.extentRef(e,i.field)});return V(e.add(hj({extents:r})))}function Bj(t,e){return t.signal||U(t)?Dl(t,e):e.objectProperty(t)}function Tj(t){return et(t)?{interval:dn(t.interval),step:dn(t.step)}:dn(t)}function Rj(t,e){e.interpolate=dn(t.type||t),t.gamma!=null&&(e.interpolateGamma=dn(t.gamma))}function y5(t,e,n){const r=e.config.range;let i=t.range;if(i.signal)return e.signalRef(i.signal);if(xt(i)){if(r&&X(r,i))return t=nt({},t,{range:r[i]}),y5(t,e,n);i===\"width\"?i=[0,{signal:\"width\"}]:i===\"height\"?i=Ya(t.type)?[0,{signal:\"height\"}]:[{signal:\"height\"},0]:$(\"Unrecognized scale range value: \"+Y(i))}else if(i.scheme){n.scheme=U(i.scheme)?Dl(i.scheme,e):dn(i.scheme,e),i.extent&&(n.schemeExtent=Dl(i.extent,e)),i.count&&(n.schemeCount=dn(i.count,e));return}else if(i.step){n.rangeStep=dn(i.step,e);return}else{if(Ya(t.type)&&!U(i))return p5(i,t,e);U(i)||$(\"Unsupported range type: \"+Y(i))}return i.map(a=>(U(a)?Dl:dn)(a,e))}function Oj(t,e){const n=e.config.projection||{},r={};for(const i in t)i!==\"name\"&&(r[i]=m1(t[i],i,e));for(const i in n)r[i]==null&&(r[i]=m1(n[i],i,e));e.addProjection(t.name,r)}function m1(t,e,n){return U(t)?t.map(r=>m1(r,e,n)):et(t)?t.signal?n.signalRef(t.signal):e===\"fit\"?t:$(\"Unsupported parameter object: \"+Y(t)):t}const Nn=\"top\",gu=\"left\",pu=\"right\",li=\"bottom\",x5=\"center\",Nj=\"vertical\",Lj=\"start\",Pj=\"middle\",zj=\"end\",y1=\"index\",wy=\"label\",Ij=\"offset\",Qa=\"perc\",Uj=\"perc2\",gn=\"value\",Ds=\"guide-label\",Ey=\"guide-title\",qj=\"group-title\",jj=\"group-subtitle\",fb=\"symbol\",Fl=\"gradient\",x1=\"discrete\",v1=\"size\",Wj=\"shape\",Yj=\"fill\",Hj=\"stroke\",Gj=\"strokeWidth\",Xj=\"strokeDash\",Vj=\"opacity\",_y=[v1,Wj,Yj,Hj,Gj,Xj,Vj],Fs={name:1,style:1,interactive:1},lt={value:0},pn={value:1},gh=\"group\",v5=\"rect\",Cy=\"rule\",Kj=\"symbol\",oa=\"text\";function Ho(t){return t.type=gh,t.interactive=t.interactive||!1,t}function Xe(t,e){const n=(r,i)=>An(t[r],An(e[r],i));return n.isVertical=r=>Nj===An(t.direction,e.direction||(r?e.symbolDirection:e.gradientDirection)),n.gradientLength=()=>An(t.gradientLength,e.gradientLength||e.gradientWidth),n.gradientThickness=()=>An(t.gradientThickness,e.gradientThickness||e.gradientHeight),n.entryColumns=()=>An(t.columns,An(e.columns,+n.isVertical(!0))),n}function b5(t,e){const n=e&&(e.update&&e.update[t]||e.enter&&e.enter[t]);return n&&n.signal?n:n?n.value:null}function Qj(t,e,n){const r=e.config.style[n];return r&&r[t]}function ph(t,e,n){return`item.anchor === '${Lj}' ? ${t} : item.anchor === '${zj}' ? ${e} : ${n}`}const Dy=ph(Y(gu),Y(pu),Y(x5));function Zj(t){const e=t(\"tickBand\");let n=t(\"tickOffset\"),r,i;return e?e.signal?(r={signal:`(${e.signal}) === 'extent' ? 1 : 0.5`},i={signal:`(${e.signal}) === 'extent'`},et(n)||(n={signal:`(${e.signal}) === 'extent' ? 0 : ${n}`})):e===\"extent\"?(r=1,i=!0,n=0):(r=.5,i=!1):(r=t(\"bandPosition\"),i=t(\"tickExtra\")),{extra:i,band:r,offset:n}}function A5(t,e){return e?t?et(t)?Object.assign({},t,{offset:A5(t.offset,e)}):{value:t,offset:e}:e:t}function sn(t,e){return e?(t.name=e.name,t.style=e.style||t.style,t.interactive=!!e.interactive,t.encode=du(t.encode,e,Fs)):t.interactive=!1,t}function Jj(t,e,n,r){const i=Xe(t,n),a=i.isVertical(),u=i.gradientThickness(),o=i.gradientLength();let s,l,f,c,h;a?(l=[0,1],f=[0,0],c=u,h=o):(l=[0,0],f=[1,0],c=o,h=u);const d={enter:s={opacity:lt,x:lt,y:lt,width:Yt(c),height:Yt(h)},update:nt({},s,{opacity:pn,fill:{gradient:e,start:l,stop:f}}),exit:{opacity:lt}};return te(d,{stroke:i(\"gradientStrokeColor\"),strokeWidth:i(\"gradientStrokeWidth\")},{opacity:i(\"gradientOpacity\")}),sn({type:v5,role:Dq,encode:d},r)}function tW(t,e,n,r,i){const a=Xe(t,n),u=a.isVertical(),o=a.gradientThickness(),s=a.gradientLength();let l,f,c,h,d=\"\";u?(l=\"y\",c=\"y2\",f=\"x\",h=\"width\",d=\"1-\"):(l=\"x\",c=\"x2\",f=\"y\",h=\"height\");const g={opacity:lt,fill:{scale:e,field:gn}};g[l]={signal:d+\"datum.\"+Qa,mult:s},g[f]=lt,g[c]={signal:d+\"datum.\"+Uj,mult:s},g[h]=Yt(o);const p={enter:g,update:nt({},g,{opacity:pn}),exit:{opacity:lt}};return te(p,{stroke:a(\"gradientStrokeColor\"),strokeWidth:a(\"gradientStrokeWidth\")},{opacity:a(\"gradientOpacity\")}),sn({type:v5,role:_q,key:gn,from:i,encode:p},r)}const eW=`datum.${Qa}<=0?\"${gu}\":datum.${Qa}>=1?\"${pu}\":\"${x5}\"`,nW=`datum.${Qa}<=0?\"${li}\":datum.${Qa}>=1?\"${Nn}\":\"${Pj}\"`;function cb(t,e,n,r){const i=Xe(t,e),a=i.isVertical(),u=Yt(i.gradientThickness()),o=i.gradientLength();let s=i(\"labelOverlap\"),l,f,c,h,d=\"\";const g={enter:l={opacity:lt},update:f={opacity:pn,text:{field:wy}},exit:{opacity:lt}};return te(g,{fill:i(\"labelColor\"),fillOpacity:i(\"labelOpacity\"),font:i(\"labelFont\"),fontSize:i(\"labelFontSize\"),fontStyle:i(\"labelFontStyle\"),fontWeight:i(\"labelFontWeight\"),limit:An(t.labelLimit,e.gradientLabelLimit)}),a?(l.align={value:\"left\"},l.baseline=f.baseline={signal:nW},c=\"y\",h=\"x\",d=\"1-\"):(l.align=f.align={signal:eW},l.baseline={value:\"top\"},c=\"x\",h=\"y\"),l[c]=f[c]={signal:d+\"datum.\"+Qa,mult:o},l[h]=f[h]=u,u.offset=An(t.labelOffset,e.gradientLabelOffset)||0,s=s?{separation:i(\"labelSeparation\"),method:s,order:\"datum.\"+y1}:void 0,sn({type:oa,role:n5,style:Ds,key:gn,from:r,encode:g,overlap:s},n)}function rW(t,e,n,r,i){const a=Xe(t,e),u=n.entries,o=!!(u&&u.interactive),s=u?u.name:void 0,l=a(\"clipHeight\"),f=a(\"symbolOffset\"),c={data:\"value\"},h=`(${i}) ? datum.${Ij} : datum.${v1}`,d=l?Yt(l):{field:v1},g=`datum.${y1}`,p=`max(1, ${i})`;let m,y,x,v,b;d.mult=.5,m={enter:y={opacity:lt,x:{signal:h,mult:.5,offset:f},y:d},update:x={opacity:pn,x:y.x,y:y.y},exit:{opacity:lt}};let w=null,E=null;t.fill||(w=e.symbolBaseFillColor,E=e.symbolBaseStrokeColor),te(m,{fill:a(\"symbolFillColor\",w),shape:a(\"symbolType\"),size:a(\"symbolSize\"),stroke:a(\"symbolStrokeColor\",E),strokeDash:a(\"symbolDash\"),strokeDashOffset:a(\"symbolDashOffset\"),strokeWidth:a(\"symbolStrokeWidth\")},{opacity:a(\"symbolOpacity\")}),_y.forEach(F=>{t[F]&&(x[F]=y[F]={scale:t[F],field:gn})});const A=sn({type:Kj,role:Fq,key:gn,from:c,clip:l?!0:void 0,encode:m},n.symbols),_=Yt(f);_.offset=a(\"labelOffset\"),m={enter:y={opacity:lt,x:{signal:h,offset:_},y:d},update:x={opacity:pn,text:{field:wy},x:y.x,y:y.y},exit:{opacity:lt}},te(m,{align:a(\"labelAlign\"),baseline:a(\"labelBaseline\"),fill:a(\"labelColor\"),fillOpacity:a(\"labelOpacity\"),font:a(\"labelFont\"),fontSize:a(\"labelFontSize\"),fontStyle:a(\"labelFontStyle\"),fontWeight:a(\"labelFontWeight\"),limit:a(\"labelLimit\")});const C=sn({type:oa,role:n5,style:Ds,key:gn,from:c,encode:m},n.labels);return m={enter:{noBound:{value:!l},width:lt,height:l?Yt(l):lt,opacity:lt},exit:{opacity:lt},update:x={opacity:pn,row:{signal:null},column:{signal:null}}},a.isVertical(!0)?(v=`ceil(item.mark.items.length / ${p})`,x.row.signal=`${g}%${v}`,x.column.signal=`floor(${g} / ${v})`,b={field:[\"row\",g]}):(x.row.signal=`floor(${g} / ${p})`,x.column.signal=`${g} % ${p}`,b={field:g}),x.column.signal=`(${i})?${x.column.signal}:${g}`,r={facet:{data:r,name:\"value\",groupby:y1}},Ho({role:vy,from:r,encode:du(m,u,Fs),marks:[A,C],name:s,interactive:o,sort:b})}function iW(t,e){const n=Xe(t,e);return{align:n(\"gridAlign\"),columns:n.entryColumns(),center:{row:!0,column:!1},padding:{row:n(\"rowPadding\"),column:n(\"columnPadding\")}}}const Fy='item.orient === \"left\"',My='item.orient === \"right\"',mh=`(${Fy} || ${My})`,aW=`datum.vgrad && ${mh}`,uW=ph('\"top\"','\"bottom\"','\"middle\"'),oW=ph('\"right\"','\"left\"','\"center\"'),sW=`datum.vgrad && ${My} ? (${oW}) : (${mh} && !(datum.vgrad && ${Fy})) ? \"left\" : ${Dy}`,lW=`item._anchor || (${mh} ? \"middle\" : \"start\")`,fW=`${aW} ? (${Fy} ? -90 : 90) : 0`,cW=`${mh} ? (datum.vgrad ? (${My} ? \"bottom\" : \"top\") : ${uW}) : \"top\"`;function hW(t,e,n,r){const i=Xe(t,e),a={enter:{opacity:lt},update:{opacity:pn,x:{field:{group:\"padding\"}},y:{field:{group:\"padding\"}}},exit:{opacity:lt}};return te(a,{orient:i(\"titleOrient\"),_anchor:i(\"titleAnchor\"),anchor:{signal:lW},angle:{signal:fW},align:{signal:sW},baseline:{signal:cW},text:t.title,fill:i(\"titleColor\"),fillOpacity:i(\"titleOpacity\"),font:i(\"titleFont\"),fontSize:i(\"titleFontSize\"),fontStyle:i(\"titleFontStyle\"),fontWeight:i(\"titleFontWeight\"),limit:i(\"titleLimit\"),lineHeight:i(\"titleLineHeight\")},{align:i(\"titleAlign\"),baseline:i(\"titleBaseline\")}),sn({type:oa,role:Mq,style:Ey,from:r,encode:a},n)}function dW(t,e){let n;return et(t)&&(t.signal?n=t.signal:t.path?n=\"pathShape(\"+hb(t.path)+\")\":t.sphere&&(n=\"geoShape(\"+hb(t.sphere)+', {type: \"Sphere\"})')),n?e.signalRef(n):!!t}function hb(t){return et(t)&&t.signal?t.signal:Y(t)}function w5(t){const e=t.role||\"\";return!e.indexOf(\"axis\")||!e.indexOf(\"legend\")||!e.indexOf(\"title\")?e:t.type===gh?vy:e||yy}function gW(t){return{marktype:t.type,name:t.name||void 0,role:t.role||w5(t),zindex:+t.zindex||void 0,aria:t.aria,description:t.description}}function pW(t,e){return t&&t.signal?e.signalRef(t.signal):t!==!1}function ky(t,e){const n=iE(t.type);n||$(\"Unrecognized transform type: \"+Y(t.type));const r=ch(n.type.toLowerCase(),null,E5(n,t,e));return t.signal&&e.addSignal(t.signal,e.proxy(r)),r.metadata=n.metadata||{},r}function E5(t,e,n){const r={},i=t.params.length;for(let a=0;adb(t,a,n)):db(t,i,n)}function db(t,e,n){const r=t.type;if(Lt(e))return pb(r)?$(\"Expression references can not be signals.\"):F0(r)?n.fieldRef(e):mb(r)?n.compareRef(e):n.signalRef(e.signal);{const i=t.expr||F0(r);return i&&vW(e)?n.exprRef(e.expr,e.as):i&&bW(e)?Wo(e.field,e.as):pb(r)?tr(e,n):AW(r)?V(n.getData(e).values):F0(r)?Wo(e):mb(r)?n.compareRef(e):e}}function yW(t,e,n){return xt(e.from)||$('Lookup \"from\" parameter must be a string literal.'),n.getData(e.from).lookupRef(n,e.key)}function xW(t,e,n){const r=e[t.name];return t.array?(U(r)||$(\"Expected an array of sub-parameters. Instead: \"+Y(r)),r.map(i=>gb(t,i,n))):gb(t,r,n)}function gb(t,e,n){const r=t.params.length;let i;for(let u=0;ut&&t.expr,bW=t=>t&&t.field,AW=t=>t===\"data\",pb=t=>t===\"expr\",F0=t=>t===\"field\",mb=t=>t===\"compare\";function wW(t,e,n){let r,i,a,u,o;return t?(r=t.facet)&&(e||$(\"Only group marks can be faceted.\"),r.field!=null?u=o=Ml(r,n):(t.data?o=V(n.getData(t.data).aggregate):(a=ky(nt({type:\"aggregate\",groupby:H(r.groupby)},r.aggregate),n),a.params.key=n.keyRef(r.groupby),a.params.pulse=Ml(r,n),u=o=V(n.add(a))),i=n.keyRef(r.groupby,!0))):u=V(n.add(On(null,[{}]))),u||(u=Ml(t,n)),{key:i,pulse:u,parent:o}}function Ml(t,e){return t.$ref?t:t.data&&t.data.$ref?t.data:V(e.getData(t.data).output)}function Ki(t,e,n,r,i){this.scope=t,this.input=e,this.output=n,this.values=r,this.aggregate=i,this.index={}}Ki.fromEntries=function(t,e){const n=e.length,r=e[n-1],i=e[n-2];let a=e[0],u=null,o=1;for(a&&a.type===\"load\"&&(a=e[1]),t.add(e[0]);oc??\"null\").join(\",\")+\"),0)\",f=tr(l,e);s.update=f.$expr,s.params=f.$params}function yh(t,e){const n=w5(t),r=t.type===gh,i=t.from&&t.from.facet,a=t.overlap;let u=t.layout||n===vy||n===xy,o,s,l,f,c,h,d;const g=n===yy||u||i,p=wW(t.from,r,e);s=e.add(ij({key:p.key||(t.key?Wo(t.key):void 0),pulse:p.pulse,clean:!r}));const m=V(s);s=l=e.add(On({pulse:m})),s=e.add(cj({markdef:gW(t),interactive:pW(t.interactive,e),clip:dW(t.clip,e),context:{$context:!0},groups:e.lookup(),parent:e.signals.parent?e.signalRef(\"parent\"):null,index:e.markpath(),pulse:V(s)}));const y=V(s);s=f=e.add(f5(u5(t.encode,t.type,n,t.style,e,{mod:!1,pulse:y}))),s.params.parent=e.encode(),t.transform&&t.transform.forEach(E=>{const A=ky(E,e),_=A.metadata;(_.generates||_.changes)&&$(\"Mark transforms should not generate new data.\"),_.nomod||(f.params.mod=!0),A.params.pulse=V(s),e.add(s=A)}),t.sort&&(s=e.add(bj({sort:e.compareRef(t.sort),pulse:V(s)})));const x=V(s);(i||u)&&(u=e.add(d5({layout:e.objectProperty(t.layout),legends:e.legends,mark:y,pulse:x})),h=V(u));const v=e.add(l5({mark:y,pulse:h||x}));d=V(v),r&&(g&&(o=e.operators,o.pop(),u&&o.pop()),e.pushState(x,h||d,m),i?EW(t,e,p):g?_W(t,e,p):e.parse(t),e.popState(),g&&(u&&o.push(u),o.push(v))),a&&(d=CW(a,d,e));const b=e.add(h5({pulse:d})),w=e.add(ua({pulse:V(b)},void 0,e.parent()));t.name!=null&&(c=t.name,e.addData(c,new Ki(e,l,b,w)),t.on&&t.on.forEach(E=>{(E.insert||E.remove||E.toggle)&&$(\"Marks only support modify triggers.\"),C5(E,e,c)}))}function CW(t,e,n){const r=t.method,i=t.bound,a=t.separation,u={separation:Lt(a)?n.signalRef(a.signal):a,method:Lt(r)?n.signalRef(r.signal):r,pulse:e};if(t.order&&(u.sort=n.compareRef({field:t.order})),i){const o=i.tolerance;u.boundTolerance=Lt(o)?n.signalRef(o.signal):+o,u.boundScale=n.scaleRef(i.scale),u.boundOrient=i.orient}return V(n.add(gj(u)))}function DW(t,e){const n=e.config.legend,r=t.encode||{},i=Xe(t,n),a=r.legend||{},u=a.name||void 0,o=a.interactive,s=a.style,l={};let f=0,c,h,d;_y.forEach(v=>t[v]?(l[v]=t[v],f=f||t[v]):0),f||$(\"Missing valid scale for legend.\");const g=FW(t,e.scaleType(f)),p={title:t.title!=null,scales:l,type:g,vgrad:g!==\"symbol\"&&i.isVertical()},m=V(e.add(On(null,[p]))),y={enter:{x:{value:0},y:{value:0}}},x=V(e.add(lj(h={type:g,scale:e.scaleRef(f),count:e.objectProperty(i(\"tickCount\")),limit:e.property(i(\"symbolLimit\")),values:e.objectProperty(t.values),minstep:e.property(t.tickMinStep),formatType:e.property(t.formatType),formatSpecifier:e.property(t.format)})));return g===Fl?(d=[Jj(t,f,n,r.gradient),cb(t,n,r.labels,x)],h.count=h.count||e.signalRef(`max(2,2*floor((${zi(i.gradientLength())})/100))`)):g===x1?d=[tW(t,f,n,r.gradient,x),cb(t,n,r.labels,x)]:(c=iW(t,n),d=[rW(t,n,r,x,zi(c.columns))],h.size=$W(t,e,d[0].marks)),d=[Ho({role:Cq,from:m,encode:y,marks:d,layout:c,interactive:o})],p.title&&d.push(hW(t,n,r.title,m)),yh(Ho({role:Eq,from:m,encode:du(kW(i,t,n),a,Fs),marks:d,aria:i(\"aria\"),description:i(\"description\"),zindex:i(\"zindex\"),name:u,interactive:o,style:s}),e)}function FW(t,e){let n=t.type||fb;return!t.type&&MW(t)===1&&(t.fill||t.stroke)&&(n=Mp(e)?Fl:Sd(e)?x1:fb),n!==Fl?n:Sd(e)?x1:Fl}function MW(t){return _y.reduce((e,n)=>e+(t[n]?1:0),0)}function kW(t,e,n){const r={enter:{},update:{}};return te(r,{orient:t(\"orient\"),offset:t(\"offset\"),padding:t(\"padding\"),titlePadding:t(\"titlePadding\"),cornerRadius:t(\"cornerRadius\"),fill:t(\"fillColor\"),stroke:t(\"strokeColor\"),strokeWidth:n.strokeWidth,strokeDash:n.strokeDash,x:t(\"legendX\"),y:t(\"legendY\"),format:e.format,formatType:e.formatType}),r}function $W(t,e,n){const r=zi(xb(\"size\",t,n)),i=zi(xb(\"strokeWidth\",t,n)),a=zi(SW(n[1].encode,e,Ds));return tr(`max(ceil(sqrt(${r})+${i}),${a})`,e)}function xb(t,e,n){return e[t]?`scale(\"${e[t]}\",datum)`:b5(t,n[0].encode)}function SW(t,e,n){return b5(\"fontSize\",t)||Qj(\"fontSize\",e,n)}const BW=`item.orient===\"${gu}\"?-90:item.orient===\"${pu}\"?90:0`;function TW(t,e){t=xt(t)?{text:t}:t;const n=Xe(t,e.config.title),r=t.encode||{},i=r.group||{},a=i.name||void 0,u=i.interactive,o=i.style,s=[],l={},f=V(e.add(On(null,[l])));return s.push(NW(t,n,RW(t),f)),t.subtitle&&s.push(LW(t,n,r.subtitle,f)),yh(Ho({role:kq,from:f,encode:OW(n,i),marks:s,aria:n(\"aria\"),description:n(\"description\"),zindex:n(\"zindex\"),name:a,interactive:u,style:o}),e)}function RW(t){const e=t.encode;return e&&e.title||nt({name:t.name,interactive:t.interactive,style:t.style},e)}function OW(t,e){const n={enter:{},update:{}};return te(n,{orient:t(\"orient\"),anchor:t(\"anchor\"),align:{signal:Dy},angle:{signal:BW},limit:t(\"limit\"),frame:t(\"frame\"),offset:t(\"offset\")||0,padding:t(\"subtitlePadding\")}),du(n,e,Fs)}function NW(t,e,n,r){const i={value:0},a=t.text,u={enter:{opacity:i},update:{opacity:{value:1}},exit:{opacity:i}};return te(u,{text:a,align:{signal:\"item.mark.group.align\"},angle:{signal:\"item.mark.group.angle\"},limit:{signal:\"item.mark.group.limit\"},baseline:\"top\",dx:e(\"dx\"),dy:e(\"dy\"),fill:e(\"color\"),font:e(\"font\"),fontSize:e(\"fontSize\"),fontStyle:e(\"fontStyle\"),fontWeight:e(\"fontWeight\"),lineHeight:e(\"lineHeight\")},{align:e(\"align\"),angle:e(\"angle\"),baseline:e(\"baseline\")}),sn({type:oa,role:$q,style:qj,from:r,encode:u},n)}function LW(t,e,n,r){const i={value:0},a=t.subtitle,u={enter:{opacity:i},update:{opacity:{value:1}},exit:{opacity:i}};return te(u,{text:a,align:{signal:\"item.mark.group.align\"},angle:{signal:\"item.mark.group.angle\"},limit:{signal:\"item.mark.group.limit\"},baseline:\"top\",dx:e(\"dx\"),dy:e(\"dy\"),fill:e(\"subtitleColor\"),font:e(\"subtitleFont\"),fontSize:e(\"subtitleFontSize\"),fontStyle:e(\"subtitleFontStyle\"),fontWeight:e(\"subtitleFontWeight\"),lineHeight:e(\"subtitleLineHeight\")},{align:e(\"align\"),angle:e(\"angle\"),baseline:e(\"baseline\")}),sn({type:oa,role:Sq,style:jj,from:r,encode:u},n)}function PW(t,e){const n=[];t.transform&&t.transform.forEach(r=>{n.push(ky(r,e))}),t.on&&t.on.forEach(r=>{C5(r,e,t.name)}),e.addDataPipeline(t.name,zW(t,e,n))}function zW(t,e,n){const r=[];let i=null,a=!1,u=!1,o,s,l,f,c;for(t.values?Lt(t.values)||Cl(t.format)?(r.push(vb(e,t)),r.push(i=vi())):r.push(i=vi({$ingest:t.values,$format:t.format})):t.url?Cl(t.url)||Cl(t.format)?(r.push(vb(e,t)),r.push(i=vi())):r.push(i=vi({$request:t.url,$format:t.format})):t.source&&(i=o=H(t.source).map(h=>V(e.getData(h).output)),r.push(null)),s=0,l=n.length;st===li||t===Nn,xh=(t,e,n)=>Lt(t)?jW(t.signal,e,n):t===gu||t===Nn?e:n,Ht=(t,e,n)=>Lt(t)?UW(t.signal,e,n):D5(t)?e:n,$n=(t,e,n)=>Lt(t)?qW(t.signal,e,n):D5(t)?n:e,F5=(t,e,n)=>Lt(t)?WW(t.signal,e,n):t===Nn?{value:e}:{value:n},IW=(t,e,n)=>Lt(t)?YW(t.signal,e,n):t===pu?{value:e}:{value:n},UW=(t,e,n)=>M5(`${t} === '${Nn}' || ${t} === '${li}'`,e,n),qW=(t,e,n)=>M5(`${t} !== '${Nn}' && ${t} !== '${li}'`,e,n),jW=(t,e,n)=>$y(`${t} === '${gu}' || ${t} === '${Nn}'`,e,n),WW=(t,e,n)=>$y(`${t} === '${Nn}'`,e,n),YW=(t,e,n)=>$y(`${t} === '${pu}'`,e,n),M5=(t,e,n)=>(e=e!=null?Yt(e):e,n=n!=null?Yt(n):n,bb(e)&&bb(n)?(e=e?e.signal||Y(e.value):null,n=n?n.signal||Y(n.value):null,{signal:`${t} ? (${e}) : (${n})`}):[nt({test:t},e)].concat(n||[])),bb=t=>t==null||Object.keys(t).length===1,$y=(t,e,n)=>({signal:`${t} ? (${Ca(e)}) : (${Ca(n)})`}),HW=(t,e,n,r,i)=>({signal:(r!=null?`${t} === '${gu}' ? (${Ca(r)}) : `:\"\")+(n!=null?`${t} === '${li}' ? (${Ca(n)}) : `:\"\")+(i!=null?`${t} === '${pu}' ? (${Ca(i)}) : `:\"\")+(e!=null?`${t} === '${Nn}' ? (${Ca(e)}) : `:\"\")+\"(null)\"}),Ca=t=>Lt(t)?t.signal:t==null?null:Y(t),GW=(t,e)=>e===0?0:Lt(t)?{signal:`(${t.signal}) * ${e}`}:{value:t*e},$a=(t,e)=>{const n=t.signal;return n&&n.endsWith(\"(null)\")?{signal:n.slice(0,-6)+e.signal}:t};function ya(t,e,n,r){let i;if(e&&X(e,t))return e[t];if(X(n,t))return n[t];if(t.startsWith(\"title\")){switch(t){case\"titleColor\":i=\"fill\";break;case\"titleFont\":case\"titleFontSize\":case\"titleFontWeight\":i=t[5].toLowerCase()+t.slice(6)}return r[Ey][i]}else if(t.startsWith(\"label\")){switch(t){case\"labelColor\":i=\"fill\";break;case\"labelFont\":case\"labelFontSize\":i=t[5].toLowerCase()+t.slice(6)}return r[Ds][i]}return null}function Ab(t){const e={};for(const n of t)if(n)for(const r in n)e[r]=1;return Object.keys(e)}function XW(t,e){var n=e.config,r=n.style,i=n.axis,a=e.scaleType(t.scale)===\"band\"&&n.axisBand,u=t.orient,o,s,l;if(Lt(u)){const c=Ab([n.axisX,n.axisY]),h=Ab([n.axisTop,n.axisBottom,n.axisLeft,n.axisRight]);o={};for(l of c)o[l]=Ht(u,ya(l,n.axisX,i,r),ya(l,n.axisY,i,r));s={};for(l of h)s[l]=HW(u.signal,ya(l,n.axisTop,i,r),ya(l,n.axisBottom,i,r),ya(l,n.axisLeft,i,r),ya(l,n.axisRight,i,r))}else o=u===Nn||u===li?n.axisX:n.axisY,s=n[\"axis\"+u[0].toUpperCase()+u.slice(1)];return o||s||a?nt({},i,o,s,a):i}function VW(t,e,n,r){const i=Xe(t,e),a=t.orient;let u,o;const s={enter:u={opacity:lt},update:o={opacity:pn},exit:{opacity:lt}};te(s,{stroke:i(\"domainColor\"),strokeCap:i(\"domainCap\"),strokeDash:i(\"domainDash\"),strokeDashOffset:i(\"domainDashOffset\"),strokeWidth:i(\"domainWidth\"),strokeOpacity:i(\"domainOpacity\")});const l=wb(t,0),f=wb(t,1);return u.x=o.x=Ht(a,l,lt),u.x2=o.x2=Ht(a,f),u.y=o.y=$n(a,l,lt),u.y2=o.y2=$n(a,f),sn({type:Cy,role:xq,from:r,encode:s},n)}function wb(t,e){return{scale:t.scale,range:e}}function KW(t,e,n,r,i){const a=Xe(t,e),u=t.orient,o=t.gridScale,s=xh(u,1,-1),l=QW(t.offset,s);let f,c,h;const d={enter:f={opacity:lt},update:h={opacity:pn},exit:c={opacity:lt}};te(d,{stroke:a(\"gridColor\"),strokeCap:a(\"gridCap\"),strokeDash:a(\"gridDash\"),strokeDashOffset:a(\"gridDashOffset\"),strokeOpacity:a(\"gridOpacity\"),strokeWidth:a(\"gridWidth\")});const g={scale:t.scale,field:gn,band:i.band,extra:i.extra,offset:i.offset,round:a(\"tickRound\")},p=Ht(u,{signal:\"height\"},{signal:\"width\"}),m=o?{scale:o,range:0,mult:s,offset:l}:{value:0,offset:l},y=o?{scale:o,range:1,mult:s,offset:l}:nt(p,{mult:s,offset:l});return f.x=h.x=Ht(u,g,m),f.y=h.y=$n(u,g,m),f.x2=h.x2=$n(u,y),f.y2=h.y2=Ht(u,y),c.x=Ht(u,g),c.y=$n(u,g),sn({type:Cy,role:vq,key:gn,from:r,encode:d},n)}function QW(t,e){if(e!==1)if(!et(t))t=Lt(e)?{signal:`(${e.signal}) * (${t||0})`}:e*(t||0);else{let n=t=nt({},t);for(;n.mult!=null;)if(et(n.mult))n=n.mult=nt({},n.mult);else return n.mult=Lt(e)?{signal:`(${n.mult}) * (${e.signal})`}:n.mult*e,t;n.mult=e}return t}function ZW(t,e,n,r,i,a){const u=Xe(t,e),o=t.orient,s=xh(o,-1,1);let l,f,c;const h={enter:l={opacity:lt},update:c={opacity:pn},exit:f={opacity:lt}};te(h,{stroke:u(\"tickColor\"),strokeCap:u(\"tickCap\"),strokeDash:u(\"tickDash\"),strokeDashOffset:u(\"tickDashOffset\"),strokeOpacity:u(\"tickOpacity\"),strokeWidth:u(\"tickWidth\")});const d=Yt(i);d.mult=s;const g={scale:t.scale,field:gn,band:a.band,extra:a.extra,offset:a.offset,round:u(\"tickRound\")};return c.y=l.y=Ht(o,lt,g),c.y2=l.y2=Ht(o,d),f.x=Ht(o,g),c.x=l.x=$n(o,lt,g),c.x2=l.x2=$n(o,d),f.y=$n(o,g),sn({type:Cy,role:Aq,key:gn,from:r,encode:h},n)}function M0(t,e,n,r,i){return{signal:'flush(range(\"'+t+'\"), scale(\"'+t+'\", datum.value), '+e+\",\"+n+\",\"+r+\",\"+i+\")\"}}function JW(t,e,n,r,i,a){const u=Xe(t,e),o=t.orient,s=t.scale,l=xh(o,-1,1),f=zi(u(\"labelFlush\")),c=zi(u(\"labelFlushOffset\")),h=u(\"labelAlign\"),d=u(\"labelBaseline\");let g=f===0||!!f,p;const m=Yt(i);m.mult=l,m.offset=Yt(u(\"labelPadding\")||0),m.offset.mult=l;const y={scale:s,field:gn,band:.5,offset:A5(a.offset,u(\"labelOffset\"))},x=Ht(o,g?M0(s,f,'\"left\"','\"right\"','\"center\"'):{value:\"center\"},IW(o,\"left\",\"right\")),v=Ht(o,F5(o,\"bottom\",\"top\"),g?M0(s,f,'\"top\"','\"bottom\"','\"middle\"'):{value:\"middle\"}),b=M0(s,f,`-(${c})`,c,0);g=g&&c;const w={opacity:lt,x:Ht(o,y,m),y:$n(o,y,m)},E={enter:w,update:p={opacity:pn,text:{field:wy},x:w.x,y:w.y,align:x,baseline:v},exit:{opacity:lt,x:w.x,y:w.y}};te(E,{dx:!h&&g?Ht(o,b):null,dy:!d&&g?$n(o,b):null}),te(E,{angle:u(\"labelAngle\"),fill:u(\"labelColor\"),fillOpacity:u(\"labelOpacity\"),font:u(\"labelFont\"),fontSize:u(\"labelFontSize\"),fontWeight:u(\"labelFontWeight\"),fontStyle:u(\"labelFontStyle\"),limit:u(\"labelLimit\"),lineHeight:u(\"labelLineHeight\")},{align:h,baseline:d});const A=u(\"labelBound\");let _=u(\"labelOverlap\");return _=_||A?{separation:u(\"labelSeparation\"),method:_,order:\"datum.index\",bound:A?{scale:s,orient:o,tolerance:A}:null}:void 0,p.align!==x&&(p.align=$a(p.align,x)),p.baseline!==v&&(p.baseline=$a(p.baseline,v)),sn({type:oa,role:bq,style:Ds,key:gn,from:r,encode:E,overlap:_},n)}function tY(t,e,n,r){const i=Xe(t,e),a=t.orient,u=xh(a,-1,1);let o,s;const l={enter:o={opacity:lt,anchor:Yt(i(\"titleAnchor\",null)),align:{signal:Dy}},update:s=nt({},o,{opacity:pn,text:Yt(t.title)}),exit:{opacity:lt}},f={signal:`lerp(range(\"${t.scale}\"), ${ph(0,1,.5)})`};return s.x=Ht(a,f),s.y=$n(a,f),o.angle=Ht(a,lt,GW(u,90)),o.baseline=Ht(a,F5(a,li,Nn),{value:li}),s.angle=o.angle,s.baseline=o.baseline,te(l,{fill:i(\"titleColor\"),fillOpacity:i(\"titleOpacity\"),font:i(\"titleFont\"),fontSize:i(\"titleFontSize\"),fontStyle:i(\"titleFontStyle\"),fontWeight:i(\"titleFontWeight\"),limit:i(\"titleLimit\"),lineHeight:i(\"titleLineHeight\")},{align:i(\"titleAlign\"),angle:i(\"titleAngle\"),baseline:i(\"titleBaseline\")}),eY(i,a,l,n),l.update.align=$a(l.update.align,o.align),l.update.angle=$a(l.update.angle,o.angle),l.update.baseline=$a(l.update.baseline,o.baseline),sn({type:oa,role:wq,style:Ey,from:r,encode:l},n)}function eY(t,e,n,r){const i=(o,s)=>o!=null?(n.update[s]=$a(Yt(o),n.update[s]),!1):!va(s,r),a=i(t(\"titleX\"),\"x\"),u=i(t(\"titleY\"),\"y\");n.enter.auto=u===a?Yt(u):Ht(e,Yt(u),Yt(a))}function nY(t,e){const n=XW(t,e),r=t.encode||{},i=r.axis||{},a=i.name||void 0,u=i.interactive,o=i.style,s=Xe(t,n),l=Zj(s),f={scale:t.scale,ticks:!!s(\"ticks\"),labels:!!s(\"labels\"),grid:!!s(\"grid\"),domain:!!s(\"domain\"),title:t.title!=null},c=V(e.add(On({},[f]))),h=V(e.add(rj({scale:e.scaleRef(t.scale),extra:e.property(l.extra),count:e.objectProperty(t.tickCount),values:e.objectProperty(t.values),minstep:e.property(t.tickMinStep),formatType:e.property(t.formatType),formatSpecifier:e.property(t.format)}))),d=[];let g;return f.grid&&d.push(KW(t,n,r.grid,h,l)),f.ticks&&(g=s(\"tickSize\"),d.push(ZW(t,n,r.ticks,h,g,l))),f.labels&&(g=f.ticks?g:0,d.push(JW(t,n,r.labels,h,g,l))),f.domain&&d.push(VW(t,n,r.domain,c)),f.title&&d.push(tY(t,n,r.title,c)),yh(Ho({role:yq,from:c,encode:du(rY(s,t),i,Fs),marks:d,aria:s(\"aria\"),description:s(\"description\"),zindex:s(\"zindex\"),name:a,interactive:u,style:o}),e)}function rY(t,e){const n={enter:{},update:{}};return te(n,{orient:t(\"orient\"),offset:t(\"offset\")||0,position:An(e.position,0),titlePadding:t(\"titlePadding\"),minExtent:t(\"minExtent\"),maxExtent:t(\"maxExtent\"),range:{signal:`abs(span(range(\"${e.scale}\")))`},translate:t(\"translate\"),format:e.format,formatType:e.formatType}),n}function k5(t,e,n){const r=H(t.signals),i=H(t.scales);return n||r.forEach(a=>o5(a,e)),H(t.projections).forEach(a=>Oj(a,e)),i.forEach(a=>Ej(a,e)),H(t.data).forEach(a=>PW(a,e)),i.forEach(a=>_j(a,e)),(n||r).forEach(a=>nj(a,e)),H(t.axes).forEach(a=>nY(a,e)),H(t.marks).forEach(a=>yh(a,e)),H(t.legends).forEach(a=>DW(a,e)),t.title&&TW(t.title,e),e.parseLambdas(),e}const iY=t=>du({enter:{x:{value:0},y:{value:0}},update:{width:{signal:\"width\"},height:{signal:\"height\"}}},t);function aY(t,e){const n=e.config,r=V(e.root=e.add(jf())),i=uY(t,n);i.forEach(l=>o5(l,e)),e.description=t.description||n.description,e.eventConfig=n.events,e.legends=e.objectProperty(n.legend&&n.legend.layout),e.locale=n.locale;const a=e.add(On()),u=e.add(f5(u5(iY(t.encode),gh,xy,t.style,e,{pulse:V(a)}))),o=e.add(d5({layout:e.objectProperty(t.layout),legends:e.legends,autosize:e.signalRef(\"autosize\"),mark:r,pulse:V(u)}));e.operators.pop(),e.pushState(V(u),V(o),null),k5(t,e,i),e.operators.push(o);let s=e.add(l5({mark:r,pulse:V(o)}));return s=e.add(h5({pulse:V(s)})),s=e.add(ua({pulse:V(s)})),e.addData(\"root\",new Ki(e,a,a,s)),e}function Lu(t,e){return e&&e.signal?{name:t,update:e.signal}:{name:t,value:e}}function uY(t,e){const n=u=>An(t[u],e[u]),r=[Lu(\"background\",n(\"background\")),Lu(\"autosize\",gq(n(\"autosize\"))),Lu(\"padding\",mq(n(\"padding\"))),Lu(\"width\",n(\"width\")||0),Lu(\"height\",n(\"height\")||0)],i=r.reduce((u,o)=>(u[o.name]=o,u),{}),a={};return H(t.signals).forEach(u=>{X(i,u.name)?u=nt(i[u.name],u):r.push(u),a[u.name]=u}),H(e.signals).forEach(u=>{!X(a,u.name)&&!X(i,u.name)&&r.push(u)}),r}function $5(t,e){this.config=t||{},this.options=e||{},this.bindings=[],this.field={},this.signals={},this.lambdas={},this.scales={},this.events={},this.data={},this.streams=[],this.updates=[],this.operators=[],this.eventConfig=null,this.locale=null,this._id=0,this._subid=0,this._nextsub=[0],this._parent=[],this._encode=[],this._lookup=[],this._markpath=[]}function Eb(t){this.config=t.config,this.options=t.options,this.legends=t.legends,this.field=Object.create(t.field),this.signals=Object.create(t.signals),this.lambdas=Object.create(t.lambdas),this.scales=Object.create(t.scales),this.events=Object.create(t.events),this.data=Object.create(t.data),this.streams=[],this.updates=[],this.operators=[],this._id=0,this._subid=++t._nextsub[0],this._nextsub=t._nextsub,this._parent=t._parent.slice(),this._encode=t._encode.slice(),this._lookup=t._lookup.slice(),this._markpath=t._markpath}$5.prototype=Eb.prototype={parse(t){return k5(t,this)},fork(){return new Eb(this)},isSubscope(){return this._subid>0},toRuntime(){return this.finish(),{description:this.description,operators:this.operators,streams:this.streams,updates:this.updates,bindings:this.bindings,eventConfig:this.eventConfig,locale:this.locale}},id(){return(this._subid?this._subid+\":\":0)+this._id++},add(t){return this.operators.push(t),t.id=this.id(),t.refs&&(t.refs.forEach(e=>{e.$ref=t.id}),t.refs=null),t},proxy(t){const e=t instanceof d1?V(t):t;return this.add(yj({value:e}))},addStream(t){return this.streams.push(t),t.id=this.id(),t},addUpdate(t){return this.updates.push(t),t},finish(){let t,e;this.root&&(this.root.root=!0);for(t in this.signals)this.signals[t].signal=t;for(t in this.scales)this.scales[t].scale=t;function n(r,i,a){let u,o;r&&(u=r.data||(r.data={}),o=u[i]||(u[i]=[]),o.push(a))}for(t in this.data){e=this.data[t],n(e.input,t,\"input\"),n(e.output,t,\"output\"),n(e.values,t,\"values\");for(const r in e.index)n(e.index[r],t,\"index:\"+r)}return this},pushState(t,e,n){this._encode.push(V(this.add(ua({pulse:t})))),this._parent.push(e),this._lookup.push(n?V(this.proxy(n)):null),this._markpath.push(-1)},popState(){this._encode.pop(),this._parent.pop(),this._lookup.pop(),this._markpath.pop()},parent(){return ut(this._parent)},encode(){return ut(this._encode)},lookup(){return ut(this._lookup)},markpath(){const t=this._markpath;return++t[t.length-1]},fieldRef(t,e){if(xt(t))return Wo(t,e);t.signal||$(\"Unsupported field reference: \"+Y(t));const n=t.signal;let r=this.field[n];if(!r){const i={name:this.signalRef(n)};e&&(i.as=e),this.field[n]=r=V(this.add(oj(i)))}return r},compareRef(t){let e=!1;const n=a=>Lt(a)?(e=!0,this.signalRef(a.signal)):Hq(a)?(e=!0,this.exprRef(a.expr)):a,r=H(t.field).map(n),i=H(t.order).map(n);return e?V(this.add(lb({fields:r,orders:i}))):ob(r,i)},keyRef(t,e){let n=!1;const r=a=>Lt(a)?(n=!0,V(i[a.signal])):a,i=this.signals;return t=H(t).map(r),n?V(this.add(sj({fields:t,flat:e}))):qq(t,e)},sortRef(t){if(!t)return t;const e=hh(t.op,t.field),n=t.order||jq;return n.signal?V(this.add(lb({fields:e,orders:this.signalRef(n.signal)}))):ob(e,n)},event(t,e){const n=t+\":\"+e;if(!this.events[n]){const r=this.id();this.streams.push({id:r,source:t,type:e}),this.events[n]=r}return this.events[n]},hasOwnSignal(t){return X(this.signals,t)},addSignal(t,e){this.hasOwnSignal(t)&&$(\"Duplicate signal name: \"+Y(t));const n=e instanceof d1?e:this.add(jf(e));return this.signals[t]=n},getSignal(t){return this.signals[t]||$(\"Unrecognized signal name: \"+Y(t)),this.signals[t]},signalRef(t){return this.signals[t]?V(this.signals[t]):(X(this.lambdas,t)||(this.lambdas[t]=this.add(jf(null))),V(this.lambdas[t]))},parseLambdas(){const t=Object.keys(this.lambdas);for(let e=0,n=t.length;e0?\",\":\"\")+(et(i)?i.signal||Sy(i):Y(i))}return n+\"]\"}function sY(t){let e=\"{\",n=0,r,i;for(r in t)i=t[r],e+=(++n>1?\",\":\"\")+Y(r)+\":\"+(et(i)?i.signal||Sy(i):Y(i));return e+\"}\"}function lY(){const t=\"sans-serif\",r=\"#4c78a8\",i=\"#000\",a=\"#888\",u=\"#ddd\";return{description:\"Vega visualization\",padding:0,autosize:\"pad\",background:null,events:{defaults:{allow:[\"wheel\"]}},group:null,mark:null,arc:{fill:r},area:{fill:r},image:null,line:{stroke:r,strokeWidth:2},path:{stroke:r},rect:{fill:r},rule:{stroke:i},shape:{stroke:r},symbol:{fill:r,size:64},text:{fill:i,font:t,fontSize:11},trail:{fill:r,size:2},style:{\"guide-label\":{fill:i,font:t,fontSize:10},\"guide-title\":{fill:i,font:t,fontSize:11,fontWeight:\"bold\"},\"group-title\":{fill:i,font:t,fontSize:13,fontWeight:\"bold\"},\"group-subtitle\":{fill:i,font:t,fontSize:12},point:{size:30,strokeWidth:2,shape:\"circle\"},circle:{size:30,strokeWidth:2},square:{size:30,strokeWidth:2,shape:\"square\"},cell:{fill:\"transparent\",stroke:u},view:{fill:\"transparent\"}},title:{orient:\"top\",anchor:\"middle\",offset:4,subtitlePadding:3},axis:{minExtent:0,maxExtent:200,bandPosition:.5,domain:!0,domainWidth:1,domainColor:a,grid:!1,gridWidth:1,gridColor:u,labels:!0,labelAngle:0,labelLimit:180,labelOffset:0,labelPadding:2,ticks:!0,tickColor:a,tickOffset:0,tickRound:!0,tickSize:5,tickWidth:1,titlePadding:4},axisBand:{tickOffset:-.5},projection:{type:\"mercator\"},legend:{orient:\"right\",padding:0,gridAlign:\"each\",columnPadding:10,rowPadding:2,symbolDirection:\"vertical\",gradientDirection:\"vertical\",gradientLength:200,gradientThickness:16,gradientStrokeColor:u,gradientStrokeWidth:0,gradientLabelOffset:2,labelAlign:\"left\",labelBaseline:\"middle\",labelLimit:160,labelOffset:4,labelOverlap:!0,symbolLimit:30,symbolType:\"circle\",symbolSize:100,symbolOffset:0,symbolStrokeWidth:1.5,symbolBaseFillColor:\"transparent\",symbolBaseStrokeColor:a,titleLimit:180,titleOrient:\"top\",titlePadding:5,layout:{offset:18,direction:\"horizontal\",left:{direction:\"vertical\"},right:{direction:\"vertical\"}}},range:{category:{scheme:\"tableau10\"},ordinal:{scheme:\"blues\"},heatmap:{scheme:\"yellowgreenblue\"},ramp:{scheme:\"blues\"},diverging:{scheme:\"blueorange\",extent:[1,0]},symbol:[\"circle\",\"square\",\"triangle-up\",\"cross\",\"diamond\",\"triangle-right\",\"triangle-down\",\"triangle-left\"]}}}function fY(t,e,n){return et(t)||$(\"Input Vega specification must be an object.\"),e=v3(lY(),e,t.config),aY(t,new $5(e,n)).toRuntime()}const cY=\"RawCode\",hY=\"Literal\",dY=\"Property\",gY=\"Identifier\",pY=\"ArrayExpression\",mY=\"BinaryExpression\",yY=\"CallExpression\",xY=\"ConditionalExpression\",vY=\"LogicalExpression\",bY=\"MemberExpression\",AY=\"ObjectExpression\",wY=\"UnaryExpression\";function Ln(t){this.type=t}Ln.prototype.visit=function(t){let e,n,r;if(t(this))return 1;for(e=EY(this),n=0,r=e.length;n\";or[Qi]=\"Identifier\";or[pi]=\"Keyword\";or[bh]=\"Null\";or[sa]=\"Numeric\";or[Oe]=\"Punctuator\";or[ks]=\"String\";or[_Y]=\"RegularExpression\";var CY=\"ArrayExpression\",DY=\"BinaryExpression\",FY=\"CallExpression\",MY=\"ConditionalExpression\",S5=\"Identifier\",kY=\"Literal\",$Y=\"LogicalExpression\",SY=\"MemberExpression\",BY=\"ObjectExpression\",TY=\"Property\",RY=\"UnaryExpression\",Gt=\"Unexpected token %0\",OY=\"Unexpected number\",NY=\"Unexpected string\",LY=\"Unexpected identifier\",PY=\"Unexpected reserved word\",zY=\"Unexpected end of input\",b1=\"Invalid regular expression\",k0=\"Invalid regular expression: missing /\",B5=\"Octal literals are not allowed in strict mode.\",IY=\"Duplicate data property in object literal not allowed in strict mode\",Zt=\"ILLEGAL\",Go=\"Disabled.\",UY=new RegExp(\"[\\\\xAA\\\\xB5\\\\xBA\\\\xC0-\\\\xD6\\\\xD8-\\\\xF6\\\\xF8-\\\\u02C1\\\\u02C6-\\\\u02D1\\\\u02E0-\\\\u02E4\\\\u02EC\\\\u02EE\\\\u0370-\\\\u0374\\\\u0376\\\\u0377\\\\u037A-\\\\u037D\\\\u037F\\\\u0386\\\\u0388-\\\\u038A\\\\u038C\\\\u038E-\\\\u03A1\\\\u03A3-\\\\u03F5\\\\u03F7-\\\\u0481\\\\u048A-\\\\u052F\\\\u0531-\\\\u0556\\\\u0559\\\\u0561-\\\\u0587\\\\u05D0-\\\\u05EA\\\\u05F0-\\\\u05F2\\\\u0620-\\\\u064A\\\\u066E\\\\u066F\\\\u0671-\\\\u06D3\\\\u06D5\\\\u06E5\\\\u06E6\\\\u06EE\\\\u06EF\\\\u06FA-\\\\u06FC\\\\u06FF\\\\u0710\\\\u0712-\\\\u072F\\\\u074D-\\\\u07A5\\\\u07B1\\\\u07CA-\\\\u07EA\\\\u07F4\\\\u07F5\\\\u07FA\\\\u0800-\\\\u0815\\\\u081A\\\\u0824\\\\u0828\\\\u0840-\\\\u0858\\\\u08A0-\\\\u08B2\\\\u0904-\\\\u0939\\\\u093D\\\\u0950\\\\u0958-\\\\u0961\\\\u0971-\\\\u0980\\\\u0985-\\\\u098C\\\\u098F\\\\u0990\\\\u0993-\\\\u09A8\\\\u09AA-\\\\u09B0\\\\u09B2\\\\u09B6-\\\\u09B9\\\\u09BD\\\\u09CE\\\\u09DC\\\\u09DD\\\\u09DF-\\\\u09E1\\\\u09F0\\\\u09F1\\\\u0A05-\\\\u0A0A\\\\u0A0F\\\\u0A10\\\\u0A13-\\\\u0A28\\\\u0A2A-\\\\u0A30\\\\u0A32\\\\u0A33\\\\u0A35\\\\u0A36\\\\u0A38\\\\u0A39\\\\u0A59-\\\\u0A5C\\\\u0A5E\\\\u0A72-\\\\u0A74\\\\u0A85-\\\\u0A8D\\\\u0A8F-\\\\u0A91\\\\u0A93-\\\\u0AA8\\\\u0AAA-\\\\u0AB0\\\\u0AB2\\\\u0AB3\\\\u0AB5-\\\\u0AB9\\\\u0ABD\\\\u0AD0\\\\u0AE0\\\\u0AE1\\\\u0B05-\\\\u0B0C\\\\u0B0F\\\\u0B10\\\\u0B13-\\\\u0B28\\\\u0B2A-\\\\u0B30\\\\u0B32\\\\u0B33\\\\u0B35-\\\\u0B39\\\\u0B3D\\\\u0B5C\\\\u0B5D\\\\u0B5F-\\\\u0B61\\\\u0B71\\\\u0B83\\\\u0B85-\\\\u0B8A\\\\u0B8E-\\\\u0B90\\\\u0B92-\\\\u0B95\\\\u0B99\\\\u0B9A\\\\u0B9C\\\\u0B9E\\\\u0B9F\\\\u0BA3\\\\u0BA4\\\\u0BA8-\\\\u0BAA\\\\u0BAE-\\\\u0BB9\\\\u0BD0\\\\u0C05-\\\\u0C0C\\\\u0C0E-\\\\u0C10\\\\u0C12-\\\\u0C28\\\\u0C2A-\\\\u0C39\\\\u0C3D\\\\u0C58\\\\u0C59\\\\u0C60\\\\u0C61\\\\u0C85-\\\\u0C8C\\\\u0C8E-\\\\u0C90\\\\u0C92-\\\\u0CA8\\\\u0CAA-\\\\u0CB3\\\\u0CB5-\\\\u0CB9\\\\u0CBD\\\\u0CDE\\\\u0CE0\\\\u0CE1\\\\u0CF1\\\\u0CF2\\\\u0D05-\\\\u0D0C\\\\u0D0E-\\\\u0D10\\\\u0D12-\\\\u0D3A\\\\u0D3D\\\\u0D4E\\\\u0D60\\\\u0D61\\\\u0D7A-\\\\u0D7F\\\\u0D85-\\\\u0D96\\\\u0D9A-\\\\u0DB1\\\\u0DB3-\\\\u0DBB\\\\u0DBD\\\\u0DC0-\\\\u0DC6\\\\u0E01-\\\\u0E30\\\\u0E32\\\\u0E33\\\\u0E40-\\\\u0E46\\\\u0E81\\\\u0E82\\\\u0E84\\\\u0E87\\\\u0E88\\\\u0E8A\\\\u0E8D\\\\u0E94-\\\\u0E97\\\\u0E99-\\\\u0E9F\\\\u0EA1-\\\\u0EA3\\\\u0EA5\\\\u0EA7\\\\u0EAA\\\\u0EAB\\\\u0EAD-\\\\u0EB0\\\\u0EB2\\\\u0EB3\\\\u0EBD\\\\u0EC0-\\\\u0EC4\\\\u0EC6\\\\u0EDC-\\\\u0EDF\\\\u0F00\\\\u0F40-\\\\u0F47\\\\u0F49-\\\\u0F6C\\\\u0F88-\\\\u0F8C\\\\u1000-\\\\u102A\\\\u103F\\\\u1050-\\\\u1055\\\\u105A-\\\\u105D\\\\u1061\\\\u1065\\\\u1066\\\\u106E-\\\\u1070\\\\u1075-\\\\u1081\\\\u108E\\\\u10A0-\\\\u10C5\\\\u10C7\\\\u10CD\\\\u10D0-\\\\u10FA\\\\u10FC-\\\\u1248\\\\u124A-\\\\u124D\\\\u1250-\\\\u1256\\\\u1258\\\\u125A-\\\\u125D\\\\u1260-\\\\u1288\\\\u128A-\\\\u128D\\\\u1290-\\\\u12B0\\\\u12B2-\\\\u12B5\\\\u12B8-\\\\u12BE\\\\u12C0\\\\u12C2-\\\\u12C5\\\\u12C8-\\\\u12D6\\\\u12D8-\\\\u1310\\\\u1312-\\\\u1315\\\\u1318-\\\\u135A\\\\u1380-\\\\u138F\\\\u13A0-\\\\u13F4\\\\u1401-\\\\u166C\\\\u166F-\\\\u167F\\\\u1681-\\\\u169A\\\\u16A0-\\\\u16EA\\\\u16EE-\\\\u16F8\\\\u1700-\\\\u170C\\\\u170E-\\\\u1711\\\\u1720-\\\\u1731\\\\u1740-\\\\u1751\\\\u1760-\\\\u176C\\\\u176E-\\\\u1770\\\\u1780-\\\\u17B3\\\\u17D7\\\\u17DC\\\\u1820-\\\\u1877\\\\u1880-\\\\u18A8\\\\u18AA\\\\u18B0-\\\\u18F5\\\\u1900-\\\\u191E\\\\u1950-\\\\u196D\\\\u1970-\\\\u1974\\\\u1980-\\\\u19AB\\\\u19C1-\\\\u19C7\\\\u1A00-\\\\u1A16\\\\u1A20-\\\\u1A54\\\\u1AA7\\\\u1B05-\\\\u1B33\\\\u1B45-\\\\u1B4B\\\\u1B83-\\\\u1BA0\\\\u1BAE\\\\u1BAF\\\\u1BBA-\\\\u1BE5\\\\u1C00-\\\\u1C23\\\\u1C4D-\\\\u1C4F\\\\u1C5A-\\\\u1C7D\\\\u1CE9-\\\\u1CEC\\\\u1CEE-\\\\u1CF1\\\\u1CF5\\\\u1CF6\\\\u1D00-\\\\u1DBF\\\\u1E00-\\\\u1F15\\\\u1F18-\\\\u1F1D\\\\u1F20-\\\\u1F45\\\\u1F48-\\\\u1F4D\\\\u1F50-\\\\u1F57\\\\u1F59\\\\u1F5B\\\\u1F5D\\\\u1F5F-\\\\u1F7D\\\\u1F80-\\\\u1FB4\\\\u1FB6-\\\\u1FBC\\\\u1FBE\\\\u1FC2-\\\\u1FC4\\\\u1FC6-\\\\u1FCC\\\\u1FD0-\\\\u1FD3\\\\u1FD6-\\\\u1FDB\\\\u1FE0-\\\\u1FEC\\\\u1FF2-\\\\u1FF4\\\\u1FF6-\\\\u1FFC\\\\u2071\\\\u207F\\\\u2090-\\\\u209C\\\\u2102\\\\u2107\\\\u210A-\\\\u2113\\\\u2115\\\\u2119-\\\\u211D\\\\u2124\\\\u2126\\\\u2128\\\\u212A-\\\\u212D\\\\u212F-\\\\u2139\\\\u213C-\\\\u213F\\\\u2145-\\\\u2149\\\\u214E\\\\u2160-\\\\u2188\\\\u2C00-\\\\u2C2E\\\\u2C30-\\\\u2C5E\\\\u2C60-\\\\u2CE4\\\\u2CEB-\\\\u2CEE\\\\u2CF2\\\\u2CF3\\\\u2D00-\\\\u2D25\\\\u2D27\\\\u2D2D\\\\u2D30-\\\\u2D67\\\\u2D6F\\\\u2D80-\\\\u2D96\\\\u2DA0-\\\\u2DA6\\\\u2DA8-\\\\u2DAE\\\\u2DB0-\\\\u2DB6\\\\u2DB8-\\\\u2DBE\\\\u2DC0-\\\\u2DC6\\\\u2DC8-\\\\u2DCE\\\\u2DD0-\\\\u2DD6\\\\u2DD8-\\\\u2DDE\\\\u2E2F\\\\u3005-\\\\u3007\\\\u3021-\\\\u3029\\\\u3031-\\\\u3035\\\\u3038-\\\\u303C\\\\u3041-\\\\u3096\\\\u309D-\\\\u309F\\\\u30A1-\\\\u30FA\\\\u30FC-\\\\u30FF\\\\u3105-\\\\u312D\\\\u3131-\\\\u318E\\\\u31A0-\\\\u31BA\\\\u31F0-\\\\u31FF\\\\u3400-\\\\u4DB5\\\\u4E00-\\\\u9FCC\\\\uA000-\\\\uA48C\\\\uA4D0-\\\\uA4FD\\\\uA500-\\\\uA60C\\\\uA610-\\\\uA61F\\\\uA62A\\\\uA62B\\\\uA640-\\\\uA66E\\\\uA67F-\\\\uA69D\\\\uA6A0-\\\\uA6EF\\\\uA717-\\\\uA71F\\\\uA722-\\\\uA788\\\\uA78B-\\\\uA78E\\\\uA790-\\\\uA7AD\\\\uA7B0\\\\uA7B1\\\\uA7F7-\\\\uA801\\\\uA803-\\\\uA805\\\\uA807-\\\\uA80A\\\\uA80C-\\\\uA822\\\\uA840-\\\\uA873\\\\uA882-\\\\uA8B3\\\\uA8F2-\\\\uA8F7\\\\uA8FB\\\\uA90A-\\\\uA925\\\\uA930-\\\\uA946\\\\uA960-\\\\uA97C\\\\uA984-\\\\uA9B2\\\\uA9CF\\\\uA9E0-\\\\uA9E4\\\\uA9E6-\\\\uA9EF\\\\uA9FA-\\\\uA9FE\\\\uAA00-\\\\uAA28\\\\uAA40-\\\\uAA42\\\\uAA44-\\\\uAA4B\\\\uAA60-\\\\uAA76\\\\uAA7A\\\\uAA7E-\\\\uAAAF\\\\uAAB1\\\\uAAB5\\\\uAAB6\\\\uAAB9-\\\\uAABD\\\\uAAC0\\\\uAAC2\\\\uAADB-\\\\uAADD\\\\uAAE0-\\\\uAAEA\\\\uAAF2-\\\\uAAF4\\\\uAB01-\\\\uAB06\\\\uAB09-\\\\uAB0E\\\\uAB11-\\\\uAB16\\\\uAB20-\\\\uAB26\\\\uAB28-\\\\uAB2E\\\\uAB30-\\\\uAB5A\\\\uAB5C-\\\\uAB5F\\\\uAB64\\\\uAB65\\\\uABC0-\\\\uABE2\\\\uAC00-\\\\uD7A3\\\\uD7B0-\\\\uD7C6\\\\uD7CB-\\\\uD7FB\\\\uF900-\\\\uFA6D\\\\uFA70-\\\\uFAD9\\\\uFB00-\\\\uFB06\\\\uFB13-\\\\uFB17\\\\uFB1D\\\\uFB1F-\\\\uFB28\\\\uFB2A-\\\\uFB36\\\\uFB38-\\\\uFB3C\\\\uFB3E\\\\uFB40\\\\uFB41\\\\uFB43\\\\uFB44\\\\uFB46-\\\\uFBB1\\\\uFBD3-\\\\uFD3D\\\\uFD50-\\\\uFD8F\\\\uFD92-\\\\uFDC7\\\\uFDF0-\\\\uFDFB\\\\uFE70-\\\\uFE74\\\\uFE76-\\\\uFEFC\\\\uFF21-\\\\uFF3A\\\\uFF41-\\\\uFF5A\\\\uFF66-\\\\uFFBE\\\\uFFC2-\\\\uFFC7\\\\uFFCA-\\\\uFFCF\\\\uFFD2-\\\\uFFD7\\\\uFFDA-\\\\uFFDC]\"),qY=new RegExp(\"[\\\\xAA\\\\xB5\\\\xBA\\\\xC0-\\\\xD6\\\\xD8-\\\\xF6\\\\xF8-\\\\u02C1\\\\u02C6-\\\\u02D1\\\\u02E0-\\\\u02E4\\\\u02EC\\\\u02EE\\\\u0300-\\\\u0374\\\\u0376\\\\u0377\\\\u037A-\\\\u037D\\\\u037F\\\\u0386\\\\u0388-\\\\u038A\\\\u038C\\\\u038E-\\\\u03A1\\\\u03A3-\\\\u03F5\\\\u03F7-\\\\u0481\\\\u0483-\\\\u0487\\\\u048A-\\\\u052F\\\\u0531-\\\\u0556\\\\u0559\\\\u0561-\\\\u0587\\\\u0591-\\\\u05BD\\\\u05BF\\\\u05C1\\\\u05C2\\\\u05C4\\\\u05C5\\\\u05C7\\\\u05D0-\\\\u05EA\\\\u05F0-\\\\u05F2\\\\u0610-\\\\u061A\\\\u0620-\\\\u0669\\\\u066E-\\\\u06D3\\\\u06D5-\\\\u06DC\\\\u06DF-\\\\u06E8\\\\u06EA-\\\\u06FC\\\\u06FF\\\\u0710-\\\\u074A\\\\u074D-\\\\u07B1\\\\u07C0-\\\\u07F5\\\\u07FA\\\\u0800-\\\\u082D\\\\u0840-\\\\u085B\\\\u08A0-\\\\u08B2\\\\u08E4-\\\\u0963\\\\u0966-\\\\u096F\\\\u0971-\\\\u0983\\\\u0985-\\\\u098C\\\\u098F\\\\u0990\\\\u0993-\\\\u09A8\\\\u09AA-\\\\u09B0\\\\u09B2\\\\u09B6-\\\\u09B9\\\\u09BC-\\\\u09C4\\\\u09C7\\\\u09C8\\\\u09CB-\\\\u09CE\\\\u09D7\\\\u09DC\\\\u09DD\\\\u09DF-\\\\u09E3\\\\u09E6-\\\\u09F1\\\\u0A01-\\\\u0A03\\\\u0A05-\\\\u0A0A\\\\u0A0F\\\\u0A10\\\\u0A13-\\\\u0A28\\\\u0A2A-\\\\u0A30\\\\u0A32\\\\u0A33\\\\u0A35\\\\u0A36\\\\u0A38\\\\u0A39\\\\u0A3C\\\\u0A3E-\\\\u0A42\\\\u0A47\\\\u0A48\\\\u0A4B-\\\\u0A4D\\\\u0A51\\\\u0A59-\\\\u0A5C\\\\u0A5E\\\\u0A66-\\\\u0A75\\\\u0A81-\\\\u0A83\\\\u0A85-\\\\u0A8D\\\\u0A8F-\\\\u0A91\\\\u0A93-\\\\u0AA8\\\\u0AAA-\\\\u0AB0\\\\u0AB2\\\\u0AB3\\\\u0AB5-\\\\u0AB9\\\\u0ABC-\\\\u0AC5\\\\u0AC7-\\\\u0AC9\\\\u0ACB-\\\\u0ACD\\\\u0AD0\\\\u0AE0-\\\\u0AE3\\\\u0AE6-\\\\u0AEF\\\\u0B01-\\\\u0B03\\\\u0B05-\\\\u0B0C\\\\u0B0F\\\\u0B10\\\\u0B13-\\\\u0B28\\\\u0B2A-\\\\u0B30\\\\u0B32\\\\u0B33\\\\u0B35-\\\\u0B39\\\\u0B3C-\\\\u0B44\\\\u0B47\\\\u0B48\\\\u0B4B-\\\\u0B4D\\\\u0B56\\\\u0B57\\\\u0B5C\\\\u0B5D\\\\u0B5F-\\\\u0B63\\\\u0B66-\\\\u0B6F\\\\u0B71\\\\u0B82\\\\u0B83\\\\u0B85-\\\\u0B8A\\\\u0B8E-\\\\u0B90\\\\u0B92-\\\\u0B95\\\\u0B99\\\\u0B9A\\\\u0B9C\\\\u0B9E\\\\u0B9F\\\\u0BA3\\\\u0BA4\\\\u0BA8-\\\\u0BAA\\\\u0BAE-\\\\u0BB9\\\\u0BBE-\\\\u0BC2\\\\u0BC6-\\\\u0BC8\\\\u0BCA-\\\\u0BCD\\\\u0BD0\\\\u0BD7\\\\u0BE6-\\\\u0BEF\\\\u0C00-\\\\u0C03\\\\u0C05-\\\\u0C0C\\\\u0C0E-\\\\u0C10\\\\u0C12-\\\\u0C28\\\\u0C2A-\\\\u0C39\\\\u0C3D-\\\\u0C44\\\\u0C46-\\\\u0C48\\\\u0C4A-\\\\u0C4D\\\\u0C55\\\\u0C56\\\\u0C58\\\\u0C59\\\\u0C60-\\\\u0C63\\\\u0C66-\\\\u0C6F\\\\u0C81-\\\\u0C83\\\\u0C85-\\\\u0C8C\\\\u0C8E-\\\\u0C90\\\\u0C92-\\\\u0CA8\\\\u0CAA-\\\\u0CB3\\\\u0CB5-\\\\u0CB9\\\\u0CBC-\\\\u0CC4\\\\u0CC6-\\\\u0CC8\\\\u0CCA-\\\\u0CCD\\\\u0CD5\\\\u0CD6\\\\u0CDE\\\\u0CE0-\\\\u0CE3\\\\u0CE6-\\\\u0CEF\\\\u0CF1\\\\u0CF2\\\\u0D01-\\\\u0D03\\\\u0D05-\\\\u0D0C\\\\u0D0E-\\\\u0D10\\\\u0D12-\\\\u0D3A\\\\u0D3D-\\\\u0D44\\\\u0D46-\\\\u0D48\\\\u0D4A-\\\\u0D4E\\\\u0D57\\\\u0D60-\\\\u0D63\\\\u0D66-\\\\u0D6F\\\\u0D7A-\\\\u0D7F\\\\u0D82\\\\u0D83\\\\u0D85-\\\\u0D96\\\\u0D9A-\\\\u0DB1\\\\u0DB3-\\\\u0DBB\\\\u0DBD\\\\u0DC0-\\\\u0DC6\\\\u0DCA\\\\u0DCF-\\\\u0DD4\\\\u0DD6\\\\u0DD8-\\\\u0DDF\\\\u0DE6-\\\\u0DEF\\\\u0DF2\\\\u0DF3\\\\u0E01-\\\\u0E3A\\\\u0E40-\\\\u0E4E\\\\u0E50-\\\\u0E59\\\\u0E81\\\\u0E82\\\\u0E84\\\\u0E87\\\\u0E88\\\\u0E8A\\\\u0E8D\\\\u0E94-\\\\u0E97\\\\u0E99-\\\\u0E9F\\\\u0EA1-\\\\u0EA3\\\\u0EA5\\\\u0EA7\\\\u0EAA\\\\u0EAB\\\\u0EAD-\\\\u0EB9\\\\u0EBB-\\\\u0EBD\\\\u0EC0-\\\\u0EC4\\\\u0EC6\\\\u0EC8-\\\\u0ECD\\\\u0ED0-\\\\u0ED9\\\\u0EDC-\\\\u0EDF\\\\u0F00\\\\u0F18\\\\u0F19\\\\u0F20-\\\\u0F29\\\\u0F35\\\\u0F37\\\\u0F39\\\\u0F3E-\\\\u0F47\\\\u0F49-\\\\u0F6C\\\\u0F71-\\\\u0F84\\\\u0F86-\\\\u0F97\\\\u0F99-\\\\u0FBC\\\\u0FC6\\\\u1000-\\\\u1049\\\\u1050-\\\\u109D\\\\u10A0-\\\\u10C5\\\\u10C7\\\\u10CD\\\\u10D0-\\\\u10FA\\\\u10FC-\\\\u1248\\\\u124A-\\\\u124D\\\\u1250-\\\\u1256\\\\u1258\\\\u125A-\\\\u125D\\\\u1260-\\\\u1288\\\\u128A-\\\\u128D\\\\u1290-\\\\u12B0\\\\u12B2-\\\\u12B5\\\\u12B8-\\\\u12BE\\\\u12C0\\\\u12C2-\\\\u12C5\\\\u12C8-\\\\u12D6\\\\u12D8-\\\\u1310\\\\u1312-\\\\u1315\\\\u1318-\\\\u135A\\\\u135D-\\\\u135F\\\\u1380-\\\\u138F\\\\u13A0-\\\\u13F4\\\\u1401-\\\\u166C\\\\u166F-\\\\u167F\\\\u1681-\\\\u169A\\\\u16A0-\\\\u16EA\\\\u16EE-\\\\u16F8\\\\u1700-\\\\u170C\\\\u170E-\\\\u1714\\\\u1720-\\\\u1734\\\\u1740-\\\\u1753\\\\u1760-\\\\u176C\\\\u176E-\\\\u1770\\\\u1772\\\\u1773\\\\u1780-\\\\u17D3\\\\u17D7\\\\u17DC\\\\u17DD\\\\u17E0-\\\\u17E9\\\\u180B-\\\\u180D\\\\u1810-\\\\u1819\\\\u1820-\\\\u1877\\\\u1880-\\\\u18AA\\\\u18B0-\\\\u18F5\\\\u1900-\\\\u191E\\\\u1920-\\\\u192B\\\\u1930-\\\\u193B\\\\u1946-\\\\u196D\\\\u1970-\\\\u1974\\\\u1980-\\\\u19AB\\\\u19B0-\\\\u19C9\\\\u19D0-\\\\u19D9\\\\u1A00-\\\\u1A1B\\\\u1A20-\\\\u1A5E\\\\u1A60-\\\\u1A7C\\\\u1A7F-\\\\u1A89\\\\u1A90-\\\\u1A99\\\\u1AA7\\\\u1AB0-\\\\u1ABD\\\\u1B00-\\\\u1B4B\\\\u1B50-\\\\u1B59\\\\u1B6B-\\\\u1B73\\\\u1B80-\\\\u1BF3\\\\u1C00-\\\\u1C37\\\\u1C40-\\\\u1C49\\\\u1C4D-\\\\u1C7D\\\\u1CD0-\\\\u1CD2\\\\u1CD4-\\\\u1CF6\\\\u1CF8\\\\u1CF9\\\\u1D00-\\\\u1DF5\\\\u1DFC-\\\\u1F15\\\\u1F18-\\\\u1F1D\\\\u1F20-\\\\u1F45\\\\u1F48-\\\\u1F4D\\\\u1F50-\\\\u1F57\\\\u1F59\\\\u1F5B\\\\u1F5D\\\\u1F5F-\\\\u1F7D\\\\u1F80-\\\\u1FB4\\\\u1FB6-\\\\u1FBC\\\\u1FBE\\\\u1FC2-\\\\u1FC4\\\\u1FC6-\\\\u1FCC\\\\u1FD0-\\\\u1FD3\\\\u1FD6-\\\\u1FDB\\\\u1FE0-\\\\u1FEC\\\\u1FF2-\\\\u1FF4\\\\u1FF6-\\\\u1FFC\\\\u200C\\\\u200D\\\\u203F\\\\u2040\\\\u2054\\\\u2071\\\\u207F\\\\u2090-\\\\u209C\\\\u20D0-\\\\u20DC\\\\u20E1\\\\u20E5-\\\\u20F0\\\\u2102\\\\u2107\\\\u210A-\\\\u2113\\\\u2115\\\\u2119-\\\\u211D\\\\u2124\\\\u2126\\\\u2128\\\\u212A-\\\\u212D\\\\u212F-\\\\u2139\\\\u213C-\\\\u213F\\\\u2145-\\\\u2149\\\\u214E\\\\u2160-\\\\u2188\\\\u2C00-\\\\u2C2E\\\\u2C30-\\\\u2C5E\\\\u2C60-\\\\u2CE4\\\\u2CEB-\\\\u2CF3\\\\u2D00-\\\\u2D25\\\\u2D27\\\\u2D2D\\\\u2D30-\\\\u2D67\\\\u2D6F\\\\u2D7F-\\\\u2D96\\\\u2DA0-\\\\u2DA6\\\\u2DA8-\\\\u2DAE\\\\u2DB0-\\\\u2DB6\\\\u2DB8-\\\\u2DBE\\\\u2DC0-\\\\u2DC6\\\\u2DC8-\\\\u2DCE\\\\u2DD0-\\\\u2DD6\\\\u2DD8-\\\\u2DDE\\\\u2DE0-\\\\u2DFF\\\\u2E2F\\\\u3005-\\\\u3007\\\\u3021-\\\\u302F\\\\u3031-\\\\u3035\\\\u3038-\\\\u303C\\\\u3041-\\\\u3096\\\\u3099\\\\u309A\\\\u309D-\\\\u309F\\\\u30A1-\\\\u30FA\\\\u30FC-\\\\u30FF\\\\u3105-\\\\u312D\\\\u3131-\\\\u318E\\\\u31A0-\\\\u31BA\\\\u31F0-\\\\u31FF\\\\u3400-\\\\u4DB5\\\\u4E00-\\\\u9FCC\\\\uA000-\\\\uA48C\\\\uA4D0-\\\\uA4FD\\\\uA500-\\\\uA60C\\\\uA610-\\\\uA62B\\\\uA640-\\\\uA66F\\\\uA674-\\\\uA67D\\\\uA67F-\\\\uA69D\\\\uA69F-\\\\uA6F1\\\\uA717-\\\\uA71F\\\\uA722-\\\\uA788\\\\uA78B-\\\\uA78E\\\\uA790-\\\\uA7AD\\\\uA7B0\\\\uA7B1\\\\uA7F7-\\\\uA827\\\\uA840-\\\\uA873\\\\uA880-\\\\uA8C4\\\\uA8D0-\\\\uA8D9\\\\uA8E0-\\\\uA8F7\\\\uA8FB\\\\uA900-\\\\uA92D\\\\uA930-\\\\uA953\\\\uA960-\\\\uA97C\\\\uA980-\\\\uA9C0\\\\uA9CF-\\\\uA9D9\\\\uA9E0-\\\\uA9FE\\\\uAA00-\\\\uAA36\\\\uAA40-\\\\uAA4D\\\\uAA50-\\\\uAA59\\\\uAA60-\\\\uAA76\\\\uAA7A-\\\\uAAC2\\\\uAADB-\\\\uAADD\\\\uAAE0-\\\\uAAEF\\\\uAAF2-\\\\uAAF6\\\\uAB01-\\\\uAB06\\\\uAB09-\\\\uAB0E\\\\uAB11-\\\\uAB16\\\\uAB20-\\\\uAB26\\\\uAB28-\\\\uAB2E\\\\uAB30-\\\\uAB5A\\\\uAB5C-\\\\uAB5F\\\\uAB64\\\\uAB65\\\\uABC0-\\\\uABEA\\\\uABEC\\\\uABED\\\\uABF0-\\\\uABF9\\\\uAC00-\\\\uD7A3\\\\uD7B0-\\\\uD7C6\\\\uD7CB-\\\\uD7FB\\\\uF900-\\\\uFA6D\\\\uFA70-\\\\uFAD9\\\\uFB00-\\\\uFB06\\\\uFB13-\\\\uFB17\\\\uFB1D-\\\\uFB28\\\\uFB2A-\\\\uFB36\\\\uFB38-\\\\uFB3C\\\\uFB3E\\\\uFB40\\\\uFB41\\\\uFB43\\\\uFB44\\\\uFB46-\\\\uFBB1\\\\uFBD3-\\\\uFD3D\\\\uFD50-\\\\uFD8F\\\\uFD92-\\\\uFDC7\\\\uFDF0-\\\\uFDFB\\\\uFE00-\\\\uFE0F\\\\uFE20-\\\\uFE2D\\\\uFE33\\\\uFE34\\\\uFE4D-\\\\uFE4F\\\\uFE70-\\\\uFE74\\\\uFE76-\\\\uFEFC\\\\uFF10-\\\\uFF19\\\\uFF21-\\\\uFF3A\\\\uFF3F\\\\uFF41-\\\\uFF5A\\\\uFF66-\\\\uFFBE\\\\uFFC2-\\\\uFFC7\\\\uFFCA-\\\\uFFCF\\\\uFFD2-\\\\uFFD7\\\\uFFDA-\\\\uFFDC]\");function Ah(t,e){if(!t)throw new Error(\"ASSERT: \"+e)}function gr(t){return t>=48&&t<=57}function By(t){return\"0123456789abcdefABCDEF\".indexOf(t)>=0}function xo(t){return\"01234567\".indexOf(t)>=0}function jY(t){return t===32||t===9||t===11||t===12||t===160||t>=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(t)>=0}function Xo(t){return t===10||t===13||t===8232||t===8233}function $s(t){return t===36||t===95||t>=65&&t<=90||t>=97&&t<=122||t===92||t>=128&&UY.test(String.fromCharCode(t))}function Wf(t){return t===36||t===95||t>=65&&t<=90||t>=97&&t<=122||t>=48&&t<=57||t===92||t>=128&&qY.test(String.fromCharCode(t))}const WY={if:1,in:1,do:1,var:1,for:1,new:1,try:1,let:1,this:1,else:1,case:1,void:1,with:1,enum:1,while:1,break:1,catch:1,throw:1,const:1,yield:1,class:1,super:1,return:1,typeof:1,delete:1,switch:1,export:1,import:1,public:1,static:1,default:1,finally:1,extends:1,package:1,private:1,function:1,continue:1,debugger:1,interface:1,protected:1,instanceof:1,implements:1};function T5(){for(;T1114111||t!==\"}\")&&ht({},Gt,Zt),e<=65535?String.fromCharCode(e):(n=(e-65536>>10)+55296,r=(e-65536&1023)+56320,String.fromCharCode(n,r))}function R5(){var t,e;for(t=j.charCodeAt(T++),e=String.fromCharCode(t),t===92&&(j.charCodeAt(T)!==117&&ht({},Gt,Zt),++T,t=A1(\"u\"),(!t||t===\"\\\\\"||!$s(t.charCodeAt(0)))&&ht({},Gt,Zt),e=t);T>>=\")return T+=4,{type:Oe,value:u,start:t,end:T};if(a=u.substr(0,3),a===\">>>\"||a===\"<<=\"||a===\">>=\")return T+=3,{type:Oe,value:a,start:t,end:T};if(i=a.substr(0,2),r===i[1]&&\"+-<>&|\".indexOf(r)>=0||i===\"=>\")return T+=2,{type:Oe,value:i,start:t,end:T};if(i===\"//\"&&ht({},Gt,Zt),\"<>=!+-*%&|^/\".indexOf(r)>=0)return++T,{type:Oe,value:r,start:t,end:T};ht({},Gt,Zt)}function XY(t){let e=\"\";for(;T=0&&T=0&&(n=n.replace(/\\\\u\\{([0-9a-fA-F]+)\\}/g,(r,i)=>{if(parseInt(i,16)<=1114111)return\"x\";ht({},b1)}).replace(/[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g,\"x\"));try{new RegExp(n)}catch{ht({},b1)}try{return new RegExp(t,e)}catch{return null}}function ZY(){var t,e,n,r,i;for(t=j[T],Ah(t===\"/\",\"Regular expression literal must start with a slash\"),e=j[T++],n=!1,r=!1;T=0&&ht({},b1,n),{value:n,literal:e}}function tH(){var t,e,n,r;return yt=null,T5(),t=T,e=ZY(),n=JY(),r=QY(e.value,n.value),{literal:e.literal+n.literal,value:r,regex:{pattern:e.value,flags:n.value},start:t,end:T}}function eH(t){return t.type===Qi||t.type===pi||t.type===vh||t.type===bh}function O5(){if(T5(),T>=he)return{type:Ms,start:T,end:T};const t=j.charCodeAt(T);return $s(t)?GY():t===40||t===41||t===59?$0():t===39||t===34?KY():t===46?gr(j.charCodeAt(T+1))?_b():$0():gr(t)?_b():$0()}function ze(){const t=yt;return T=t.end,yt=O5(),T=t.end,t}function N5(){const t=T;yt=O5(),T=t}function nH(t){const e=new Ln(CY);return e.elements=t,e}function Cb(t,e,n){const r=new Ln(t===\"||\"||t===\"&&\"?$Y:DY);return r.operator=t,r.left=e,r.right=n,r}function rH(t,e){const n=new Ln(FY);return n.callee=t,n.arguments=e,n}function iH(t,e,n){const r=new Ln(MY);return r.test=t,r.consequent=e,r.alternate=n,r}function Ty(t){const e=new Ln(S5);return e.name=t,e}function ao(t){const e=new Ln(kY);return e.value=t.value,e.raw=j.slice(t.start,t.end),t.regex&&(e.raw===\"//\"&&(e.raw=\"/(?:)/\"),e.regex=t.regex),e}function Db(t,e,n){const r=new Ln(SY);return r.computed=t===\"[\",r.object=e,r.property=n,r.computed||(n.member=!0),r}function aH(t){const e=new Ln(BY);return e.properties=t,e}function Fb(t,e,n){const r=new Ln(TY);return r.key=e,r.value=n,r.kind=t,r}function uH(t,e){const n=new Ln(RY);return n.operator=t,n.argument=e,n.prefix=!0,n}function ht(t,e){var n,r=Array.prototype.slice.call(arguments,2),i=e.replace(/%(\\d)/g,(a,u)=>(Ah(u\":case\"<=\":case\">=\":case\"instanceof\":case\"in\":e=7;break;case\"<<\":case\">>\":case\">>>\":e=8;break;case\"+\":case\"-\":e=9;break;case\"*\":case\"/\":case\"%\":e=11;break}return e}function xH(){var t,e,n,r,i,a,u,o,s,l;if(t=yt,s=kl(),r=yt,i=$b(r),i===0)return s;for(r.prec=i,ze(),e=[t,yt],u=kl(),a=[s,r,u];(i=$b(yt))>0;){for(;a.length>2&&i<=a[a.length-2].prec;)u=a.pop(),o=a.pop().value,s=a.pop(),e.pop(),n=Cb(o,s,u),a.push(n);r=ze(),r.prec=i,a.push(r),e.push(yt),n=kl(),a.push(n)}for(l=a.length-1,n=a[l],e.pop();l>1;)e.pop(),n=Cb(a[l-1].value,a[l-2],n),l-=2;return n}function Zi(){var t,e,n;return t=xH(),_t(\"?\")&&(ze(),e=Zi(),de(\":\"),n=Zi(),t=iH(t,e,n)),t}function Ry(){const t=Zi();if(_t(\",\"))throw new Error(Go);return t}function vH(t){j=t,T=0,he=j.length,yt=null,N5();const e=Ry();if(yt.type!==Ms)throw new Error(\"Unexpect token after expression.\");return e}var bH={NaN:\"NaN\",E:\"Math.E\",LN2:\"Math.LN2\",LN10:\"Math.LN10\",LOG2E:\"Math.LOG2E\",LOG10E:\"Math.LOG10E\",PI:\"Math.PI\",SQRT1_2:\"Math.SQRT1_2\",SQRT2:\"Math.SQRT2\",MIN_VALUE:\"Number.MIN_VALUE\",MAX_VALUE:\"Number.MAX_VALUE\"};function AH(t){function e(u,o,s,l){let f=t(o[0]);return s&&(f=s+\"(\"+f+\")\",s.lastIndexOf(\"new \",0)===0&&(f=\"(\"+f+\")\")),f+\".\"+u+(l<0?\"\":l===0?\"()\":\"(\"+o.slice(1).map(t).join(\",\")+\")\")}function n(u,o,s){return l=>e(u,l,o,s)}const r=\"new Date\",i=\"String\",a=\"RegExp\";return{isNaN:\"Number.isNaN\",isFinite:\"Number.isFinite\",abs:\"Math.abs\",acos:\"Math.acos\",asin:\"Math.asin\",atan:\"Math.atan\",atan2:\"Math.atan2\",ceil:\"Math.ceil\",cos:\"Math.cos\",exp:\"Math.exp\",floor:\"Math.floor\",log:\"Math.log\",max:\"Math.max\",min:\"Math.min\",pow:\"Math.pow\",random:\"Math.random\",round:\"Math.round\",sin:\"Math.sin\",sqrt:\"Math.sqrt\",tan:\"Math.tan\",clamp:function(u){u.length<3&&$(\"Missing arguments to clamp function.\"),u.length>3&&$(\"Too many arguments to clamp function.\");const o=u.map(t);return\"Math.max(\"+o[1]+\", Math.min(\"+o[2]+\",\"+o[0]+\"))\"},now:\"Date.now\",utc:\"Date.UTC\",datetime:r,date:n(\"getDate\",r,0),day:n(\"getDay\",r,0),year:n(\"getFullYear\",r,0),month:n(\"getMonth\",r,0),hours:n(\"getHours\",r,0),minutes:n(\"getMinutes\",r,0),seconds:n(\"getSeconds\",r,0),milliseconds:n(\"getMilliseconds\",r,0),time:n(\"getTime\",r,0),timezoneoffset:n(\"getTimezoneOffset\",r,0),utcdate:n(\"getUTCDate\",r,0),utcday:n(\"getUTCDay\",r,0),utcyear:n(\"getUTCFullYear\",r,0),utcmonth:n(\"getUTCMonth\",r,0),utchours:n(\"getUTCHours\",r,0),utcminutes:n(\"getUTCMinutes\",r,0),utcseconds:n(\"getUTCSeconds\",r,0),utcmilliseconds:n(\"getUTCMilliseconds\",r,0),length:n(\"length\",null,-1),parseFloat:\"parseFloat\",parseInt:\"parseInt\",upper:n(\"toUpperCase\",i,0),lower:n(\"toLowerCase\",i,0),substring:n(\"substring\",i),split:n(\"split\",i),trim:n(\"trim\",i,0),regexp:a,test:n(\"test\",a),if:function(u){u.length<3&&$(\"Missing arguments to if function.\"),u.length>3&&$(\"Too many arguments to if function.\");const o=u.map(t);return\"(\"+o[0]+\"?\"+o[1]+\":\"+o[2]+\")\"}}}function wH(t){const e=t&&t.length-1;return e&&(t[0]==='\"'&&t[e]==='\"'||t[0]===\"'\"&&t[e]===\"'\")?t.slice(1,-1):t}function EH(t){t=t||{};const e=t.allowed?nn(t.allowed):{},n=t.forbidden?nn(t.forbidden):{},r=t.constants||bH,i=(t.functions||AH)(c),a=t.globalvar,u=t.fieldvar,o=tt(a)?a:g=>`${a}[\"${g}\"]`;let s={},l={},f=0;function c(g){if(xt(g))return g;const p=h[g.type];return p==null&&$(\"Unsupported type: \"+g.type),p(g)}const h={Literal:g=>g.raw,Identifier:g=>{const p=g.name;return f>0?p:X(n,p)?$(\"Illegal identifier: \"+p):X(r,p)?r[p]:X(e,p)?p:(s[p]=1,o(p))},MemberExpression:g=>{const p=!g.computed,m=c(g.object);p&&(f+=1);const y=c(g.property);return m===u&&(l[wH(y)]=1),p&&(f-=1),m+(p?\".\"+y:\"[\"+y+\"]\")},CallExpression:g=>{g.callee.type!==\"Identifier\"&&$(\"Illegal callee type: \"+g.callee.type);const p=g.callee.name,m=g.arguments,y=X(i,p)&&i[p];return y||$(\"Unrecognized function: \"+p),tt(y)?y(m):y+\"(\"+m.map(c).join(\",\")+\")\"},ArrayExpression:g=>\"[\"+g.elements.map(c).join(\",\")+\"]\",BinaryExpression:g=>\"(\"+c(g.left)+\" \"+g.operator+\" \"+c(g.right)+\")\",UnaryExpression:g=>\"(\"+g.operator+c(g.argument)+\")\",ConditionalExpression:g=>\"(\"+c(g.test)+\"?\"+c(g.consequent)+\":\"+c(g.alternate)+\")\",LogicalExpression:g=>\"(\"+c(g.left)+g.operator+c(g.right)+\")\",ObjectExpression:g=>\"{\"+g.properties.map(c).join(\",\")+\"}\",Property:g=>{f+=1;const p=c(g.key);return f-=1,p+\":\"+c(g.value)}};function d(g){const p={code:c(g),globals:Object.keys(s),fields:Object.keys(l)};return s={},l={},p}return d.functions=i,d.constants=r,d}var _H=\"5.23.0\";nt(qa,uS,KR,MO,aN,hN,zN,xN,UN,YN,eL,sL);const LH=Object.freeze(Object.defineProperty({__proto__:null,Bounds:St,CanvasHandler:bs,CanvasRenderer:$f,DATE:He,DAY:oe,DAYOFYEAR:Jn,Dataflow:ka,Debug:y3,Error:lg,EventStream:Dc,Gradient:Op,GroupItem:Hc,HOURS:rn,Handler:oi,Info:m3,Item:Yc,MILLISECONDS:Bn,MINUTES:an,MONTH:le,Marks:on,MultiPulse:Wg,None:g3,Operator:At,Parameters:Cc,Pulse:Qr,QUARTER:Ye,RenderType:Hr,Renderer:ir,ResourceLoader:zp,SECONDS:yn,SVGHandler:rm,SVGRenderer:lm,SVGStringRenderer:fm,Scenegraph:em,TIME_UNITS:Fg,Transform:S,View:PD,WEEK:Nt,Warn:p3,YEAR:Jt,accessor:Ge,accessorFields:se,accessorName:$t,array:H,ascending:yc,bandwidthNRD:Xg,bin:oE,bootstrapCI:sE,boundClip:oC,boundContext:ms,boundItem:Pd,boundMark:T_,boundStroke:$r,changeset:ra,clampRange:yg,codegenExpression:EH,compare:xg,constant:pe,cumulativeLogNormal:$c,cumulativeNormal:is,cumulativeUniform:Rc,dayofyear:Sg,debounce:vg,defaultLocale:zg,definition:iE,densityLogNormal:kc,densityNormal:Fc,densityUniform:Tc,domChild:Le,domClear:Cn,domCreate:Wr,domFind:nm,dotbin:lE,error:$,expressionFunction:Rt,extend:nt,extent:Sn,extentIndex:_3,falsy:Rr,fastmap:iu,field:en,flush:bg,font:Qc,fontFamily:vs,fontSize:rr,format:fl,formatLocale:vf,formats:qg,hasOwnProperty:X,id:ns,identity:ge,inferType:G3,inferTypes:X3,ingest:gt,inherits:L,inrange:Bi,interpolate:$p,interpolateColors:jc,interpolateRange:n_,intersect:cm,intersectBoxLine:Ea,intersectPath:Ip,intersectPoint:Up,intersectRule:w_,isArray:U,isBoolean:Ag,isDate:Cr,isFunction:tt,isIterable:C3,isNumber:Mr,isObject:et,isRegExp:wg,isString:xt,isTuple:su,key:Eg,lerp:_g,lineHeight:ai,loader:wc,locale:Y3,logger:x3,lruCache:D3,markup:sm,merge:F3,mergeConfig:v3,multiLineOffset:Zp,one:ru,pad:Cg,panLinear:cg,panLog:hg,panPow:dg,panSymlog:gg,parse:fY,parseExpression:vH,parseSelector:t5,path:Vf,pathCurves:Np,pathEqual:sC,pathParse:Gi,pathRectangle:y_,pathRender:Ha,pathSymbols:m_,pathTrail:x_,peek:ut,point:Jc,projection:Em,quantileLogNormal:Sc,quantileNormal:as,quantileUniform:Oc,quantiles:Hg,quantizeInterpolator:r_,quarter:pg,quartiles:Gg,get random(){return un},randomInteger:f$,randomKDE:Kg,randomLCG:l$,randomLogNormal:cE,randomMixture:hE,randomNormal:Vg,randomUniform:dE,read:Q3,regressionExp:pE,regressionLinear:Qg,regressionLoess:xE,regressionLog:gE,regressionPoly:yE,regressionPow:mE,regressionQuad:Zg,renderModule:th,repeat:Xu,resetDefaultLocale:u7,resetSVGClipId:b_,resetSVGDefIds:gR,responseType:K3,runtimeContext:CD,sampleCurve:Lc,sampleLogNormal:Mc,sampleNormal:rs,sampleUniform:Bc,scale:ft,sceneEqual:hm,sceneFromJSON:O_,scenePickVisit:_f,sceneToJSON:R_,sceneVisit:Tn,sceneZOrder:qp,scheme:Sp,serializeXML:K_,setRandom:o$,span:au,splitAccessPath:cc,stringValue:Y,textMetrics:kn,timeBin:P3,timeFloor:B3,timeFormatLocale:To,timeInterval:uu,timeOffset:Og,timeSequence:Lg,timeUnitSpecifier:kg,timeUnits:Mg,toBoolean:xc,toDate:vc,toNumber:Kt,toSet:nn,toString:bc,transform:aE,transforms:qa,truncate:Dg,truthy:We,tupleid:K,typeParsers:Md,utcFloor:T3,utcInterval:ou,utcOffset:Ng,utcSequence:Pg,utcdayofyear:Tg,utcquarter:mg,utcweek:Rg,version:_H,visitArray:Lr,week:Bg,writeConfig:fg,zero:Ir,zoomLinear:gc,zoomLog:pc,zoomPow:Bo,zoomSymlog:mc},Symbol.toStringTag,{value:\"Module\"}));function CH(t,e,n){let r;e.x2&&(e.x?(n&&t.x>t.x2&&(r=t.x,t.x=t.x2,t.x2=r),t.width=t.x2-t.x):t.x=t.x2-(t.width||0)),e.xc&&(t.x=t.xc-(t.width||0)/2),e.y2&&(e.y?(n&&t.y>t.y2&&(r=t.y,t.y=t.y2,t.y2=r),t.height=t.y2-t.y):t.y=t.y2-(t.height||0)),e.yc&&(t.y=t.yc-(t.height||0)/2)}var DH={NaN:NaN,E:Math.E,LN2:Math.LN2,LN10:Math.LN10,LOG2E:Math.LOG2E,LOG10E:Math.LOG10E,PI:Math.PI,SQRT1_2:Math.SQRT1_2,SQRT2:Math.SQRT2,MIN_VALUE:Number.MIN_VALUE,MAX_VALUE:Number.MAX_VALUE},FH={\"*\":(t,e)=>t*e,\"+\":(t,e)=>t+e,\"-\":(t,e)=>t-e,\"/\":(t,e)=>t/e,\"%\":(t,e)=>t%e,\">\":(t,e)=>t>e,\"<\":(t,e)=>tt<=e,\">=\":(t,e)=>t>=e,\"==\":(t,e)=>t==e,\"!=\":(t,e)=>t!=e,\"===\":(t,e)=>t===e,\"!==\":(t,e)=>t!==e,\"&\":(t,e)=>t&e,\"|\":(t,e)=>t|e,\"^\":(t,e)=>t^e,\"<<\":(t,e)=>t<>\":(t,e)=>t>>e,\">>>\":(t,e)=>t>>>e},MH={\"+\":t=>+t,\"-\":t=>-t,\"~\":t=>~t,\"!\":t=>!t};const kH=Array.prototype.slice,bi=(t,e,n)=>{const r=n?n(e[0]):e[0];return r[t].apply(r,kH.call(e,1))},$H=(t,e,n,r,i,a,u)=>new Date(t,e||0,n??1,r||0,i||0,a||0,u||0);var SH={isNaN:Number.isNaN,isFinite:Number.isFinite,abs:Math.abs,acos:Math.acos,asin:Math.asin,atan:Math.atan,atan2:Math.atan2,ceil:Math.ceil,cos:Math.cos,exp:Math.exp,floor:Math.floor,log:Math.log,max:Math.max,min:Math.min,pow:Math.pow,random:Math.random,round:Math.round,sin:Math.sin,sqrt:Math.sqrt,tan:Math.tan,clamp:(t,e,n)=>Math.max(e,Math.min(n,t)),now:Date.now,utc:Date.UTC,datetime:$H,date:t=>new Date(t).getDate(),day:t=>new Date(t).getDay(),year:t=>new Date(t).getFullYear(),month:t=>new Date(t).getMonth(),hours:t=>new Date(t).getHours(),minutes:t=>new Date(t).getMinutes(),seconds:t=>new Date(t).getSeconds(),milliseconds:t=>new Date(t).getMilliseconds(),time:t=>new Date(t).getTime(),timezoneoffset:t=>new Date(t).getTimezoneOffset(),utcdate:t=>new Date(t).getUTCDate(),utcday:t=>new Date(t).getUTCDay(),utcyear:t=>new Date(t).getUTCFullYear(),utcmonth:t=>new Date(t).getUTCMonth(),utchours:t=>new Date(t).getUTCHours(),utcminutes:t=>new Date(t).getUTCMinutes(),utcseconds:t=>new Date(t).getUTCSeconds(),utcmilliseconds:t=>new Date(t).getUTCMilliseconds(),length:t=>t.length,join:function(){return bi(\"join\",arguments)},indexof:function(){return bi(\"indexOf\",arguments)},lastindexof:function(){return bi(\"lastIndexOf\",arguments)},slice:function(){return bi(\"slice\",arguments)},reverse:t=>t.slice().reverse(),parseFloat,parseInt,upper:t=>String(t).toUpperCase(),lower:t=>String(t).toLowerCase(),substring:function(){return bi(\"substring\",arguments,String)},split:function(){return bi(\"split\",arguments,String)},replace:function(){return bi(\"replace\",arguments,String)},trim:t=>String(t).trim(),regexp:RegExp,test:(t,e)=>RegExp(t).test(e)};const BH=[\"view\",\"item\",\"group\",\"xy\",\"x\",\"y\"],w1=new Set([Function,eval,setTimeout,setInterval]);typeof setImmediate==\"function\"&&w1.add(setImmediate);const TH={Literal:(t,e)=>e.value,Identifier:(t,e)=>{const n=e.name;return t.memberDepth>0?n:n===\"datum\"?t.datum:n===\"event\"?t.event:n===\"item\"?t.item:DH[n]||t.params[\"$\"+n]},MemberExpression:(t,e)=>{const n=!e.computed,r=t(e.object);n&&(t.memberDepth+=1);const i=t(e.property);if(n&&(t.memberDepth-=1),w1.has(r[i])){console.error(`Prevented interpretation of member \"${i}\" which could lead to insecure code execution`);return}return r[i]},CallExpression:(t,e)=>{const n=e.arguments;let r=e.callee.name;return r.startsWith(\"_\")&&(r=r.slice(1)),r===\"if\"?t(n[0])?t(n[1]):t(n[2]):(t.fn[r]||SH[r]).apply(t.fn,n.map(t))},ArrayExpression:(t,e)=>e.elements.map(t),BinaryExpression:(t,e)=>FH[e.operator](t(e.left),t(e.right)),UnaryExpression:(t,e)=>MH[e.operator](t(e.argument)),ConditionalExpression:(t,e)=>t(e.test)?t(e.consequent):t(e.alternate),LogicalExpression:(t,e)=>e.operator===\"&&\"?t(e.left)&&t(e.right):t(e.left)||t(e.right),ObjectExpression:(t,e)=>e.properties.reduce((n,r)=>{t.memberDepth+=1;const i=t(r.key);return t.memberDepth-=1,w1.has(t(r.value))?console.error(`Prevented interpretation of property \"${i}\" which could lead to insecure code execution`):n[i]=t(r.value),n},{})};function Pu(t,e,n,r,i,a){const u=o=>TH[o.type](u,o);return u.memberDepth=0,u.fn=Object.create(e),u.params=n,u.datum=r,u.event=i,u.item=a,BH.forEach(o=>u.fn[o]=function(){return i.vega[o](...arguments)}),u(t)}var PH={operator(t,e){const n=e.ast,r=t.functions;return i=>Pu(n,r,i)},parameter(t,e){const n=e.ast,r=t.functions;return(i,a)=>Pu(n,r,a,i)},event(t,e){const n=e.ast,r=t.functions;return i=>Pu(n,r,void 0,void 0,i)},handler(t,e){const n=e.ast,r=t.functions;return(i,a)=>{const u=a.item&&a.item.datum;return Pu(n,r,i,u,a)}},encode(t,e){const{marktype:n,channels:r}=e,i=t.functions,a=n===\"group\"||n===\"image\"||n===\"rect\";return(u,o)=>{const s=u.datum;let l=0,f;for(const c in r)f=Pu(r[c].ast,i,o,s,void 0,u),u[c]!==f&&(u[c]=f,l=1);return n!==\"rule\"&&CH(u,r,a),l}}};export{Y as $,p3 as W,xt as a,et as b,Ag as c,U as d,H as e,tt as f,t5 as g,X as h,Mr as i,ge as j,ug as k,x3 as l,v3 as m,PH as n,pP as p,cc as s,LH as v,fg as w};\n//# sourceMappingURL=vega-interpreter.module.js.map\n"],"names":["l","L5"],"mappings":"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,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC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C,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAA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E,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAA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,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC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,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC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,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC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,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC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AC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CA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GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,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AAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,qBAAqB,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,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E,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAA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C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,EAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,C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,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,OAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC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,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,EAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC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,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,gBAAgB,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,CAAC,EAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAC,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CA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AC,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,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KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAE,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,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AAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,C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AAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAE,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,KAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,SAAS,GAAE,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAE,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,GAAE,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAC,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAE,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAE,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,C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AAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,GAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,C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AAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAI,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,C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,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC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,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAE,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAE,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAE,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC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AE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,UAAU,CAAC,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAE,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,GAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,GAAE,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,GAAE,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,GAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,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CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,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CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAM,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAM,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,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CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,OAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,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CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,KAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,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EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,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C,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAA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C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAA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C,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAA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C,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAA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C,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAA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EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,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KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,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C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,C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AS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CA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AE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CA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CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,EAAE,QAAQ,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAG,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAK,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,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CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,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CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,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AC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CA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GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,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AC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CA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OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,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CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAA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C,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,qCAAqC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAM,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,qDAAqD,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,4BAA4B,CAAC,EAAE,CAAC,iGAAiG,CAAC,EAAE,CAAC,6DAA6D,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,MAAM,EAAE,CAAC,CAAC,IAAI,GAAG,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,eAAe,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,OAAO,EAAE,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,CAAC,wBAAwB,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,CAAC,iCAAiC,EAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAM,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,OAAM,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AACtzsB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,OAAO,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,6CAA6C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,YAAY,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,WAAW,GAAG,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,IAAI,C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,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC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,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC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AAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,C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AAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,C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AAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,C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AmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,6BAA6B,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,C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AAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,C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AAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,C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AAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,C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AC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CA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AC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CA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AE,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CA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,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC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,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC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CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,GAAE,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAA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C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAA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E,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAA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CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,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CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,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C,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,GAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,G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CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,GAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,GAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,GAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAA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C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,C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AAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,C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AAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,C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,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CA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EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,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CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,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C,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAA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,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC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AC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CA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AE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,EAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,EAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CA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AC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,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CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,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MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,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CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,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CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,4DAA4D,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,C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,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC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,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC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AAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,C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AAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,C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AAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,I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AC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CA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CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,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AQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CA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AG,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CA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AC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,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AC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CA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AC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,OAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,SA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CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,gDAAgD,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,wDAAwD,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,uBAAuB,CAAC,EAAE,CAAC,mBAAmB,CAAC,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAC,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,OAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,OAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,CAAC,OAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,CAAC,OAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,OAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,OAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,OAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,uBAAuB,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,mBAAmB,CAAC,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,qBAAqB,CAAC,EAAE,CAAC,mBAAmB,CAAC,EAAE,CAAC,mBAAmB,CAAC,EAAE,CAAC,uBAAuB,CAAC,EAAE,CAAC,0BAA0B,CAAC,EAAE,CAAC,yBAAyB,CAAC,EAAE,CAAC,4BAA4B,CAAC,EAAE,CAAC,uCAAuC,CAAC,EAAE,CAAC,gDAAgD,CAAC,EAAE,CAAC,sEAAsE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,szJAAszJ,CAAC,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,muLAAmuL,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CA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AC,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAE,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,YAAY,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EA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G,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAM,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAA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C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,sCAAsC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,OAAO,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAM,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAA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,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,sCAAsC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,OAAO,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAM,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC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AE,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CA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C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAA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,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CA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,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC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,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,KAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE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C,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAA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AE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CA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AAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,OAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,C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AC,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CA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AE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,YAAY,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,CA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C,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAA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"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/webworkerAll-COumIYOS.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/webworkerAll-COumIYOS.js new file mode 100644 index 0000000000000000000000000000000000000000..0e5b1fafef791073b80b49700b94b00160c23914 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/webworkerAll-COumIYOS.js @@ -0,0 +1,14 @@ +import './init-Dm1OEjUU.js'; +import './Index3-DezoQBCD.js'; +import './colorToUniform-BWqj7xWF.js'; +import './Component-NmRBwSfF.js'; +import './ssr-C3HYbsxA.js'; +import './2-2QjpS3e7.js'; +import './index-ClteBeTX.js'; +import 'path'; +import 'url'; +import 'fs'; +import './ImagePreview-CkivoaK1.js'; +import './ModifyUpload-D3TChhFo.js'; +import './tinycolor-BAU9cgwS.js'; +//# sourceMappingURL=webworkerAll-COumIYOS.js.map diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/webworkerAll-COumIYOS.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/webworkerAll-COumIYOS.js.map new file mode 100644 index 0000000000000000000000000000000000000000..012bf35d0244255fa7e5c10bb5218cb94243ef78 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/webworkerAll-COumIYOS.js.map @@ -0,0 +1 @@ +{"version":3,"file":"webworkerAll-COumIYOS.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/wrapper-CYei9jbK.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/wrapper-CYei9jbK.js new file mode 100644 index 0000000000000000000000000000000000000000..7588fd51ccd3c4a01c980db3c52853b4a87d0b97 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/wrapper-CYei9jbK.js @@ -0,0 +1,31 @@ +import { H as Hr$1, aC as Ks$1 } from './2-2QjpS3e7.js'; +import yt from 'stream'; +import qt from 'zlib'; +import { r } from './_commonjs-dynamic-modules-DX_xVkta.js'; +import require$$1$1 from 'fs'; +import require$$2 from 'path'; +import Kt from 'os'; +import Xt from 'buffer'; +import Zt from 'net'; +import Qt from 'tls'; +import Ie from 'crypto'; +import vt from 'events'; +import Jt from 'https'; +import St from 'http'; +import require$$1 from 'url'; +import './ssr-C3HYbsxA.js'; +import './index-ClteBeTX.js'; +import './Component-NmRBwSfF.js'; + +const{Duplex:tr}=yt;function je(r){r.emit("close");}function rr(){!this.destroyed&&this._writableState.finished&&this.destroy();}function xt(r){this.removeListener("error",xt),this.destroy(),this.listenerCount("error")===0&&this.emit("error",r);}function sr(r,e){let t=!0;const s=new tr({...e,autoDestroy:!1,emitClose:!1,objectMode:!1,writableObjectMode:!1});return r.on("message",function(n,o){const a=!o&&s._readableState.objectMode?n.toString():n;s.push(a)||r.pause();}),r.once("error",function(n){s.destroyed||(t=!1,s.destroy(n));}),r.once("close",function(){s.destroyed||s.push(null);}),s._destroy=function(i,n){if(r.readyState===r.CLOSED){n(i),process.nextTick(je,s);return}let o=!1;r.once("error",function(l){o=!0,n(l);}),r.once("close",function(){o||n(i),process.nextTick(je,s);}),t&&r.terminate();},s._final=function(i){if(r.readyState===r.CONNECTING){r.once("open",function(){s._final(i);});return}r._socket!==null&&(r._socket._writableState.finished?(i(),s._readableState.endEmitted&&s.destroy()):(r._socket.once("finish",function(){i();}),r.close()));},s._read=function(){r.isPaused&&r.resume();},s._write=function(i,n,o){if(r.readyState===r.CONNECTING){r.once("open",function(){s._write(i,n,o);});return}r.send(i,o);},s.on("end",rr),s.on("error",xt),s}var ir=sr;const qs=Hr$1(ir);var ue={exports:{}},W={BINARY_TYPES:["nodebuffer","arraybuffer","fragments"],EMPTY_BUFFER:Buffer.alloc(0),GUID:"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",kForOnEventAttribute:Symbol("kIsForOnEventAttribute"),kListener:Symbol("kListener"),kStatusCode:Symbol("status-code"),kWebSocket:Symbol("websocket"),NOOP:()=>{}},ie={exports:{}},ne={exports:{}},be,Ge;function nr(){if(Ge)return be;Ge=1;var r$1=require$$1$1,e=require$$2,t=Kt,s=typeof __webpack_require__=="function"?__non_webpack_require__:r,i=process.config&&process.config.variables||{},n=!!process.env.PREBUILDS_ONLY,o=process.versions.modules,a=xe()?"electron":Y()?"node-webkit":"node",l=process.env.npm_config_arch||t.arch(),f=process.env.npm_config_platform||t.platform(),h=process.env.LIBC||(At(f)?"musl":"glibc"),c=process.env.ARM_VERSION||(l==="arm64"?"8":i.arm_version)||"",y=(process.versions.uv||"").split(".")[0];be=p;function p(u){return s(p.resolve(u))}p.resolve=p.path=function(u){u=e.resolve(u||".");try{var m=s(e.join(u,"package.json")).name.toUpperCase().replace(/-/g,"_");process.env[m+"_PREBUILD"]&&(u=process.env[m+"_PREBUILD"]);}catch{}if(!n){var _=d(e.join(u,"build/Release"),E);if(_)return _;var k=d(e.join(u,"build/Debug"),E);if(k)return k}var j=De(u);if(j)return j;var b=De(e.dirname(process.execPath));if(b)return b;var Wt=["platform="+f,"arch="+l,"runtime="+a,"abi="+o,"uv="+y,c?"armv="+c:"","libc="+h,"node="+process.versions.node,process.versions.electron?"electron="+process.versions.electron:"",typeof __webpack_require__=="function"?"webpack=true":""].filter(Boolean).join(" ");throw new Error("No native build was found for "+Wt+` + loaded from: `+u+` +`);function De(Ee){var Ft=g(e.join(Ee,"prebuilds")).map(L),Ae=Ft.filter(I(f,l)).sort(R)[0];if(Ae){var We=e.join(Ee,"prebuilds",Ae.name),jt=g(We).map(C),Gt=jt.filter(q(a,o)),Fe=Gt.sort(z(a))[0];if(Fe)return e.join(We,Fe.file)}}};function g(u){try{return r$1.readdirSync(u)}catch{return []}}function d(u,m){var _=g(u).filter(m);return _[0]&&e.join(u,_[0])}function E(u){return /\.node$/.test(u)}function L(u){var m=u.split("-");if(m.length===2){var _=m[0],k=m[1].split("+");if(_&&k.length&&k.every(Boolean))return {name:u,platform:_,architectures:k}}}function I(u,m){return function(_){return _==null||_.platform!==u?!1:_.architectures.includes(m)}}function R(u,m){return u.architectures.length-m.architectures.length}function C(u){var m=u.split("."),_=m.pop(),k={file:u,specificity:0};if(_==="node"){for(var j=0;j_.specificity?-1:1:0}}function Y(){return !!(process.versions&&process.versions.nw)}function xe(){return process.versions&&process.versions.electron||process.env.ELECTRON_RUN_AS_NODE?!0:typeof window<"u"&&window.process&&window.process.type==="renderer"}function At(u){return u==="linux"&&r$1.existsSync("/etc/alpine-release")}return p.parseTags=C,p.matchTags=q,p.compareTags=z,p.parseTuple=L,p.matchTuple=I,p.compareTuples=R,be}var Ve;function or(){return Ve||(Ve=1,typeof process.addon=="function"?ne.exports=process.addon.bind(process):ne.exports=nr()),ne.exports}var we,qe;function ar(){return qe||(qe=1,we={mask:(t,s,i,n,o)=>{for(var a=0;a{const i=t.length;for(var n=0;n{this.pending--,this[ke]();},this.concurrency=e||1/0,this.jobs=[],this.pending=0;}add(e){this.jobs.push(e),this[ke]();}[ke](){if(this.pending!==this.concurrency&&this.jobs.length){const e=this.jobs.shift();this.pending++,e(this[ze]);}}};var pr=_r;const K=qt,Ye=me,mr=pr,{kStatusCode:wt}=W,gr=Buffer[Symbol.species],yr=Buffer.from([0,0,255,255]),de=Symbol("permessage-deflate"),$=Symbol("total-length"),ee=Symbol("callback"),B=Symbol("buffers"),ce=Symbol("error");let oe,vr=class{constructor(e,t,s){if(this._maxPayload=s|0,this._options=e||{},this._threshold=this._options.threshold!==void 0?this._options.threshold:1024,this._isServer=!!t,this._deflate=null,this._inflate=null,this.params=null,!oe){const i=this._options.concurrencyLimit!==void 0?this._options.concurrencyLimit:10;oe=new mr(i);}}static get extensionName(){return "permessage-deflate"}offer(){const e={};return this._options.serverNoContextTakeover&&(e.server_no_context_takeover=!0),this._options.clientNoContextTakeover&&(e.client_no_context_takeover=!0),this._options.serverMaxWindowBits&&(e.server_max_window_bits=this._options.serverMaxWindowBits),this._options.clientMaxWindowBits?e.client_max_window_bits=this._options.clientMaxWindowBits:this._options.clientMaxWindowBits==null&&(e.client_max_window_bits=!0),e}accept(e){return e=this.normalizeParams(e),this.params=this._isServer?this.acceptAsServer(e):this.acceptAsClient(e),this.params}cleanup(){if(this._inflate&&(this._inflate.close(),this._inflate=null),this._deflate){const e=this._deflate[ee];this._deflate.close(),this._deflate=null,e&&e(new Error("The deflate stream was closed while data was being processed"));}}acceptAsServer(e){const t=this._options,s=e.find(i=>!(t.serverNoContextTakeover===!1&&i.server_no_context_takeover||i.server_max_window_bits&&(t.serverMaxWindowBits===!1||typeof t.serverMaxWindowBits=="number"&&t.serverMaxWindowBits>i.server_max_window_bits)||typeof t.clientMaxWindowBits=="number"&&!i.client_max_window_bits));if(!s)throw new Error("None of the extension offers can be accepted");return t.serverNoContextTakeover&&(s.server_no_context_takeover=!0),t.clientNoContextTakeover&&(s.client_no_context_takeover=!0),typeof t.serverMaxWindowBits=="number"&&(s.server_max_window_bits=t.serverMaxWindowBits),typeof t.clientMaxWindowBits=="number"?s.client_max_window_bits=t.clientMaxWindowBits:(s.client_max_window_bits===!0||t.clientMaxWindowBits===!1)&&delete s.client_max_window_bits,s}acceptAsClient(e){const t=e[0];if(this._options.clientNoContextTakeover===!1&&t.client_no_context_takeover)throw new Error('Unexpected parameter "client_no_context_takeover"');if(!t.client_max_window_bits)typeof this._options.clientMaxWindowBits=="number"&&(t.client_max_window_bits=this._options.clientMaxWindowBits);else if(this._options.clientMaxWindowBits===!1||typeof this._options.clientMaxWindowBits=="number"&&t.client_max_window_bits>this._options.clientMaxWindowBits)throw new Error('Unexpected or invalid parameter "client_max_window_bits"');return t}normalizeParams(e){return e.forEach(t=>{Object.keys(t).forEach(s=>{let i=t[s];if(i.length>1)throw new Error(`Parameter "${s}" must have only a single value`);if(i=i[0],s==="client_max_window_bits"){if(i!==!0){const n=+i;if(!Number.isInteger(n)||n<8||n>15)throw new TypeError(`Invalid value for parameter "${s}": ${i}`);i=n;}else if(!this._isServer)throw new TypeError(`Invalid value for parameter "${s}": ${i}`)}else if(s==="server_max_window_bits"){const n=+i;if(!Number.isInteger(n)||n<8||n>15)throw new TypeError(`Invalid value for parameter "${s}": ${i}`);i=n;}else if(s==="client_no_context_takeover"||s==="server_no_context_takeover"){if(i!==!0)throw new TypeError(`Invalid value for parameter "${s}": ${i}`)}else throw new Error(`Unknown parameter "${s}"`);t[s]=i;});}),e}decompress(e,t,s){oe.add(i=>{this._decompress(e,t,(n,o)=>{i(),s(n,o);});});}compress(e,t,s){oe.add(i=>{this._compress(e,t,(n,o)=>{i(),s(n,o);});});}_decompress(e,t,s){const i=this._isServer?"client":"server";if(!this._inflate){const n=`${i}_max_window_bits`,o=typeof this.params[n]!="number"?K.Z_DEFAULT_WINDOWBITS:this.params[n];this._inflate=K.createInflateRaw({...this._options.zlibInflateOptions,windowBits:o}),this._inflate[de]=this,this._inflate[$]=0,this._inflate[B]=[],this._inflate.on("error",xr),this._inflate.on("data",kt);}this._inflate[ee]=s,this._inflate.write(e),t&&this._inflate.write(yr),this._inflate.flush(()=>{const n=this._inflate[ce];if(n){this._inflate.close(),this._inflate=null,s(n);return}const o=Ye.concat(this._inflate[B],this._inflate[$]);this._inflate._readableState.endEmitted?(this._inflate.close(),this._inflate=null):(this._inflate[$]=0,this._inflate[B]=[],t&&this.params[`${i}_no_context_takeover`]&&this._inflate.reset()),s(null,o);});}_compress(e,t,s){const i=this._isServer?"server":"client";if(!this._deflate){const n=`${i}_max_window_bits`,o=typeof this.params[n]!="number"?K.Z_DEFAULT_WINDOWBITS:this.params[n];this._deflate=K.createDeflateRaw({...this._options.zlibDeflateOptions,windowBits:o}),this._deflate[$]=0,this._deflate[B]=[],this._deflate.on("data",Sr);}this._deflate[ee]=s,this._deflate.write(e),this._deflate.flush(K.Z_SYNC_FLUSH,()=>{if(!this._deflate)return;let n=Ye.concat(this._deflate[B],this._deflate[$]);t&&(n=new gr(n.buffer,n.byteOffset,n.length-4)),this._deflate[ee]=null,this._deflate[$]=0,this._deflate[B]=[],t&&this.params[`${i}_no_context_takeover`]&&this._deflate.reset(),s(null,n);});}};var ge=vr;function Sr(r){this[B].push(r),this[$]+=r.length;}function kt(r){if(this[$]+=r.length,this[de]._maxPayload<1||this[$]<=this[de]._maxPayload){this[B].push(r);return}this[ce]=new RangeError("Max payload size exceeded"),this[ce].code="WS_ERR_UNSUPPORTED_MESSAGE_LENGTH",this[ce][wt]=1009,this.removeListener("data",kt),this.reset();}function xr(r){this[de]._inflate=null,r[wt]=1007,this[ee](r);}var _e={exports:{}};const Er={},br=Object.freeze(Object.defineProperty({__proto__:null,default:Er},Symbol.toStringTag,{value:"Module"})),wr=Ks$1(br);var Ke;const{isUtf8:Xe}=Xt,kr=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,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,0,0,0,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,0,1,0,1,0];function Or(r){return r>=1e3&&r<=1014&&r!==1004&&r!==1005&&r!==1006||r>=3e3&&r<=4999}function Ue(r){const e=r.length;let t=0;for(;t=e||(r[t+1]&192)!==128||(r[t+2]&192)!==128||r[t]===224&&(r[t+1]&224)===128||r[t]===237&&(r[t+1]&224)===160)return !1;t+=3;}else if((r[t]&248)===240){if(t+3>=e||(r[t+1]&192)!==128||(r[t+2]&192)!==128||(r[t+3]&192)!==128||r[t]===240&&(r[t+1]&240)===128||r[t]===244&&r[t+1]>143||r[t]>244)return !1;t+=4;}else return !1;return !0}_e.exports={isValidStatusCode:Or,isValidUTF8:Ue,tokenChars:kr};if(Xe)Ke=_e.exports.isValidUTF8=function(r){return r.length<24?Ue(r):Xe(r)};else if(!process.env.WS_NO_UTF_8_VALIDATE)try{const r=wr;Ke=_e.exports.isValidUTF8=function(e){return e.length<32?Ue(e):r(e)};}catch{}var ye=_e.exports;const{Writable:Tr}=yt,Ze=ge,{BINARY_TYPES:Cr,EMPTY_BUFFER:Qe,kStatusCode:Nr,kWebSocket:Lr}=W,{concat:Oe,toArrayBuffer:$r,unmask:Pr}=me,{isValidStatusCode:Rr,isValidUTF8:Je}=ye,ae=Buffer[Symbol.species],X=0,et=1,tt=2,rt=3,Te=4,Br=5;let Ur=class extends Tr{constructor(e={}){super(),this._binaryType=e.binaryType||Cr[0],this._extensions=e.extensions||{},this._isServer=!!e.isServer,this._maxPayload=e.maxPayload|0,this._skipUTF8Validation=!!e.skipUTF8Validation,this[Lr]=void 0,this._bufferedBytes=0,this._buffers=[],this._compressed=!1,this._payloadLength=0,this._mask=void 0,this._fragmented=0,this._masked=!1,this._fin=!1,this._opcode=0,this._totalPayloadLength=0,this._messageLength=0,this._fragments=[],this._state=X,this._loop=!1;}_write(e,t,s){if(this._opcode===8&&this._state==X)return s();this._bufferedBytes+=e.length,this._buffers.push(e),this.startLoop(s);}consume(e){if(this._bufferedBytes-=e,e===this._buffers[0].length)return this._buffers.shift();if(e=s.length?t.set(this._buffers.shift(),i):(t.set(new Uint8Array(s.buffer,s.byteOffset,e),i),this._buffers[0]=new ae(s.buffer,s.byteOffset+e,s.length-e)),e-=s.length;}while(e>0);return t}startLoop(e){let t;this._loop=!0;do switch(this._state){case X:t=this.getInfo();break;case et:t=this.getPayloadLength16();break;case tt:t=this.getPayloadLength64();break;case rt:this.getMask();break;case Te:t=this.getData(e);break;default:this._loop=!1;return}while(this._loop);e(t);}getInfo(){if(this._bufferedBytes<2){this._loop=!1;return}const e=this.consume(2);if(e[0]&48)return this._loop=!1,x(RangeError,"RSV2 and RSV3 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_2_3");const t=(e[0]&64)===64;if(t&&!this._extensions[Ze.extensionName])return this._loop=!1,x(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");if(this._fin=(e[0]&128)===128,this._opcode=e[0]&15,this._payloadLength=e[1]&127,this._opcode===0){if(t)return this._loop=!1,x(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");if(!this._fragmented)return this._loop=!1,x(RangeError,"invalid opcode 0",!0,1002,"WS_ERR_INVALID_OPCODE");this._opcode=this._fragmented;}else if(this._opcode===1||this._opcode===2){if(this._fragmented)return this._loop=!1,x(RangeError,`invalid opcode ${this._opcode}`,!0,1002,"WS_ERR_INVALID_OPCODE");this._compressed=t;}else if(this._opcode>7&&this._opcode<11){if(!this._fin)return this._loop=!1,x(RangeError,"FIN must be set",!0,1002,"WS_ERR_EXPECTED_FIN");if(t)return this._loop=!1,x(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");if(this._payloadLength>125||this._opcode===8&&this._payloadLength===1)return this._loop=!1,x(RangeError,`invalid payload length ${this._payloadLength}`,!0,1002,"WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH")}else return this._loop=!1,x(RangeError,`invalid opcode ${this._opcode}`,!0,1002,"WS_ERR_INVALID_OPCODE");if(!this._fin&&!this._fragmented&&(this._fragmented=this._opcode),this._masked=(e[1]&128)===128,this._isServer){if(!this._masked)return this._loop=!1,x(RangeError,"MASK must be set",!0,1002,"WS_ERR_EXPECTED_MASK")}else if(this._masked)return this._loop=!1,x(RangeError,"MASK must be clear",!0,1002,"WS_ERR_UNEXPECTED_MASK");if(this._payloadLength===126)this._state=et;else if(this._payloadLength===127)this._state=tt;else return this.haveLength()}getPayloadLength16(){if(this._bufferedBytes<2){this._loop=!1;return}return this._payloadLength=this.consume(2).readUInt16BE(0),this.haveLength()}getPayloadLength64(){if(this._bufferedBytes<8){this._loop=!1;return}const e=this.consume(8),t=e.readUInt32BE(0);return t>Math.pow(2,21)-1?(this._loop=!1,x(RangeError,"Unsupported WebSocket frame: payload length > 2^53 - 1",!1,1009,"WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH")):(this._payloadLength=t*Math.pow(2,32)+e.readUInt32BE(4),this.haveLength())}haveLength(){if(this._payloadLength&&this._opcode<8&&(this._totalPayloadLength+=this._payloadLength,this._totalPayloadLength>this._maxPayload&&this._maxPayload>0))return this._loop=!1,x(RangeError,"Max payload size exceeded",!1,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH");this._masked?this._state=rt:this._state=Te;}getMask(){if(this._bufferedBytes<4){this._loop=!1;return}this._mask=this.consume(4),this._state=Te;}getData(e){let t=Qe;if(this._payloadLength){if(this._bufferedBytes7)return this.controlMessage(t);if(this._compressed){this._state=Br,this.decompress(t,e);return}return t.length&&(this._messageLength=this._totalPayloadLength,this._fragments.push(t)),this.dataMessage()}decompress(e,t){this._extensions[Ze.extensionName].decompress(e,this._fin,(i,n)=>{if(i)return t(i);if(n.length){if(this._messageLength+=n.length,this._messageLength>this._maxPayload&&this._maxPayload>0)return t(x(RangeError,"Max payload size exceeded",!1,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"));this._fragments.push(n);}const o=this.dataMessage();if(o)return t(o);this.startLoop(t);});}dataMessage(){if(this._fin){const e=this._messageLength,t=this._fragments;if(this._totalPayloadLength=0,this._messageLength=0,this._fragmented=0,this._fragments=[],this._opcode===2){let s;this._binaryType==="nodebuffer"?s=Oe(t,e):this._binaryType==="arraybuffer"?s=$r(Oe(t,e)):s=t,this.emit("message",s,!0);}else {const s=Oe(t,e);if(!this._skipUTF8Validation&&!Je(s))return this._loop=!1,x(Error,"invalid UTF-8 sequence",!0,1007,"WS_ERR_INVALID_UTF8");this.emit("message",s,!1);}}this._state=X;}controlMessage(e){if(this._opcode===8)if(this._loop=!1,e.length===0)this.emit("conclude",1005,Qe),this.end();else {const t=e.readUInt16BE(0);if(!Rr(t))return x(RangeError,`invalid status code ${t}`,!0,1002,"WS_ERR_INVALID_CLOSE_CODE");const s=new ae(e.buffer,e.byteOffset+2,e.length-2);if(!this._skipUTF8Validation&&!Je(s))return x(Error,"invalid UTF-8 sequence",!0,1007,"WS_ERR_INVALID_UTF8");this.emit("conclude",t,s),this.end();}else this._opcode===9?this.emit("ping",e):this.emit("pong",e);this._state=X;}};var Ot=Ur;function x(r,e,t,s,i){const n=new r(t?`Invalid WebSocket frame: ${e}`:e);return Error.captureStackTrace(n,x),n.code=i,n[Nr]=s,n}const Ks=Hr$1(Ot),{randomFillSync:Ir}=Ie,st=ge,{EMPTY_BUFFER:Mr}=W,{isValidStatusCode:Dr}=ye,{mask:it,toBuffer:G}=me,T=Symbol("kByteLength"),Ar=Buffer.alloc(4);let Wr=class D{constructor(e,t,s){this._extensions=t||{},s&&(this._generateMask=s,this._maskBuffer=Buffer.alloc(4)),this._socket=e,this._firstFragment=!0,this._compress=!1,this._bufferedBytes=0,this._deflating=!1,this._queue=[];}static frame(e,t){let s,i=!1,n=2,o=!1;t.mask&&(s=t.maskBuffer||Ar,t.generateMask?t.generateMask(s):Ir(s,0,4),o=(s[0]|s[1]|s[2]|s[3])===0,n=6);let a;typeof e=="string"?(!t.mask||o)&&t[T]!==void 0?a=t[T]:(e=Buffer.from(e),a=e.length):(a=e.length,i=t.mask&&t.readOnly&&!o);let l=a;a>=65536?(n+=8,l=127):a>125&&(n+=2,l=126);const f=Buffer.allocUnsafe(i?a+n:n);return f[0]=t.fin?t.opcode|128:t.opcode,t.rsv1&&(f[0]|=64),f[1]=l,l===126?f.writeUInt16BE(a,2):l===127&&(f[2]=f[3]=0,f.writeUIntBE(a,4,6)),t.mask?(f[1]|=128,f[n-4]=s[0],f[n-3]=s[1],f[n-2]=s[2],f[n-1]=s[3],o?[f,e]:i?(it(e,s,f,n,a),[f]):(it(e,s,e,0,a),[f,e])):[f,e]}close(e,t,s,i){let n;if(e===void 0)n=Mr;else {if(typeof e!="number"||!Dr(e))throw new TypeError("First argument must be a valid error code number");if(t===void 0||!t.length)n=Buffer.allocUnsafe(2),n.writeUInt16BE(e,0);else {const a=Buffer.byteLength(t);if(a>123)throw new RangeError("The message must not be greater than 123 bytes");n=Buffer.allocUnsafe(2+a),n.writeUInt16BE(e,0),typeof t=="string"?n.write(t,2):n.set(t,2);}}const o={[T]:n.length,fin:!0,generateMask:this._generateMask,mask:s,maskBuffer:this._maskBuffer,opcode:8,readOnly:!1,rsv1:!1};this._deflating?this.enqueue([this.dispatch,n,!1,o,i]):this.sendFrame(D.frame(n,o),i);}ping(e,t,s){let i,n;if(typeof e=="string"?(i=Buffer.byteLength(e),n=!1):(e=G(e),i=e.length,n=G.readOnly),i>125)throw new RangeError("The data size must not be greater than 125 bytes");const o={[T]:i,fin:!0,generateMask:this._generateMask,mask:t,maskBuffer:this._maskBuffer,opcode:9,readOnly:n,rsv1:!1};this._deflating?this.enqueue([this.dispatch,e,!1,o,s]):this.sendFrame(D.frame(e,o),s);}pong(e,t,s){let i,n;if(typeof e=="string"?(i=Buffer.byteLength(e),n=!1):(e=G(e),i=e.length,n=G.readOnly),i>125)throw new RangeError("The data size must not be greater than 125 bytes");const o={[T]:i,fin:!0,generateMask:this._generateMask,mask:t,maskBuffer:this._maskBuffer,opcode:10,readOnly:n,rsv1:!1};this._deflating?this.enqueue([this.dispatch,e,!1,o,s]):this.sendFrame(D.frame(e,o),s);}send(e,t,s){const i=this._extensions[st.extensionName];let n=t.binary?2:1,o=t.compress,a,l;if(typeof e=="string"?(a=Buffer.byteLength(e),l=!1):(e=G(e),a=e.length,l=G.readOnly),this._firstFragment?(this._firstFragment=!1,o&&i&&i.params[i._isServer?"server_no_context_takeover":"client_no_context_takeover"]&&(o=a>=i._threshold),this._compress=o):(o=!1,n=0),t.fin&&(this._firstFragment=!0),i){const f={[T]:a,fin:t.fin,generateMask:this._generateMask,mask:t.mask,maskBuffer:this._maskBuffer,opcode:n,readOnly:l,rsv1:o};this._deflating?this.enqueue([this.dispatch,e,this._compress,f,s]):this.dispatch(e,this._compress,f,s);}else this.sendFrame(D.frame(e,{[T]:a,fin:t.fin,generateMask:this._generateMask,mask:t.mask,maskBuffer:this._maskBuffer,opcode:n,readOnly:l,rsv1:!1}),s);}dispatch(e,t,s,i){if(!t){this.sendFrame(D.frame(e,s),i);return}const n=this._extensions[st.extensionName];this._bufferedBytes+=s[T],this._deflating=!0,n.compress(e,s.fin,(o,a)=>{if(this._socket.destroyed){const l=new Error("The socket was closed while data was being compressed");typeof i=="function"&&i(l);for(let f=0;f{let t=r[e];return Array.isArray(t)||(t=[t]),t.map(s=>[e].concat(Object.keys(s).map(i=>{let n=s[i];return Array.isArray(n)||(n=[n]),n.map(o=>o===!0?i:`${i}=${o}`).join("; ")})).join("; ")).join(", ")}).join(", ")}var Ct={format:Vr,parse:Gr};const qr=vt,Hr=Jt,zr=St,Nt=Zt,Yr=Qt,{randomBytes:Kr,createHash:Xr}=Ie,{URL:Ne}=require$$1,U=ge,Zr=Ot,Qr=Tt,{BINARY_TYPES:ut,EMPTY_BUFFER:le,GUID:Jr,kForOnEventAttribute:Le,kListener:es,kStatusCode:ts,kWebSocket:w,NOOP:Lt}=W,{EventTarget:{addEventListener:rs,removeEventListener:ss}}=jr,{format:is,parse:ns}=Ct,{toBuffer:os}=me,as=30*1e3,$t=Symbol("kAborted"),$e=[8,13],P=["CONNECTING","OPEN","CLOSING","CLOSED"],fs=/^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;let S=class v extends qr{constructor(e,t,s){super(),this._binaryType=ut[0],this._closeCode=1006,this._closeFrameReceived=!1,this._closeFrameSent=!1,this._closeMessage=le,this._closeTimer=null,this._extensions={},this._paused=!1,this._protocol="",this._readyState=v.CONNECTING,this._receiver=null,this._sender=null,this._socket=null,e!==null?(this._bufferedAmount=0,this._isServer=!1,this._redirects=0,t===void 0?t=[]:Array.isArray(t)||(typeof t=="object"&&t!==null?(s=t,t=[]):t=[t]),Rt(this,e,t,s)):this._isServer=!0;}get binaryType(){return this._binaryType}set binaryType(e){ut.includes(e)&&(this._binaryType=e,this._receiver&&(this._receiver._binaryType=e));}get bufferedAmount(){return this._socket?this._socket._writableState.length+this._sender._bufferedBytes:this._bufferedAmount}get extensions(){return Object.keys(this._extensions).join()}get isPaused(){return this._paused}get onclose(){return null}get onerror(){return null}get onopen(){return null}get onmessage(){return null}get protocol(){return this._protocol}get readyState(){return this._readyState}get url(){return this._url}setSocket(e,t,s){const i=new Zr({binaryType:this.binaryType,extensions:this._extensions,isServer:this._isServer,maxPayload:s.maxPayload,skipUTF8Validation:s.skipUTF8Validation});this._sender=new Qr(e,this._extensions,s.generateMask),this._receiver=i,this._socket=e,i[w]=this,e[w]=this,i.on("conclude",hs),i.on("drain",us),i.on("error",ds),i.on("message",_s),i.on("ping",ps),i.on("pong",ms),e.setTimeout(0),e.setNoDelay(),t.length>0&&e.unshift(t),e.on("close",Ut),e.on("data",Se),e.on("end",It),e.on("error",Mt),this._readyState=v.OPEN,this.emit("open");}emitClose(){if(!this._socket){this._readyState=v.CLOSED,this.emit("close",this._closeCode,this._closeMessage);return}this._extensions[U.extensionName]&&this._extensions[U.extensionName].cleanup(),this._receiver.removeAllListeners(),this._readyState=v.CLOSED,this.emit("close",this._closeCode,this._closeMessage);}close(e,t){if(this.readyState!==v.CLOSED){if(this.readyState===v.CONNECTING){O(this,this._req,"WebSocket was closed before the connection was established");return}if(this.readyState===v.CLOSING){this._closeFrameSent&&(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end();return}this._readyState=v.CLOSING,this._sender.close(e,t,!this._isServer,s=>{s||(this._closeFrameSent=!0,(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end());}),this._closeTimer=setTimeout(this._socket.destroy.bind(this._socket),as);}}pause(){this.readyState===v.CONNECTING||this.readyState===v.CLOSED||(this._paused=!0,this._socket.pause());}ping(e,t,s){if(this.readyState===v.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof e=="function"?(s=e,e=t=void 0):typeof t=="function"&&(s=t,t=void 0),typeof e=="number"&&(e=e.toString()),this.readyState!==v.OPEN){Pe(this,e,s);return}t===void 0&&(t=!this._isServer),this._sender.ping(e||le,t,s);}pong(e,t,s){if(this.readyState===v.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof e=="function"?(s=e,e=t=void 0):typeof t=="function"&&(s=t,t=void 0),typeof e=="number"&&(e=e.toString()),this.readyState!==v.OPEN){Pe(this,e,s);return}t===void 0&&(t=!this._isServer),this._sender.pong(e||le,t,s);}resume(){this.readyState===v.CONNECTING||this.readyState===v.CLOSED||(this._paused=!1,this._receiver._writableState.needDrain||this._socket.resume());}send(e,t,s){if(this.readyState===v.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof t=="function"&&(s=t,t={}),typeof e=="number"&&(e=e.toString()),this.readyState!==v.OPEN){Pe(this,e,s);return}const i={binary:typeof e!="string",mask:!this._isServer,compress:!0,fin:!0,...t};this._extensions[U.extensionName]||(i.compress=!1),this._sender.send(e||le,i,s);}terminate(){if(this.readyState!==v.CLOSED){if(this.readyState===v.CONNECTING){O(this,this._req,"WebSocket was closed before the connection was established");return}this._socket&&(this._readyState=v.CLOSING,this._socket.destroy());}}};Object.defineProperty(S,"CONNECTING",{enumerable:!0,value:P.indexOf("CONNECTING")});Object.defineProperty(S.prototype,"CONNECTING",{enumerable:!0,value:P.indexOf("CONNECTING")});Object.defineProperty(S,"OPEN",{enumerable:!0,value:P.indexOf("OPEN")});Object.defineProperty(S.prototype,"OPEN",{enumerable:!0,value:P.indexOf("OPEN")});Object.defineProperty(S,"CLOSING",{enumerable:!0,value:P.indexOf("CLOSING")});Object.defineProperty(S.prototype,"CLOSING",{enumerable:!0,value:P.indexOf("CLOSING")});Object.defineProperty(S,"CLOSED",{enumerable:!0,value:P.indexOf("CLOSED")});Object.defineProperty(S.prototype,"CLOSED",{enumerable:!0,value:P.indexOf("CLOSED")});["binaryType","bufferedAmount","extensions","isPaused","protocol","readyState","url"].forEach(r=>{Object.defineProperty(S.prototype,r,{enumerable:!0});});["open","error","close","message"].forEach(r=>{Object.defineProperty(S.prototype,`on${r}`,{enumerable:!0,get(){for(const e of this.listeners(r))if(e[Le])return e[es];return null},set(e){for(const t of this.listeners(r))if(t[Le]){this.removeListener(r,t);break}typeof e=="function"&&this.addEventListener(r,e,{[Le]:!0});}});});S.prototype.addEventListener=rs;S.prototype.removeEventListener=ss;var Pt=S;function Rt(r,e,t,s){const i={protocolVersion:$e[1],maxPayload:104857600,skipUTF8Validation:!1,perMessageDeflate:!0,followRedirects:!1,maxRedirects:10,...s,createConnection:void 0,socketPath:void 0,hostname:void 0,protocol:void 0,timeout:void 0,method:"GET",host:void 0,path:void 0,port:void 0};if(!$e.includes(i.protocolVersion))throw new RangeError(`Unsupported protocol version: ${i.protocolVersion} (supported versions: ${$e.join(", ")})`);let n;if(e instanceof Ne)n=e,r._url=e.href;else {try{n=new Ne(e);}catch{throw new SyntaxError(`Invalid URL: ${e}`)}r._url=e;}const o=n.protocol==="wss:",a=n.protocol==="ws+unix:";let l;if(n.protocol!=="ws:"&&!o&&!a?l=`The URL's protocol must be one of "ws:", "wss:", or "ws+unix:"`:a&&!n.pathname?l="The URL's pathname is empty":n.hash&&(l="The URL contains a fragment identifier"),l){const d=new SyntaxError(l);if(r._redirects===0)throw d;he(r,d);return}const f=o?443:80,h=Kr(16).toString("base64"),c=o?Hr.request:zr.request,y=new Set;let p;if(i.createConnection=o?cs:ls,i.defaultPort=i.defaultPort||f,i.port=n.port||f,i.host=n.hostname.startsWith("[")?n.hostname.slice(1,-1):n.hostname,i.headers={...i.headers,"Sec-WebSocket-Version":i.protocolVersion,"Sec-WebSocket-Key":h,Connection:"Upgrade",Upgrade:"websocket"},i.path=n.pathname+n.search,i.timeout=i.handshakeTimeout,i.perMessageDeflate&&(p=new U(i.perMessageDeflate!==!0?i.perMessageDeflate:{},!1,i.maxPayload),i.headers["Sec-WebSocket-Extensions"]=is({[U.extensionName]:p.offer()})),t.length){for(const d of t){if(typeof d!="string"||!fs.test(d)||y.has(d))throw new SyntaxError("An invalid or duplicated subprotocol was specified");y.add(d);}i.headers["Sec-WebSocket-Protocol"]=t.join(",");}if(i.origin&&(i.protocolVersion<13?i.headers["Sec-WebSocket-Origin"]=i.origin:i.headers.Origin=i.origin),(n.username||n.password)&&(i.auth=`${n.username}:${n.password}`),a){const d=i.path.split(":");i.socketPath=d[0],i.path=d[1];}let g;if(i.followRedirects){if(r._redirects===0){r._originalIpc=a,r._originalSecure=o,r._originalHostOrSocketPath=a?i.socketPath:n.host;const d=s&&s.headers;if(s={...s,headers:{}},d)for(const[E,L]of Object.entries(d))s.headers[E.toLowerCase()]=L;}else if(r.listenerCount("redirect")===0){const d=a?r._originalIpc?i.socketPath===r._originalHostOrSocketPath:!1:r._originalIpc?!1:n.host===r._originalHostOrSocketPath;(!d||r._originalSecure&&!o)&&(delete i.headers.authorization,delete i.headers.cookie,d||delete i.headers.host,i.auth=void 0);}i.auth&&!s.headers.authorization&&(s.headers.authorization="Basic "+Buffer.from(i.auth).toString("base64")),g=r._req=c(i),r._redirects&&r.emit("redirect",r.url,g);}else g=r._req=c(i);i.timeout&&g.on("timeout",()=>{O(r,g,"Opening handshake has timed out");}),g.on("error",d=>{g===null||g[$t]||(g=r._req=null,he(r,d));}),g.on("response",d=>{const E=d.headers.location,L=d.statusCode;if(E&&i.followRedirects&&L>=300&&L<400){if(++r._redirects>i.maxRedirects){O(r,g,"Maximum redirects exceeded");return}g.abort();let I;try{I=new Ne(E,e);}catch{const C=new SyntaxError(`Invalid URL: ${E}`);he(r,C);return}Rt(r,I,t,s);}else r.emit("unexpected-response",g,d)||O(r,g,`Unexpected server response: ${d.statusCode}`);}),g.on("upgrade",(d,E,L)=>{if(r.emit("upgrade",d),r.readyState!==S.CONNECTING)return;if(g=r._req=null,d.headers.upgrade.toLowerCase()!=="websocket"){O(r,E,"Invalid Upgrade header");return}const I=Xr("sha1").update(h+Jr).digest("base64");if(d.headers["sec-websocket-accept"]!==I){O(r,E,"Invalid Sec-WebSocket-Accept header");return}const R=d.headers["sec-websocket-protocol"];let C;if(R!==void 0?y.size?y.has(R)||(C="Server sent an invalid subprotocol"):C="Server sent a subprotocol but none was requested":y.size&&(C="Server sent no subprotocol"),C){O(r,E,C);return}R&&(r._protocol=R);const q=d.headers["sec-websocket-extensions"];if(q!==void 0){if(!p){O(r,E,"Server sent a Sec-WebSocket-Extensions header but no extension was requested");return}let H;try{H=ns(q);}catch{O(r,E,"Invalid Sec-WebSocket-Extensions header");return}const z=Object.keys(H);if(z.length!==1||z[0]!==U.extensionName){O(r,E,"Server indicated an extension that was not requested");return}try{p.accept(H[U.extensionName]);}catch{O(r,E,"Invalid Sec-WebSocket-Extensions header");return}r._extensions[U.extensionName]=p;}r.setSocket(E,L,{generateMask:i.generateMask,maxPayload:i.maxPayload,skipUTF8Validation:i.skipUTF8Validation});}),i.finishRequest?i.finishRequest(g,r):g.end();}function he(r,e){r._readyState=S.CLOSING,r.emit("error",e),r.emitClose();}function ls(r){return r.path=r.socketPath,Nt.connect(r)}function cs(r){return r.path=void 0,!r.servername&&r.servername!==""&&(r.servername=Nt.isIP(r.host)?"":r.host),Yr.connect(r)}function O(r,e,t){r._readyState=S.CLOSING;const s=new Error(t);Error.captureStackTrace(s,O),e.setHeader?(e[$t]=!0,e.abort(),e.socket&&!e.socket.destroyed&&e.socket.destroy(),process.nextTick(he,r,s)):(e.destroy(s),e.once("error",r.emit.bind(r,"error")),e.once("close",r.emitClose.bind(r)));}function Pe(r,e,t){if(e){const s=os(e).length;r._socket?r._sender._bufferedBytes+=s:r._bufferedAmount+=s;}if(t){const s=new Error(`WebSocket is not open: readyState ${r.readyState} (${P[r.readyState]})`);process.nextTick(t,s);}}function hs(r,e){const t=this[w];t._closeFrameReceived=!0,t._closeMessage=e,t._closeCode=r,t._socket[w]!==void 0&&(t._socket.removeListener("data",Se),process.nextTick(Bt,t._socket),r===1005?t.close():t.close(r,e));}function us(){const r=this[w];r.isPaused||r._socket.resume();}function ds(r){const e=this[w];e._socket[w]!==void 0&&(e._socket.removeListener("data",Se),process.nextTick(Bt,e._socket),e.close(r[ts])),e.emit("error",r);}function dt(){this[w].emitClose();}function _s(r,e){this[w].emit("message",r,e);}function ps(r){const e=this[w];e.pong(r,!e._isServer,Lt),e.emit("ping",r);}function ms(r){this[w].emit("pong",r);}function Bt(r){r.resume();}function Ut(){const r=this[w];this.removeListener("close",Ut),this.removeListener("data",Se),this.removeListener("end",It),r._readyState=S.CLOSING;let e;!this._readableState.endEmitted&&!r._closeFrameReceived&&!r._receiver._writableState.errorEmitted&&(e=r._socket.read())!==null&&r._receiver.write(e),r._receiver.end(),this[w]=void 0,clearTimeout(r._closeTimer),r._receiver._writableState.finished||r._receiver._writableState.errorEmitted?r.emitClose():(r._receiver.on("error",dt),r._receiver.on("finish",dt));}function Se(r){this[w]._receiver.write(r)||this.pause();}function It(){const r=this[w];r._readyState=S.CLOSING,r._receiver.end(),this.end();}function Mt(){const r=this[w];this.removeListener("error",Mt),this.on("error",Lt),r&&(r._readyState=S.CLOSING,this.destroy());}const Zs=Hr$1(Pt),{tokenChars:gs}=ye;function ys(r){const e=new Set;let t=-1,s=-1,i=0;for(i;i{const n=pe.STATUS_CODES[426];i.writeHead(426,{"Content-Length":n.length,"Content-Type":"text/plain"}),i.end(n);}),this._server.listen(e.port,e.host,e.backlog,t)):e.server&&(this._server=e.server),this._server){const s=this.emit.bind(this,"connection");this._removeListeners=Ns(this._server,{listening:this.emit.bind(this,"listening"),error:this.emit.bind(this,"error"),upgrade:(i,n,o)=>{this.handleUpgrade(i,n,o,s);}});}e.perMessageDeflate===!0&&(e.perMessageDeflate={}),e.clientTracking&&(this.clients=new Set,this._shouldEmitClose=!1),this.options=e,this._state=pt;}address(){if(this.options.noServer)throw new Error('The server is operating in "noServer" mode');return this._server?this._server.address():null}close(e){if(this._state===Dt){e&&this.once("close",()=>{e(new Error("The server is not running"));}),process.nextTick(J,this);return}if(e&&this.once("close",e),this._state!==mt)if(this._state=mt,this.options.noServer||this.options.server)this._server&&(this._removeListeners(),this._removeListeners=this._server=null),this.clients?this.clients.size?this._shouldEmitClose=!0:process.nextTick(J,this):process.nextTick(J,this);else {const t=this._server;this._removeListeners(),this._removeListeners=this._server=null,t.close(()=>{J(this);});}}shouldHandle(e){if(this.options.path){const t=e.url.indexOf("?");if((t!==-1?e.url.slice(0,t):e.url)!==this.options.path)return !1}return !0}handleUpgrade(e,t,s,i){t.on("error",gt);const n=e.headers["sec-websocket-key"],o=+e.headers["sec-websocket-version"];if(e.method!=="GET"){A(this,e,t,405,"Invalid HTTP method");return}if(e.headers.upgrade.toLowerCase()!=="websocket"){A(this,e,t,400,"Invalid Upgrade header");return}if(!n||!Os.test(n)){A(this,e,t,400,"Missing or invalid Sec-WebSocket-Key header");return}if(o!==8&&o!==13){A(this,e,t,400,"Missing or invalid Sec-WebSocket-Version header");return}if(!this.shouldHandle(e)){te(t,400);return}const a=e.headers["sec-websocket-protocol"];let l=new Set;if(a!==void 0)try{l=Es.parse(a);}catch{A(this,e,t,400,"Invalid Sec-WebSocket-Protocol header");return}const f=e.headers["sec-websocket-extensions"],h={};if(this.options.perMessageDeflate&&f!==void 0){const c=new M(this.options.perMessageDeflate,!0,this.options.maxPayload);try{const y=_t.parse(f);y[M.extensionName]&&(c.accept(y[M.extensionName]),h[M.extensionName]=c);}catch{A(this,e,t,400,"Invalid or unacceptable Sec-WebSocket-Extensions header");return}}if(this.options.verifyClient){const c={origin:e.headers[`${o===8?"sec-websocket-origin":"origin"}`],secure:!!(e.socket.authorized||e.socket.encrypted),req:e};if(this.options.verifyClient.length===2){this.options.verifyClient(c,(y,p,g,d)=>{if(!y)return te(t,p||401,g,d);this.completeUpgrade(h,n,l,e,t,s,i);});return}if(!this.options.verifyClient(c))return te(t,401)}this.completeUpgrade(h,n,l,e,t,s,i);}completeUpgrade(e,t,s,i,n,o,a){if(!n.readable||!n.writable)return n.destroy();if(n[ks])throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration");if(this._state>pt)return te(n,503);const f=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${xs("sha1").update(t+ws).digest("base64")}`],h=new this.options.WebSocket(null);if(s.size){const c=this.options.handleProtocols?this.options.handleProtocols(s,i):s.values().next().value;c&&(f.push(`Sec-WebSocket-Protocol: ${c}`),h._protocol=c);}if(e[M.extensionName]){const c=e[M.extensionName].params,y=_t.format({[M.extensionName]:[c]});f.push(`Sec-WebSocket-Extensions: ${y}`),h._extensions=e;}this.emit("headers",f,i),n.write(f.concat(`\r +`).join(`\r +`)),n.removeListener("error",gt),h.setSocket(n,o,{maxPayload:this.options.maxPayload,skipUTF8Validation:this.options.skipUTF8Validation}),this.clients&&(this.clients.add(h),h.on("close",()=>{this.clients.delete(h),this._shouldEmitClose&&!this.clients.size&&process.nextTick(J,this);})),a(h,i);}}var Cs=Ts;function Ns(r,e){for(const t of Object.keys(e))r.on(t,e[t]);return function(){for(const s of Object.keys(e))r.removeListener(s,e[s]);}}function J(r){r._state=Dt,r.emit("close");}function gt(){this.destroy();}function te(r,e,t,s){t=t||pe.STATUS_CODES[e],s={Connection:"close","Content-Type":"text/html","Content-Length":Buffer.byteLength(t),...s},r.once("finish",r.destroy),r.end(`HTTP/1.1 ${e} ${pe.STATUS_CODES[e]}\r +`+Object.keys(s).map(i=>`${i}: ${s[i]}`).join(`\r +`)+`\r +\r +`+t);}function A(r,e,t,s,i){if(r.listenerCount("wsClientError")){const n=new Error(i);Error.captureStackTrace(n,A),r.emit("wsClientError",n,t,e);}else te(t,s,i);}const Qs=Hr$1(Cs); + +export { Ks as Receiver, Xs as Sender, Zs as WebSocket, Qs as WebSocketServer, qs as createWebSocketStream, Zs as default }; +//# sourceMappingURL=wrapper-CYei9jbK.js.map diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/wrapper-CYei9jbK.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/wrapper-CYei9jbK.js.map new file mode 100644 index 0000000000000000000000000000000000000000..01e5da59bbb5022ec0f3020affee8a50e1691a0e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/wrapper-CYei9jbK.js.map @@ -0,0 +1 @@ +{"version":3,"file":"wrapper-CYei9jbK.js","sources":["../../../../../../js/app/.svelte-kit/adapter-node/chunks/wrapper.js"],"sourcesContent":["import{j as re,x as Vt}from\"./client.js\";import yt from\"stream\";import qt from\"zlib\";import{c as Ht}from\"./_commonjs-dynamic-modules.js\";import zt from\"fs\";import Yt from\"path\";import Kt from\"os\";import Xt from\"buffer\";import Zt from\"net\";import Qt from\"tls\";import Ie from\"crypto\";import vt from\"events\";import Jt from\"https\";import St from\"http\";import er from\"url\";const{Duplex:tr}=yt;function je(r){r.emit(\"close\")}function rr(){!this.destroyed&&this._writableState.finished&&this.destroy()}function xt(r){this.removeListener(\"error\",xt),this.destroy(),this.listenerCount(\"error\")===0&&this.emit(\"error\",r)}function sr(r,e){let t=!0;const s=new tr({...e,autoDestroy:!1,emitClose:!1,objectMode:!1,writableObjectMode:!1});return r.on(\"message\",function(n,o){const a=!o&&s._readableState.objectMode?n.toString():n;s.push(a)||r.pause()}),r.once(\"error\",function(n){s.destroyed||(t=!1,s.destroy(n))}),r.once(\"close\",function(){s.destroyed||s.push(null)}),s._destroy=function(i,n){if(r.readyState===r.CLOSED){n(i),process.nextTick(je,s);return}let o=!1;r.once(\"error\",function(l){o=!0,n(l)}),r.once(\"close\",function(){o||n(i),process.nextTick(je,s)}),t&&r.terminate()},s._final=function(i){if(r.readyState===r.CONNECTING){r.once(\"open\",function(){s._final(i)});return}r._socket!==null&&(r._socket._writableState.finished?(i(),s._readableState.endEmitted&&s.destroy()):(r._socket.once(\"finish\",function(){i()}),r.close()))},s._read=function(){r.isPaused&&r.resume()},s._write=function(i,n,o){if(r.readyState===r.CONNECTING){r.once(\"open\",function(){s._write(i,n,o)});return}r.send(i,o)},s.on(\"end\",rr),s.on(\"error\",xt),s}var ir=sr;const qs=re(ir);var ue={exports:{}},W={BINARY_TYPES:[\"nodebuffer\",\"arraybuffer\",\"fragments\"],EMPTY_BUFFER:Buffer.alloc(0),GUID:\"258EAFA5-E914-47DA-95CA-C5AB0DC85B11\",kForOnEventAttribute:Symbol(\"kIsForOnEventAttribute\"),kListener:Symbol(\"kListener\"),kStatusCode:Symbol(\"status-code\"),kWebSocket:Symbol(\"websocket\"),NOOP:()=>{}},ie={exports:{}},ne={exports:{}},be,Ge;function nr(){if(Ge)return be;Ge=1;var r=zt,e=Yt,t=Kt,s=typeof __webpack_require__==\"function\"?__non_webpack_require__:Ht,i=process.config&&process.config.variables||{},n=!!process.env.PREBUILDS_ONLY,o=process.versions.modules,a=xe()?\"electron\":Y()?\"node-webkit\":\"node\",l=process.env.npm_config_arch||t.arch(),f=process.env.npm_config_platform||t.platform(),h=process.env.LIBC||(At(f)?\"musl\":\"glibc\"),c=process.env.ARM_VERSION||(l===\"arm64\"?\"8\":i.arm_version)||\"\",y=(process.versions.uv||\"\").split(\".\")[0];be=p;function p(u){return s(p.resolve(u))}p.resolve=p.path=function(u){u=e.resolve(u||\".\");try{var m=s(e.join(u,\"package.json\")).name.toUpperCase().replace(/-/g,\"_\");process.env[m+\"_PREBUILD\"]&&(u=process.env[m+\"_PREBUILD\"])}catch{}if(!n){var _=d(e.join(u,\"build/Release\"),E);if(_)return _;var k=d(e.join(u,\"build/Debug\"),E);if(k)return k}var j=De(u);if(j)return j;var b=De(e.dirname(process.execPath));if(b)return b;var Wt=[\"platform=\"+f,\"arch=\"+l,\"runtime=\"+a,\"abi=\"+o,\"uv=\"+y,c?\"armv=\"+c:\"\",\"libc=\"+h,\"node=\"+process.versions.node,process.versions.electron?\"electron=\"+process.versions.electron:\"\",typeof __webpack_require__==\"function\"?\"webpack=true\":\"\"].filter(Boolean).join(\" \");throw new Error(\"No native build was found for \"+Wt+`\n loaded from: `+u+`\n`);function De(Ee){var Ft=g(e.join(Ee,\"prebuilds\")).map(L),Ae=Ft.filter(I(f,l)).sort(R)[0];if(Ae){var We=e.join(Ee,\"prebuilds\",Ae.name),jt=g(We).map(C),Gt=jt.filter(q(a,o)),Fe=Gt.sort(z(a))[0];if(Fe)return e.join(We,Fe.file)}}};function g(u){try{return r.readdirSync(u)}catch{return[]}}function d(u,m){var _=g(u).filter(m);return _[0]&&e.join(u,_[0])}function E(u){return/\\.node$/.test(u)}function L(u){var m=u.split(\"-\");if(m.length===2){var _=m[0],k=m[1].split(\"+\");if(_&&k.length&&k.every(Boolean))return{name:u,platform:_,architectures:k}}}function I(u,m){return function(_){return _==null||_.platform!==u?!1:_.architectures.includes(m)}}function R(u,m){return u.architectures.length-m.architectures.length}function C(u){var m=u.split(\".\"),_=m.pop(),k={file:u,specificity:0};if(_===\"node\"){for(var j=0;j_.specificity?-1:1:0}}function Y(){return!!(process.versions&&process.versions.nw)}function xe(){return process.versions&&process.versions.electron||process.env.ELECTRON_RUN_AS_NODE?!0:typeof window<\"u\"&&window.process&&window.process.type===\"renderer\"}function At(u){return u===\"linux\"&&r.existsSync(\"/etc/alpine-release\")}return p.parseTags=C,p.matchTags=q,p.compareTags=z,p.parseTuple=L,p.matchTuple=I,p.compareTuples=R,be}var Ve;function or(){return Ve||(Ve=1,typeof process.addon==\"function\"?ne.exports=process.addon.bind(process):ne.exports=nr()),ne.exports}var we,qe;function ar(){return qe||(qe=1,we={mask:(t,s,i,n,o)=>{for(var a=0;a{const i=t.length;for(var n=0;n{this.pending--,this[ke]()},this.concurrency=e||1/0,this.jobs=[],this.pending=0}add(e){this.jobs.push(e),this[ke]()}[ke](){if(this.pending!==this.concurrency&&this.jobs.length){const e=this.jobs.shift();this.pending++,e(this[ze])}}};var pr=_r;const K=qt,Ye=me,mr=pr,{kStatusCode:wt}=W,gr=Buffer[Symbol.species],yr=Buffer.from([0,0,255,255]),de=Symbol(\"permessage-deflate\"),$=Symbol(\"total-length\"),ee=Symbol(\"callback\"),B=Symbol(\"buffers\"),ce=Symbol(\"error\");let oe,vr=class{constructor(e,t,s){if(this._maxPayload=s|0,this._options=e||{},this._threshold=this._options.threshold!==void 0?this._options.threshold:1024,this._isServer=!!t,this._deflate=null,this._inflate=null,this.params=null,!oe){const i=this._options.concurrencyLimit!==void 0?this._options.concurrencyLimit:10;oe=new mr(i)}}static get extensionName(){return\"permessage-deflate\"}offer(){const e={};return this._options.serverNoContextTakeover&&(e.server_no_context_takeover=!0),this._options.clientNoContextTakeover&&(e.client_no_context_takeover=!0),this._options.serverMaxWindowBits&&(e.server_max_window_bits=this._options.serverMaxWindowBits),this._options.clientMaxWindowBits?e.client_max_window_bits=this._options.clientMaxWindowBits:this._options.clientMaxWindowBits==null&&(e.client_max_window_bits=!0),e}accept(e){return e=this.normalizeParams(e),this.params=this._isServer?this.acceptAsServer(e):this.acceptAsClient(e),this.params}cleanup(){if(this._inflate&&(this._inflate.close(),this._inflate=null),this._deflate){const e=this._deflate[ee];this._deflate.close(),this._deflate=null,e&&e(new Error(\"The deflate stream was closed while data was being processed\"))}}acceptAsServer(e){const t=this._options,s=e.find(i=>!(t.serverNoContextTakeover===!1&&i.server_no_context_takeover||i.server_max_window_bits&&(t.serverMaxWindowBits===!1||typeof t.serverMaxWindowBits==\"number\"&&t.serverMaxWindowBits>i.server_max_window_bits)||typeof t.clientMaxWindowBits==\"number\"&&!i.client_max_window_bits));if(!s)throw new Error(\"None of the extension offers can be accepted\");return t.serverNoContextTakeover&&(s.server_no_context_takeover=!0),t.clientNoContextTakeover&&(s.client_no_context_takeover=!0),typeof t.serverMaxWindowBits==\"number\"&&(s.server_max_window_bits=t.serverMaxWindowBits),typeof t.clientMaxWindowBits==\"number\"?s.client_max_window_bits=t.clientMaxWindowBits:(s.client_max_window_bits===!0||t.clientMaxWindowBits===!1)&&delete s.client_max_window_bits,s}acceptAsClient(e){const t=e[0];if(this._options.clientNoContextTakeover===!1&&t.client_no_context_takeover)throw new Error('Unexpected parameter \"client_no_context_takeover\"');if(!t.client_max_window_bits)typeof this._options.clientMaxWindowBits==\"number\"&&(t.client_max_window_bits=this._options.clientMaxWindowBits);else if(this._options.clientMaxWindowBits===!1||typeof this._options.clientMaxWindowBits==\"number\"&&t.client_max_window_bits>this._options.clientMaxWindowBits)throw new Error('Unexpected or invalid parameter \"client_max_window_bits\"');return t}normalizeParams(e){return e.forEach(t=>{Object.keys(t).forEach(s=>{let i=t[s];if(i.length>1)throw new Error(`Parameter \"${s}\" must have only a single value`);if(i=i[0],s===\"client_max_window_bits\"){if(i!==!0){const n=+i;if(!Number.isInteger(n)||n<8||n>15)throw new TypeError(`Invalid value for parameter \"${s}\": ${i}`);i=n}else if(!this._isServer)throw new TypeError(`Invalid value for parameter \"${s}\": ${i}`)}else if(s===\"server_max_window_bits\"){const n=+i;if(!Number.isInteger(n)||n<8||n>15)throw new TypeError(`Invalid value for parameter \"${s}\": ${i}`);i=n}else if(s===\"client_no_context_takeover\"||s===\"server_no_context_takeover\"){if(i!==!0)throw new TypeError(`Invalid value for parameter \"${s}\": ${i}`)}else throw new Error(`Unknown parameter \"${s}\"`);t[s]=i})}),e}decompress(e,t,s){oe.add(i=>{this._decompress(e,t,(n,o)=>{i(),s(n,o)})})}compress(e,t,s){oe.add(i=>{this._compress(e,t,(n,o)=>{i(),s(n,o)})})}_decompress(e,t,s){const i=this._isServer?\"client\":\"server\";if(!this._inflate){const n=`${i}_max_window_bits`,o=typeof this.params[n]!=\"number\"?K.Z_DEFAULT_WINDOWBITS:this.params[n];this._inflate=K.createInflateRaw({...this._options.zlibInflateOptions,windowBits:o}),this._inflate[de]=this,this._inflate[$]=0,this._inflate[B]=[],this._inflate.on(\"error\",xr),this._inflate.on(\"data\",kt)}this._inflate[ee]=s,this._inflate.write(e),t&&this._inflate.write(yr),this._inflate.flush(()=>{const n=this._inflate[ce];if(n){this._inflate.close(),this._inflate=null,s(n);return}const o=Ye.concat(this._inflate[B],this._inflate[$]);this._inflate._readableState.endEmitted?(this._inflate.close(),this._inflate=null):(this._inflate[$]=0,this._inflate[B]=[],t&&this.params[`${i}_no_context_takeover`]&&this._inflate.reset()),s(null,o)})}_compress(e,t,s){const i=this._isServer?\"server\":\"client\";if(!this._deflate){const n=`${i}_max_window_bits`,o=typeof this.params[n]!=\"number\"?K.Z_DEFAULT_WINDOWBITS:this.params[n];this._deflate=K.createDeflateRaw({...this._options.zlibDeflateOptions,windowBits:o}),this._deflate[$]=0,this._deflate[B]=[],this._deflate.on(\"data\",Sr)}this._deflate[ee]=s,this._deflate.write(e),this._deflate.flush(K.Z_SYNC_FLUSH,()=>{if(!this._deflate)return;let n=Ye.concat(this._deflate[B],this._deflate[$]);t&&(n=new gr(n.buffer,n.byteOffset,n.length-4)),this._deflate[ee]=null,this._deflate[$]=0,this._deflate[B]=[],t&&this.params[`${i}_no_context_takeover`]&&this._deflate.reset(),s(null,n)})}};var ge=vr;function Sr(r){this[B].push(r),this[$]+=r.length}function kt(r){if(this[$]+=r.length,this[de]._maxPayload<1||this[$]<=this[de]._maxPayload){this[B].push(r);return}this[ce]=new RangeError(\"Max payload size exceeded\"),this[ce].code=\"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH\",this[ce][wt]=1009,this.removeListener(\"data\",kt),this.reset()}function xr(r){this[de]._inflate=null,r[wt]=1007,this[ee](r)}var _e={exports:{}};const Er={},br=Object.freeze(Object.defineProperty({__proto__:null,default:Er},Symbol.toStringTag,{value:\"Module\"})),wr=Vt(br);var Ke;const{isUtf8:Xe}=Xt,kr=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,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,0,0,0,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,0,1,0,1,0];function Or(r){return r>=1e3&&r<=1014&&r!==1004&&r!==1005&&r!==1006||r>=3e3&&r<=4999}function Ue(r){const e=r.length;let t=0;for(;t=e||(r[t+1]&192)!==128||(r[t+2]&192)!==128||r[t]===224&&(r[t+1]&224)===128||r[t]===237&&(r[t+1]&224)===160)return!1;t+=3}else if((r[t]&248)===240){if(t+3>=e||(r[t+1]&192)!==128||(r[t+2]&192)!==128||(r[t+3]&192)!==128||r[t]===240&&(r[t+1]&240)===128||r[t]===244&&r[t+1]>143||r[t]>244)return!1;t+=4}else return!1;return!0}_e.exports={isValidStatusCode:Or,isValidUTF8:Ue,tokenChars:kr};if(Xe)Ke=_e.exports.isValidUTF8=function(r){return r.length<24?Ue(r):Xe(r)};else if(!process.env.WS_NO_UTF_8_VALIDATE)try{const r=wr;Ke=_e.exports.isValidUTF8=function(e){return e.length<32?Ue(e):r(e)}}catch{}var ye=_e.exports;const{Writable:Tr}=yt,Ze=ge,{BINARY_TYPES:Cr,EMPTY_BUFFER:Qe,kStatusCode:Nr,kWebSocket:Lr}=W,{concat:Oe,toArrayBuffer:$r,unmask:Pr}=me,{isValidStatusCode:Rr,isValidUTF8:Je}=ye,ae=Buffer[Symbol.species],X=0,et=1,tt=2,rt=3,Te=4,Br=5;let Ur=class extends Tr{constructor(e={}){super(),this._binaryType=e.binaryType||Cr[0],this._extensions=e.extensions||{},this._isServer=!!e.isServer,this._maxPayload=e.maxPayload|0,this._skipUTF8Validation=!!e.skipUTF8Validation,this[Lr]=void 0,this._bufferedBytes=0,this._buffers=[],this._compressed=!1,this._payloadLength=0,this._mask=void 0,this._fragmented=0,this._masked=!1,this._fin=!1,this._opcode=0,this._totalPayloadLength=0,this._messageLength=0,this._fragments=[],this._state=X,this._loop=!1}_write(e,t,s){if(this._opcode===8&&this._state==X)return s();this._bufferedBytes+=e.length,this._buffers.push(e),this.startLoop(s)}consume(e){if(this._bufferedBytes-=e,e===this._buffers[0].length)return this._buffers.shift();if(e=s.length?t.set(this._buffers.shift(),i):(t.set(new Uint8Array(s.buffer,s.byteOffset,e),i),this._buffers[0]=new ae(s.buffer,s.byteOffset+e,s.length-e)),e-=s.length}while(e>0);return t}startLoop(e){let t;this._loop=!0;do switch(this._state){case X:t=this.getInfo();break;case et:t=this.getPayloadLength16();break;case tt:t=this.getPayloadLength64();break;case rt:this.getMask();break;case Te:t=this.getData(e);break;default:this._loop=!1;return}while(this._loop);e(t)}getInfo(){if(this._bufferedBytes<2){this._loop=!1;return}const e=this.consume(2);if(e[0]&48)return this._loop=!1,x(RangeError,\"RSV2 and RSV3 must be clear\",!0,1002,\"WS_ERR_UNEXPECTED_RSV_2_3\");const t=(e[0]&64)===64;if(t&&!this._extensions[Ze.extensionName])return this._loop=!1,x(RangeError,\"RSV1 must be clear\",!0,1002,\"WS_ERR_UNEXPECTED_RSV_1\");if(this._fin=(e[0]&128)===128,this._opcode=e[0]&15,this._payloadLength=e[1]&127,this._opcode===0){if(t)return this._loop=!1,x(RangeError,\"RSV1 must be clear\",!0,1002,\"WS_ERR_UNEXPECTED_RSV_1\");if(!this._fragmented)return this._loop=!1,x(RangeError,\"invalid opcode 0\",!0,1002,\"WS_ERR_INVALID_OPCODE\");this._opcode=this._fragmented}else if(this._opcode===1||this._opcode===2){if(this._fragmented)return this._loop=!1,x(RangeError,`invalid opcode ${this._opcode}`,!0,1002,\"WS_ERR_INVALID_OPCODE\");this._compressed=t}else if(this._opcode>7&&this._opcode<11){if(!this._fin)return this._loop=!1,x(RangeError,\"FIN must be set\",!0,1002,\"WS_ERR_EXPECTED_FIN\");if(t)return this._loop=!1,x(RangeError,\"RSV1 must be clear\",!0,1002,\"WS_ERR_UNEXPECTED_RSV_1\");if(this._payloadLength>125||this._opcode===8&&this._payloadLength===1)return this._loop=!1,x(RangeError,`invalid payload length ${this._payloadLength}`,!0,1002,\"WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH\")}else return this._loop=!1,x(RangeError,`invalid opcode ${this._opcode}`,!0,1002,\"WS_ERR_INVALID_OPCODE\");if(!this._fin&&!this._fragmented&&(this._fragmented=this._opcode),this._masked=(e[1]&128)===128,this._isServer){if(!this._masked)return this._loop=!1,x(RangeError,\"MASK must be set\",!0,1002,\"WS_ERR_EXPECTED_MASK\")}else if(this._masked)return this._loop=!1,x(RangeError,\"MASK must be clear\",!0,1002,\"WS_ERR_UNEXPECTED_MASK\");if(this._payloadLength===126)this._state=et;else if(this._payloadLength===127)this._state=tt;else return this.haveLength()}getPayloadLength16(){if(this._bufferedBytes<2){this._loop=!1;return}return this._payloadLength=this.consume(2).readUInt16BE(0),this.haveLength()}getPayloadLength64(){if(this._bufferedBytes<8){this._loop=!1;return}const e=this.consume(8),t=e.readUInt32BE(0);return t>Math.pow(2,21)-1?(this._loop=!1,x(RangeError,\"Unsupported WebSocket frame: payload length > 2^53 - 1\",!1,1009,\"WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH\")):(this._payloadLength=t*Math.pow(2,32)+e.readUInt32BE(4),this.haveLength())}haveLength(){if(this._payloadLength&&this._opcode<8&&(this._totalPayloadLength+=this._payloadLength,this._totalPayloadLength>this._maxPayload&&this._maxPayload>0))return this._loop=!1,x(RangeError,\"Max payload size exceeded\",!1,1009,\"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH\");this._masked?this._state=rt:this._state=Te}getMask(){if(this._bufferedBytes<4){this._loop=!1;return}this._mask=this.consume(4),this._state=Te}getData(e){let t=Qe;if(this._payloadLength){if(this._bufferedBytes7)return this.controlMessage(t);if(this._compressed){this._state=Br,this.decompress(t,e);return}return t.length&&(this._messageLength=this._totalPayloadLength,this._fragments.push(t)),this.dataMessage()}decompress(e,t){this._extensions[Ze.extensionName].decompress(e,this._fin,(i,n)=>{if(i)return t(i);if(n.length){if(this._messageLength+=n.length,this._messageLength>this._maxPayload&&this._maxPayload>0)return t(x(RangeError,\"Max payload size exceeded\",!1,1009,\"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH\"));this._fragments.push(n)}const o=this.dataMessage();if(o)return t(o);this.startLoop(t)})}dataMessage(){if(this._fin){const e=this._messageLength,t=this._fragments;if(this._totalPayloadLength=0,this._messageLength=0,this._fragmented=0,this._fragments=[],this._opcode===2){let s;this._binaryType===\"nodebuffer\"?s=Oe(t,e):this._binaryType===\"arraybuffer\"?s=$r(Oe(t,e)):s=t,this.emit(\"message\",s,!0)}else{const s=Oe(t,e);if(!this._skipUTF8Validation&&!Je(s))return this._loop=!1,x(Error,\"invalid UTF-8 sequence\",!0,1007,\"WS_ERR_INVALID_UTF8\");this.emit(\"message\",s,!1)}}this._state=X}controlMessage(e){if(this._opcode===8)if(this._loop=!1,e.length===0)this.emit(\"conclude\",1005,Qe),this.end();else{const t=e.readUInt16BE(0);if(!Rr(t))return x(RangeError,`invalid status code ${t}`,!0,1002,\"WS_ERR_INVALID_CLOSE_CODE\");const s=new ae(e.buffer,e.byteOffset+2,e.length-2);if(!this._skipUTF8Validation&&!Je(s))return x(Error,\"invalid UTF-8 sequence\",!0,1007,\"WS_ERR_INVALID_UTF8\");this.emit(\"conclude\",t,s),this.end()}else this._opcode===9?this.emit(\"ping\",e):this.emit(\"pong\",e);this._state=X}};var Ot=Ur;function x(r,e,t,s,i){const n=new r(t?`Invalid WebSocket frame: ${e}`:e);return Error.captureStackTrace(n,x),n.code=i,n[Nr]=s,n}const Ks=re(Ot),{randomFillSync:Ir}=Ie,st=ge,{EMPTY_BUFFER:Mr}=W,{isValidStatusCode:Dr}=ye,{mask:it,toBuffer:G}=me,T=Symbol(\"kByteLength\"),Ar=Buffer.alloc(4);let Wr=class D{constructor(e,t,s){this._extensions=t||{},s&&(this._generateMask=s,this._maskBuffer=Buffer.alloc(4)),this._socket=e,this._firstFragment=!0,this._compress=!1,this._bufferedBytes=0,this._deflating=!1,this._queue=[]}static frame(e,t){let s,i=!1,n=2,o=!1;t.mask&&(s=t.maskBuffer||Ar,t.generateMask?t.generateMask(s):Ir(s,0,4),o=(s[0]|s[1]|s[2]|s[3])===0,n=6);let a;typeof e==\"string\"?(!t.mask||o)&&t[T]!==void 0?a=t[T]:(e=Buffer.from(e),a=e.length):(a=e.length,i=t.mask&&t.readOnly&&!o);let l=a;a>=65536?(n+=8,l=127):a>125&&(n+=2,l=126);const f=Buffer.allocUnsafe(i?a+n:n);return f[0]=t.fin?t.opcode|128:t.opcode,t.rsv1&&(f[0]|=64),f[1]=l,l===126?f.writeUInt16BE(a,2):l===127&&(f[2]=f[3]=0,f.writeUIntBE(a,4,6)),t.mask?(f[1]|=128,f[n-4]=s[0],f[n-3]=s[1],f[n-2]=s[2],f[n-1]=s[3],o?[f,e]:i?(it(e,s,f,n,a),[f]):(it(e,s,e,0,a),[f,e])):[f,e]}close(e,t,s,i){let n;if(e===void 0)n=Mr;else{if(typeof e!=\"number\"||!Dr(e))throw new TypeError(\"First argument must be a valid error code number\");if(t===void 0||!t.length)n=Buffer.allocUnsafe(2),n.writeUInt16BE(e,0);else{const a=Buffer.byteLength(t);if(a>123)throw new RangeError(\"The message must not be greater than 123 bytes\");n=Buffer.allocUnsafe(2+a),n.writeUInt16BE(e,0),typeof t==\"string\"?n.write(t,2):n.set(t,2)}}const o={[T]:n.length,fin:!0,generateMask:this._generateMask,mask:s,maskBuffer:this._maskBuffer,opcode:8,readOnly:!1,rsv1:!1};this._deflating?this.enqueue([this.dispatch,n,!1,o,i]):this.sendFrame(D.frame(n,o),i)}ping(e,t,s){let i,n;if(typeof e==\"string\"?(i=Buffer.byteLength(e),n=!1):(e=G(e),i=e.length,n=G.readOnly),i>125)throw new RangeError(\"The data size must not be greater than 125 bytes\");const o={[T]:i,fin:!0,generateMask:this._generateMask,mask:t,maskBuffer:this._maskBuffer,opcode:9,readOnly:n,rsv1:!1};this._deflating?this.enqueue([this.dispatch,e,!1,o,s]):this.sendFrame(D.frame(e,o),s)}pong(e,t,s){let i,n;if(typeof e==\"string\"?(i=Buffer.byteLength(e),n=!1):(e=G(e),i=e.length,n=G.readOnly),i>125)throw new RangeError(\"The data size must not be greater than 125 bytes\");const o={[T]:i,fin:!0,generateMask:this._generateMask,mask:t,maskBuffer:this._maskBuffer,opcode:10,readOnly:n,rsv1:!1};this._deflating?this.enqueue([this.dispatch,e,!1,o,s]):this.sendFrame(D.frame(e,o),s)}send(e,t,s){const i=this._extensions[st.extensionName];let n=t.binary?2:1,o=t.compress,a,l;if(typeof e==\"string\"?(a=Buffer.byteLength(e),l=!1):(e=G(e),a=e.length,l=G.readOnly),this._firstFragment?(this._firstFragment=!1,o&&i&&i.params[i._isServer?\"server_no_context_takeover\":\"client_no_context_takeover\"]&&(o=a>=i._threshold),this._compress=o):(o=!1,n=0),t.fin&&(this._firstFragment=!0),i){const f={[T]:a,fin:t.fin,generateMask:this._generateMask,mask:t.mask,maskBuffer:this._maskBuffer,opcode:n,readOnly:l,rsv1:o};this._deflating?this.enqueue([this.dispatch,e,this._compress,f,s]):this.dispatch(e,this._compress,f,s)}else this.sendFrame(D.frame(e,{[T]:a,fin:t.fin,generateMask:this._generateMask,mask:t.mask,maskBuffer:this._maskBuffer,opcode:n,readOnly:l,rsv1:!1}),s)}dispatch(e,t,s,i){if(!t){this.sendFrame(D.frame(e,s),i);return}const n=this._extensions[st.extensionName];this._bufferedBytes+=s[T],this._deflating=!0,n.compress(e,s.fin,(o,a)=>{if(this._socket.destroyed){const l=new Error(\"The socket was closed while data was being compressed\");typeof i==\"function\"&&i(l);for(let f=0;f{let t=r[e];return Array.isArray(t)||(t=[t]),t.map(s=>[e].concat(Object.keys(s).map(i=>{let n=s[i];return Array.isArray(n)||(n=[n]),n.map(o=>o===!0?i:`${i}=${o}`).join(\"; \")})).join(\"; \")).join(\", \")}).join(\", \")}var Ct={format:Vr,parse:Gr};const qr=vt,Hr=Jt,zr=St,Nt=Zt,Yr=Qt,{randomBytes:Kr,createHash:Xr}=Ie,{URL:Ne}=er,U=ge,Zr=Ot,Qr=Tt,{BINARY_TYPES:ut,EMPTY_BUFFER:le,GUID:Jr,kForOnEventAttribute:Le,kListener:es,kStatusCode:ts,kWebSocket:w,NOOP:Lt}=W,{EventTarget:{addEventListener:rs,removeEventListener:ss}}=jr,{format:is,parse:ns}=Ct,{toBuffer:os}=me,as=30*1e3,$t=Symbol(\"kAborted\"),$e=[8,13],P=[\"CONNECTING\",\"OPEN\",\"CLOSING\",\"CLOSED\"],fs=/^[!#$%&'*+\\-.0-9A-Z^_`|a-z~]+$/;let S=class v extends qr{constructor(e,t,s){super(),this._binaryType=ut[0],this._closeCode=1006,this._closeFrameReceived=!1,this._closeFrameSent=!1,this._closeMessage=le,this._closeTimer=null,this._extensions={},this._paused=!1,this._protocol=\"\",this._readyState=v.CONNECTING,this._receiver=null,this._sender=null,this._socket=null,e!==null?(this._bufferedAmount=0,this._isServer=!1,this._redirects=0,t===void 0?t=[]:Array.isArray(t)||(typeof t==\"object\"&&t!==null?(s=t,t=[]):t=[t]),Rt(this,e,t,s)):this._isServer=!0}get binaryType(){return this._binaryType}set binaryType(e){ut.includes(e)&&(this._binaryType=e,this._receiver&&(this._receiver._binaryType=e))}get bufferedAmount(){return this._socket?this._socket._writableState.length+this._sender._bufferedBytes:this._bufferedAmount}get extensions(){return Object.keys(this._extensions).join()}get isPaused(){return this._paused}get onclose(){return null}get onerror(){return null}get onopen(){return null}get onmessage(){return null}get protocol(){return this._protocol}get readyState(){return this._readyState}get url(){return this._url}setSocket(e,t,s){const i=new Zr({binaryType:this.binaryType,extensions:this._extensions,isServer:this._isServer,maxPayload:s.maxPayload,skipUTF8Validation:s.skipUTF8Validation});this._sender=new Qr(e,this._extensions,s.generateMask),this._receiver=i,this._socket=e,i[w]=this,e[w]=this,i.on(\"conclude\",hs),i.on(\"drain\",us),i.on(\"error\",ds),i.on(\"message\",_s),i.on(\"ping\",ps),i.on(\"pong\",ms),e.setTimeout(0),e.setNoDelay(),t.length>0&&e.unshift(t),e.on(\"close\",Ut),e.on(\"data\",Se),e.on(\"end\",It),e.on(\"error\",Mt),this._readyState=v.OPEN,this.emit(\"open\")}emitClose(){if(!this._socket){this._readyState=v.CLOSED,this.emit(\"close\",this._closeCode,this._closeMessage);return}this._extensions[U.extensionName]&&this._extensions[U.extensionName].cleanup(),this._receiver.removeAllListeners(),this._readyState=v.CLOSED,this.emit(\"close\",this._closeCode,this._closeMessage)}close(e,t){if(this.readyState!==v.CLOSED){if(this.readyState===v.CONNECTING){O(this,this._req,\"WebSocket was closed before the connection was established\");return}if(this.readyState===v.CLOSING){this._closeFrameSent&&(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end();return}this._readyState=v.CLOSING,this._sender.close(e,t,!this._isServer,s=>{s||(this._closeFrameSent=!0,(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end())}),this._closeTimer=setTimeout(this._socket.destroy.bind(this._socket),as)}}pause(){this.readyState===v.CONNECTING||this.readyState===v.CLOSED||(this._paused=!0,this._socket.pause())}ping(e,t,s){if(this.readyState===v.CONNECTING)throw new Error(\"WebSocket is not open: readyState 0 (CONNECTING)\");if(typeof e==\"function\"?(s=e,e=t=void 0):typeof t==\"function\"&&(s=t,t=void 0),typeof e==\"number\"&&(e=e.toString()),this.readyState!==v.OPEN){Pe(this,e,s);return}t===void 0&&(t=!this._isServer),this._sender.ping(e||le,t,s)}pong(e,t,s){if(this.readyState===v.CONNECTING)throw new Error(\"WebSocket is not open: readyState 0 (CONNECTING)\");if(typeof e==\"function\"?(s=e,e=t=void 0):typeof t==\"function\"&&(s=t,t=void 0),typeof e==\"number\"&&(e=e.toString()),this.readyState!==v.OPEN){Pe(this,e,s);return}t===void 0&&(t=!this._isServer),this._sender.pong(e||le,t,s)}resume(){this.readyState===v.CONNECTING||this.readyState===v.CLOSED||(this._paused=!1,this._receiver._writableState.needDrain||this._socket.resume())}send(e,t,s){if(this.readyState===v.CONNECTING)throw new Error(\"WebSocket is not open: readyState 0 (CONNECTING)\");if(typeof t==\"function\"&&(s=t,t={}),typeof e==\"number\"&&(e=e.toString()),this.readyState!==v.OPEN){Pe(this,e,s);return}const i={binary:typeof e!=\"string\",mask:!this._isServer,compress:!0,fin:!0,...t};this._extensions[U.extensionName]||(i.compress=!1),this._sender.send(e||le,i,s)}terminate(){if(this.readyState!==v.CLOSED){if(this.readyState===v.CONNECTING){O(this,this._req,\"WebSocket was closed before the connection was established\");return}this._socket&&(this._readyState=v.CLOSING,this._socket.destroy())}}};Object.defineProperty(S,\"CONNECTING\",{enumerable:!0,value:P.indexOf(\"CONNECTING\")});Object.defineProperty(S.prototype,\"CONNECTING\",{enumerable:!0,value:P.indexOf(\"CONNECTING\")});Object.defineProperty(S,\"OPEN\",{enumerable:!0,value:P.indexOf(\"OPEN\")});Object.defineProperty(S.prototype,\"OPEN\",{enumerable:!0,value:P.indexOf(\"OPEN\")});Object.defineProperty(S,\"CLOSING\",{enumerable:!0,value:P.indexOf(\"CLOSING\")});Object.defineProperty(S.prototype,\"CLOSING\",{enumerable:!0,value:P.indexOf(\"CLOSING\")});Object.defineProperty(S,\"CLOSED\",{enumerable:!0,value:P.indexOf(\"CLOSED\")});Object.defineProperty(S.prototype,\"CLOSED\",{enumerable:!0,value:P.indexOf(\"CLOSED\")});[\"binaryType\",\"bufferedAmount\",\"extensions\",\"isPaused\",\"protocol\",\"readyState\",\"url\"].forEach(r=>{Object.defineProperty(S.prototype,r,{enumerable:!0})});[\"open\",\"error\",\"close\",\"message\"].forEach(r=>{Object.defineProperty(S.prototype,`on${r}`,{enumerable:!0,get(){for(const e of this.listeners(r))if(e[Le])return e[es];return null},set(e){for(const t of this.listeners(r))if(t[Le]){this.removeListener(r,t);break}typeof e==\"function\"&&this.addEventListener(r,e,{[Le]:!0})}})});S.prototype.addEventListener=rs;S.prototype.removeEventListener=ss;var Pt=S;function Rt(r,e,t,s){const i={protocolVersion:$e[1],maxPayload:104857600,skipUTF8Validation:!1,perMessageDeflate:!0,followRedirects:!1,maxRedirects:10,...s,createConnection:void 0,socketPath:void 0,hostname:void 0,protocol:void 0,timeout:void 0,method:\"GET\",host:void 0,path:void 0,port:void 0};if(!$e.includes(i.protocolVersion))throw new RangeError(`Unsupported protocol version: ${i.protocolVersion} (supported versions: ${$e.join(\", \")})`);let n;if(e instanceof Ne)n=e,r._url=e.href;else{try{n=new Ne(e)}catch{throw new SyntaxError(`Invalid URL: ${e}`)}r._url=e}const o=n.protocol===\"wss:\",a=n.protocol===\"ws+unix:\";let l;if(n.protocol!==\"ws:\"&&!o&&!a?l=`The URL's protocol must be one of \"ws:\", \"wss:\", or \"ws+unix:\"`:a&&!n.pathname?l=\"The URL's pathname is empty\":n.hash&&(l=\"The URL contains a fragment identifier\"),l){const d=new SyntaxError(l);if(r._redirects===0)throw d;he(r,d);return}const f=o?443:80,h=Kr(16).toString(\"base64\"),c=o?Hr.request:zr.request,y=new Set;let p;if(i.createConnection=o?cs:ls,i.defaultPort=i.defaultPort||f,i.port=n.port||f,i.host=n.hostname.startsWith(\"[\")?n.hostname.slice(1,-1):n.hostname,i.headers={...i.headers,\"Sec-WebSocket-Version\":i.protocolVersion,\"Sec-WebSocket-Key\":h,Connection:\"Upgrade\",Upgrade:\"websocket\"},i.path=n.pathname+n.search,i.timeout=i.handshakeTimeout,i.perMessageDeflate&&(p=new U(i.perMessageDeflate!==!0?i.perMessageDeflate:{},!1,i.maxPayload),i.headers[\"Sec-WebSocket-Extensions\"]=is({[U.extensionName]:p.offer()})),t.length){for(const d of t){if(typeof d!=\"string\"||!fs.test(d)||y.has(d))throw new SyntaxError(\"An invalid or duplicated subprotocol was specified\");y.add(d)}i.headers[\"Sec-WebSocket-Protocol\"]=t.join(\",\")}if(i.origin&&(i.protocolVersion<13?i.headers[\"Sec-WebSocket-Origin\"]=i.origin:i.headers.Origin=i.origin),(n.username||n.password)&&(i.auth=`${n.username}:${n.password}`),a){const d=i.path.split(\":\");i.socketPath=d[0],i.path=d[1]}let g;if(i.followRedirects){if(r._redirects===0){r._originalIpc=a,r._originalSecure=o,r._originalHostOrSocketPath=a?i.socketPath:n.host;const d=s&&s.headers;if(s={...s,headers:{}},d)for(const[E,L]of Object.entries(d))s.headers[E.toLowerCase()]=L}else if(r.listenerCount(\"redirect\")===0){const d=a?r._originalIpc?i.socketPath===r._originalHostOrSocketPath:!1:r._originalIpc?!1:n.host===r._originalHostOrSocketPath;(!d||r._originalSecure&&!o)&&(delete i.headers.authorization,delete i.headers.cookie,d||delete i.headers.host,i.auth=void 0)}i.auth&&!s.headers.authorization&&(s.headers.authorization=\"Basic \"+Buffer.from(i.auth).toString(\"base64\")),g=r._req=c(i),r._redirects&&r.emit(\"redirect\",r.url,g)}else g=r._req=c(i);i.timeout&&g.on(\"timeout\",()=>{O(r,g,\"Opening handshake has timed out\")}),g.on(\"error\",d=>{g===null||g[$t]||(g=r._req=null,he(r,d))}),g.on(\"response\",d=>{const E=d.headers.location,L=d.statusCode;if(E&&i.followRedirects&&L>=300&&L<400){if(++r._redirects>i.maxRedirects){O(r,g,\"Maximum redirects exceeded\");return}g.abort();let I;try{I=new Ne(E,e)}catch{const C=new SyntaxError(`Invalid URL: ${E}`);he(r,C);return}Rt(r,I,t,s)}else r.emit(\"unexpected-response\",g,d)||O(r,g,`Unexpected server response: ${d.statusCode}`)}),g.on(\"upgrade\",(d,E,L)=>{if(r.emit(\"upgrade\",d),r.readyState!==S.CONNECTING)return;if(g=r._req=null,d.headers.upgrade.toLowerCase()!==\"websocket\"){O(r,E,\"Invalid Upgrade header\");return}const I=Xr(\"sha1\").update(h+Jr).digest(\"base64\");if(d.headers[\"sec-websocket-accept\"]!==I){O(r,E,\"Invalid Sec-WebSocket-Accept header\");return}const R=d.headers[\"sec-websocket-protocol\"];let C;if(R!==void 0?y.size?y.has(R)||(C=\"Server sent an invalid subprotocol\"):C=\"Server sent a subprotocol but none was requested\":y.size&&(C=\"Server sent no subprotocol\"),C){O(r,E,C);return}R&&(r._protocol=R);const q=d.headers[\"sec-websocket-extensions\"];if(q!==void 0){if(!p){O(r,E,\"Server sent a Sec-WebSocket-Extensions header but no extension was requested\");return}let H;try{H=ns(q)}catch{O(r,E,\"Invalid Sec-WebSocket-Extensions header\");return}const z=Object.keys(H);if(z.length!==1||z[0]!==U.extensionName){O(r,E,\"Server indicated an extension that was not requested\");return}try{p.accept(H[U.extensionName])}catch{O(r,E,\"Invalid Sec-WebSocket-Extensions header\");return}r._extensions[U.extensionName]=p}r.setSocket(E,L,{generateMask:i.generateMask,maxPayload:i.maxPayload,skipUTF8Validation:i.skipUTF8Validation})}),i.finishRequest?i.finishRequest(g,r):g.end()}function he(r,e){r._readyState=S.CLOSING,r.emit(\"error\",e),r.emitClose()}function ls(r){return r.path=r.socketPath,Nt.connect(r)}function cs(r){return r.path=void 0,!r.servername&&r.servername!==\"\"&&(r.servername=Nt.isIP(r.host)?\"\":r.host),Yr.connect(r)}function O(r,e,t){r._readyState=S.CLOSING;const s=new Error(t);Error.captureStackTrace(s,O),e.setHeader?(e[$t]=!0,e.abort(),e.socket&&!e.socket.destroyed&&e.socket.destroy(),process.nextTick(he,r,s)):(e.destroy(s),e.once(\"error\",r.emit.bind(r,\"error\")),e.once(\"close\",r.emitClose.bind(r)))}function Pe(r,e,t){if(e){const s=os(e).length;r._socket?r._sender._bufferedBytes+=s:r._bufferedAmount+=s}if(t){const s=new Error(`WebSocket is not open: readyState ${r.readyState} (${P[r.readyState]})`);process.nextTick(t,s)}}function hs(r,e){const t=this[w];t._closeFrameReceived=!0,t._closeMessage=e,t._closeCode=r,t._socket[w]!==void 0&&(t._socket.removeListener(\"data\",Se),process.nextTick(Bt,t._socket),r===1005?t.close():t.close(r,e))}function us(){const r=this[w];r.isPaused||r._socket.resume()}function ds(r){const e=this[w];e._socket[w]!==void 0&&(e._socket.removeListener(\"data\",Se),process.nextTick(Bt,e._socket),e.close(r[ts])),e.emit(\"error\",r)}function dt(){this[w].emitClose()}function _s(r,e){this[w].emit(\"message\",r,e)}function ps(r){const e=this[w];e.pong(r,!e._isServer,Lt),e.emit(\"ping\",r)}function ms(r){this[w].emit(\"pong\",r)}function Bt(r){r.resume()}function Ut(){const r=this[w];this.removeListener(\"close\",Ut),this.removeListener(\"data\",Se),this.removeListener(\"end\",It),r._readyState=S.CLOSING;let e;!this._readableState.endEmitted&&!r._closeFrameReceived&&!r._receiver._writableState.errorEmitted&&(e=r._socket.read())!==null&&r._receiver.write(e),r._receiver.end(),this[w]=void 0,clearTimeout(r._closeTimer),r._receiver._writableState.finished||r._receiver._writableState.errorEmitted?r.emitClose():(r._receiver.on(\"error\",dt),r._receiver.on(\"finish\",dt))}function Se(r){this[w]._receiver.write(r)||this.pause()}function It(){const r=this[w];r._readyState=S.CLOSING,r._receiver.end(),this.end()}function Mt(){const r=this[w];this.removeListener(\"error\",Mt),this.on(\"error\",Lt),r&&(r._readyState=S.CLOSING,this.destroy())}const Zs=re(Pt),{tokenChars:gs}=ye;function ys(r){const e=new Set;let t=-1,s=-1,i=0;for(i;i{const n=pe.STATUS_CODES[426];i.writeHead(426,{\"Content-Length\":n.length,\"Content-Type\":\"text/plain\"}),i.end(n)}),this._server.listen(e.port,e.host,e.backlog,t)):e.server&&(this._server=e.server),this._server){const s=this.emit.bind(this,\"connection\");this._removeListeners=Ns(this._server,{listening:this.emit.bind(this,\"listening\"),error:this.emit.bind(this,\"error\"),upgrade:(i,n,o)=>{this.handleUpgrade(i,n,o,s)}})}e.perMessageDeflate===!0&&(e.perMessageDeflate={}),e.clientTracking&&(this.clients=new Set,this._shouldEmitClose=!1),this.options=e,this._state=pt}address(){if(this.options.noServer)throw new Error('The server is operating in \"noServer\" mode');return this._server?this._server.address():null}close(e){if(this._state===Dt){e&&this.once(\"close\",()=>{e(new Error(\"The server is not running\"))}),process.nextTick(J,this);return}if(e&&this.once(\"close\",e),this._state!==mt)if(this._state=mt,this.options.noServer||this.options.server)this._server&&(this._removeListeners(),this._removeListeners=this._server=null),this.clients?this.clients.size?this._shouldEmitClose=!0:process.nextTick(J,this):process.nextTick(J,this);else{const t=this._server;this._removeListeners(),this._removeListeners=this._server=null,t.close(()=>{J(this)})}}shouldHandle(e){if(this.options.path){const t=e.url.indexOf(\"?\");if((t!==-1?e.url.slice(0,t):e.url)!==this.options.path)return!1}return!0}handleUpgrade(e,t,s,i){t.on(\"error\",gt);const n=e.headers[\"sec-websocket-key\"],o=+e.headers[\"sec-websocket-version\"];if(e.method!==\"GET\"){A(this,e,t,405,\"Invalid HTTP method\");return}if(e.headers.upgrade.toLowerCase()!==\"websocket\"){A(this,e,t,400,\"Invalid Upgrade header\");return}if(!n||!Os.test(n)){A(this,e,t,400,\"Missing or invalid Sec-WebSocket-Key header\");return}if(o!==8&&o!==13){A(this,e,t,400,\"Missing or invalid Sec-WebSocket-Version header\");return}if(!this.shouldHandle(e)){te(t,400);return}const a=e.headers[\"sec-websocket-protocol\"];let l=new Set;if(a!==void 0)try{l=Es.parse(a)}catch{A(this,e,t,400,\"Invalid Sec-WebSocket-Protocol header\");return}const f=e.headers[\"sec-websocket-extensions\"],h={};if(this.options.perMessageDeflate&&f!==void 0){const c=new M(this.options.perMessageDeflate,!0,this.options.maxPayload);try{const y=_t.parse(f);y[M.extensionName]&&(c.accept(y[M.extensionName]),h[M.extensionName]=c)}catch{A(this,e,t,400,\"Invalid or unacceptable Sec-WebSocket-Extensions header\");return}}if(this.options.verifyClient){const c={origin:e.headers[`${o===8?\"sec-websocket-origin\":\"origin\"}`],secure:!!(e.socket.authorized||e.socket.encrypted),req:e};if(this.options.verifyClient.length===2){this.options.verifyClient(c,(y,p,g,d)=>{if(!y)return te(t,p||401,g,d);this.completeUpgrade(h,n,l,e,t,s,i)});return}if(!this.options.verifyClient(c))return te(t,401)}this.completeUpgrade(h,n,l,e,t,s,i)}completeUpgrade(e,t,s,i,n,o,a){if(!n.readable||!n.writable)return n.destroy();if(n[ks])throw new Error(\"server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration\");if(this._state>pt)return te(n,503);const f=[\"HTTP/1.1 101 Switching Protocols\",\"Upgrade: websocket\",\"Connection: Upgrade\",`Sec-WebSocket-Accept: ${xs(\"sha1\").update(t+ws).digest(\"base64\")}`],h=new this.options.WebSocket(null);if(s.size){const c=this.options.handleProtocols?this.options.handleProtocols(s,i):s.values().next().value;c&&(f.push(`Sec-WebSocket-Protocol: ${c}`),h._protocol=c)}if(e[M.extensionName]){const c=e[M.extensionName].params,y=_t.format({[M.extensionName]:[c]});f.push(`Sec-WebSocket-Extensions: ${y}`),h._extensions=e}this.emit(\"headers\",f,i),n.write(f.concat(`\\r\n`).join(`\\r\n`)),n.removeListener(\"error\",gt),h.setSocket(n,o,{maxPayload:this.options.maxPayload,skipUTF8Validation:this.options.skipUTF8Validation}),this.clients&&(this.clients.add(h),h.on(\"close\",()=>{this.clients.delete(h),this._shouldEmitClose&&!this.clients.size&&process.nextTick(J,this)})),a(h,i)}}var Cs=Ts;function Ns(r,e){for(const t of Object.keys(e))r.on(t,e[t]);return function(){for(const s of Object.keys(e))r.removeListener(s,e[s])}}function J(r){r._state=Dt,r.emit(\"close\")}function gt(){this.destroy()}function te(r,e,t,s){t=t||pe.STATUS_CODES[e],s={Connection:\"close\",\"Content-Type\":\"text/html\",\"Content-Length\":Buffer.byteLength(t),...s},r.once(\"finish\",r.destroy),r.end(`HTTP/1.1 ${e} ${pe.STATUS_CODES[e]}\\r\n`+Object.keys(s).map(i=>`${i}: ${s[i]}`).join(`\\r\n`)+`\\r\n\\r\n`+t)}function A(r,e,t,s,i){if(r.listenerCount(\"wsClientError\")){const n=new Error(i);Error.captureStackTrace(n,A),r.emit(\"wsClientError\",n,t,e)}else te(t,s,i)}const Qs=re(Cs);export{Ks as Receiver,Xs as Sender,Zs as WebSocket,Qs as WebSocketServer,qs as createWebSocketStream,Zs as default};\n//# sourceMappingURL=wrapper.js.map\n"],"names":["re","r","zt","Yt","Ht","Vt","er"],"mappings":"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CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,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,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,MAAM,IAAI,WAAW,CAAC,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAA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"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/yaml-C6fZICTl.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/yaml-C6fZICTl.js new file mode 100644 index 0000000000000000000000000000000000000000..6403ee82040e3f6da5679b71cab08e37b8154394 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/yaml-C6fZICTl.js @@ -0,0 +1,4 @@ +var l=["true","false","on","off","yes","no"],f=new RegExp("\\b(("+l.join(")|(")+"))$","i");const a={name:"yaml",token:function(n,i){var r=n.peek(),e=i.escaped;if(i.escaped=!1,r=="#"&&(n.pos==0||/\s/.test(n.string.charAt(n.pos-1))))return n.skipToEnd(),"comment";if(n.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/))return "string";if(i.literal&&n.indentation()>i.keyCol)return n.skipToEnd(),"string";if(i.literal&&(i.literal=!1),n.sol()){if(i.keyCol=0,i.pair=!1,i.pairStart=!1,n.match("---")||n.match("..."))return "def";if(n.match(/^\s*-\s+/))return "meta"}if(n.match(/^(\{|\}|\[|\])/))return r=="{"?i.inlinePairs++:r=="}"?i.inlinePairs--:r=="["?i.inlineList++:i.inlineList--,"meta";if(i.inlineList>0&&!e&&r==",")return n.next(),"meta";if(i.inlinePairs>0&&!e&&r==",")return i.keyCol=0,i.pair=!1,i.pairStart=!1,n.next(),"meta";if(i.pairStart){if(n.match(/^\s*(\||\>)\s*/))return i.literal=!0,"meta";if(n.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i))return "variable";if(i.inlinePairs==0&&n.match(/^\s*-?[0-9\.\,]+\s?$/)||i.inlinePairs>0&&n.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/))return "number";if(n.match(f))return "keyword"}return !i.pair&&n.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)?(i.pair=!0,i.keyCol=n.indentation(),"atom"):i.pair&&n.match(/^:\s*/)?(i.pairStart=!0,"meta"):(i.pairStart=!1,i.escaped=r=="\\",n.next(),null)},startState:function(){return {pair:!1,pairStart:!1,keyCol:0,inlinePairs:0,inlineList:0,literal:!1,escaped:!1}},languageData:{commentTokens:{line:"#"}}}; + +export { a as yaml }; +//# sourceMappingURL=yaml-C6fZICTl.js.map diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/yaml-C6fZICTl.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/yaml-C6fZICTl.js.map new file mode 100644 index 0000000000000000000000000000000000000000..f7eec09b5fe0a1a2acac1ba5c68f1338d4d9ec59 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/yaml-C6fZICTl.js.map @@ -0,0 +1 @@ +{"version":3,"file":"yaml-C6fZICTl.js","sources":["../../../../../../js/app/.svelte-kit/adapter-node/chunks/yaml.js"],"sourcesContent":["var l=[\"true\",\"false\",\"on\",\"off\",\"yes\",\"no\"],f=new RegExp(\"\\\\b((\"+l.join(\")|(\")+\"))$\",\"i\");const a={name:\"yaml\",token:function(n,i){var r=n.peek(),e=i.escaped;if(i.escaped=!1,r==\"#\"&&(n.pos==0||/\\s/.test(n.string.charAt(n.pos-1))))return n.skipToEnd(),\"comment\";if(n.match(/^('([^']|\\\\.)*'?|\"([^\"]|\\\\.)*\"?)/))return\"string\";if(i.literal&&n.indentation()>i.keyCol)return n.skipToEnd(),\"string\";if(i.literal&&(i.literal=!1),n.sol()){if(i.keyCol=0,i.pair=!1,i.pairStart=!1,n.match(\"---\")||n.match(\"...\"))return\"def\";if(n.match(/^\\s*-\\s+/))return\"meta\"}if(n.match(/^(\\{|\\}|\\[|\\])/))return r==\"{\"?i.inlinePairs++:r==\"}\"?i.inlinePairs--:r==\"[\"?i.inlineList++:i.inlineList--,\"meta\";if(i.inlineList>0&&!e&&r==\",\")return n.next(),\"meta\";if(i.inlinePairs>0&&!e&&r==\",\")return i.keyCol=0,i.pair=!1,i.pairStart=!1,n.next(),\"meta\";if(i.pairStart){if(n.match(/^\\s*(\\||\\>)\\s*/))return i.literal=!0,\"meta\";if(n.match(/^\\s*(\\&|\\*)[a-z0-9\\._-]+\\b/i))return\"variable\";if(i.inlinePairs==0&&n.match(/^\\s*-?[0-9\\.\\,]+\\s?$/)||i.inlinePairs>0&&n.match(/^\\s*-?[0-9\\.\\,]+\\s?(?=(,|}))/))return\"number\";if(n.match(f))return\"keyword\"}return!i.pair&&n.match(/^\\s*(?:[,\\[\\]{}&*!|>'\"%@`][^\\s'\":]|[^,\\[\\]{}#&*!|>'\"%@`])[^#]*?(?=\\s*:($|\\s))/)?(i.pair=!0,i.keyCol=n.indentation(),\"atom\"):i.pair&&n.match(/^:\\s*/)?(i.pairStart=!0,\"meta\"):(i.pairStart=!1,i.escaped=r==\"\\\\\",n.next(),null)},startState:function(){return{pair:!1,pairStart:!1,keyCol:0,inlinePairs:0,inlineList:0,literal:!1,escaped:!1}},languageData:{commentTokens:{line:\"#\"}}};export{a as yaml};\n//# sourceMappingURL=yaml.js.map\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/zh-CN-CPutFXEq.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/zh-CN-CPutFXEq.js new file mode 100644 index 0000000000000000000000000000000000000000..dbda5b9818f03bb35e2614e3b3099c151accf006 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/zh-CN-CPutFXEq.js @@ -0,0 +1,4 @@ +const o="简体中文",e={annotated_image:"标注图像"},r={allow_recording_access:"请允许访问麦克风以进行录音。",audio:"音频",record_from_microphone:"从麦克风录制",stop_recording:"停止录制",no_device_support:"无法访问媒体设备。请检查您是否在安全来源(https)或本地主机上运行(或者您已经通过 ssl_verify 传递了有效的 SSL 证书),并且您已经允许浏览器访问您的设备。",stop:"停止",resume:"继续",record:"录制",no_microphone:"找不到麦克风",pause:"暂停",play:"播放",waiting:"等待中",drop_to_upload:"将音频文件拖放到此处以上传"},t={connection_can_break:"在移动设备上,如果此标签页失去焦点或设备休眠,连接可能会中断,导致您在队列中失去位置。",long_requests_queue:"有一个长时间的待处理请求队列。复制此 Space 以跳过队列。",lost_connection:"由于离开页面,连接已丢失。正在重新加入队列...",waiting_for_inputs:"等待文件上传完成,请稍后重试。"},a={checkbox:"复选框",checkbox_group:"复选框组"},c={code:"代码"},_={color_picker:"颜色选择器"},n={built_with:"构建于",built_with_gradio:"使用 Gradio 构建",clear:"清除",download:"下载",edit:"编辑",empty:"空",error:"错误",hosted_on:"托管在",loading:"加载中",logo:"标志",or:"或",remove:"移除",share:"分享",submit:"提交",undo:"撤销",settings:"设置",no_devices:"未找到设备",language:"语言",display_theme:"显示主题",pwa:"渐进式 Web 应用"},d={incorrect_format:"格式不正确,仅支持 CSV 和 TSV 文件",new_column:"添加列",new_row:"新行",add_row_above:"在上方添加行",add_row_below:"在下方添加行",delete_row:"删除行",delete_column:"删除列",add_column_left:"在左侧添加列",add_column_right:"在右侧添加列",sort_column:"排序列",sort_ascending:"升序排序",sort_descending:"降序排序",drop_to_upload:"将 CSV 或 TSV 文件拖放到此处以将数据导入数据框",clear_sort:"清除排序"},i={dropdown:"下拉菜单"},s={build_error:"存在构建错误",config_error:"存在配置错误",contact_page_author:"请联系页面的作者并告知他们。",no_app_file:"不存在应用文件",runtime_error:"存在运行时错误",space_not_working:'"Space 无法工作,原因:" {0}',space_paused:"Space 已暂停",use_via_api:"通过 API 使用",use_via_api_or_mcp:"通过 API 或 MCP 使用"},l={uploading:"正在上传..."},p={highlighted_text:"高亮文本"},u={allow_webcam_access:"请允许访问网络摄像头以进行录制。",brush_color:"画笔颜色",brush_radius:"画笔大小",image:"图像",remove_image:"移除图像",select_brush_color:"选择画笔颜色",start_drawing:"开始绘画",use_brush:"使用画笔",drop_to_upload:"将图像文件拖放到此处以上传"},g={label:"标签"},m={enable_cookies:"如果您正在使用隐身模式访问 HuggingFace Space,您必须启用第三方 cookie。",incorrect_credentials:"凭据不正确",login:"登录",username:"用户名",password:"密码"},b={number:"数字"},h={plot:"图表"},w={radio:"单选框"},k={slider:"滑块"},f={click_to_upload:"点击上传",drop_audio:"将音频拖放到此处",drop_csv:"将 CSV 文件拖放到此处",drop_file:"将文件拖放到此处",drop_image:"将图像拖放到此处",drop_video:"将视频拖放到此处",drop_gallery:"在此处放置媒体文件",paste_clipboard:"从剪贴板粘贴"},v={drop_to_upload:"将视频文件拖放到此处以上传"},S={edit:"编辑",retry:"重试",undo:"撤销",submit:"发送",cancel:"取消",like:"赞",dislike:"踩",clear:"清空对话"},x={_name:o,"3D_model":{"3d_model":"3D模型",drop_to_upload:"将 3D 模型(.obj、.glb、.stl、.gltf、.splat 或 .ply)文件拖放到此处以上传"},annotated_image:e,audio:r,blocks:t,checkbox:a,code:c,color_picker:_,common:n,dataframe:d,dropdown:i,errors:s,file:l,highlighted_text:p,image:u,label:g,login:m,number:b,plot:h,radio:w,slider:k,upload_text:f,video:v,chatbot:S}; + +export { o as _name, e as annotated_image, r as audio, t as blocks, S as chatbot, a as checkbox, c as code, _ as color_picker, n as common, d as dataframe, x as default, i as dropdown, s as errors, l as file, p as highlighted_text, u as image, g as label, m as login, b as number, h as plot, w as radio, k as slider, f as upload_text, v as video }; +//# sourceMappingURL=zh-CN-CPutFXEq.js.map diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/zh-CN-CPutFXEq.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/zh-CN-CPutFXEq.js.map new file mode 100644 index 0000000000000000000000000000000000000000..8f44ac9b609726a87baebbb19ffbf3affacee6cc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/zh-CN-CPutFXEq.js.map @@ -0,0 +1 @@ +{"version":3,"file":"zh-CN-CPutFXEq.js","sources":["../../../../../../js/app/.svelte-kit/adapter-node/chunks/zh-CN.js"],"sourcesContent":["const o=\"简体中文\",e={annotated_image:\"标注图像\"},r={allow_recording_access:\"请允许访问麦克风以进行录音。\",audio:\"音频\",record_from_microphone:\"从麦克风录制\",stop_recording:\"停止录制\",no_device_support:\"无法访问媒体设备。请检查您是否在安全来源(https)或本地主机上运行(或者您已经通过 ssl_verify 传递了有效的 SSL 证书),并且您已经允许浏览器访问您的设备。\",stop:\"停止\",resume:\"继续\",record:\"录制\",no_microphone:\"找不到麦克风\",pause:\"暂停\",play:\"播放\",waiting:\"等待中\",drop_to_upload:\"将音频文件拖放到此处以上传\"},t={connection_can_break:\"在移动设备上,如果此标签页失去焦点或设备休眠,连接可能会中断,导致您在队列中失去位置。\",long_requests_queue:\"有一个长时间的待处理请求队列。复制此 Space 以跳过队列。\",lost_connection:\"由于离开页面,连接已丢失。正在重新加入队列...\",waiting_for_inputs:\"等待文件上传完成,请稍后重试。\"},a={checkbox:\"复选框\",checkbox_group:\"复选框组\"},c={code:\"代码\"},_={color_picker:\"颜色选择器\"},n={built_with:\"构建于\",built_with_gradio:\"使用 Gradio 构建\",clear:\"清除\",download:\"下载\",edit:\"编辑\",empty:\"空\",error:\"错误\",hosted_on:\"托管在\",loading:\"加载中\",logo:\"标志\",or:\"或\",remove:\"移除\",share:\"分享\",submit:\"提交\",undo:\"撤销\",settings:\"设置\",no_devices:\"未找到设备\",language:\"语言\",display_theme:\"显示主题\",pwa:\"渐进式 Web 应用\"},d={incorrect_format:\"格式不正确,仅支持 CSV 和 TSV 文件\",new_column:\"添加列\",new_row:\"新行\",add_row_above:\"在上方添加行\",add_row_below:\"在下方添加行\",delete_row:\"删除行\",delete_column:\"删除列\",add_column_left:\"在左侧添加列\",add_column_right:\"在右侧添加列\",sort_column:\"排序列\",sort_ascending:\"升序排序\",sort_descending:\"降序排序\",drop_to_upload:\"将 CSV 或 TSV 文件拖放到此处以将数据导入数据框\",clear_sort:\"清除排序\"},i={dropdown:\"下拉菜单\"},s={build_error:\"存在构建错误\",config_error:\"存在配置错误\",contact_page_author:\"请联系页面的作者并告知他们。\",no_app_file:\"不存在应用文件\",runtime_error:\"存在运行时错误\",space_not_working:'\"Space 无法工作,原因:\" {0}',space_paused:\"Space 已暂停\",use_via_api:\"通过 API 使用\",use_via_api_or_mcp:\"通过 API 或 MCP 使用\"},l={uploading:\"正在上传...\"},p={highlighted_text:\"高亮文本\"},u={allow_webcam_access:\"请允许访问网络摄像头以进行录制。\",brush_color:\"画笔颜色\",brush_radius:\"画笔大小\",image:\"图像\",remove_image:\"移除图像\",select_brush_color:\"选择画笔颜色\",start_drawing:\"开始绘画\",use_brush:\"使用画笔\",drop_to_upload:\"将图像文件拖放到此处以上传\"},g={label:\"标签\"},m={enable_cookies:\"如果您正在使用隐身模式访问 HuggingFace Space,您必须启用第三方 cookie。\",incorrect_credentials:\"凭据不正确\",login:\"登录\",username:\"用户名\",password:\"密码\"},b={number:\"数字\"},h={plot:\"图表\"},w={radio:\"单选框\"},k={slider:\"滑块\"},f={click_to_upload:\"点击上传\",drop_audio:\"将音频拖放到此处\",drop_csv:\"将 CSV 文件拖放到此处\",drop_file:\"将文件拖放到此处\",drop_image:\"将图像拖放到此处\",drop_video:\"将视频拖放到此处\",drop_gallery:\"在此处放置媒体文件\",paste_clipboard:\"从剪贴板粘贴\"},v={drop_to_upload:\"将视频文件拖放到此处以上传\"},S={edit:\"编辑\",retry:\"重试\",undo:\"撤销\",submit:\"发送\",cancel:\"取消\",like:\"赞\",dislike:\"踩\",clear:\"清空对话\"},x={_name:o,\"3D_model\":{\"3d_model\":\"3D模型\",drop_to_upload:\"将 3D 模型(.obj、.glb、.stl、.gltf、.splat 或 .ply)文件拖放到此处以上传\"},annotated_image:e,audio:r,blocks:t,checkbox:a,code:c,color_picker:_,common:n,dataframe:d,dropdown:i,errors:s,file:l,highlighted_text:p,image:u,label:g,login:m,number:b,plot:h,radio:w,slider:k,upload_text:f,video:v,chatbot:S};export{o as _name,e as annotated_image,r as audio,t as blocks,S as chatbot,a as checkbox,c as code,_ as color_picker,n as common,d as dataframe,x as default,i as dropdown,s as errors,l as file,p as highlighted_text,u as image,g as label,m as login,b as number,h as plot,w as radio,k as slider,f as upload_text,v as video};\n//# sourceMappingURL=zh-CN.js.map\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/zh-TW-CFo1-iyM.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/zh-TW-CFo1-iyM.js new file mode 100644 index 0000000000000000000000000000000000000000..a759afed973cbe079c6a7ee0e7783293fb293e4f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/zh-TW-CFo1-iyM.js @@ -0,0 +1,4 @@ +const o="繁體中文",e={built_with_gradio:"使用 Gradio 建構",clear:"清除",or:"或",submit:"提交",built_with:"使用",download:"下載",edit:"編輯",empty:"空白",error:"錯誤",hosted_on:"托管於",loading:"載入中",logo:"標誌",remove:"移除",settings:"設定",share:"分享",undo:"復原",no_devices:"未找到裝置",language:"語言",display_theme:"顯示主題",pwa:"漸進式網頁應用程式"},r={click_to_upload:"點擊上傳",drop_audio:"拖放音訊至此處",drop_csv:"拖放 CSV 至此處",drop_file:"拖放檔案至此處",drop_image:"拖放圖片至此處",drop_video:"拖放影片至此處",drop_gallery:"在此處拖放媒體",paste_clipboard:"從剪貼簿貼上"},t={annotated_image:"標註圖像"},a={allow_recording_access:"請允許存取麥克風以進行錄音。",audio:"音訊",drop_to_upload:"將音訊檔案拖放到這裡上傳",record_from_microphone:"從麥克風錄音",stop_recording:"停止錄製",no_device_support:"無法存取媒體裝置。請確認您正在使用安全來源(https)或本機主機(或您已提供有效的 SSL 憑證以進行 ssl_verify),並且已允許瀏覽器存取您的裝置。",stop:"停止",resume:"繼續",record:"錄製",no_microphone:"未找到麥克風",pause:"暫停",play:"播放",waiting:"等待中"},c={connection_can_break:"在行動裝置上,如果此分頁失去焦點或裝置進入睡眠模式,連線可能會中斷,導致您在隊列中的位置遺失。",long_requests_queue:"目前有許多待處理的請求。複製此 Space 以跳過隊列。",lost_connection:"因離開頁面而失去連接。正在重新加入隊列...",waiting_for_inputs:"等待檔案上傳完成,請稍後重試。"},_={checkbox:"核取方塊",checkbox_group:"核取方塊群組"},n={code:"程式碼"},d={color_picker:"顏色選擇器"},i={incorrect_format:"格式不正確,僅支援 CSV 和 TSV 檔案",new_column:"新增欄位",new_row:"新增列",add_row_above:"在上方新增列",add_row_below:"在下方新增列",delete_row:"刪除列",delete_column:"刪除欄位",add_column_left:"在左側新增欄位",add_column_right:"在右側新增欄位",sort_column:"排序欄位",sort_ascending:"升冪排序",sort_descending:"降冪排序",drop_to_upload:"將 CSV 或 TSV 檔案拖放到這裡以匯入資料到資料框中",clear_sort:"清除排序"},s={dropdown:"下拉選單"},l={build_error:"有建置錯誤",config_error:"有設定錯誤",contact_page_author:"請聯繫頁面的作者以通知他們。",no_app_file:"沒有應用程式檔案",runtime_error:"有執行時錯誤",space_not_working:'"Space 無法運作,因為" {0}',space_paused:"Space 已暫停",use_via_api:"透過 API 使用",use_via_api_or_mcp:"透過 API 或 MCP 使用"},p={uploading:"上傳中..."},u={highlighted_text:"醒目提示的文字"},g={allow_webcam_access:"請允許存取網路攝影機以進行錄製。",brush_color:"筆刷顏色",brush_radius:"筆刷大小",image:"圖像",remove_image:"移除圖片",select_brush_color:"選擇筆刷顏色",start_drawing:"開始繪圖",use_brush:"使用筆刷",drop_to_upload:"將圖像檔案拖放到這裡上傳"},m={label:"標籤"},b={enable_cookies:"如果您在無痕模式下訪問 HuggingFace Space,您必須啟用第三方 Cookie。",incorrect_credentials:"憑證錯誤",username:"使用者名稱",password:"密碼",login:"登入"},h={number:"數字"},w={plot:"圖表"},k={radio:"單選按鈕"},f={slider:"滑桿"},v={drop_to_upload:"將影片檔案拖放到這裡上傳"},S={edit:"編輯",retry:"重試",undo:"復原",submit:"送出",cancel:"取消",like:"讚",dislike:"不讚",clear:"清空對話"},x={_name:o,common:e,upload_text:r,"3D_model":{"3d_model":"3D 模型",drop_to_upload:"將 3D 模型 (.obj、.glb、.stl、.gltf、.splat 或 .ply) 檔案拖放到這裡上傳"},annotated_image:t,audio:a,blocks:c,checkbox:_,code:n,color_picker:d,dataframe:i,dropdown:s,errors:l,file:p,highlighted_text:u,image:g,label:m,login:b,number:h,plot:w,radio:k,slider:f,video:v,chatbot:S}; + +export { o as _name, t as annotated_image, a as audio, c as blocks, S as chatbot, _ as checkbox, n as code, d as color_picker, e as common, i as dataframe, x as default, s as dropdown, l as errors, p as file, u as highlighted_text, g as image, m as label, b as login, h as number, w as plot, k as radio, f as slider, r as upload_text, v as video }; +//# sourceMappingURL=zh-TW-CFo1-iyM.js.map diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/zh-TW-CFo1-iyM.js.map b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/zh-TW-CFo1-iyM.js.map new file mode 100644 index 0000000000000000000000000000000000000000..04957dc5a18225e3567546b5b75b2a472653b957 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/chunks/zh-TW-CFo1-iyM.js.map @@ -0,0 +1 @@ +{"version":3,"file":"zh-TW-CFo1-iyM.js","sources":["../../../../../../js/app/.svelte-kit/adapter-node/chunks/zh-TW.js"],"sourcesContent":["const o=\"繁體中文\",e={built_with_gradio:\"使用 Gradio 建構\",clear:\"清除\",or:\"或\",submit:\"提交\",built_with:\"使用\",download:\"下載\",edit:\"編輯\",empty:\"空白\",error:\"錯誤\",hosted_on:\"托管於\",loading:\"載入中\",logo:\"標誌\",remove:\"移除\",settings:\"設定\",share:\"分享\",undo:\"復原\",no_devices:\"未找到裝置\",language:\"語言\",display_theme:\"顯示主題\",pwa:\"漸進式網頁應用程式\"},r={click_to_upload:\"點擊上傳\",drop_audio:\"拖放音訊至此處\",drop_csv:\"拖放 CSV 至此處\",drop_file:\"拖放檔案至此處\",drop_image:\"拖放圖片至此處\",drop_video:\"拖放影片至此處\",drop_gallery:\"在此處拖放媒體\",paste_clipboard:\"從剪貼簿貼上\"},t={annotated_image:\"標註圖像\"},a={allow_recording_access:\"請允許存取麥克風以進行錄音。\",audio:\"音訊\",drop_to_upload:\"將音訊檔案拖放到這裡上傳\",record_from_microphone:\"從麥克風錄音\",stop_recording:\"停止錄製\",no_device_support:\"無法存取媒體裝置。請確認您正在使用安全來源(https)或本機主機(或您已提供有效的 SSL 憑證以進行 ssl_verify),並且已允許瀏覽器存取您的裝置。\",stop:\"停止\",resume:\"繼續\",record:\"錄製\",no_microphone:\"未找到麥克風\",pause:\"暫停\",play:\"播放\",waiting:\"等待中\"},c={connection_can_break:\"在行動裝置上,如果此分頁失去焦點或裝置進入睡眠模式,連線可能會中斷,導致您在隊列中的位置遺失。\",long_requests_queue:\"目前有許多待處理的請求。複製此 Space 以跳過隊列。\",lost_connection:\"因離開頁面而失去連接。正在重新加入隊列...\",waiting_for_inputs:\"等待檔案上傳完成,請稍後重試。\"},_={checkbox:\"核取方塊\",checkbox_group:\"核取方塊群組\"},n={code:\"程式碼\"},d={color_picker:\"顏色選擇器\"},i={incorrect_format:\"格式不正確,僅支援 CSV 和 TSV 檔案\",new_column:\"新增欄位\",new_row:\"新增列\",add_row_above:\"在上方新增列\",add_row_below:\"在下方新增列\",delete_row:\"刪除列\",delete_column:\"刪除欄位\",add_column_left:\"在左側新增欄位\",add_column_right:\"在右側新增欄位\",sort_column:\"排序欄位\",sort_ascending:\"升冪排序\",sort_descending:\"降冪排序\",drop_to_upload:\"將 CSV 或 TSV 檔案拖放到這裡以匯入資料到資料框中\",clear_sort:\"清除排序\"},s={dropdown:\"下拉選單\"},l={build_error:\"有建置錯誤\",config_error:\"有設定錯誤\",contact_page_author:\"請聯繫頁面的作者以通知他們。\",no_app_file:\"沒有應用程式檔案\",runtime_error:\"有執行時錯誤\",space_not_working:'\"Space 無法運作,因為\" {0}',space_paused:\"Space 已暫停\",use_via_api:\"透過 API 使用\",use_via_api_or_mcp:\"透過 API 或 MCP 使用\"},p={uploading:\"上傳中...\"},u={highlighted_text:\"醒目提示的文字\"},g={allow_webcam_access:\"請允許存取網路攝影機以進行錄製。\",brush_color:\"筆刷顏色\",brush_radius:\"筆刷大小\",image:\"圖像\",remove_image:\"移除圖片\",select_brush_color:\"選擇筆刷顏色\",start_drawing:\"開始繪圖\",use_brush:\"使用筆刷\",drop_to_upload:\"將圖像檔案拖放到這裡上傳\"},m={label:\"標籤\"},b={enable_cookies:\"如果您在無痕模式下訪問 HuggingFace Space,您必須啟用第三方 Cookie。\",incorrect_credentials:\"憑證錯誤\",username:\"使用者名稱\",password:\"密碼\",login:\"登入\"},h={number:\"數字\"},w={plot:\"圖表\"},k={radio:\"單選按鈕\"},f={slider:\"滑桿\"},v={drop_to_upload:\"將影片檔案拖放到這裡上傳\"},S={edit:\"編輯\",retry:\"重試\",undo:\"復原\",submit:\"送出\",cancel:\"取消\",like:\"讚\",dislike:\"不讚\",clear:\"清空對話\"},x={_name:o,common:e,upload_text:r,\"3D_model\":{\"3d_model\":\"3D 模型\",drop_to_upload:\"將 3D 模型 (.obj、.glb、.stl、.gltf、.splat 或 .ply) 檔案拖放到這裡上傳\"},annotated_image:t,audio:a,blocks:c,checkbox:_,code:n,color_picker:d,dataframe:i,dropdown:s,errors:l,file:p,highlighted_text:u,image:g,label:m,login:b,number:h,plot:w,radio:k,slider:f,video:v,chatbot:S};export{o as _name,t as annotated_image,a as audio,c as blocks,S as chatbot,_ as checkbox,n as code,d as color_picker,e as common,i as dataframe,x as default,s as dropdown,l as errors,p as file,u as highlighted_text,g as image,m as label,b as login,h as number,w as plot,k as radio,f as slider,r as upload_text,v as video};\n//# sourceMappingURL=zh-TW.js.map\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/index.js b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/index.js new file mode 100644 index 0000000000000000000000000000000000000000..5bbf94662af73a48cdba74b8fdd123595140e18a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio/templates/node/build/server/index.js @@ -0,0 +1,215 @@ +import { c as create_ssr_component, k as setContext, v as validate_component, m as missing_component } from './chunks/ssr-C3HYbsxA.js'; +import { a as afterUpdate } from './chunks/ssr-BO6k2UBO.js'; +import { c as c$1, r } from './chunks/index4-HDyePXPv.js'; +import { m as m$1, U as U$1, T, P, b, y, O as O$1, j, S } from './chunks/exports-Cu4i9J_Z.js'; +import { r as readable, w as writable } from './chunks/index-ClteBeTX.js'; +import './chunks/Component-NmRBwSfF.js'; + +let c="",m=c;const v={base:c,assets:m};function q$1(t){c=t.base,m=t.assets;}function B$1(){c=v.base,m=v.assets;}let G$1={},O={};function W(t){G$1=t;}function E(t){O=t;}const I$1=create_ssr_component((t,e,n,b)=>{let{stores:i}=e,{page:p}=e,{constructors:s}=e,{components:a=[]}=e,{form:l}=e,{data_0:d=null}=e,{data_1:f=null}=e;setContext("__svelte__",i),afterUpdate(i.page.notify);e.stores===void 0&&n.stores&&i!==void 0&&n.stores(i),e.page===void 0&&n.page&&p!==void 0&&n.page(p),e.constructors===void 0&&n.constructors&&s!==void 0&&n.constructors(s),e.components===void 0&&n.components&&a!==void 0&&n.components(a),e.form===void 0&&n.form&&l!==void 0&&n.form(l),e.data_0===void 0&&n.data_0&&d!==void 0&&n.data_0(d),e.data_1===void 0&&n.data_1&&f!==void 0&&n.data_1(f);let r,w,x=t.head;do r=!0,t.head=x,i.page.set(p),w=` ${s[1]?`${validate_component(s[0]||missing_component,"svelte:component").$$render(t,{data:d,this:a[0]},{this:o=>{a[0]=o,r=!1;}},{default:()=>`${validate_component(s[1]||missing_component,"svelte:component").$$render(t,{data:f,form:l,this:a[1]},{this:o=>{a[1]=o,r=!1;}},{})}`})}`:`${validate_component(s[0]||missing_component,"svelte:component").$$render(t,{data:d,form:l,this:a[0]},{this:o=>{a[0]=o,r=!1;}},{})}`} ${""}`;while(!r);return w});const D$1={app_dir:"_app",app_template_contains_nonce:!1,csp:{mode:"auto",directives:{"upgrade-insecure-requests":!1,"block-all-mixed-content":!1},reportOnly:{"upgrade-insecure-requests":!1,"block-all-mixed-content":!1}},csrf_check_origin:!0,embedded:!1,env_public_prefix:"PUBLIC_",env_private_prefix:"",hooks:null,preload_strategy:"modulepreload",root:I$1,service_worker:!1,templates:{app:({head:t,body:e,assets:n,nonce:b,env:i})=>` + + + + + + + + + + + + + + + + ", r.text) + try: + config = json.loads(result.group(1)) # type: ignore + except AttributeError as ae: + raise ValueError( + f"Could not get Gradio config from: {self.src}" + ) from ae + if "allow_flagging" in config: + raise ValueError( + "Gradio 2.x is not supported by this client. Please upgrade your Gradio app to Gradio 3.x or higher." + ) + return config + + def deploy_discord( + self, + discord_bot_token: str | None = None, + api_names: list[str | tuple[str, str]] | None = None, + to_id: str | None = None, + hf_token: str | None = None, + private: bool = False, + ): + """ + Deploy the upstream app as a discord bot. Currently only supports gr.ChatInterface. + Parameters: + discord_bot_token: This is the "password" needed to be able to launch the bot. Users can get a token by creating a bot app on the discord website. If run the method without specifying a token, the space will explain how to get one. See here: https://huggingface.co/spaces/freddyaboulton/test-discord-bot-v1. + api_names: The api_names of the app to turn into bot commands. This parameter currently has no effect as ChatInterface only has one api_name ('/chat'). + to_id: The name of the space hosting the discord bot. If None, the name will be gradio-discord-bot-{random-substring} + hf_token: HF api token with write priviledges in order to upload the files to HF space. Can be ommitted if logged in via the HuggingFace CLI, unless the upstream space is private. Obtain from: https://huggingface.co/settings/token + private: Whether the space hosting the discord bot is private. The visibility of the discord bot itself is set via the discord website. See https://huggingface.co/spaces/freddyaboulton/test-discord-bot-v1 + """ + warnings.warn( + "The 'deploy_discord' method will be removed in Gradio 6.0. " + "Please see the documentation on how to create a discord bot with Gradio: " + "https://www.gradio.app/guides/creating-a-discord-bot-from-a-gradio-app", + DeprecationWarning, + stacklevel=2, + ) + if self.config["mode"] == "chat_interface" and not api_names: + api_names = [("chat", "chat")] + + valid_list = isinstance(api_names, list) and ( + isinstance(n, str) + or ( + isinstance(n, tuple) and isinstance(n[0], str) and isinstance(n[1], str) + ) + for n in api_names + ) + if api_names is None or not valid_list: + raise ValueError( + f"Each entry in api_names must be either a string or a tuple of strings. Received {api_names}" + ) + if len(api_names) != 1: + raise ValueError("Currently only one api_name can be deployed to discord.") + + for i, name in enumerate(api_names): + if isinstance(name, str): + api_names[i] = (name, name) + + fn = next( + ( + ep + for ep in self.endpoints.values() + if ep.api_name == f"/{api_names[0][0]}" + ), + None, + ) + if not fn: + raise ValueError( + f"api_name {api_names[0][0]} not present in {self.space_id or self.src}" + ) + inputs = [inp for inp in fn.input_component_types if not inp.skip] + outputs = [inp for inp in fn.input_component_types if not inp.skip] + if not inputs == ["textbox"] and outputs == ["textbox"]: + raise ValueError( + "Currently only api_names with a single textbox as input and output are supported. " + f"Received {inputs} and {outputs}" + ) + + is_private = False + if self.space_id: + is_private = huggingface_hub.space_info(self.space_id).private + if is_private and not hf_token: + raise ValueError( + f"Since {self.space_id} is private, you must explicitly pass in hf_token " + "so that it can be added as a secret in the discord bot space." + ) + + if to_id: + if "/" in to_id: + to_id = to_id.split("/")[1] + space_id = huggingface_hub.get_full_repo_name(to_id, token=hf_token) + else: + if self.space_id: + space_id = f"{self.space_id.split('/')[1]}-gradio-discord-bot" + else: + space_id = f"gradio-discord-bot-{secrets.token_hex(4)}" + space_id = huggingface_hub.get_full_repo_name(space_id, token=hf_token) + + api = huggingface_hub.HfApi() + + try: + huggingface_hub.space_info(space_id) + first_upload = False + except huggingface_hub.utils.RepositoryNotFoundError: + first_upload = True + + huggingface_hub.create_repo( + space_id, + repo_type="space", + space_sdk="gradio", + token=hf_token, + exist_ok=True, + private=private, + ) + if first_upload: + huggingface_hub.metadata_update( + repo_id=space_id, + repo_type="space", + metadata={"tags": ["gradio-discord-bot"]}, + ) + + with open( + str(Path(__file__).parent / "templates" / "discord_chat.py"), + encoding="utf-8", + ) as f: + app = f.read() + app = app.replace("<>", self.src) + app = app.replace("<>", api_names[0][0]) + app = app.replace("<>", api_names[0][1]) + + with tempfile.NamedTemporaryFile( + mode="w", delete=False, encoding="utf-8" + ) as app_file: + with tempfile.NamedTemporaryFile(mode="w", delete=False) as requirements: + app_file.write(app) + requirements.write("\n".join(["discord.py==2.3.1"])) + + operations = [ + CommitOperationAdd(path_in_repo="app.py", path_or_fileobj=app_file.name), + CommitOperationAdd( + path_in_repo="requirements.txt", path_or_fileobj=requirements.name + ), + ] + + api.create_commit( + repo_id=space_id, + commit_message="Deploy Discord Bot", + repo_type="space", + operations=operations, + token=hf_token, + ) + + if discord_bot_token: + huggingface_hub.add_space_secret( + space_id, "DISCORD_TOKEN", discord_bot_token, token=hf_token + ) + if is_private: + huggingface_hub.add_space_secret( + space_id, + "HF_TOKEN", + hf_token, # type: ignore + token=hf_token, + ) + + url = f"https://huggingface.co/spaces/{space_id}" + print(f"See your discord bot here! {url}") + return url + + +@dataclass +class ComponentApiType: + skip: bool + value_is_file: bool + is_state: bool + + +@dataclass +class ReplaceMe: + index: int + + +class Endpoint: + """Helper class for storing all the information about a single API endpoint.""" + + def __init__( + self, client: Client, fn_index: int, dependency: dict, protocol: str = "sse_v1" + ): + self.client: Client = client + self.fn_index = fn_index + self.dependency = dependency + api_name = dependency.get("api_name") + self.api_name: str | Literal[False] | None = ( + "/" + api_name if isinstance(api_name, str) else api_name + ) + self._info = self.client._info + self.protocol = protocol + self.input_component_types = [ + self._get_component_type(id_) for id_ in dependency["inputs"] + ] + self.output_component_types = [ + self._get_component_type(id_) for id_ in dependency["outputs"] + ] + self.parameters_info = self._get_parameters_info() + self.root_url = self.client.src_prefixed + + # Disallow hitting endpoints that the Gradio app has disabled + self.is_valid = self.api_name is not False + self.backend_fn = dependency.get("backend_fn") + self.show_api = dependency.get("show_api") + + def _get_component_type(self, component_id: int): + component = next( + i for i in self.client.config["components"] if i["id"] == component_id + ) + skip_api = component.get("skip_api", component["type"] in utils.SKIP_COMPONENTS) + return ComponentApiType( + skip_api, + self.value_is_file(component), + component["type"] == "state", + ) + + def _get_parameters_info(self) -> list[ParameterInfo] | None: + if self.api_name in self._info["named_endpoints"]: + return self._info["named_endpoints"][self.api_name]["parameters"] + return None + + @staticmethod + def value_is_file(component: dict) -> bool: + # This is still hacky as it does not tell us which part of the payload is a file. + # If a component has a complex payload, part of which is a file, this will simply + # return True, which means that all parts of the payload will be uploaded as files + # if they are valid file paths. We will deprecate this 1.0. + if "api_info" not in component: + return False + return utils.value_is_file(component["api_info"]) + + def __repr__(self): + return f"Endpoint src: {self.client.src}, api_name: {self.api_name}, fn_index: {self.fn_index}" + + def __str__(self): + return self.__repr__() + + def make_end_to_end_fn(self, helper: Communicator): + _predict = self.make_predict(helper) + + def _inner(*data, **kwargs): + if not self.is_valid: + raise utils.InvalidAPIEndpointError() + + if self.client._skip_components: + data = self.insert_empty_state(*data) + data = self.process_input_files(*data) + predictions = _predict(*data, **kwargs) + predictions = self.process_predictions(*predictions) + + # Append final output only if not already present + # for consistency between generators and not generators + if helper: + with helper.lock: + if not helper.job.outputs: + helper.job.outputs.append(predictions) + return predictions + + return _inner + + def make_cancel( + self, + helper: Communicator | None, + ): + if helper is None: + return + if self.client.app_version > version.Version("4.29.0"): + url = urllib.parse.urljoin(self.client.src_prefixed, utils.CANCEL_URL) + + # The event_id won't be set on the helper until later + # so need to create the data in a function that's run at cancel time + def post_data(): + return { + "fn_index": self.fn_index, + "session_hash": self.client.session_hash, + "event_id": helper.event_id, + } + + cancel_msg = None + cancellable = True + else: + candidates: list[tuple[int, list[int]]] = [] + for i, dep in enumerate(self.client.config["dependencies"]): + if self.fn_index in dep["cancels"]: + candidates.append( + (i, [d for d in dep["cancels"] if d != self.fn_index]) + ) + + fn_index, other_cancelled = ( + min(candidates, key=lambda x: len(x[1])) if candidates else (None, None) + ) + cancellable = fn_index is not None + cancel_msg = None + if cancellable and other_cancelled: + other_api_names = [ + "/" + self.client.config["dependencies"][i].get("api_name") + for i in other_cancelled + ] + cancel_msg = ( + f"Cancelled this job will also cancel any jobs for {', '.join(other_api_names)} " + "that are currently running." + ) + elif not cancellable: + cancel_msg = ( + "Cancelling this job will not stop the server from running. " + "To fix this, an event must be added to the upstream app that explicitly cancels this one or " + "the upstream app must be running Gradio 4.29.0 and greater." + ) + + def post_data(): + return { + "data": [], + "fn_index": fn_index, + "session_hash": self.client.session_hash, + } + + url = self.client.api_url + + def _cancel(): + if cancel_msg: + warnings.warn(cancel_msg) + if cancellable: + httpx.post( + url, + json=post_data(), + headers=self.client.headers, + cookies=self.client.cookies, + verify=self.client.ssl_verify, + **self.client.httpx_kwargs, + ) + + return _cancel + + def make_predict(self, helper: Communicator): + def _predict(*data, **kwargs) -> tuple: + data = { + "data": data or [], + "fn_index": self.fn_index, + **kwargs, + } + + hash_data = { + "fn_index": self.fn_index, + "session_hash": kwargs.get("session_hash", self.client.session_hash), + } + + if self.protocol == "sse": + result = self._sse_fn_v0(data, hash_data, helper) # type: ignore + elif self.protocol in ("sse_v1", "sse_v2", "sse_v2.1", "sse_v3"): + event_id = self.client.send_data( + data, hash_data, self.protocol, helper.request_headers + ) + self.client.pending_event_ids.add(event_id) + self.client.pending_messages_per_event[event_id] = [] + helper.event_id = event_id + result = self._sse_fn_v1plus(helper, event_id, self.protocol) + else: + raise ValueError(f"Unsupported protocol: {self.protocol}") + + if "error" in result: + if result["error"] is None: + raise AppError( + "The upstream Gradio app has raised an exception but has not enabled " + "verbose error reporting. To enable, set show_error=True in launch()." + ) + else: + message = result.pop("error") + raise AppError(message=message, **result) + + try: + output = result["data"] + except KeyError as ke: + is_public_space = ( + self.client.space_id + and not huggingface_hub.space_info(self.client.space_id).private + ) + if "error" in result and "429" in result["error"] and is_public_space: + raise utils.TooManyRequestsError( + f"Too many requests to the API, please try again later. To avoid being rate-limited, " + f"please duplicate the Space using Client.duplicate({self.client.space_id}) " + f"and pass in your Hugging Face token." + ) from None + elif "error" in result: + raise ValueError(result["error"]) from None + raise KeyError( + f"Could not find 'data' key in response. Response received: {result}" + ) from ke + return tuple(output) + + return _predict + + def insert_empty_state(self, *data) -> tuple: + data = list(data) + for i, input_component_type in enumerate(self.input_component_types): + if input_component_type.is_state: + data.insert(i, None) + return tuple(data) + + def process_input_files(self, *data) -> tuple: + data_ = [] + for i, d in enumerate(data): + d = utils.traverse( + d, + partial(self._upload_file, data_index=i), + utils.is_file_obj_with_meta, + ) + data_.append(d) + return tuple(data_) + + def process_predictions(self, *predictions): + # If self.download_file is True, we assume that that the user is using the Client directly (as opposed + # within gr.load) and therefore, download any files generated by the server and skip values for + # components that the user likely does not want to see (e.g. gr.State, gr.Tab). + if self.client.download_files: + predictions = self.download_files(*predictions) + if self.client._skip_components: + predictions = self.remove_skipped_components(*predictions) + predictions = self.reduce_singleton_output(*predictions) + return predictions + + def download_files(self, *data) -> tuple: + data_ = list(data) + if self.client.protocol == "sse_v2.1": + data_ = utils.traverse( + data_, self._download_file, utils.is_file_obj_with_meta + ) + else: + data_ = utils.traverse(data_, self._download_file, utils.is_file_obj) + return tuple(data_) + + def remove_skipped_components(self, *data) -> tuple: + """""" + data = [ + d + for d, oct in zip(data, self.output_component_types, strict=False) + if not oct.skip + ] + return tuple(data) + + def reduce_singleton_output(self, *data) -> Any: + if self.client._skip_components: + effective_output_components = [ + o for o in self.output_component_types if not o.skip + ] + else: + effective_output_components = self.output_component_types + if len(effective_output_components) == 1: + return data[0] + else: + return data + + def _upload_file(self, f: dict, data_index: int) -> dict[str, str]: + file_path = f["path"] + orig_name = Path(file_path) + if not utils.is_http_url_like(file_path): + component_id = self.dependency["inputs"][data_index] + component_config = next( + ( + c + for c in self.client.config["components"] + if c["id"] == component_id + ), + {}, + ) + max_file_size = self.client.config.get("max_file_size", None) + max_file_size = math.inf if max_file_size is None else max_file_size + if os.path.getsize(file_path) > max_file_size: + raise ValueError( + f"File {file_path} exceeds the maximum file size of {max_file_size} bytes " + f"set in {component_config.get('label', '') + ''} component." + ) + with open(file_path, "rb") as f_: + files = [("files", (orig_name.name, f_))] + r = httpx.post( + self.client.upload_url, + headers=self.client.headers, + cookies=self.client.cookies, + verify=self.client.ssl_verify, + files=files, + **self.client.httpx_kwargs, + ) + r.raise_for_status() + result = r.json() + file_path = result[0] + # Only return orig_name if has a suffix because components + # use the suffix of the original name to determine format to save it to in cache. + return { + "path": file_path, + "orig_name": utils.strip_invalid_filename_characters(orig_name.name), + "meta": {"_type": "gradio.FileData"}, + } + + def _download_file(self, x: dict) -> str: + url_path = self.root_url + "file=" + x["path"] + if self.client.output_dir is not None: + os.makedirs(self.client.output_dir, exist_ok=True) + + sha = hashlib.sha256() + temp_dir = Path(tempfile.gettempdir()) / secrets.token_hex(20) + temp_dir.mkdir(exist_ok=True, parents=True) + + with httpx.stream( + "GET", + url_path, + headers=self.client.headers, + cookies=self.client.cookies, + verify=self.client.ssl_verify, + follow_redirects=True, + **self.client.httpx_kwargs, + ) as response: + response.raise_for_status() + with open(temp_dir / Path(url_path).name, "wb") as f: + for chunk in response.iter_bytes(chunk_size=128 * sha.block_size): + sha.update(chunk) + f.write(chunk) + + directory = Path(self.client.output_dir) / sha.hexdigest() + directory.mkdir(exist_ok=True, parents=True) + dest = directory / Path(url_path).name + shutil.move(temp_dir / Path(url_path).name, dest) + return str(dest.resolve()) + + def _sse_fn_v0(self, data: dict, hash_data: dict, helper: Communicator): + with httpx.Client( + timeout=httpx.Timeout(timeout=None), + verify=self.client.ssl_verify, + **self.client.httpx_kwargs, + ) as client: + return utils.get_pred_from_sse_v0( + client, + data, + hash_data, + helper, + self.client.sse_url, + self.client.sse_data_url, + self.client.headers, + self.client.cookies, + self.client.ssl_verify, + self.client.executor, + ) + + def _sse_fn_v1plus( + self, + helper: Communicator, + event_id: str, + protocol: Literal["sse_v1", "sse_v2", "sse_v2.1", "sse_v3"], + ): + return utils.get_pred_from_sse_v1plus( + helper, + self.client.headers, + self.client.cookies, + self.client.pending_messages_per_event, + event_id, + protocol, + self.client.ssl_verify, + self.client.executor, + ) + + +@document("result", "outputs", "status") +class Job(Future): + """ + A Job is a wrapper over the Future class that represents a prediction call that has been + submitted by the Gradio client. This class is not meant to be instantiated directly, but rather + is created by the Client.submit() method. + + A Job object includes methods to get the status of the prediction call, as well to get the outputs + of the prediction call. Job objects are also iterable, and can be used in a loop to get the outputs + of prediction calls as they become available for generator endpoints. + """ + + def __init__( + self, + future: Future, + communicator: Communicator | None = None, + verbose: bool = True, + space_id: str | None = None, + _cancel_fn: Callable[[], None] | None = None, + ): + """ + Parameters: + future: The future object that represents the prediction call, created by the Client.submit() method + communicator: The communicator object that is used to communicate between the client and the background thread running the job + verbose: Whether to print any status-related messages to the console + space_id: The space ID corresponding to the Client object that created this Job object + """ + self.future = future + self.communicator = communicator + self._counter = 0 + self.verbose = verbose + self.space_id = space_id + self.cancel_fn = _cancel_fn + + def __iter__(self) -> Job: + return self + + def __next__(self) -> tuple | Any: + if not self.communicator: + raise StopIteration() + + while True: + with self.communicator.lock: + if len(self.communicator.job.outputs) >= self._counter + 1: + o = self.communicator.job.outputs[self._counter] + self._counter += 1 + return o + if ( + self.communicator.job.latest_status.code == Status.FINISHED + and self._counter >= len(self.communicator.job.outputs) + ): + raise StopIteration() + time.sleep(0.001) + + async def __aiter__(self) -> AsyncGenerator[Update, None]: + """Async iterator that yields all updates from the communicator.updates queue.""" + if not self.communicator: + return + + while True: + get = self.communicator.updates.get() + try: + update = await asyncio.wait_for(get, timeout=0.5) + yield update + except asyncio.TimeoutError: + if self.done(): + return + continue + + def result(self, timeout: float | None = None) -> Any: + """ + Return the result of the call that the future represents. Raises CancelledError: If the future was cancelled, TimeoutError: If the future didn't finish executing before the given timeout, and Exception: If the call raised then that exception will be raised. + + Parameters: + timeout: The number of seconds to wait for the result if the future isn't done. If None, then there is no limit on the wait time. + Returns: + The result of the call that the future represents. For generator functions, it will return the final iteration. + Example: + from gradio_client import Client + calculator = Client(src="gradio/calculator") + job = calculator.submit("foo", "add", 4, fn_index=0) + job.result(timeout=5) + >> 9 + """ + return super().result(timeout=timeout) + + def outputs(self) -> list[tuple | Any]: + """ + Returns a list containing the latest outputs from the Job. + + If the endpoint has multiple output components, the list will contain + a tuple of results. Otherwise, it will contain the results without storing them + in tuples. + + For endpoints that are queued, this list will contain the final job output even + if that endpoint does not use a generator function. + + Example: + from gradio_client import Client + client = Client(src="gradio/count_generator") + job = client.submit(3, api_name="/count") + while not job.done(): + time.sleep(0.1) + job.outputs() + >> ['0', '1', '2'] + """ + if not self.communicator: + return [] + else: + with self.communicator.lock: + return self.communicator.job.outputs + + def status(self) -> StatusUpdate: + """ + Returns the latest status update from the Job in the form of a StatusUpdate + object, which contains the following fields: code, rank, queue_size, success, time, eta, and progress_data. + + progress_data is a list of updates emitted by the gr.Progress() tracker of the event handler. Each element + of the list has the following fields: index, length, unit, progress, desc. If the event handler does not have + a gr.Progress() tracker, the progress_data field will be None. + + Example: + from gradio_client import Client + client = Client(src="gradio/calculator") + job = client.submit(5, "add", 4, api_name="/predict") + job.status() + >> + job.status().eta + >> 43.241 # seconds + """ + time = datetime.now() + cancelled = False + if self.communicator: + with self.communicator.lock: + cancelled = self.communicator.should_cancel + if cancelled: + return StatusUpdate( + code=Status.CANCELLED, + rank=0, + queue_size=None, + success=False, + time=time, + eta=None, + progress_data=None, + ) + if self.done(): + if not self.future._exception: # type: ignore + return StatusUpdate( + code=Status.FINISHED, + rank=0, + queue_size=None, + success=True, + time=time, + eta=None, + progress_data=None, + ) + else: + return StatusUpdate( + code=Status.FINISHED, + rank=0, + queue_size=None, + success=False, + time=time, + eta=None, + progress_data=None, + ) + elif not self.communicator: + return StatusUpdate( + code=Status.PROCESSING, + rank=0, + queue_size=None, + success=None, + time=time, + eta=None, + progress_data=None, + ) + else: + with self.communicator.lock: + eta = self.communicator.job.latest_status.eta + if self.verbose and self.space_id and eta and eta > 30: + print( + f"Due to heavy traffic on this app, the prediction will take approximately {int(eta)} seconds." + f"For faster predictions without waiting in queue, you may duplicate the space using: Client.duplicate({self.space_id})" + ) + return self.communicator.job.latest_status + + def cancel(self) -> bool: + """Cancels the job as best as possible. + + If the app you are connecting to has the gradio queue enabled, the job + will be cancelled locally as soon as possible. For apps that do not use the + queue, the job cannot be cancelled if it's been sent to the local executor + (for the time being). + + Note: In general, this DOES not stop the process from running in the upstream server + except for the following situations: + + 1. If the job is queued upstream, it will be removed from the queue and the server will not run the job + 2. If the job has iterative outputs, the job will finish as soon as the current iteration finishes running + 3. If the job has not been picked up by the queue yet, the queue will not pick up the job + """ + if self.communicator: + with self.communicator.lock: + self.communicator.should_cancel = True + if self.cancel_fn: + self.cancel_fn() + return True + return self.future.cancel() + + def __getattr__(self, name): + """Forwards any properties to the Future class.""" + return getattr(self.future, name) diff --git a/.venv/lib/python3.13/site-packages/gradio_client/compatibility.py b/.venv/lib/python3.13/site-packages/gradio_client/compatibility.py new file mode 100644 index 0000000000000000000000000000000000000000..8348cf0c191a8f494ee0b425a87d416ee04d770d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio_client/compatibility.py @@ -0,0 +1,341 @@ +"""This module contains the EndpointV3Compatibility class, which is used to connect to Gradio apps running 3.x.x versions of Gradio.""" + +from __future__ import annotations + +import json +from pathlib import Path +from typing import TYPE_CHECKING, Any, Literal + +import httpx +import huggingface_hub +import websockets +from packaging import version + +from gradio_client import serializing, utils +from gradio_client.exceptions import SerializationSetupError +from gradio_client.utils import ( + Communicator, +) + +if TYPE_CHECKING: + from gradio_client import Client + + +class EndpointV3Compatibility: + """Endpoint class for connecting to v3 endpoints. Backwards compatibility.""" + + def __init__(self, client: Client, fn_index: int, dependency: dict, *_args): + self.client: Client = client + self.fn_index = fn_index + self.dependency = dependency + api_name = dependency.get("api_name") + self.api_name: str | Literal[False] | None = ( + "/" + api_name if isinstance(api_name, str) else api_name + ) + self.use_ws = self._use_websocket(self.dependency) + self.protocol = "ws" if self.use_ws else "http" + self.input_component_types = [] + self.output_component_types = [] + self.root_url = client.src + "/" if not client.src.endswith("/") else client.src + try: + # Only a real API endpoint if backend_fn is True (so not just a frontend function), serializers are valid, + # and api_name is not False (meaning that the developer has explicitly disabled the API endpoint) + self.serializers, self.deserializers = self._setup_serializers() + self.is_valid = self.dependency["backend_fn"] and self.api_name is not False + except SerializationSetupError: + self.is_valid = False + self.backend_fn = dependency.get("backend_fn") + self.show_api = True + + def __repr__(self): + return f"Endpoint src: {self.client.src}, api_name: {self.api_name}, fn_index: {self.fn_index}" + + def __str__(self): + return self.__repr__() + + def make_end_to_end_fn(self, helper: Communicator | None = None): + _predict = self.make_predict(helper) + + def _inner(*data): + if not self.is_valid: + raise utils.InvalidAPIEndpointError() + data = self.insert_state(*data) + data = self.serialize(*data) + predictions = _predict(*data) + predictions = self.process_predictions(*predictions) + # Append final output only if not already present + # for consistency between generators and not generators + if helper: + with helper.lock: + if not helper.job.outputs: + helper.job.outputs.append(predictions) + return predictions + + return _inner + + def make_cancel(self, helper: Communicator | None = None): # noqa: ARG002 (needed so that both endpoints classes have the same api) + return None + + def make_predict(self, helper: Communicator | None = None): + def _predict(*data) -> tuple: + data = json.dumps( + { + "data": data, + "fn_index": self.fn_index, + "session_hash": self.client.session_hash, + } + ) + hash_data = json.dumps( + { + "fn_index": self.fn_index, + "session_hash": self.client.session_hash, + } + ) + if self.use_ws: + result = utils.synchronize_async(self._ws_fn, data, hash_data, helper) + if "error" in result: + raise ValueError(result["error"]) + else: + response = httpx.post( + self.client.api_url, + headers=self.client.headers, + json=data, + verify=self.client.ssl_verify, + **self.client.httpx_kwargs, + ) + result = json.loads(response.content.decode("utf-8")) + try: + output = result["data"] + except KeyError as ke: + is_public_space = ( + self.client.space_id + and not huggingface_hub.space_info(self.client.space_id).private + ) + if "error" in result and "429" in result["error"] and is_public_space: + raise utils.TooManyRequestsError( + f"Too many requests to the API, please try again later. To avoid being rate-limited, " + f"please duplicate the Space using Client.duplicate({self.client.space_id}) " + f"and pass in your Hugging Face token." + ) from None + elif "error" in result: + raise ValueError(result["error"]) from None + raise KeyError( + f"Could not find 'data' key in response. Response received: {result}" + ) from ke + return tuple(output) + + return _predict + + def _predict_resolve(self, *data) -> Any: + """Needed for gradio.load(), which has a slightly different signature for serializing/deserializing""" + outputs = self.make_predict()(*data) + if len(self.dependency["outputs"]) == 1: + return outputs[0] + return outputs + + def _upload( + self, file_paths: list[str | list[str]] + ) -> list[str | list[str]] | list[dict[str, Any] | list[dict[str, Any]]]: + if not file_paths: + return [] + # Put all the filepaths in one file + # but then keep track of which index in the + # original list they came from so we can recreate + # the original structure + files = [] + indices = [] + for i, fs in enumerate(file_paths): + if not isinstance(fs, list): + fs = [fs] + for f in fs: + files.append(("files", (Path(f).name, open(f, "rb")))) # noqa: SIM115 + indices.append(i) + r = httpx.post( + self.client.upload_url, + headers=self.client.headers, + files=files, + verify=self.client.ssl_verify, + **self.client.httpx_kwargs, + ) + if r.status_code != 200: + uploaded = file_paths + else: + uploaded = [] + result = r.json() + for i, fs in enumerate(file_paths): + if isinstance(fs, list): + output = [o for ix, o in enumerate(result) if indices[ix] == i] + res = [ + { + "is_file": True, + "name": o, + "orig_name": Path(f).name, + "data": None, + } + for f, o in zip(fs, output, strict=False) + ] + else: + o = next(o for ix, o in enumerate(result) if indices[ix] == i) + res = { + "is_file": True, + "name": o, + "orig_name": Path(fs).name, + "data": None, + } + uploaded.append(res) + return uploaded + + def _add_uploaded_files_to_data( + self, + files: list[str | list[str]] | list[dict[str, Any] | list[dict[str, Any]]], + data: list[Any], + ) -> None: + """Helper function to modify the input data with the uploaded files.""" + file_counter = 0 + for i, t in enumerate(self.input_component_types): + if t in ["file", "uploadbutton"]: + data[i] = files[file_counter] + file_counter += 1 + + def insert_state(self, *data) -> tuple: + data = list(data) + for i, input_component_type in enumerate(self.input_component_types): + if input_component_type == utils.STATE_COMPONENT: + data.insert(i, None) + return tuple(data) + + def remove_skipped_components(self, *data) -> tuple: + data = [ + d + for d, oct in zip(data, self.output_component_types, strict=False) + if oct not in utils.SKIP_COMPONENTS + ] + return tuple(data) + + def reduce_singleton_output(self, *data) -> Any: + if ( + len( + [ + oct + for oct in self.output_component_types + if oct not in utils.SKIP_COMPONENTS + ] + ) + == 1 + ): + return data[0] + else: + return data + + def serialize(self, *data) -> tuple: + if len(data) != len(self.serializers): + raise ValueError( + f"Expected {len(self.serializers)} arguments, got {len(data)}" + ) + + files = [ + f + for f, t in zip(data, self.input_component_types, strict=False) + if t in ["file", "uploadbutton"] + ] + uploaded_files = self._upload(files) + data = list(data) + self._add_uploaded_files_to_data(uploaded_files, data) + o = tuple( + [s.serialize(d) for s, d in zip(self.serializers, data, strict=False)] + ) + return o + + def deserialize(self, *data) -> tuple: + if len(data) != len(self.deserializers): + raise ValueError( + f"Expected {len(self.deserializers)} outputs, got {len(data)}" + ) + outputs = tuple( + [ + s.deserialize( + d, + save_dir=self.client.output_dir, + hf_token=self.client.hf_token, + root_url=self.root_url, + ) + for s, d in zip(self.deserializers, data, strict=False) + ] + ) + return outputs + + def process_predictions(self, *predictions): + if self.client.download_files: + predictions = self.deserialize(*predictions) + predictions = self.remove_skipped_components(*predictions) + predictions = self.reduce_singleton_output(*predictions) + return predictions + + def _setup_serializers( + self, + ) -> tuple[list[serializing.Serializable], list[serializing.Serializable]]: + inputs = self.dependency["inputs"] + serializers = [] + + for i in inputs: + for component in self.client.config["components"]: + if component["id"] == i: + component_name = component["type"] + self.input_component_types.append(component_name) + if component.get("serializer"): + serializer_name = component["serializer"] + if serializer_name not in serializing.SERIALIZER_MAPPING: + raise SerializationSetupError( + f"Unknown serializer: {serializer_name}, you may need to update your gradio_client version." + ) + serializer = serializing.SERIALIZER_MAPPING[serializer_name] + elif component_name in serializing.COMPONENT_MAPPING: + serializer = serializing.COMPONENT_MAPPING[component_name] + else: + raise SerializationSetupError( + f"Unknown component: {component_name}, you may need to update your gradio_client version." + ) + serializers.append(serializer()) # type: ignore + + outputs = self.dependency["outputs"] + deserializers = [] + for i in outputs: + for component in self.client.config["components"]: + if component["id"] == i: + component_name = component["type"] + self.output_component_types.append(component_name) + if component.get("serializer"): + serializer_name = component["serializer"] + if serializer_name not in serializing.SERIALIZER_MAPPING: + raise SerializationSetupError( + f"Unknown serializer: {serializer_name}, you may need to update your gradio_client version." + ) + deserializer = serializing.SERIALIZER_MAPPING[serializer_name] + elif component_name in utils.SKIP_COMPONENTS: + deserializer = serializing.SimpleSerializable + elif component_name in serializing.COMPONENT_MAPPING: + deserializer = serializing.COMPONENT_MAPPING[component_name] + else: + raise SerializationSetupError( + f"Unknown component: {component_name}, you may need to update your gradio_client version." + ) + deserializers.append(deserializer()) # type: ignore + + return serializers, deserializers + + def _use_websocket(self, dependency: dict) -> bool: + queue_enabled = self.client.config.get("enable_queue", False) + queue_uses_websocket = version.parse( + self.client.config.get("version", "2.0") + ) >= version.Version("3.2") + dependency_uses_queue = dependency.get("queue", False) is not False + return queue_enabled and queue_uses_websocket and dependency_uses_queue + + async def _ws_fn(self, data, hash_data, helper: Communicator): + async with websockets.connect( # type: ignore + self.client.ws_url, + open_timeout=10, + extra_headers=self.client.headers, + max_size=1024 * 1024 * 1024, + ) as websocket: + return await utils.get_pred_from_ws(websocket, data, hash_data, helper) diff --git a/.venv/lib/python3.13/site-packages/gradio_client/data_classes.py b/.venv/lib/python3.13/site-packages/gradio_client/data_classes.py new file mode 100644 index 0000000000000000000000000000000000000000..267be1ebc8174838ae783d727438798f5e5a70fb --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio_client/data_classes.py @@ -0,0 +1,28 @@ +from __future__ import annotations + +from typing import Any, TypedDict + +from typing_extensions import NotRequired + + +class FileData(TypedDict): + name: str | None # filename + data: str | None # base64 encoded data + size: NotRequired[int | None] # size in bytes + is_file: NotRequired[ + bool + ] # whether the data corresponds to a file or base64 encoded data + orig_name: NotRequired[str] # original filename + mime_type: NotRequired[str] + is_stream: NotRequired[bool] + + +class ParameterInfo(TypedDict): + label: str + parameter_name: str + parameter_has_default: NotRequired[bool] + parameter_default: NotRequired[Any] + type: dict + python_type: dict + component: str + example_input: Any diff --git a/.venv/lib/python3.13/site-packages/gradio_client/documentation.py b/.venv/lib/python3.13/site-packages/gradio_client/documentation.py new file mode 100644 index 0000000000000000000000000000000000000000..f21234ed650ca4090209e9bd78cd26224cfdce7b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio_client/documentation.py @@ -0,0 +1,354 @@ +"""Contains methods that generate documentation for Gradio functions and classes.""" + +from __future__ import annotations + +import dataclasses +import inspect +import warnings +from collections import defaultdict +from collections.abc import Callable +from functools import lru_cache + +classes_to_document = defaultdict(list) +classes_inherit_documentation = {} + + +def set_documentation_group(m): # noqa: ARG001 + """A no-op for backwards compatibility of custom components published prior to 4.16.0""" + pass + + +def extract_instance_attr_doc(cls, attr): + code = inspect.getsource(cls.__init__) + lines = [line.strip() for line in code.split("\n")] + i = None + for i, line in enumerate(lines): # noqa: B007 + if line.startswith("self." + attr + ":") or line.startswith( + "self." + attr + " =" + ): + break + if i is None: + raise NameError(f"Could not find {attr} in {cls.__name__}") + start_line = lines.index('"""', i) + end_line = lines.index('"""', start_line + 1) + for j in range(i + 1, start_line): + if lines[j].startswith("self."): + raise ValueError( + f"Found another attribute before docstring for {attr} in {cls.__name__}: " + + lines[j] + + "\n start:" + + lines[i] + ) + doc_string = " ".join(lines[start_line + 1 : end_line]) + return doc_string + + +_module_prefixes = [ + ("gradio._simple_templates", "component"), + ("gradio.block", "block"), + ("gradio.chat", "chatinterface"), + ("gradio.component", "component"), + ("gradio.events", "helpers"), + ("gradio.data_classes", "helpers"), + ("gradio.exceptions", "helpers"), + ("gradio.external", "helpers"), + ("gradio.flag", "flagging"), + ("gradio.helpers", "helpers"), + ("gradio.interface", "interface"), + ("gradio.layout", "layout"), + ("gradio.route", "routes"), + ("gradio.theme", "themes"), + ("gradio_client.", "py-client"), + ("gradio.utils", "helpers"), + ("gradio.renderable", "renderable"), +] + + +@lru_cache(maxsize=10) +def _get_module_documentation_group(modname) -> str: + for prefix, group in _module_prefixes: + if modname.startswith(prefix): + return group + raise ValueError(f"No known documentation group for module {modname!r}") + + +def document(*fns, inherit=False, documentation_group=None): + """ + Defines the @document decorator which adds classes or functions to the Gradio + documentation at www.gradio.app/docs. + + Usage examples: + - Put @document() above a class to document the class and its constructor. + - Put @document("fn1", "fn2") above a class to also document methods fn1 and fn2. + - Put @document("*fn3") with an asterisk above a class to document the instance attribute methods f3. + """ + _documentation_group = documentation_group + + def inner_doc(cls): + functions = list(fns) + if hasattr(cls, "EVENTS"): + functions += cls.EVENTS + if inherit: + classes_inherit_documentation[cls] = None + + documentation_group = _documentation_group # avoid `nonlocal` reassignment + if _documentation_group is None: + try: + modname = inspect.getmodule(cls).__name__ # type: ignore + if modname.startswith("gradio.") or modname.startswith( + "gradio_client." + ): + documentation_group = _get_module_documentation_group(modname) + else: + # Then this is likely a custom Gradio component that we do not include in the documentation + pass + except Exception as exc: + warnings.warn(f"Could not get documentation group for {cls}: {exc}") + classes_to_document[documentation_group].append((cls, functions)) + return cls + + return inner_doc + + +def document_fn(fn: Callable, cls) -> tuple[str, list[dict], dict, str | None]: + """ + Generates documentation for any function. + Parameters: + fn: Function to document + Returns: + description: General description of fn + parameters: A list of dicts for each parameter, storing data for the parameter name, annotation and doc + return: A dict storing data for the returned annotation and doc + example: Code for an example use of the fn + """ + doc_str = inspect.getdoc(fn) or "" + doc_lines = doc_str.split("\n") + signature = inspect.signature(fn) + description, parameters, returns, examples = [], {}, [], [] + mode = "description" + for line in doc_lines: + line = line.rstrip() + if line == "Parameters:": + mode = "parameter" + elif line.startswith("Example:"): + mode = "example" + if "(" in line and ")" in line: + c = line.split("(")[1].split(")")[0] + if c != cls.__name__: + mode = "ignore" + elif line == "Returns:": + mode = "return" + else: + if mode == "description": + description.append(line if line.strip() else "
") + continue + if not (line.startswith(" ") or line.strip() == ""): + print(line) + if not (line.startswith(" ") or line.strip() == ""): + raise SyntaxError( + f"Documentation format for {fn.__name__} has format error in line: {line}" + ) + line = line[4:] + if mode == "parameter": + colon_index = line.index(": ") + if colon_index < -1: + raise SyntaxError( + f"Documentation format for {fn.__name__} has format error in line: {line}" + ) + parameter = line[:colon_index] + parameter_doc = line[colon_index + 2 :] + parameters[parameter] = parameter_doc + elif mode == "return": + returns.append(line) + elif mode == "example": + examples.append(line) + description_doc = " ".join(description) + parameter_docs = [] + for param_name, param in signature.parameters.items(): + if param_name.startswith("_"): + continue + if param_name == "self": + continue + if param_name in ["kwargs", "args"] and param_name not in parameters: + continue + parameter_doc = { + "name": param_name, + "annotation": param.annotation, + "doc": parameters.get(param_name), + } + if param_name in parameters: + del parameters[param_name] + if param.default != inspect.Parameter.empty: + default = param.default + if isinstance(default, str): + default = '"' + default + '"' + if default.__class__.__module__ != "builtins": + default = f"{default.__class__.__name__}()" + parameter_doc["default"] = default + elif parameter_doc["doc"] is not None: + if "kwargs" in parameter_doc["doc"]: + parameter_doc["kwargs"] = True + if "args" in parameter_doc["doc"]: + parameter_doc["args"] = True + parameter_docs.append(parameter_doc) + if parameters: + raise ValueError( + f"Documentation format for {fn.__name__} documents " + f"nonexistent parameters: {', '.join(parameters.keys())}. " + f"Valid parameters: {', '.join(signature.parameters.keys())}" + ) + if len(returns) == 0: + return_docs = {} + elif len(returns) == 1: + return_docs = {"annotation": signature.return_annotation, "doc": returns[0]} + else: + return_docs = {} + # raise ValueError("Does not support multiple returns yet.") + examples_doc = "\n".join(examples) if len(examples) > 0 else None + return description_doc, parameter_docs, return_docs, examples_doc + + +def document_cls(cls): + doc_str = inspect.getdoc(cls) + if doc_str is None: + return "", {}, "" + tags = {} + description_lines = [] + mode = "description" + for line in doc_str.split("\n"): + line = line.rstrip() + if line.endswith(":") and " " not in line: + mode = line[:-1].lower() + tags[mode] = [] + elif line.split(" ")[0].endswith(":") and not line.startswith(" "): + tag = line[: line.index(":")].lower() + value = line[line.index(":") + 2 :] + tags[tag] = value + elif mode == "description": + description_lines.append(line if line.strip() else "
") + else: + if not (line.startswith(" ") or not line.strip()): + raise SyntaxError( + f"Documentation format for {cls.__name__} has format error in line: {line}" + ) + tags[mode].append(line[4:]) + if "example" in tags: + example = "\n".join(tags["example"]) + del tags["example"] + else: + example = None + for key, val in tags.items(): + if isinstance(val, list): + tags[key] = "
".join(val) + description = " ".join(description_lines).replace("\n", "
") + return description, tags, example + + +def generate_documentation(): + documentation = {} + for mode, class_list in classes_to_document.items(): + documentation[mode] = [] + for cls, fns in class_list: + fn_to_document = ( + cls + if inspect.isfunction(cls) or dataclasses.is_dataclass(cls) + else cls.__init__ + ) + _, parameter_doc, return_doc, _ = document_fn(fn_to_document, cls) + if ( + hasattr(cls, "preprocess") + and callable(cls.preprocess) # type: ignore + and hasattr(cls, "postprocess") + and callable(cls.postprocess) # type: ignore + ): + preprocess_doc = document_fn(cls.preprocess, cls) # type: ignore + postprocess_doc = document_fn(cls.postprocess, cls) # type: ignore + preprocess_doc, postprocess_doc = ( + { + "parameter_doc": preprocess_doc[1], + "return_doc": preprocess_doc[2], + }, + { + "parameter_doc": postprocess_doc[1], + "return_doc": postprocess_doc[2], + }, + ) + cls_description, cls_tags, cls_example = document_cls(cls) + cls_documentation = { + "class": cls, + "name": cls.__name__, + "description": cls_description, + "tags": cls_tags, + "parameters": parameter_doc, + "returns": return_doc, + "example": cls_example, + "fns": [], + } + if ( + hasattr(cls, "preprocess") + and callable(cls.preprocess) # type: ignore + and hasattr(cls, "postprocess") + and callable(cls.postprocess) # type: ignore + ): + cls_documentation["preprocess"] = preprocess_doc # type: ignore + cls_documentation["postprocess"] = postprocess_doc # type: ignore + for fn_name in fns: + instance_attribute_fn = fn_name.startswith("*") + if instance_attribute_fn: + fn_name = fn_name[1:] + # Instance attribute fns are classes + # whose __call__ method determines their behavior + fn = getattr(cls(), fn_name).__call__ + else: + fn = getattr(cls, fn_name) + if not callable(fn): + description_doc = str(fn) + parameter_docs = {} + return_docs = {} + examples_doc = "" + override_signature = f"gr.{cls.__name__}.{fn_name}" + else: + ( + description_doc, + parameter_docs, + return_docs, + examples_doc, + ) = document_fn(fn, cls) + if fn_name in getattr(cls, "EVENTS", []): + parameter_docs = parameter_docs[1:] + override_signature = None + if instance_attribute_fn: + description_doc = extract_instance_attr_doc(cls, fn_name) + cls_documentation["fns"].append( + { + "fn": fn, + "name": fn_name, + "description": description_doc, + "tags": {}, + "parameters": parameter_docs, + "returns": return_docs, + "example": examples_doc, + "override_signature": override_signature, + } + ) + documentation[mode].append(cls_documentation) + if cls in classes_inherit_documentation: + classes_inherit_documentation[cls] = cls_documentation["fns"] + for mode, class_list in classes_to_document.items(): + for i, (cls, _) in enumerate(class_list): + for super_class, fns in classes_inherit_documentation.items(): + if ( + inspect.isclass(cls) + and issubclass(cls, super_class) + and cls != super_class + ): + for inherited_fn in fns: + inherited_fn = dict(inherited_fn) + try: + inherited_fn["description"] = extract_instance_attr_doc( + cls, inherited_fn["name"] + ) + except ValueError: + pass + documentation[mode][i]["fns"].append(inherited_fn) + return documentation diff --git a/.venv/lib/python3.13/site-packages/gradio_client/exceptions.py b/.venv/lib/python3.13/site-packages/gradio_client/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..961a7504a484b7fe53b95c43c2c8278ec59d52f9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio_client/exceptions.py @@ -0,0 +1,43 @@ +class SerializationSetupError(ValueError): + """Raised when a serializers cannot be set up correctly.""" + + pass + + +class AuthenticationError(ValueError): + """Raised when the client is unable to authenticate itself to a Gradio app due to invalid or missing credentials.""" + + pass + + +class ValidationError(ValueError): + """Raised when the data that is passed into the Gradio app fails developer-defined validation.""" + + pass + + +class AppError(ValueError): + """Raised when the upstream Gradio app throws an error because of the value submitted by the client.""" + + def __init__( + self, + message: str = "Error raised.", + duration: float | None = 10, + visible: bool = True, + title: str = "Error", + print_exception: bool = True, + ): + """ + Parameters: + message: The error message to be displayed to the user. Can be HTML, which will be rendered in the modal. + duration: The duration in seconds to display the error message. If None or 0, the error message will be displayed until the user closes it. + visible: Whether the error message should be displayed in the UI. + title: The title to be displayed to the user at the top of the error modal. + print_exception: Whether to print traceback of the error to the console when the error is raised. + """ + self.title = title + self.message = message + self.duration = duration + self.visible = visible + self.print_exception = print_exception + super().__init__(self.message) diff --git a/.venv/lib/python3.13/site-packages/gradio_client/media_data.py b/.venv/lib/python3.13/site-packages/gradio_client/media_data.py new file mode 100644 index 0000000000000000000000000000000000000000..ee63e899b65c7a6d0cadb6105cac797668dbe56e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio_client/media_data.py @@ -0,0 +1,8659 @@ +from pathlib import Path + +_REPO_ROOT = Path(__file__).parents[3] + +BASE64_IMAGE = ( # test/test_files/bus.png + "data:image/png;base64," + "R0lGODlhPQBEAPeoAJosM//AwO/AwHVYZ/z595kzAP/s7P+goOXMv8+fhw/v739/f+8PD98fH/8mJl+fn/9ZWb8/PzWlwv///6wWGbImAPgTEMImIN9gUFCEm/gDALULDN8PAD6atYdCTX9gUNKlj8wZAKUsAOzZz+UMAOsJAP/Z2ccMDA8PD/95eX5NWvsJCOVNQPtfX/8zM8+QePLl38MGBr8JCP+zs9myn/8GBqwpAP/GxgwJCPny78lzYLgjAJ8vAP9fX/+MjMUcAN8zM/9wcM8ZGcATEL+QePdZWf/29uc/P9cmJu9MTDImIN+/r7+/vz8/P8VNQGNugV8AAF9fX8swMNgTAFlDOICAgPNSUnNWSMQ5MBAQEJE3QPIGAM9AQMqGcG9vb6MhJsEdGM8vLx8fH98AANIWAMuQeL8fABkTEPPQ0OM5OSYdGFl5jo+Pj/+pqcsTE78wMFNGQLYmID4dGPvd3UBAQJmTkP+8vH9QUK+vr8ZWSHpzcJMmILdwcLOGcHRQUHxwcK9PT9DQ0O/v70w5MLypoG8wKOuwsP/g4P/Q0IcwKEswKMl8aJ9fX2xjdOtGRs/Pz+Dg4GImIP8gIH0sKEAwKKmTiKZ8aB/f39Wsl+LFt8dgUE9PT5x5aHBwcP+AgP+WltdgYMyZfyywz78AAAAAAAD///8AAP9mZv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAKgALAAAAAA9AEQAAAj/AFEJHEiwoMGDCBMqXMiwocAbBww4nEhxoYkUpzJGrMixogkfGUNqlNixJEIDB0SqHGmyJSojM1bKZOmyop0gM3Oe2liTISKMOoPy7GnwY9CjIYcSRYm0aVKSLmE6nfq05QycVLPuhDrxBlCtYJUqNAq2bNWEBj6ZXRuyxZyDRtqwnXvkhACDV+euTeJm1Ki7A73qNWtFiF+/gA95Gly2CJLDhwEHMOUAAuOpLYDEgBxZ4GRTlC1fDnpkM+fOqD6DDj1aZpITp0dtGCDhr+fVuCu3zlg49ijaokTZTo27uG7Gjn2P+hI8+PDPERoUB318bWbfAJ5sUNFcuGRTYUqV/3ogfXp1rWlMc6awJjiAAd2fm4ogXjz56aypOoIde4OE5u/F9x199dlXnnGiHZWEYbGpsAEA3QXYnHwEFliKAgswgJ8LPeiUXGwedCAKABACCN+EA1pYIIYaFlcDhytd51sGAJbo3onOpajiihlO92KHGaUXGwWjUBChjSPiWJuOO/LYIm4v1tXfE6J4gCSJEZ7YgRYUNrkji9P55sF/ogxw5ZkSqIDaZBV6aSGYq/lGZplndkckZ98xoICbTcIJGQAZcNmdmUc210hs35nCyJ58fgmIKX5RQGOZowxaZwYA+JaoKQwswGijBV4C6SiTUmpphMspJx9unX4KaimjDv9aaXOEBteBqmuuxgEHoLX6Kqx+yXqqBANsgCtit4FWQAEkrNbpq7HSOmtwag5w57GrmlJBASEU18ADjUYb3ADTinIttsgSB1oJFfA63bduimuqKB1keqwUhoCSK374wbujvOSu4QG6UvxBRydcpKsav++Ca6G8A6Pr1x2kVMyHwsVxUALDq/krnrhPSOzXG1lUTIoffqGR7Goi2MAxbv6O2kEG56I7CSlRsEFKFVyovDJoIRTg7sugNRDGqCJzJgcKE0ywc0ELm6KBCCJo8DIPFeCWNGcyqNFE06ToAfV0HBRgxsvLThHn1oddQMrXj5DyAQgjEHSAJMWZwS3HPxT/QMbabI/iBCliMLEJKX2EEkomBAUCxRi42VDADxyTYDVogV+wSChqmKxEKCDAYFDFj4OmwbY7bDGdBhtrnTQYOigeChUmc1K3QTnAUfEgGFgAWt88hKA6aCRIXhxnQ1yg3BCayK44EWdkUQcBByEQChFXfCB776aQsG0BIlQgQgE8qO26X1h8cEUep8ngRBnOy74E9QgRgEAC8SvOfQkh7FDBDmS43PmGoIiKUUEGkMEC/PJHgxw0xH74yx/3XnaYRJgMB8obxQW6kL9QYEJ0FIFgByfIL7/IQAlvQwEpnAC7DtLNJCKUoO/w45c44GwCXiAFB/OXAATQryUxdN4LfFiwgjCNYg+kYMIEFkCKDs6PKAIJouyGWMS1FSKJOMRB/BoIxYJIUXFUxNwoIkEKPAgCBZSQHQ1A2EWDfDEUVLyADj5AChSIQW6gu10bE/JG2VnCZGfo4R4d0sdQoBAHhPjhIB94v/wRoRKQWGRHgrhGSQJxCS+0pCZbEhAAOw==" +) +BASE64_AUDIO = { + "path": str(_REPO_ROOT / "gradio" / "media_assets" / "audio" / "audio_sample.wav"), + "data": "data:audio/wav;base64,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gwobAWwAoQTr+LgFs/1Q7/sCcPj0AJ72QQC9/Qr4NgOE+NYFt/hRABEDm/xzAH/9DQLyAyT/PwQVAiP/wwUdAtb/DAFnATn/owdP/1UJe/pSDFEGUPt/Ezz4GAVj/BX7nP+P9W0CB/ti8ogAp/OF/yr3e/hJ/5z4egiV/uQEswHyAaEEmPpMCMEDwQKBAlL/Ygc78fwCQwVN9sr+KAXbAMgEyPwOAuQB5fnZDOv3mQrbCSP7yAlg94MHpvVc+LIIr/izAcb+pgKMAY75vfz3/Lf30foJ/bj5k/vBBcvytARRBOcE4AMVAFoJzfnMAVYADwC7ABsDtgRCCB4CgwtoAmn/cAX+/0AAMgWiAdP9JQIF+oEDHPYZAaD6x/VCAWvwUQG88hcAIgFp+8oC5v63BKD9pgKI/a8ErvxHBx4DgwGnBF4EN/w3BQH8ff86ASj8qQdr9JgLz/mwCI74EgOvAtn+cwaw/o4GK/1eAZEJ8/diAAYDjfX4CInqdBIE87YBjwFu9A0H2/Y1/3b3M/nF+SgAH/nQCt787Qa3/68E7wQG/sQA8gSv/dYBsgsQ+ogLtABkBxwDSAcLBXADVP4LBDcA6vPZBQr1NwLV+zn8IwKt9Kz88PzO7QsHa/wz/r0HqPi/Cn35yASb/7MBuv0cDPsCYQMiAD75GwVk830GfflZ/3MI3wFH+MkH0/xpBT37ZQadBgv8DAlO+7gDCPyTBrr3awvc+AMDDP+n+gcF0/fj/Mn7cwFM//787fTeA0/z3wLn9HX/uQSb/dwDcf1QAMsEDAKL/oAJO/vBB9cFuf5D/1EDZAEBBs7+qQof/hgNAwO4/dcDm/zUBw/4Gv+m9nX9wvbl9RT22//D/HwCPfnF/7/7oQJXA6D5ywdRAUIHMgA+Ayf9FwQBBi39M/6YAxX97ACJ/Zb73QAsAaMF2v/8AnADgwMpAj//SvyNB2UBl/tMBGT8ggVD+4MHQPzC/2gDCv1p+ov9Zv9x85cF/PJt+p4BCP1n/eb8x/ypCiXzgAqT/xX7jAhq+tYFN/tACMAA3QL8BDAK+P6LBuIE6ATBBL8DegTMBOT6WQbx/ED1UQS07z3/cvdE/Ib76fppAfj4jfdMSVNUYgAAAElORk9JTkFNEAAAAEltcGFjdCBNb2RlcmF0bwBJUFJEFgAAAFlvdVR1YmUgQXVkaW8gTGlicmFyeQBJQVJUDgAAAEtldmluIE1hY0xlb2QASUdOUgoAAABDaW5lbWF0aWMAaWQzIHAAAABJRDMDAAAAAABmVElUMgAAABAAAABJbXBhY3QgTW9kZXJhdG9UQUxCAAAAFgAAAFlvdVR1YmUgQXVkaW8gTGlicmFyeVRQRTEAAAAOAAAAS2V2aW4gTWFjTGVvZFRDT04AAAAKAAAAQ2luZW1hdGlj", +} + +BASE64_AUDIO_DUPLICATE = { + "path": str(_REPO_ROOT / "gradio" / "media_assets" / "audio" / "audio_sample.wav"), + "data": "data:audio/wav;base64,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gwobAWwAoQTr+LgFs/1Q7/sCcPj0AJ72QQC9/Qr4NgOE+NYFt/hRABEDm/xzAH/9DQLyAyT/PwQVAiP/wwUdAtb/DAFnATn/owdP/1UJe/pSDFEGUPt/Ezz4GAVj/BX7nP+P9W0CB/ti8ogAp/OF/yr3e/hJ/5z4egiV/uQEswHyAaEEmPpMCMEDwQKBAlL/Ygc78fwCQwVN9sr+KAXbAMgEyPwOAuQB5fnZDOv3mQrbCSP7yAlg94MHpvVc+LIIr/izAcb+pgKMAY75vfz3/Lf30foJ/bj5k/vBBcvytARRBOcE4AMVAFoJzfnMAVYADwC7ABsDtgRCCB4CgwtoAmn/cAX+/0AAMgWiAdP9JQIF+oEDHPYZAaD6x/VCAWvwUQG88hcAIgFp+8oC5v63BKD9pgKI/a8ErvxHBx4DgwGnBF4EN/w3BQH8ff86ASj8qQdr9JgLz/mwCI74EgOvAtn+cwaw/o4GK/1eAZEJ8/diAAYDjfX4CInqdBIE87YBjwFu9A0H2/Y1/3b3M/nF+SgAH/nQCt787Qa3/68E7wQG/sQA8gSv/dYBsgsQ+ogLtABkBxwDSAcLBXADVP4LBDcA6vPZBQr1NwLV+zn8IwKt9Kz88PzO7QsHa/wz/r0HqPi/Cn35yASb/7MBuv0cDPsCYQMiAD75GwVk830GfflZ/3MI3wFH+MkH0/xpBT37ZQadBgv8DAlO+7gDCPyTBrr3awvc+AMDDP+n+gcF0/fj/Mn7cwFM//787fTeA0/z3wLn9HX/uQSb/dwDcf1QAMsEDAKL/oAJO/vBB9cFuf5D/1EDZAEBBs7+qQof/hgNAwO4/dcDm/zUBw/4Gv+m9nX9wvbl9RT22//D/HwCPfnF/7/7oQJXA6D5ywdRAUIHMgA+Ayf9FwQBBi39M/6YAxX97ACJ/Zb73QAsAaMF2v/8AnADgwMpAj//SvyNB2UBl/tMBGT8ggVD+4MHQPzC/2gDCv1p+ov9Zv9x85cF/PJt+p4BCP1n/eb8x/ypCiXzgAqT/xX7jAhq+tYFN/tACMAA3QL8BDAK+P6LBuIE6ATBBL8DegTMBOT6WQbx/ED1UQS07z3/cvdE/Ib76fppAfj4jfdMSVNUYgAAAElORk9JTkFNEAAAAEltcGFjdCBNb2RlcmF0bwBJUFJEFgAAAFlvdVR1YmUgQXVkaW8gTGlicmFyeQBJQVJUDgAAAEtldmluIE1hY0xlb2QASUdOUgoAAABDaW5lbWF0aWMAaWQzIHAAAABJRDMDAAAAAABmVElUMgAAABAAAABJbXBhY3QgTW9kZXJhdG9UQUxCAAAAFgAAAFlvdVR1YmUgQXVkaW8gTGlicmFyeVRQRTEAAAAOAAAAS2V2aW4gTWFjTGVvZFRDT04AAAAKAAAAQ2luZW1hdGlj", +} +BASE64_VIDEO = { + "is_file": True, + "path": str(_REPO_ROOT / "gradio" / "media_assets" / "videos" / "b.mp4"), + "data": "data:video/mp4;base64,AAAAHGZ0eXBtcDQyAAAAAWlzb21tcDQxbXA0MgAAAAFtZGF0AAAAAAAD8BohEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8AAAC4gYF///e3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE0NiByMTFNIDEyMTM5NmMgLSBILjI2NC9NUEVHLTQgQVZDIGNvZGVjIC0gQ29weWxlZnQgMjAwMy0yMDE1IC0gaHR0cDovL3d3dy52aWRlb2xhbi5vcmcveDI2NC5odG1sIC0gb3B0aW9uczogY2FiYWM9MCByZWY9MyBkZWJsb2NrPTE6MDowIGFuYWx5c2U9MHgxOjB4MTExIG1lPWhleCBzdWJtZT03IHBzeT0xIHBzeV9yZD0xLjAwOjAuMDAgbWl4ZWRfcmVmPTEgbWVfcmFuZ2U9MTYgY2hyb21hX21lPTEgdHJlbGxpcz0xIDh4OGRjdD0wIGNxbT0wIGRlYWR6b25lPTIxLDExIGZhc3RfcHNraXA9MSBjaHJvbWFfcXBfb2Zmc2V0PS0yIHRocmVhZHM9NDggbG9va2FoZWFkX3RocmVhZHM9MiBzbGljZWRfdGhyZWFkcz0wIG5yPTAgZGVjaW1hdGU9MSBpbnRlcmxhY2VkPTAgYmx1cmF5X2NvbXBhdD0wIHN0aXRjaGFibGU9MSBjb25zdHJhaW5lZF9pbnRyYT0wIGJmcmFtZXM9MCB3ZWlnaHRwPTAga2V5aW50PWluZmluaXRlIGtleWludF9taW49MzAgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD00MCByYz0ycGFzcyBtYnRyZWU9MSBiaXRyYXRlPTMwMCByYXRldG9sPTEuMCBxY29tcD0wLjYwIHFwbWluPTUgcXBtYXg9NjkgcXBzdGVwPTQgY3BseGJsdXI9MjAuMCBxYmx1cj0wLjUgdmJ2X21heHJhdGU9MzMwIHZi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PcnL10/Cvr6+kSq/FeyoRHS4/u8MZclfrWoI+7zQyT+v/Vf30X/SJ9WLDgsz4EeAIRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0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WTvfBNyaQO5hYw6x0WPO5hLvd7+T3wrkgo7vbLO61+CLe8XW7363d/666KmR39iUCK7u/ZPTT+pgQ3dp5fIzjGfcLrr6ybr19fS+b6cN+SrX+HvjYCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8AAACikGbz0pAK+CvzDs1pfN40Wnza3vfNx9xq+Xbthj0RKpf/sXLJmSb3FH6nRNn/wqWcCpsRFPp7v8v3vbLCBnw3EZ3Dt0eatetoFrbUvD8tD7cJHqfpy5yz3P6k2vxdN9ByxeX/6fhpfF8s/mMliFPFDOE3xWhePCdl/u3GRlewuE2LpvQJElJqtwf2n3eT3Utz6D2+4KvRuC/7vhzV3jHf4jaH97B3Dy6buEi3Ve8od+EtBFQQzLnE+qxMEk4KvPayfy96tAolg/d3On5CnFQy9/vy5CfmCXDtya2i9deX/dr6mX8KPfG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WlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vAAABVBBm6AV8FflHZg+nL/vhAvNg2QvDjRKR3+YmEX9v8u7hmUxfqaGFlcI99YX8EhNIJPAqly/+4Q87zGan2ajZB8pUzejQG9xpQRrZR3fTe7vkHz59o8JF5pgMluTcv73hEmdfIPXQXQvB7FJPptzzutX9LLa1/+U5iJZlO0gp4odzNhjZTzWDXX2NywLR0NG8CRnPqfwp2WyjtlLofjjzDhEzn/lgv2Q60cwvOJYfvjX0Y/z93nYIZl5o1zLrvatU5f4krvdJ31p/tkK7v+Xl5kQTL/7gsGMnvaLkWMi13cb9TPuJvUv1xNIgrVTil8v3dbKc3fsSwRQEzKz/b//xVvVn9Hao7k/SuvBTD3ty/P4Bduuv3vcL57bnI4S2350D3tboHvhLxWtOTb37gqM3Rl63ljfxWaLxAYtZO2hrjN0mdidOuFI8+9Ducf1jSzAuHb/LuRtG6fEfteaQm5Sn+5JO4D5zOH+1fGl4R685UGMvXu+7fSNN/5Przt7CFvuUavIHMJcA19UrYk90Tlhv+Qm77L6woZtsZGfDDihPZZYetJc01eJteuc3Czx+zv250RjabH+R3Z9y5w2OCQB2Xb6PGZbM+C9gEtHwGyhfEQu2RobbOf9gp6jA0QIr63HICcZKH4PSpT+1k1zvJy/5ehKeEfQpmX/ywS92jqeVRWT6Vr8PWdwyzK4bSch/GPA+i4WTeevfWaF/rInCkjyTzNrFafVbGtFTwq9G+G5/6u+3pjB0rPT1VO36v+CCuDHaDrnDNhuzWh591j6JrPZKU/lKEvC2bz5SXwxu5Vyr91xlf6azwRTzvSq1KjMFuE5x7IRL3cpV0pbaluFDelv993u8q8pWB1zp6p3lIvbWThHwTbZ/m8rOLdVhe+7u9n1desEk2/x2LYLZdvKXfi7ro7BEU+RbdYJdO+PFz8usEnc6eXWCK7v7rIIhyj+mzqwQid2d+1V/ynveshMEZnd22hHwRkP76/GCR6v5+raG5oP3fysJdJ3st7vrSplu+T0uqXMZ39ZCny/Xk9qxP9EKDS5pcNQa36ylJUpTVFQRu93d7nTfk+umugV93z9/OmXgOoR7FECnP6Zm/cZe6T6dmq/LBO73rorCgnPnH2VTuXLPYcJ0w0rkQe3vD7Ubejpl+bSVpex1lBd6DMSf3JLThG+yz+zv17yc0dEi4lh1wrfLvlGbXcXJKz4J/rHLumsZfdOZDu9/0NU4q9x24eW8I9CZl47SMz5zxudvZ1MITLzMXdROETu72n72OT1utRbDO31n2vrw8WE/hM8T38+XpHQDv3dZffVN5do5PSr/dFJ/UOX3Mc/pjCy/v4sQc6YlZJtfRAk89F0p4493eQ+PR++lhPdrWOve86Fqm73W+T3cv6BNnSXeaM9CPh4lr49WrJGtGidjw2uBfVHf4JzN6Vzb3N7VBA73lxJ3e78tC0U0/bHYrfeVJPy5+gkSbbvtdwRFyZRWtH5ff8JaBvB5N/J/VSNngl6WS3W1AaXiPaTUsImd98I0h+1h8hw137LuQlrJI2W5JYSL6NXjxCnXOEuEf41Tr1+O3vY7xX9MIFOwG5P30UFo+fp5/7iBuq6ZLvdfcwjPevJ9S92+qpO8eIlwrG42cmPg/jFvwykG1N2eg70JKEO/v7GgouYPJeVYdcVTpKu3KSgnLD3fvY8Pus+FMkgWbJ68kWNTbdIRNfezr9ogouxcQXNsq/0L95CF794jeuyQU2z+YHPuqTyYWyQiRoZ7yfjPf4S3fFc0ul3sTmvJ7T0I47tczBFfc7Zf+pIYr6+sJE3ZKn6/ESF5cBZAAAE8UGbz0pAK+CzwiKw9m/Ihu7Jm+/ykW5iVe5eTXl/3y733wv5iTzMg/jeYeDj2Jt/T9h7E2/s8Mr5dy+a60xYPNSr+HIlrl/bdRhW8I7x59MzTr4muN3eWMIKPQ+vw2koVTyjppdgpSkdL+/hi8w49sITxGYu5P9x9z/7mK+neqW8r3au/xnhI/NbK3u9uHRysK+YZeOm2X93xnMcKTd63JlX9AJcRvtPy/v2FdXThxbdgacw92Sf/uItv0udxEey1139/vl/vfVl1Cnm8ZvS/vthQllO91frZOTu+W2qHvvsZ7uwyiX3vd0WQ8VFaYllhAp57bnJc/9v5J78n6XjdhK6Xy00JZsj/SlK+X14mKkeu+UF3u0Mru5IP3LduO4CLzqaox962VnIC3OM3P5P7dpy/y3NrWE3+NEKWVlb7e4I82VIptWG7PXh23/3TTQKpZNHHpPEUTk0UlVNF12FG8yBbNfyLHl9+CI8OL0U//6/9+vpr8KbHBXFpI5HI9b6q/M3Bls+/g7t6gtMYIq/ln34VLKgOGXKg0U3qYzVR/v9fIYS94S9CHb+wT1q71F7lH+3eWHso5CN5mYZEjtSJPkBH9m7rwX1U0L/7BXEB7MVbp3zs1xdga/2dXzof7QXsAl2l0ML6/9iYJOWd8v37gnlWJxtECNur+kulaAvx/w+Wl3TO9vu9+p1f9r15fV9QjMJPLjYZL3IHb5FpPdM+hqxhoaUzfIoua2jz13B+4n0JjxOG5Pd3vdOl6mJd3CHmys0vRiH/v5PcFcDykzilTJ2uv3fLoX9uvWLXuixW6osF0DV9Xfe9M9qvbvpldk+T7/8ERN3eEPBFl/WX7XiAVzpyaZS7OM2WMvv3uFDisVu8ao1G90i52fpQ22HdWuGaD8fSv81U6zJeMIiH4KRY8besJ223AjuQXi+NVs8EJrT0veJNDqL1aPd0lFvCp89+XqX3/8NGdy7rCS7G/3+Pu/d3vfp6vPLffuS9/sFhXKw9ux93SIL8s/3H+TGcbr6BSIb4HrSLCs6W3oxC/wTd3cbG/v3lOePS1T9SVOe+r5zr90VOrycxBoSXfZ+X9p819+myyB0/9lITu9qJJUI+EiZGU4+md/GEddOT3N+a79PftCxKNjfLr+zsIz/58ufC05P3t+nvOtXeE7re7f4SveQvfvye3+bizbgjV7+LRj/szZP0ksalElczvAJ3p5v7WxK+kyb33Y8rKPf8r3d5YfH2j+dYN5z+P0wj4ITS+6cPQITO/48rEnLh+5bCrcstvzJi20uT21Wqly/SklYyf99y0977PKTmy1F9nyVyfSYbl9BG5E5yl0mruz6giJ5aIx3+J97Bve1J/brbjCW77ub8At/Y7+/y+T221a0h0sPDiTF8vdLD6euSoS8IEn3G8m7w7TNVTvspwnve9e2OK9KynpP3Lb0opuxfF9+6FSl6+8puf21japAqnSFGkm5liuMCM1mn02L71XlLbh2UX2D1fA/PqDnu+RJcXX0b18a3+loRBLzb3udIVWi+T7+URJKUs3Q+7CF9+HHqPemqLFUqXNfiJbzz62V89OzIxt3k+qGVbreZ5LzhTWmS5ZU4WL9N/rZMJkKjt3u77xB577fvEdTpqt/JBFyynBtImtr1C/qkXyWmn/ET55LvL/+Tz/iIJYwy+fvnTdPvefA/8ZAAAAE3UGb70pAK+CvzDuHEfxZZLOcs5/v3MQN5b78vksL+CQlouMemy/+4R3dmQcaIL8T42vYQJe8iHZf9ywRF1zpp3J/TrnYQI6+t43AeRNi3KXqnw/nLkQdyBMyu4dv12RuOYv6/Elxs/vVHq8W3mu1V5kF62e93P2i/r3dnHFj+CPpjuhRQp5hk7VRRK79wpnSTxTjTG9uyNlvEOqOa85cuG8iPx0QzSpQZfu3oEu9cXcq33g7UnJS17jJA/3d5Qy0HOV0SGjv6acydNgvWpr77Lyff/0X4zaC+FC//YJyR3ZDizXn7M/j3dsGX3d8Tq6ZR5oaYd9aWCoqKhO+51s5KcChsrEZ63D9/v681yJ5LPBNYeaZZPsJvYu2ZPTacy1ef4UW2WMEH7u93Hdu75g3r/wpMP3vnfnPvc8dFZGPE+fvDpZh8+uN7Ydn+upIlkiH8ty6tfc2e3EFaPym2FYmHSVumqPHx9+fJF/DMGT1l14KicfEgcNaad359N7hTphBs/DezL1qtzdiDtfhH582l/90Fbt5B4ArdfrM9P18/XXRRN2zRCNYKDCH36m7N5uC0gPa/resn23bpuPyiE6/c0+Y2Eij9WZYK6j2xW5NgTVgTJoHfYUanYC8XWKO5X3yj7fdGzeos46GlNIbkF+9p2XSHn2Ji5c7MqDq3wS3f3MOTmn8FmNBZsKDSbe93KqY0kVOMNoJz+8Z7zkndMduNSGQ0zn+WJEtPTy/J6151giJe7i+TJOvuEPN5f8STI9SslNT7/BHtv1+C7huS/1JmHf22CIs0qcG7zwQ3Iy7F37wR+HV0KMd6xd7vvbVWCc0OPyFkQ39tawQlWFNv7h2VEK5fcIeTeXy/7eCMjxW9b6xwm7u7vKxW+/dT37FhH3gv77wVEcOOG7y5xlki4v3MIui7cYUxpfMl988d73d+a7v27RmCWleHmeNHBurM2rzwV5ZXhvZtVMWfkF9BDu77N7vSQvYK+Q+25U7u+UCu3E0xNOuR7/oOXvb7t1CPYKjOWRIorSn+2m3dtdthKX8+F3fuYr712mEqKcfl39nvRvt6y3IcXrX7sxX30eakBdUU/9tZ/aQ/n5w6+z984sleIVhOkvu+T7dz8n6GXKoe7uRS7vuw3CPQdjJjb9OZNFmTf5YSzRLyz+/eqUdHlorv1Glt33cvyCofSWJ/4rk2191jWEJD/MNK0UG6u77dTfwXzlCPua2FxT62n/qCAQ7vmc0Qv2Kn4g3F0oOG8DP/YRve9ITlKhKfvTtYot3d75f3096WL7vh12MI+KJjc7qQRHn8v7+jXPwgd7u93RO7cnt2/kKDAWRz9p2jxSs/Z/3IRw/dv15JO590PYSzPvd/VlfZd/cX03kRT3d7gl1JklvzxT0WrqLNw3FGkUuI/////wj47CEjcvxkSF5fyYR8mCVtNf4UItrapfB8TeT6cgEmOyRnJzC1xOSrfX2YuX+T1fqJLl/P1T++hPyRRqwg40w4e1KOQs1vr4Wh6LT8VvO05f6J9+Ld9DDi/9/gj3cvIkKeTLuifWv+tzutevpImf+sIlq+733vXkgp2/dx4T+XpxvS3up9hb2abtddYmt5TOc0rfvCIt0ezfKOL7pEODWWS8Zxwxf+IyQ+XZfNJ/J67bioqJ7qfP4qpEgsgAABUNBmgAV8FnihWYEIdyxG6T9xJNfv1Nd/F85o0pcgl9I58sL+MJy5JOYtDSBNsx4MUzUbH/GljL6tFl/mPYXTyOcmz3qcVPbnr/3ClEURvb8Em0nbhCsak13qti9tsWI33joW34k136vzRzuU4z1/4qnvqz+Er5Z8E7adcvyX4nx4Z02z/qMUhTw4aEH+mYBrekvrfJQhyl3kuEA9Or3G4azaCb+qsb4EX8Xf4fXuWcPUQeSU0s23VFwEM0t6rQ8xfe4spi9faaC9kt4tdyzJl933CkfU2d03+CT6OfKVJVw+lw07CdtEK2CdkLRv9ypvtsKejMmZfaqr61zDlp69C9QKq79IwUP+wykEq7hQoRcbhSOxjLG2lebTPzR3uct8bI5abHsMKHbSRbjeEH9W8O+cmN0QSf6FcVuDJZi69a0zlQrTeffk9JdfG0GQTjcjnCRarYRUkXEjvvjRafnSagxr/y++9BS4QMOXW/vwtwywOjvDq6Lfrghgt8sEs7c8xfb0j2kyywVz+/3l2xwwvaNwV344oim+N9xkk817mjtr3LG8Gb7Rwb7CfgsCWn/XXT50BjvCbbquOlYt72J98ZQv3uHxsve4kuifPy/9ZPpOXs827aPWa8yBh6LqizeNepp6CHKoAgPToy834YrBv0Lb3+bhVTPe1wm/seIt3e+AJNy4dn+/xnswEe+bJwxsrgjgeNO25fr3ChQWdYw/ekUeKV0menniA7K+rfcXuQX4gvHB6wqimaOfcIbIi3znyvrJhfTWzn/STxtGOmmz6BSTZjx/Wmx6ho+YksLPtk+nI9cKUVh0F8dsb+5QKWrNuDaWo+51JgvKJJ1ze+T9aCBhzHlhL1dl/3bBPDSThGjUI9t24OjwvhL3y0Y2Uk0uv6y0PDlmvJ9qo0r4U03FndwoBfyz/fDV/15p/d5w5LfK7J31amuhyqMbPoZWD+Z+EyuMa3yhONiPsWwRGoOp23y+pZOCg6Nzg14Ve8OYOnBHHBJeke7yaTbye293ikKwDH6Lp2kknhmXLUnC5jlIZRLOki5OOKXV28PLcfSVtBMS09N6e+nRNb3qEl3ghI5+/Wkt1w7E9e4Ijp98NP7JOu9/XOda5d4s7yxz8sWL7oIincK8/zhve6dMEJQ8kk+x2eFCu7923303bpvargr3d3e72+ZCHo3fgrJzMPve/t+WhPda8q5PrvfBLmf88v/q9erh6/S99G8vCL+wpTzoCa327fdsvffWLyqT/3eT1//3IXd6rP/N3fQmE5Q0+8/6WrF9X/R1pJU99uTe4R8TL/H6bv1BES532/soQE4Vcb+4rd7vsWw9z++yyelE3v/WK7vGP+/erG/dU6k9PJ1wiR3e+E+HvfEDf6lfL0cRfTRahE8xR7e979NKVN6UgqeKdIqDbhHxBoyY/P/wRGp0/HqJOK3FbitxWK5PT1y613Lr5N1ne01Vix3f5Pt8XXNLvpSokEvb9sqK/x2pyw3vc/e7XMxZnR+CSlEdVlQR3JtjrLb3d4h/kZSfuEfPFV+Nd/hc0nXhzsKgpnNV2SJvliy9vdMV9IcXdGYL6ol+5d6QbGvvUOtX/68sgh6t7EyybdvVKmGml/UvZrJ9vi1dAnM5RWEWHZRbksh/a3dOqo1xMJeYwLhhv9+78uoOe9akbu7wtWJLpviHH5oIsrny21JEXa/T6JVP5fki+X7u9uSmOxvHjoz/favrBPxuZ350ghgn1WSTeklrJ6dv+pBdajsq+bw4PWkUivCypcvmcL+qRLERE8PuP+v9778l135LjnR8FcAAAWuQZogFfBZ4sUkGs4a7h79ykJf1+Xz8M+Ykh8Ee3MQWvi8PsOhJfxfGxpLE6NFu4qcI9woUfZW/8J32b+fCCi8fhk90Rx+N56bZWiDwmGgj/dd0vdLfJ9lSYXW/3bn6TfLJX1u+T95MTLHXfNmvLlfn9ezP/CvizckNR6Z+FMfnHIXmOgkv43u1CbXq35KHEdlAE2+dNKz2Q/wxkMt+I9/7du1+7Jhwjb23G79y/flEKYY2vMj77iNK7BDt/ktTr7/m4bijF4SaY7/GbbUZi6tsMw6G4O48MjIMr/2BW/uIKNifQ8OTnrXr8dIDjM3uayLuaeZpSh+X9fCUoi7TjAZ/KbrXBhixSjh+9vCtU/+FpDuj8j64338vyeoRy8d9zInp3feliSny06vZBPzCuNyX7hQk7jGUyUhmnzuyPy0yMIux6VsnNEjv7i+8umxt2IiOpvAW1dd/csj7EvezgI/47yvvNlPktsZQ1xbUrf3VFYeKGmetLejR3p4y7m2np952UfdYS7n/WMvHZlUCF6OtP+6c8I325H+EPHonkeWNJEy+KvDbJb0O46j2LifLgyJ93Rf18FF4R+Hz6GbB29wpmgWCl23eHccE8U4s0LXB/AJwm9zptJpsKdDHxULt97eYk4SOHoZb8Fla3go1hcvzghPLGigyOImYgt2W7lx3dzxEZbQuf6TXhX3/G/mkG3akD950G1fw1LBkifqxHrjXf7BbukjSIvoqE3VUWXx91Qg8WHINM4y6U6TvY9StkjMO9IbZe95E3OdTOlGqLRUut1ITdH8EpLHw61JQZAcgnuui+6yxtoZUHtdfNdpVPr6EEP1LbdYd7x1dHk+lTp8Evcg6ndrprs+19b0uEn+CexPXZbvMmlWisb2jSmfluMQnUp3AjflnP+ObaP/6D9Eym4EHp+ogvj1kz465t1dVc0drB9dy8wzlJyZ2/+mCQzNdeexkx8n0ll3mLKIw63fL9v4JTP3gqlFW/BcV9u75GdXWX7kwyt95f31FZRKX5gc+mwiQddH3hqhkCEycgWqukJODJ64T/onfZb7hHw/3Ddbs8FMmPx7oP45i+UgJ7sY6Zf8g2luHamAOKEsvO972tQ4Kef+T1fc/E93MPsH7/IUj+gr7VkZl1/R4LZB/fNHnNLmgh0RX/aVf8FPdy61ZoRRRXV9320dYfokPL+u97u/oTv2+GPv120r9F+0C7e93f/5xfXnh8I5ILBG6u3Xd671O4qjuq+vrWONfXVVtayXfCK7wU2g337u9G+5pYZk/29sFRN2nd7710XtL9LRpRMvva3iL3u969p937WT6T/E95NCt73L+l8Vml3n+xPqyZf9o13wj4JvLw26PK8lrlwWEuHMJdk93em2T6zW85ARieSQtH4R7ujvvPuxsTdy/vvr1qpY6vWTdjfX6izPhL4sPmlyLJIpVvKXAj17ffvQ0W8V3p2be99b3uEfC8iEkw8k70jceCftNC749100ZnQM+zaxITbBQIf3vdzL5O+ET3Hct3c/5c37QKBeDrg5cL+L00uQhCTR9ZLvOtqiUIz+T2m/lJyf15JPWT2aPVZIQLaZ1y32976d1lmEPA1eK+/sXPvvL+kz5Iwk/UICCxDFaG7n5/vd7yiZx9+43VVxW9ekUrxW/J7GiTHWu6Ebd9/qjFLzdze/TGm4c4djYqEemf7iDXzv55jPWv39DYQ8fWwg5unMNd3utXtwfCPuTt3uO0PLxZhzK/qvBZe4r4cZ1P7zpCmSE+SFaTL4gydZtHqe/ExImHWSX6mu9hWnlm4rdWJ7p2gvvDctLu/Z7X/Sm0nLleSCr3fPy8dbPpxuiQSWUYldD4V8QIVfSX4qbXJlqaXJ6qVmiOLtj3vuNTVO26veT5Pr/JRzMy5ove85iVg/deSQl7hj1Tr74YxX5KnqyRBSbmZIco8FYLIAAAReQZpAFfBZ4sVy4/cN+HBHHI5L/iaWX/2wjtkOZqlkwumzu9vX4IdZiyXW7Q/e9oOCSjC2TtPhuL+Se7Ynvh7d5cfxq5v/LVe+9SxRUi/3b+CPuNtqd/fPbhXzGwwvdmfKYl/d7G4SeQNTp23LJ2IJEiXNrstqBfx4cvXosOwlPocDnZ6aB8x+sF9IOjRFNH/4U24NsFbsAYR+vP7dlTBv1VB+H2eOoqV9x1tGjYX3d91tJ7jANLAu4M+9bChQl9tby4Xsq/d3e+V5Z0zFqlLCHI3ODzSvgm1PX9Hu9/LGZ37B+N9uUOtL9CY+NxnDlO0zj8OLqPJ/XTliru8yKCP4GWPtBEpeNrLbsyqN3/l5nkaE3+KCFqzgK3Jvu/xnu7HYiYXfvOFzjr/XthMrFfcJ3gNakhUfcJ0V+dl77aF3z7hN0v4Qvve9jvf4SKY3ecR76o0/u/cFG1HRL0eAgEvv5//El9wgQcE962BK/itl+/E2vCsj+/aCfdPGxAbv97u4TXtggEZjju7vgpOnCPk+PX+O9L730Cu0BDumDZwwxlfZ/udmDRkPXRYU4yL73DMW/1o/qSkqN0JU/ZP38byHKKLBPXv8EFBi/ynIQvbBc6AZ8NqNH36OwyJ3d/6ab9xd33rqiXMIve0j1CksFjOpL/768wjLj7M7GSBZWJV/e9INVuMN6BHi4eh2IpcGeG5J0lTXpXwS5oxDmLTRTNknDO4675Mot6UI+CMRPvZ+C2GK/+d3d7iT6r9wWZVwyvlyE5d4I9L3/mMLolwVkeXbAO1xRCsVffCueVp65S+HuYTzL1TngiERurudYKy8JeUXq2j3W7xzpzFPQ72P2eCIke3/94IsI/NO02/VAgpTFbcEvDqgQ8zvMj5RJYdsc9JLZvum9mHM85m/pUVKqp0xG97v7Qy5aPz+97u9wkufBWR3d73Xbr8E0yCHYs9yy0T/s/Lc5vvvCZyRe93f4skOIs/xvf6xb9S035PbS9UumySNDNSw7zMEJK1p/P8PwSHe9qf4Iu7tCK9wViuVcV73vrfuFBLivef7p7v7sW1z1Qn1S12Pq/f2quN139krl2kvtesI+CEj7b79Ne0/Iiw23eTs/v6EPqu/v7T035C3vuveEfRH/Rn/KLe/RPilVfX15PSXrNMbI3xVe6SrkhHzHL30/y3e9asokWmZY53d+T0ndzyLL6/EKnfXrZFt+SipBtIskK9TrTd9fvKxJ+rk5P4oQ+qwKKwIr2pUi71iIR8hZf/CZNARGEieTy/r4jeXn5ffdldgmLuYNn+5JD7T4QRBeb06Xus5mPzd+T+mnkcUasYEO5vy1T+kJhLw8w8/F9Af/U8F8EH1Z+T17rJU4oW8pabf2Xd9fIGJYbu70q9U7y/kKiydiZe71o5UCW73czOLbosIXhC00/z/d+oLrps9sm6QenC662Z71ejnTVYj0oK8/e73d3pVVavQx2TDHqkSzRE5E/5ryCYRgqgAAAQiQZpgFfBX5h2Ohbi+CAubOX0a3X+LC+LJlxLDjqL2Wex/Uvq/Fy9swrxL9eUfh8srC3hwJY5k5EvDuT/hTzSNF39rZhECT+Xb395mEysYsG/LET94Z7fR+7y/veCefLwH3Fr/JK/i6KGRBYK8AEFCcjjy2UhachZ80T93xNzyp4yv3vhDY7p73DNwu8v/yllybQqyBTzGlo0Y4vx19jekErFAYu+u6geGSzf4C1VSNRae6VEve09rboz+zxvxQOea3kVmz7YU4gnu7f34b85EGdyVlpxjvn/KUMLW20PptJWJLuhc6ZkwTvm3LCEiL7QZKaN5eUx8Sw91uPpJH/75a3Cf3u+nEXPry7Zw36wS42nlX1b3H0rqvFTxlGXhxZn+a+YQ1+JLy/u4U8EAxzBetxVzkTQKeYpOgAjq9rLz01jml631uVjLtXtyxADI1/VIhtrvlLs2KQILsOIrAQKv+0M6WX5S7fg+6HRfdyvx0Cv4IDgjv14RP+vfn6bVckmdL+MJ+JTRre+IJ8g6fy7/FZacv/lKYPFPkOduJiIJbvngEnrXOmuyxneY5ZNmvA303ScS2uDfSk/Xz6BMQbE/w+3zQylp5C/SqT9dT2zR8v63rR3tZJ5cJrbLGCnsVu7/u4lzcBe3U/Txef0N8OGL00XDCTsjv/vpfd4aa190zKqfwQeETgjPD0meA75fnc0hxjepUka//L7fuOPKGkkUGldpDBX+6cvrt4KomEyBvW1w4g4OlpCUPjhOeNp8kng6v17gpGMXYBSKva86lWcYefd+qCmJsLv09h+CMbXLpkXR8MO4uBLubq9/lqnwSz3wh4q7DSjASlf/XzAt+WtNxIvJX/d69FCe73mjCPgiGZP+3+CLTuUffX4bh+Lpat1au7/0dhAkO1P/z9XBPvjAl/kHiLadCX7F/cEJnvy70V+/vJl2Nx/IwUGzPhJw9T52WOrQl6evCWUlV+ZL34gnMu5f/fRK1k/UR/9TTh93elfEQm5D/3vr7OSEfBPl/y+v2I5unRXoSy916kvosVUdBK78q/oq7LXL9X6yS+7hHwSiJn67t7db5P6+z6X0xN77G/dXrX6XqspASXf6EfBN4/TXd2/sEJnvrf2JG3d7T9P5JCO/1RTgy+i91Vif4JBBbhjFV6L3R4I+dVJd2LRDu+m/kk/CRfv3IKe7fwVne70nduf2/EC7ve/v9Zf3dOqE/J6r8EgjEQjlCj+/wXb3fS1+OLl17o73dO2hOmv+I9jf5sFneof+JtmEgHV5HPhSseSTMfneE/Jh61mlyIt97+UERsueqnKJu79Sd3usr8T9apom9wu6zMtV6pc3LnqW3m26yLdCNBETNupfucp3RLQom58fvdLhK5JvYrd4Y8EV29Ok/Ncblf+6Ov5Llb2usFcAAAP4QZqAFfBYX/3MKcKvtrymy916lSF/BJ47ImMv/uCDKHy0eLR9QM192ludUjeK8+9xZwlFxt7NOc+X99QtjpGHm54YeBWT2nb8cix+X033GzalTwn8EVvSmnBfoyWCL6Z2SM9fl/23Fkf1T+JENPXuGTsJxifi9MuHr/y96tD+je8+SkT07yd54YV8Ehrm4n12kxr3GY/OVcSEG93+vIFy5uplP7SetBNdyPczaG4us/audFW7gty5btmKaKn8ZCvjfoOjyA0KxStp7gvGJnR7lQXlTlaqsJlOJTXcBH7kb6/tS8F2fZKJHeTc6eoKcjn3l79mNH6dVvl5aZf3dy3DjbAyJr6/hPzEk29/Y0k0Ebpk4CrtcB4++HfYlUWK3XyKS9n/G7IlYNlTwclitbw9mnszG70a60W5h8/2755RNfeavthCWXMCyHGHd2Ocf+CUpSZS+ErTHbs86bvOwSbmQO06PqyXDG5BZbQ7g6nm0/r3X9YKKsr7T3L5W1uWCHjeRPxfhtJH0YMYHr42iwwluVsXaodgOZDRxcQCAztub29F8cmpCTc3nzTRU4fu9vj03hP5761omWV6uf/VdBC78vu7u4S8E4p28nb6y/9Nh4mTe74BTy6/f14btx/bBTnFIbuND8p3/Tvv1Sd8n1WXTgt4aQxnMDi6Am17f/Z+IEucP5rRFT+4LiFDpd0t+9asTZXMg9HglIZdoOlzjL/+q0gwTjJN37XWWnHu+CLLWLxeSYe+4S8EYq763+Cre5VwfLXBPda3WWCDjLpyOmnnh+EPj9f+PVV3eNYUJwQ4EWB/ieQdDcOa3+4gkuIibl2BY/VEw47sN4TFnpMe3cwSk99/cEQqau50e5/fVS6E6V0/IUj31Zu4520t02Mly7iv7qIF8N0xyCGkHqDovULRhdHuFC6ZVd7uX73d2hPxIjKxk9b1yXv2Lbu+YqqPR+6tkKP76tddfXtPwQ+Xt3QIZLiOqcqf/RSK8IeCLy/X4szj1Ho/P7/CAm772z69vX/Y0vVdifiPX1qw1yckI9gmNbt5ffXzi6b5t+j+/t+/r6L7E0JerF+0l6nrrUI9AmmZdCbn8MpEZTvk7+9ddfVq/fXhe9+SwQb+1eNr9dZfERZU5Cvff5ru8I+CUlbT8KtO9PzwUb3e99Vvt6FdriPd7dJ/J6P7ErvNxpO7T6BMXd7u6KdrjMJeMl2/JInTe+RIlOo0E5D5e+utfElOIcT91k+T230K9fk9ubIUfpvJHEKF7kH7e6stdrt5tQsT6q8Y6qi9NCf+jluvJ6pNEfITuWFURmTt6/ThfJKZ7urE6L/kiOXyeie1hf0JSJZLkjJCi+aT5C54wWQAAAO7QZqgFfBX4YHaQ24zU68c7/iyh3NHScVkJN33FkJhrYRs2f825Ub2/F70uHM58FEt3meWamSGPCBOO9UB4Qyzu9qS8f6yP3YN/spf7d9buFL34bk/c9bzRYN37inTOX7/CPd7joGzlwEjfzd3oBO/wmV4bQwWu/Lpalgj054koV8xqTQJPD+6l/d7G5Nci/J9hYVvsJ/NYEvjkqi5KeDx53l58iHp/3irvZBAbRVbMOITiUY8WZkn7GUruP7d8swn7R2H4Z66SkKzZ7j2VRTR2WMhPpj73BnTGA1tfZ2e4dgryfbaYnbqdPcQVhqeK55Xrgp0ZkDishMD+EvBM+ZzpcjfjNEvPuVi9VPX4rn9z51W0W7js719iSmQbZ/lISf5bDljCfgsCEidiepSn/ytTxef/fhTv86Bv96xqu3q4cT3Op1dGniT30fvoExaFuY0QWttMtk+kres3HZnk9JLL3CfmvK2Vq9BbCenSBN+x+uHuV/J+lqyWbjomXOCfgnp1O53tLCz2/sFRkM1ciB33PABAG7L9duOXrL721jeHqBz+6WyD6RIz7b3qL/6Mg/tHOf09pKe/VhSH2GPYqZBjYYTDj854PwFd5NaOmELZVP7vysaoTyIeJIPhFpnuNNcvwl+sXiXc2lha70m41hUiInv/uQfuiv5b31QJhbnve9FfY2KpNNOt/yGcwkCB922LSfbeLVtDDHXd6zZ0BDJ44ed9910+1vCnQPzBhCLi/pigfk3etQNpugHcBD6a/fhDfC67f6TG0noO5tHTr2JP56RDeC8xNIixHT4oYdEP/L68S1r+Ei/+XXYKxR8qkTnlPLpaEjt7ZfODTjuG96QuH394JBHD8nDvcx93VtOeT9NrizZcG8WPD8lnlEI779rXKpt7hJ/iScsdN/qzy+8EZ3v7on8KXd0D2dm3vd3s179H5PTS/wREx2T7vZOMzW/BEWndupCi8Zywh5QkTZf5YJRL3vfhJXrV7rui/zeXhHyEbdN5fJ+NN3TJ1djdbXXCfnEu+imet/ijU6dN95MvYn2/eYXe8v/qbd+/omrFoJGd9424a9NbXZIS8E8z+MmGxwq3PVlgpK7l9t3ufuc9t/fa1r3++vJ00uxO795hF2I/7m7veqlPefhGsmEu529fv0wXG9Ny973fOCUj3d78N9VaXJqxPtcn3+vt+gTFuNiwLB9g/z9t1cxb5f0oVf5T1ky8Rl17T3vv7+8WV39tVkkIfy+GHt/TXZPjv6phvqob8l1/s45KngsgAAAA2RBmsAV8Fj9xYqTC4rXsV/KTHemvdUw/L3TDHgkJDfg6uvf2lNe4R0RYZghgiROqW+ZvyvrhmV3vjoLrqXco+PtDvqlXiTeXl/sraFXcPO5cGkfcXj4UOjxe7QvgJffPtd6Abk/S71/KVJ5b0WJ0y+FkqlJ9eT5OM54V8xtQT7xf47ILk1IzcY3OUk5bfw78b9ITPctKDA/uV76FuVk2/GcePYIcNNQ9w7cSVO0iHi6l5UO/oLV3mrj8eR77nBHa48e77rt7nDa57pptpzCz9pueCgoTct3fxyuxTdFjKbYrkXQz5u/VpUuRC977lFq+zUZ2Lrw2XIH3XHKfhPxgyGdxQXv8DsV6yvDO/fJQSYO72Q7YqI7WGXVNcfjQXttjJ5EuDsvbbAx5XJuhWl+a9k/MITm+s+Yvi9xnHGuUFp9p8i5CPjIeHRWCkpgzTpjcw4eilv3AblbJ+u7qP3t3viUb0u74f3ddJbvkn17SdSTl1dPqhvCXkpXlGit26SKmw4y1/n33X8MuS5PSSTWsEd70/uO54Ht8blhvCb9oeOs3d/d/cwW6t2hn4I4VWzXwm3yfr5Xgpp4YS/OPTfYZvi4aScu/ZPvc/lIJx099Wronet+r/gqJtIw1OOGof1+kT4fiLmLlByhxQb7CfguLI1bn37f2C26IS8x/HRTfS7rcb8/NGhzReGcGdo6Rnj9LpIdDq7ol+18cSsa7OTI/xf092/DbfMHnkcWjsFIl5QvMN3n2GVDg6rVN4YMGscQ+UNvVi89P1+Upc77Hy0N7ye6pZFhO7/DM+d74QMUFvfdzq3OLsKoEkKqioEYlbF8lS8TEvNN98vCJf3iSSCr3vIrRXMn0l6uJ5gvbh9J/9nZe4/7eCO99dfuCPe6f1d5kfV3YlUqc8l3wh5Mv7/KIdv7sTe+8l37TNk6u65L+0tqvCHkx2n9DiWdKx1h/3xukfl/Lyx297vit+mTquxJbr60JaqOuqBFm3rohVfaSogIbvfoR7ZJn3dWtV4IS7v3T6yVV/J6tG7svukftvk7S5IR9CL0/PV7pNCXuxfxFe/X/k6Uul6FMp99Jr6etXhfslU+uvrqxfr3r9bPhHwfId5Mnkwst/J/TJiOUkz+T0/7JFnuk7v7+vVKSbd9eSJ3e+4YvgwgAAADikGa4BXwWeLFLKSktSP+5iZyxxpF/2stprDJf/cJEWiZyiw6SkeKS/vso0sxIpczbA5XqLTCG9fWcsp6J7KvDIb/KLfqNf/jZyNEM430LY33bgCdq7fDr3BWuJl7i7+HR3FynZ5jDbK3Z1b7PhvB5zkv+JTl7vXpFvf8ISwzyl1thmZwS9xVyyvlhtqPqK8KeCQ1I+pq2ZMv924zeEy4+QIV/8bUtqwZf3CrnAtZUEdiBGbWfksZrZDd/5Pi3Y65PbUpSroZfFoe+WGy8eLineELgy+vn19jYI//WoUsec3cInnoRu/8Ymv3D96hmdd/9N24MChu937FxovOXi//L4yy+SFMzSnLa/c9Td/btHM5S6U6w5bIgIW19uqy+SlebneQev3E3e5f0L2jcVmTv/8pZXnSsBQTf4LAk7WHakdcqlv75faq8E2/vUHc7ftXX5j5+XSbapVXeCu+KijYkg6kq6J7Hlbs6FXveXwoX7rbGmPhGXU4Dy9o6fC66x8ATLcV/rO+OkGU/NssKSPUbsPV2h3JFL7vK6H+e6kvLXldv/uMvXKItMCR/6/f+T1X3wQTLQTPHbwh/lmY3KHQRPWpRc2uf24I7gy5qiVX/8Ep0pu8F3SaYiN7hMgaSTWlf3kKvW39H9e0tQp5rKnaOmXu5i7U+7OqGkyCw6rR2Z6fHSjLvc36rssZOjtjRS+T00v7BLbed6BJYTIkn+0lpBMbLe98n73iSZfLwk/arwgEjL5k64WKESO0f+TqHqRFd7lxb/o79i3Xi+de76sSgQyy9jJ7TX9mM8iEdTGvq4S8t1qvZY+gQ31T3kRepa+97FEvd79H9vk9q/Gfs8xXd32kvQl2LFbm6eN76sFolK9N9q3mo9e7fvJvfRF5SQls/yzVfbm3d9v2/yq0JeCbe3P4aVlffWUSf0z/6EdXghLu9dj6t1+T35Pbb9VKZ5XWvJIW942F4viyEPCoYonvXPCz8vlnr9FBHu4aegu5evsTR6ql7vtI2ZNyAbMziqoyWL2aEfOVY73+/sPkbhl1nhG+0+WNu/4cX7J3qvFEPjby+/qUSF3EHek/6XsnomqI9tyObN37TNSHEFc50Oyzm/cP3Ay+09Ls1jRinwnksUtbpes296TywRHyoTSKm8kR6fWb7pPHZf3hm3lp+1kJhXyGXVeXbvy+hPSRZPrWRsWt/4ayUQ6SfD3xUAAABEJBmwAV8FngoFGln8d0fFYrzGxrTDPmyCGE59m+M8M7umNGXJagvb/AIPmZqypoGVddXvd/jL9Q5BF8fMU/BoPln6XcdBO/xWFh/fj5vxpl/uEeMnhrbtwI1X4ftL/L6vOxZM6IwHKboFLaf2JhM673svvNJLr3CHjMraO98v/0C7liad7iu/L4eXAFV7gtHFNeZSGnWit7xa3cQXeH/d/cRAT+sL3dravOrdeqY6L96y4V8KEtFxzoDVX/y1LLGThl2qnGrodNJtiSgrljPl7WE344sC+f8Y2EuI62k7hMo/l3KGr9UKxpn8ssn6t8TRiu6YTczVhK8j320ekm6CezvdIo1sTBHu86dHQLNz/3CPz1zNZJWlVJEaYKDWg97e8qatpre+Xd4TflgnEP3cNv7tAr/hL5VwYz8GrcN9q5EMp4pQ7nXGRfdgs5+xRfcG8n0/Y3ho+VM6V5y5f/yJEyuy8nt64q4ItApQ+VGwl8nf+wS2x26gJ/edEdoV15MJepLf2KuuFRdvfvrNhx70niYwhe7Xc9hejQYBzd+p3RuF/0Yeiwhirysnpb5NFO9XXuPr6oEJjpwzus9tX0fu9dd+7UWgVkKPsjBHxs73KFyFvvyyD8PUzTzpIEh5n+oQ83hx70JNk2Xsex3VWS99NJyBDyry7fhl06a21f6BcXd7yu1tJ36+rFb3e77LyfdCvlQSzlDEXte/eyZaFEnj8vtbpCD7vd/61vkkNe5eEe2Ix+jWfgrPL+XLuypv02r+pTkf9Ua93povIQ7BwnfX02rjaq/bQJLlb920ELu73fu9v9F/eVOEPIXhp6/bGkOwHn+2ty9MtkZZy9uNiketvlWL/ukcwkFGt7gl+lt/Pcr1VSiT5/RZ81hCMq6alldV3feT0kpdPDG6T3LCyqHzdPpK6HXDaSN/d3e77xPd7v0bp80Zuc7u+G5aV277PeEN3d3e7u3tIJXZvxzW9FhLe+79II73Ivd7u9bpwh4JiPXeRfLbqVxRnwQ+/D/3N7yMqKNzR20XkM7+kwlvfd6TcWlrt1hutWta4LN73hBpiXcFNb9P9dbLd/wlvd75f+iEH73e3CjY+EfBOYuxoTG7QR/+UwuQ3CywhT3FZce8V7Sl+/TooU6b8gl399WNRb37TBHO68V26qhRHvEvj9B6H7Xst9v8tXTcI+GizU6XTr47v36gqNc4rzNuolhl7J6614oj3u33dkKJEp0rvL3dl3vtaL/4heSS8xtK/x0cE9Ei9QKf10RLv9Xqdh7rZD+e4aI8JnLh5G7n5fhahMvFfRS9093fqUps/foTNu/RoISF947V7KpNwr54CxbL0d/pZ8eR5ZFubXlWq010L275cIa0IghOfJS9OtiemsRIW7+IiyXhVueHHuaOufb7uK9wx6pF91Dn4O+/4ifQu5Jet/iMZ7Nt+hF1JL+IjubN4/j+CuAAAGREGbIBXwWeKFc2LmNe5SF2Pki73zczQ3H814btX6l80wwX/3CRLjOmrlulL+94KyzI385Y/cNt78otOfh6ZBOgtNndgkbEoBpqqdnrnP2gQeq15q3bls2Qu9B9cv5e4TEmvY8yJF3Nur17lIcx716ZS6bhTwuI4b0ObXshnZmz1Hm8qeEXsXDuAV7Y3CTqbdTF5fb7AWviTzf878V3f7uqbzGSTc7iHNsv5JxGdNkaGj5WUhLaF8b7aLbsdh3oN5OG3MNvBF50zDSPYvtja92XlfO+Ntn37DcVkYNIZxtQsbut4xE/TZ7jeGmlXhL3/tfTIbK/zuV9Rky4f9NhAsJ/ZKMT/y2Bnm75x8yvyfaq7uOhO5bC+8ILRwg5NDAP6SLcTysFw8aXSXgk4fXMaV2m5Uby3vH3s+5x/dK2yIhQkV585eN2fl4Tdy2GE/BYENpHW179JaJnfxwF1Icf2y/Vbh2W6WFtTLlLGgV3AXvZk6u/YeP9+T27EvtwgV6nlnvmB5C95tEwmw+b+xMVu/KF0Uv+/l/3yyrhI5Jt0rv5On8IXM+CFv842JJEzGC+J/2Vuvlwn5KbTTdbtjYhgd1kZn2CoqrpcW034XHLf2nVmATXpdtrDvd3v+VZZdp/SR2o0mBFufO9Ub978wlRXM7n5O/qAySv2L6+CLcULjbvGcXBAQt919Q53NdruNvP5wxLMJsK+1EHcUCFt1b0Efz5KHoN7ZlW36NfIf+ylDkfFqY+ycl92uNEjkTiE6ue9xP3UxQv+3HfnTDBW2/9i3/SZLQeNKLZx6wkNML2URMnXeYl0tf9i4k8W/CFwf0P1qjxhp/G+IyMiK41b28xW9mfB+3SS42LvDN3eOTpb7CgRipoRXh8aBkuyAvgIXa14swyOvry6m8dQfaWkNoaxqmyFbUYH5ZKqfJf6/S7D73HvmJ6CYzCw7xqfrbZt7XCPgoh6tthHq68z6G3t7oxWh6DQy7Yd+/dmL/3TuC0hbdEBXxJyHg2SvyZCeLDaaPxuoBDkXdejm/P9ZoW7up8W8Am6+N9WMBf5ucfZGC+5z9KzFd+/ibHIbpmQ2/6m7J5I9uJKmnc69tvUSwa877/dfokFhMOfvc4/b2VLB7je7hijve12kFigeQWl8I9ukrdVkPKN8M0b+hMOFS1X8ax8sFO73fhuJg+XZ5pZ+qNNChMIOKZ2FtCwX+1RvMtJx0ujF4xtJ50CiHoP5zqhzzvfqyWdx1eEfBWYnpsdak39z1CHl+F9WXNj2LYJtBcyOyaGOaV9m7Swl6T88dvioTLqw77u/seR2JvuH7SQt31jTzC90qBefZ5PhMsepuXZwatM1XbbbLusFJILuZt22R/JvsdYQLck93vm3a5oojucs4LO0GvdL0DC5H+kht5dCS+blXd9Q1nxn4zKr/xxbvnzSu+ixdp2t72sRIC695Nd6fL9dZRJZTJx/gnHRy7czHad/woRfTfvGKOy25dUU43l7gqE7u4hzvO3bT54IbW7jbRShzWfXglJd33eL6BNIW+y3d28uxPrBLd+8uRfYISPeF9eu68Sd37ny9UEbvd3fd3tt0QZd3fd33Y969yw2rXwi/IzCHvr6RXvqr+ul+OLJ0+933+9ronu7/hG+73d7wj4Wy7I2OnCQs/snipX/fysz7d5hmhZ03rmI7/p5/7GsFt33JbOzJ24q7vfemsQ+/o9E78Fe7vjCPww4U+3+OEu7y/uyeE/DxrV868JbarexsmBYLDt9ZoMqy/O7yI2t+4KD3oqTpt2LL3iBM7X3vrGJwRXe6dfH733d96WlBH3c6dfv9Ah2+nXoEhrw4CB+lvsYV3vw3T2MP3cvd73pIU4e2n4nCPqkG/xxqjqousqibnO+HfZOtqhxRurvtB6ew98n3rjTxJT5vl+j+el7L2JXkf3rTSCAiY4VMLbH8IG4N7odz27+X+SuE/IUdwgy39IIea8sebK8okIGFd/F1d/jhAKxYl3vcummY5n1Kuy68hjkZ9Na0kWpStb6XsXCZT2r6Ut31TNxkv5PSp/mBF3IXSqX03XhfsE/c9mrsiSO36pFJ7f34kqZy21fdGqelX5tJtLkhm76YXST/WnRCcZ8GK/JJJrzW8kQU8xj/dEbhHXUPfGQAAAF5UGbQBXwWeERWW9KXG4Sl/xZDAo4zSmJBx7+Xmv81KXIY8xOG8XL/9i8PQ/ET75dyB0/UVhO1jWCEdlL+740rw98x8f49HqViLd1h72kbuPns6Pl+8tw9xmrczwDkXbDSX2kaT/ct56O6wk3v6rPBWalu6WwNuOlj4+JYtHRYQPMwykjfl+vcJZ98scnpKX6hnlnivbb/4QpValw/8vhXzG41ES/u+NyASCH4HpQS2r6Qe1aACPx5JuzldgYe4TBQ23200XdX1D/Y/xveu/96ZfveYKAlfORx4byP/f4yZccktuvkh9LMKPafPL8OZpw1Kt8gXbrLyelpOuEy8/aPsk63xU/Pgh/y/YmJ3u+/xheeAe9/kfaIzhPzGjtJpZGX+NJLGBG0l/uEikM/bi2KUl2z+x1WZPu9uTd/zSecfeY9zwsrkbYf7G3KYsTVelzsPWfZKjQ03fXCRpUrYkS7xBa9t/h/z/dCVhL3dTrOkj/vpsaWsypzdw/WXF5DDNN6r2PrwwHQVQrMb7yWkJMr/lSRLNFwrUiRz1xaRO3yfS5XtjbVlfluIu4D3L/5dLdu9KA7hnSDD7n7WsFfSOxXsnSDcnywNSdfBXvPF7x6OLje55dKXgouUeetBDOvOnX1hfe+odi/2E/yV+mmqG46EQX2R/l3T8sLmXFZcBVUZ8tL8+wEQpVuvl1dgwvlJeGm6CduftQWXl59dEEl6SGe3+Uu7SIzL2tOm3ksdvcnz34oS8gjdu/wpownfoXZnu25VLF+w+Y+dEkwdvaBBc2H1wncBGq0aalW4M3Pv1U5+Yhabvnn+8M3W6bMPZs/jbSI78CBf++H5di/dvHWg1ISVh4/V931XrBctFgDh9JW23bVE3UbEfpZseZYPVQcl3ZT/JYfub/iC99w6i4HAW/3V1/5H7XuNINFLzizXX73fNV/l6f3ElPnvIXZ9hexcl39/kjZVwCffQ3h2mgOtpJL5FvSZF+gN8dX9pTPIauy0zFXsKYcuGW4/402Or7fVQ8WQfn+D6znmYPP3+CGprWw/jE3Mt/Gwk1a13eJP5u0aJ/I3hCPUiv3m/6B6Pc755v/3j9Jr/J9JJedMTz3rliCz4+EfQr+9bBFdoZeN/sMbw/b+et78c7/+FDTov78sbuv7kEZnRC/65/f5Rlbgcvfc2XuC0SUffGZWrvXSd/wTbu+p1eFP1BJePov29y1/k93G9yzbvrckKEod6Snr/CT75gG6sfpKqY64/0CbunmdlyaC9kt9b5S9bZIJz3um9OUJ+CQyWGnn9y3eDt/iDvftORbqCIQnHu/b+RCdn72z/CPojflIycvf7/BId7313q+/dld230V5P6fysVPRllJX/e5mrWi6zwjszi+jve/WCK+5i62QvsDnWJpXmEr71cUV3e+6fbwiu8FJnRqw6W9Ne5du3+Mn8/vduX9v6E+mum+vqiHP5w1tczyelX/1u+jk9Ut+i3kd7hG77yhq761NvevGYQ8GHjdFrX8RUZf/xRnP3uif5WLTd+sxHf1id33vzIKF3fd93u7pV7BRve7uQTdj4Tvd33tJ/J68giWoJBD3DKSxvpfBXve08Lo4cliDfXakm3pNBEXu933vSRSShPdK997i1CPgnMfrHLhJthdKvhEzt96q1yeu8hLYUPLhYlt94tyw1/aWmu4SEuMV97v3DV71Pi/19hLMv3d9KJl7v572X3i93d77p6F5+f3u/sxuC+Jz6GZj79uX3P9Pu8n11MnQIy3n6eEfPX4Zqv8aYMvbAlbtrz3Whp63NT9ZRLYJyPwbq95/30MEzJtLOgc2c4+f/opqq+8t0Ttbzb1VP0kDAQM8RHzcBiT0XXd79Wa/yeu66fTUKZJNR1bvOyewmJFjXufbSk2T7xDbLXolkpp5PdLkyfUSVt9IltfUSZ3Ku0HPfXZITj5/7yb8jhdLWEiPpUb90kSU/G/0v+pC3Sf4JyOWny4lXxW9xW+GPVIlmiN+Ll31+93LnJ3dCxDuuCuAAABSlBm2AV8Fz3zBDHSThnz0VeHGm/4IMaDQhHy9rG7IId4FaLnzZWb/mm6C6NacW6OZ6fy/27YrOUvK/7gsvlx57hLwcszl/2n1bngoJzChcygQi4CC05bs9Tv6TcvJ+/rT3vL/l8LP7GiFDj1shK/lL85CRQ5Q6GArrQG345K0ySH9MiXruLbEraz7CShl3WB7/+2NKkZ72HbEP43B2MF60a8OxFnPI0RHGthDrpMP/H9ZfafsZBHL7M2cVCuOIf5ptAhO3HvOVHyDrXdqbewlosEOzJx4rGqXd0Euh9F6aXUWjJ+tvWpC19Zf8tv8p+eQTL/7Y0VaNLhHyeIX2UeFHjhsNpISHQePZbFb/TWtbtDdZZIquFYq8Il6Q1t3+vbv3CtpB2Pk4XD8Fr2lbfXEay+13hArEb4RKPEEHnDoS7bvT7I+x+ifBfURPY3t/JJOi899aZfdXrtwoWyiyL3MRIW4S5a93uEXjobPOJXa6jd5zbjMRe9reSkScSZ8avWBLgL/DbtYV+o2jUPuc4nswQ/Wbs+91HTitwi2y/veg9OdLhYQo/ce5c4nTkrttm3rI7G1VffPnPBLtwQ/Vom3j/Pc+pFk1C9x4iF4cvMMpPGpF3kV8XLrXBJ4ei7pU3+JKZFb7xwl4oQ99Im13+M4ZEWfyxn7k7iVtDtCrTsD9aeCCEXerG9AHivkAGI92RkYp2C42t+gP9C1JV9tP1HvONGNXnr/e+NklMgjrS0G1s5vx8RwaO984+7XUBG1M2cLsrAz54D1gTv/z+qx2LnHfrfEFtWe29fv/m93gkH7+tfjyTkU7vDDuu/vwTv/fThsr4G8flnp1jPf+vqKvaMDWr72sFRJWJTdXkbvJDd3MCENYJ48vxtoqHZYK9BoAoP/n/xwHTIhb4JW+1siW7zJ8rFwT3a+3LRst+w/PI+kmnDsAMrp2/vduFlc28Fo3ET0O8sbmsC4336j5TnWP/qEvRKy/2vk9VK68uOvjSMVk9UjtvwmaS3DYHx0rtA2V9dpAjOH4j2gvj21ViavtLcExM6+Oh4JZI0snH3WUrzBqrFxOHLzt4YcPTje+bqmfzdKo/w4JIoel5mT3RsHn5VH8n1RPuWZGBpODQXsPR/b3rUJdgkmR3VjJ6Sb3Z4Jeubvce300fQRvvuU9jsC+qfJ+lk9mLLD1ojnX1gnyjqXKF791YgmzDbwMgbJ3tKlhN+4J93e98R6QJS3u97dav71uQsq9AyamJKtf0Xe/0VnRU97+gll797/fP4QL+/hkxn7991f7fP/TKXd7/Md3SfY115IexnN2NW6z0RyqpXbVN3vcI+Cbe8rFOX4K8/ve7zb1rpoEZ3kQ0o70Q6d+6UtlGfby2X6Vd8vfqJz/e/RfWC413uY45r56K1aZUCiGXu9MytmelSF1pJzpsWJufuL3d+RkvfyRxHja7e9yoIR8Lky/Ha7AzDyQuWrzDiXtic/Ll3ftQgd993vcq9/fXkXSZiSoIS/0T12e9wl4dMULxnvKybMfGTGQf4cUNwmbfgnIXu+963b5RLu+T3/NUEJZsy1O8X191S6bFq8n6qrREHTTB8An9/a7QTHs/Tpb1xfGyux109Mgcc9/fqJ7l77v7YskZ/CqxJdGTJUVhKVhWnd/kXYvp/KVK3tuQi0uMKUh9/JZbDHp3C3iBGq8u+3d/SpKjp1fk+Mjizz6u3cl9qKjkiHRRq8SgntXENH94ZOFbTzXx/vhf0ITrkTo12T11J8QWrVGfvgsgIRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpa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4hx2Hyks/Td+yUnQff4T56bv6cKF838hnvvlk7E9dSmE8nS/21k9NGufPSiu73ffXC2SMhCpnK/Oa7O0ab5h5HGJXpXy+XPJ3Xspdmrk9pRMi/X5io5ojcRWZiIi7uXHb39Qtk/oh0rJVIksVyFW019z4/Xw98XAIRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpa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4kAna7SgYQIeh8uUdvH6PYUf4yN1fjd32rR/fL8E5N07rb1QtF5eXLr67GwREl+UGvSe69if0JK++rVeZip/uHbJf5MLLbwmIu7yZ3q+tpKnrQIT7uRPMyFS3tVckVu7gSIhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gYhS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeBiFLS0tLS0tLS0tLS0tLS0tLwhEUUAFFABRv/xClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl3gghS0tLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4GIUtLS0tLS0tLS0tLS0tLS0vCERRQAUUAFG//EKWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaXeCCFLS0tLS0tLS0tLS0tLS0tLS8IRFFABRQAUb/8QpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpd4IIUtLS0tLS0tLS0tLS0tLS0tLwAADdCZYiCAV8mKAAOKMnJycnJycnJycnJycnJycnJycnJycnJycnJycnJ11111111111///wXeAAmFEcIGm63wChQOU1oQEeEj84Ba2lPP/u7vw6IgATyCOF2cOKFpqPMANIgQwqMkPMjTYR88zMDUXZnDIT/2wMBVFRFyQ8o8AmLIC7aUBdUP35c9jxADMgEdpYBJkHUp2iKlZXx94+K8ARMxEOpH4OpLDpP8aQdXIO5Ma+G8bVvsdADZ7iv8LXiuvHTinnkOOSBqz8zMW1xGr/eFB8gIenZ4C5x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AAAGAAAAIQAAAAEAAAAHAAAADgAAAAEAAAAIAAAAIQAAAAEAAAAJAAAADgAAAAEAAAAKAAAAAQAAAAEAAAPEc3RzegAAAAAAAAAAAAAA7AAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAABKwAAASsAAAEqAAAAOHN0Y28AAAAAAAAACgAAACwAADXXAABrgQAAwYwAARKNAAFhWwABztsAAiToAAKY1gADEjk=", +} +BASE64_FILE = { + "path": "test/test_files/sample_file.pdf", + "data": "data:@file/pdf;base64,JVBERi0xLjQKJdPr6eEKMSAwIG9iago8PC9UaXRsZSAoVW50aXRsZWQgZG9jdW1lbnQpCi9Qcm9kdWNlciAoU2tpYS9QREYgbTk3IEdvb2dsZSBEb2NzIFJlbmRlcmVyKT4+CmVuZG9iagozIDAgb2JqCjw8L2NhIDEKL0JNIC9Ob3JtYWw+PgplbmRvYmoKNSAwIG9iago8PC9GaWx0ZXIgL0ZsYXRlRGVjb2RlCi9MZW5ndGggMjM2Pj4gc3RyZWFtCnicjZDfakMhDMbvfYpcD2bzTxNhFFZYe90h7AG2tTDoYO37w9S1O1A4cIyo5Bc/80mALR6pLVYY3k/hJ/RMJh6J82d4e4Dvlo2WRu1tb6UEPV538Hc4H8NqJ3C8DAWnDIQpd4lD2LdYomzcZ9O+Km1qWG0VSCRKG+xQD4FuTZeWdTcR0CiZiqtAPYXOGKOhEBnUD3hC5M0a6lcoObInwdIErsAHcI+F3cknsB3ANFJCU54Byf6B8AAvdZi9s8WokcXNFrvLEj0n0gXu5Hm8TJyiK6nm+54Ipd3IXnQiae5H5vyxTf724RdvlHTtCmVuZHN0cmVhbQplbmRvYmoKMiAwIG9iago8PC9UeXBlIC9QYWdlCi9SZXNvdXJjZXMgPDwvUHJvY1NldCBbL1BERiAvVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSV0KL0V4dEdTdGF0ZSA8PC9HMyAzIDAgUj4+Ci9Gb250IDw8L0Y0IDQgMCBSPj4+PgovTWVkaWFCb3ggWzAgMCA2MTIgNzkyXQovQ29udGVudHMgNSAwIFIKL1N0cnVjdFBhcmVudHMgMAovUGFyZW50IDYgMCBSPj4KZW5kb2JqCjYgMCBvYmoKPDwvVHlwZSAvUGFnZXMKL0NvdW50IDEKL0tpZHMgWzIgMCBSXT4+CmVuZG9iago3IDAgb2JqCjw8L1R5cGUgL0NhdGFsb2cKL1BhZ2VzIDYgMCBSPj4KZW5kb2JqCjggMCBvYmoKPDwvTGVuZ3RoMSAxNjgwOAovRmlsdGVyIC9GbGF0ZURlY29kZQovTGVuZ3RoIDgzOTM+PiBzdHJlYW0KeJztegl4VEX276m6t/dOeiFJd9a+nU4aSQOBsAaQdDZAI3uABIkkQCQoyBJQcCPOiGBwHweVccRd1EE7i0yCjjDAuCAIo4y7grg7Iui4ovT9/6q6wzLqvHzvfe97z++bezm/OnXqnFpOnXtuXdLEiKgHQKV+o8vKR7HBrDcR90I6bPSE8ZNXVmy4k0hZg3rz6MlTSqxPm64jYhHU+42fnF+wfOjmfdAX9dqpZWOrJtxywddoSiJy3Tp7Qd0idjf7Eu2VaJ8x++Kl2j0Zr/6TyH4OkbHy/EVzF+xeUb2eyH036hfNrWtcRF6yoP8R0HfOnb/i/LWfPPI+UaqTyFbSMGfB8ttq5/aAbhnI3FBfN+dg0jPojx2E/uAGCNwDLCrqmCPlNCxYurzv++ptWBzmQ5/NXzi7LrV3+h6sB/3R8gV1yxcZ1iU0QR/zIe2iugX1ntr+bxMZUGVlixY2LtXzaB34+aJ90ZL6RbmvjN2KrrEe29OQKWQmTi5iug5e+HI4fUkj6I9kgtxJ+TQVo/8JugbUFZKX3lP0+TMX7E0jo+Oo1EnHHj92qVNKTruGS4mV+uI21C2pm0Xa7BVL5pM2d0n9haQ11M9aQtr8uqUXkXayTzKkrn94ZvmKmY4RX5vTzVJ873s980T5woThm489fnyuk8x2VC0nRhSlPc5zrCYm60lnAEO4GdaWDyzAzWgQbkbDcLO4BcnVJsW9koT4GoMyUfrLSOWonUPjaRJNg+eIyk6t6++dvH/iAUVZw26CN82G9YYBmFJ6rFT+Tudzt9nAbUaVi0ulf/Pe2PHjxlMYI00zvBydyAaYRrLWsNg4jK8GDU+KHSb1Z/fl/+R6muXLe3fs5hnyfkvcav+u23BPfF9LaAYpckd7x3ZU7mVSbF6YKYP3TvLsFB4uuLB+CXRPxbgPhB6H55mkRGnFKYNSZH/5sb3T35TYgCfrJ07//+cyPEt3GabSvafU7z+1XW08+WwZC2n2KXr3/HtfpuspVRQ0XUSpirxDF1BTnGfYjYvjPIfPGuK8ghg6I86rp+gYKA1aMd4IjqiYltA8qqP5NJYqkQfqUW+EZCGJp3MQnuD+1A/tY6VkIS2lFbQIWhqdRQsgnwvdi4Aa9QGd7E3DU1IP+TLwdZCeXjup9zA0CzBCf9waZtAg+/7paKWoLQEvsA7y2Az7yjHnx8ebhxEa0NYYH71RruZi4BxoEon3RdhmNXdvE01GkhkFhTnGwZFINzZL9+wtZpGppKUlxpENlJBg7aa95YS9NW6fAHI4bN2zt1ljEzbLFCmNHCCnw/6f7bouuy1mZTnd3uVK+N+2d4F69Ejsnn1iQmzBNjmuNMJLlZKTnd2zdyTGrDC4MzZ1SgZ5Pe7u2bucsQknyHEFRx5QekZS9+yT3LEJO+S40igDlJmV0j375B6xCTvluIKjLJCmebtn70mOTRjTSI1x8nXrz07tnr03JfbEwD4txlE2KDeY0T37dIyTTnLmmTGOgqC8PK179lkZsQVj5v4YR+Iw0LdvoHv2fp80FJPPiXEyCRQUBLtnn+OXhmLTesY4JCoc4Ab36p59zxxpKGaeF+NoMGjYsN7ds8/rGVuwRkitksPBhai0pKB79v1g1Q9lLtHAGIcXN1FFxdDu2Q8uiE04T44rOKoATZ48snv2I4aASDq9OMbRZNCMc8u7Z19yZmzCODeNiXF0LmjO7Iru2Y8plYaE5Y6LcfJFa9hCqaA0w0OUqgZFXOsfgT4WZXSe/rFoFyX/FModcSLaSJvYPNpEW2k7Owqrx6mT2uk5RGcZ3UmX0620Gm+K6ZBci3fPJLxpy+hWlqq34+RyD96499Ae6E6jK2kLpTCv/gmtpFXKy7BahQyTDRdNwBvtenaOvgynqwPqb2kIzpoX0SLWpFfpN+i36PfTA9SpPKcfR0ZMw1Jm0x79c8Nr+lsIjxn0e7qDDrBbLE/gzT8N54NO5Y94961XalSmz9WPYQZ+ugRzUPFu3cO28RB6r6ePmJddrpSil/v0iL4TWhlUg3foetrCBrHR3G+YoY/V9+AM1oeWo9c7qJU24+6gv9AbzG44qt+vH0V66Y3TwEr440W2TYkevypaJBwNL/WiQrQspKfpWdrHAuyvfKHBbigwhA2X6vuRE/vTFMz2IVh+yL7lV+JeqTyjjtJLkLlX0c3C2/Q3epel4Ww6nk3lvfhCfpeyBO+03vLEMAfv/GvpdvT+DguxzdzO9yr3qY+qPxgzowf1ROxIkP6A75y/sgSsVGON7DfsFfYeL+Uz+R/4IeVW9WH1JVMdVn0eTjPX06P0LXOzoWwiO5c1sMvZanYzu4PtYfvYx7yYV/IL+RGlQVms/EUtwT1ZbVR/a7jGsNb4cbQqujP69+i3eoF+DU1EPFyF2f+e7sLKOmkvvY77AB1iBmZjibg15mdT2GW4r2TXs3vZRvYwa8co+9gh9gn7kn3NfuA40HEjT+d+no07wJfwS/it/E6+F/c+/hn/XvEo2UpIGaSMUKqVhZjVauUm3E8o76pp6l5Vh58LDOsMGwwbDY8athuOGu2m35jJvPvH+47nHX8nStE10XXR1mi7/i5ydCpiKoN8eE4n4nxVhzPmcpxRH0Ccv8zs8F0ay2Mj2TnwzEx2AVvMlsOTV7P17AE598fYU/DSq+wI5pyALwcx5758EC/h43Gfx+v5Yn4Tv4W381f4McWk2BSHkqzkKaOVGqVeWaqsUNYpEWW38rZySPlG+RG3rlpVn5qtBtWQOlqdqS5T71I/Uj8yzDC8YPjAaDUuMF5j7DB+YRpsGmmaYJpoqjHdaNps2m+uRXTuoCfoz6emAnZQuUopV56gG/gANZW/yF9EPM+kOcpYjkjlG9kafgVr5zmG5cbhfDgbR0fVIHz9DN/Av+HDlbGsgk2mC3j/WG/GJPURkd/UHXRYfQprexE9Lzfa2ZX8iNFOrfhcKcSYf1P6qSHlBXpDOcBM6j30pmplHnaYP6RMQBT8RR1pqCK/cic9pixmV9ATHGnR+oP5OsTxOPYI8kIlK2DfKfhi5+MQRUOU9+i3dCF/jQ7jOV5Dt7E56ly6gQawy+kjehBPRS/DRcY8YzJ7ns9Tm3kP1k5cfRirK2Q5TDEk0dWsRllvPMJfxyl8r2qld5Q/YfZ7+WPKWPWoYRJrwBNwBV1Di/WraIWhSn2JzSWFTaVc9SCy2+VKgepHuRJZZQZy2mY83VuQB4qVsZB4ETnnIC6mIEOsx3078oSKCJqHZ3wastiL1G6s5B0015DIkHXwBfRCdBJN1x+kO/S5dJF+C/VBPlitX44eN9IHdCNtZKuil+G8n4Un5x12jmEU32sYpffhzfx1PpmvO31/4e1c5qVPcT+Gykh8Jzerr+J1U6Rfp/8D0X0GMuwdNIvOpvexys8xwhhlGw2IjuMt+ihlEdZ7gCbqD+k+ZqUGfT6+8Z+iB0wGqjOFsMcR9hLWexnV80n6UqU+Og9+uBFeCMNby5B/rg2XTqksDheNPHPE8GGFQ4cMGjigoH+//L59eofyep3RM5ibE8j2a76szIz0tFSvJyU5qYfb5XQkJthtVovZZDSoCmfUuzwwqlaLBGsjajAwZkwfUQ/UQVB3iqA2okE06nSdiFYr1bTTNcPQPP/fNMMxzfAJTebURtCIPr218oAW2VMW0DrY9IlV4K8vC1RrkcOSHyv5mySfAN7vh4FW7m0o0yKsViuPjLq4obm8tgzdtdispYHSemuf3tRitYG1gYt4AotamGckkwz3lA9rwZd+AiYVSQuUlUdSA2ViBhElt7xuTmTCxKrysnS/v7pP7wgrnR2YFaFAScQRkipUKoeJGEsjJjmMNk+shtZqLb23NV/X4aRZtSH7nMCcuhlVEaWuWozhCmHcsojn0ve9J6vo3F1atfrU1nSludw7TxPV5ubVWuTuiVWntvoFVlejD9jy3FG1zaMw9HVwYsVkDaPxVdVVEbYKQ2piJWJVsfXVB8qFpPYCLWIJlAQami+oxdakNUdo0gp/a1pauFM/SGnlWnNlVcAfKUoPVNeVZbQkUfOkFW2pYS319JY+vVucrphjWxIdccaecCpTf6JNclJdcBWTTniWiRkFzkJARLTZGmZSFcCahgqoH0rNs4dCDVc1g1VkDnZkXsRSWtvsHCbkwj5iyHUGtOavCREQOPzZ6ZK6uMSY6/yaBCvi5ESoob2Lj4RCkbw8ESKmUuwp5jhS1gf16X1xBw8EFjk1FHAfTYBv66qH5cP9fr/Y4LUdYZqFSqRpYlWsrtGs9FYK54eqI7xWtGzrakmeIlqaulpOmNcGEMnt8n+SkiPm4Il/DmdKj/KGYRGW8h+a62PtFZMDFROnV2nlzbVx31ZUnlaLtQ890RbnIj1Kq5R0Hud4uiJbEZQzTiiLSpU9oubin1EG9ZwOkxlRKSVMGxVx1o6JYbXV7++mUYd+VFjJ4qRZfJqRYaHT68NPq582PXuzggnjVVlROb252XpaG0ItNuBZ8QIRT5VVfq00QlPwZObiX4e+baig6vRIGC4rFQqIv5goXj1NMT3OV+MS0dmn9ygkuubmUQFtVHNtc12H3jQroDkDzZ18O9/evKi8titwOvQta9Mjo66rhq8a2DA8FJxKWgJszcSWMFszeXpVJz6ztTWVVa2c8dLakuqWHLRVdWpEYSnlQiqEoqKJClUwLLKVm6V+emeYqEm2qlIg67M7GEmZuUvGaHYHj8mcXTIOmRqThaVMXCLHlFZWnRo98pGsxmcdLO7CAXs6vlUclMlSw27Nx0rNGZlZmL3LmeUgs6dDj7bb7SVTwHzZbrNJ5ptwtj0BXFCzMF84IYFPsWhOJ9DqcAC9UtKhfxXuabcbp1jSfJnORGHqtCbAzGkX/Tk1pmEV0o7QZbswlYywBnMMw0rm23bRC5jvwrAHV5M1fIY35PwmJK+aEceBI+LVmsMAKhpxfISg/v1KV4QHK+kms9FsMKtm1ZjqTfNyo81qtyZYFWNySlJKjxTFmK54/MydCPCaM/wsxeryUyjEQqE8XFexmgEuf4EnxZPiTk7iiTyQ6y8YPGTw4EEDgz2DAf9d7PtHp19ZvbRx3KU371kVbWGFNz/Qv3zsbfPHbYruNmxJzjxnVnTvzoei0YfrCjYN7l/+yYMffpuXhbXfi/OL+E60UXs42WjIMptNJlJU4XyrJctGZhOCNJzvdA80VSpna1YtgVvTElQLF/6zSI9arGIjLN325bF2i+WERDr1aJdT7cPP9YbGOb8Kdbl1rPTrOOc3NWO/ev+kT92F+SOcwrVwSrI/TveqOT/epYR+/IdytWHLpmjRn6IJmzCj+xFd2WKFzN5JCVhMSo/kgaqSZbHebd1n5VYD5zYzdqYryMxdQWYWQWYRazNrJpOxQ/9crgnMl2GbWJTRKVaE+sFwns1mnGJkYj3GmqYElsBt0kM26SGb9JAt5iHhTyum8J9cFbZJX5lFr6dHX0rcUVoC0xImJNQmLEpQh1d7QzWLu2LxZDTWxCTwlEA4r2hEYU2+DEkWGuCC70AB4P3b+bHt248bDVuOP8inHxvF246PxUzXITby4DkD/SZsZxw+M5BZU5nawR8K+01ckUtU5BIVuUSl20HwzU8eKOPPPVAf1sT2XOy02Ot12/lLhi3H/rVJ5I3Z+keGtw378X2dzlLCFWkOluRMSkr3pKerqlNNsnls6erDns2JzyQqHo83nWuZYdf4HuM94bQqQ5VlmnOKa2aP6Z6Z3qlp09LXeu7gztQsRXFn2SzJXbGQ3BULySIW5BKTg5qJ4aH4SsrBfNwuVmsS4SEWCeaoXCSYT9vFBkplsUaT2NkisW5TWlMmy3RI/zmk/xyyc0dQuM8sBGQXAjLKEDBKZ6VmzJ5x4vGoGSuyzLiuTe4SUNHhosPY35rFVFNTs7iHk/wFqkgZaiA7hw9x0oACcg3kwUA2zWZr2OAX2KhH26Obt+6Nbtn4HMt89U2WvuKTm1+Mvsp3sQXsj9ujD7x1IHr3E8+x6U9Hv43uZQNZehuz/S76Afx/D56sTYgPL2XzYWG/25bI3IMzpvvONy/wqRanWLJZokliDiJfeiZBOEQw9i7G1sW4O/RDbe60gSiPtmX3HOgS9cyeA53x0hEv0f5aW2Yw1g59Z7wU7eGzwOQmnp1xtjbZNiNjQcYSy/LEFY5V1jWO2xIednQ4Pk78yOFMtNs1lyPJ5XK4HHaLO53701KsRnzLJNgNXoslxZOWmuURM46/b7aFk8VWeDzkzxbZkbxehyPRnNUVKlldoZJ1Im1kBRPvNIoAiaeN2FMg88VAmTmMwi3GGi1nUU5TjpKT7ZUB4ZUB4ZUB4f1fPlDxVGH8aaqIP1eB4Rt/LqfGAyf1fW/8beXEHc+todBxVArz3Z5C5vIUrk7sGzJc4dwpwip06kWiP5zQwlZz2FHocA5zuYdBVM0WQ9hJifo74bTUQld2aqEblBjOKHRmJ4F8oOTCeCfV4sWWgg9JowlvN0+PgNKX45UWcEEs328B/z28eefuS3e9PPaMKefoX22fctG0Pv6Kd9k9q9aNu+2+aD/DlvHPrbjzlczcnHHLootZ/6uvG2ozHV+mDBiyYnTDNeKvsalEpotFpPLLO8mhR4XTSqZw6e7EWFbCw9ehH483KCca5LMpjhG9BKcaY7lOIJfbpMqDhCKR2+Nm4nGXZp92MV/JERDv+9ttkBjA4J0BrhcFXb3cQW8hDXYVugd7z6LRrrPco71VNM1V5Z7mdd5uvt3BW4zi/BQe4GRpqaHkgYaB9jJDmb0iudJQaT83eY5hjv3C5KWGpfbLkh2GZLtCzG0mswMnNcRpkbhc2Moa5nIXFqaHsxTVYOBGE156VizXkpDocNjxGe9OTvF4vch0I9oM5NVEaXe7RBmenmy2aIQ3pcYoiTHyGszmrGRvUnKy1223WLKS3WDdLrvDoTldSU6ny22xm73JBofLaSeOKRkUr9PhsFjMZo45ed1ul4vMaR5PmrPYwiaSRnZgMihMBjZxs6YxxlJTO9jalljw1qSljj2e5j1+PC31uHdceX3Zhyci1hm/RbBifa4uKixcPbZvaPUVO1f39f60QOCtTnTu3AkYsbOLOxVYRcQxuSLiwoG11W314pEbOrQawlwI8yDsJBKnd6qI2CBJhKTNHjaEoVSN52RJTezsdvrlZwN6pHgGD0HhRtFjAAuwYE+jibG7opc9eyAnbaiVeT59aXwgo8+HO6IXPRl9oafJkxR93rDlx6Lbfv/PHOWd42nRz/61tl157NgoteY6rX70D/fhCN1JlcoZbUGvb99TSi86COJKr9ZQpq9T6alktg73hTuUQJs7ucBR3EcR+SRfogZcCHoctFURv8WYqYgzoRO4EtQEehy0FbQPZCQCilYNtBC0AXRQtCiZSkar5nMW91RSYZuKt4ND8dARkA5SyAfMB40HzQTdCNoAMko9IVkIWgnaCjoqW8KKp/WWAZi7p3WtLNoumF8gq3Wx6owaWW2bVh0rx06MlWVnxdSGxdT6D4yJ+5bEyp69Y6U7t6BJlNaEgm3FKUoKFpmCiS8CMr6THAh0H92tJFMExBVjXBJW3G05wYINWxWVmMIVRnPIp29TWGuCq6DYynV+hNzk45/zw7EWfrgt0VWwofhsfogeB20FKfwQ7nf5u7SSHxQ+BxaBNoC2gvaCjoCM/CDuA7jf4e+Qg79N+aAi0EzQBtBW0BGQib8NdPK3xDe+RMEXgbj47Qtqb2JZbwId/A1wb/A3MLWXW4cUFnRKJpQfZ3y5ccaTHmfcKQUd/KXW73shooLYaUTUk0o2jaQBSnZrbn9fh+JtHTHP18Hfa9NCvruL+/H9FAFxzGQ/Rt5PGmgCqBa0CGQE9wq4V6gJdBPoblAEhCgDOkEa3wXaDXqF+oHCoAkgM9/XimE6+N7WYImvOIW/yJ8lDzy+hz8ny938GVm+wP8my+dRZqHcxZ9pzfJRsQ3tBBsnSifKfLQb+F/bctw+vdjFt8J3PmA+qAg0HjQTdCPIyLfy7NY5Pjc6eZJ2mQmarfSJLB+ke80UvsAXDpYiADUBwWFnggNs0DYEeTi47g5UBQRvuAWcgODV14ETELz0KnACgvMvBicgOOcCcAKC02eCExAcXwkO0MHv+nNOT9+Q8RcyrdjBL4GXLoGXLoGXLiGVXyJu+l4Vc/tDa14ePLY+HOqV52vawpqeYk2TWNO9rKmeNV3Jmq5iTSNY03msKcSaMlhTFmsKs6Yn2VC4oomF20+rFoa9rGkXa9rEmhpZU5A15bKmHNaksSHhDu5vPWuALMpl0VYsHjqUZ45E9nFwPzzqR8z7kRO2AveCdFkLQ0nLjimnZokyuy2vKFbvO6xgYfEYvgOGO7ANO+gASMUG7UAY7UAnO9CBA1gEmgnaBjoC0kFGaGdj4jdKdADzQUWgmaCVoCMgo5zOERCnhfEpPi4nlh+f9HhR4ztwiz9i+bk/nOnMcIacY5QbM5gji43P0rP4EEoRv4lwu8yuDpaw+duE775NIEuxhd/Ab6RMbMRN8fLG1u8zfR3s9tbgk77iZHYbZamIOlZIQZaLcig1yvogyjCLciBl8EdRFrRmTIWZozXY27eFJQqrzb7vM973fZLRwcF+nPGk71WtQ2Wtvn9A8uhm3/6Ma33P53eYIXkq2MFQbNGkamfGUN+mXVL1KjSsb/VdKYrNvisyRvsuzJAN9bGG8xpRCzt8k4LTfWPQX1nGLF+4EX1u9hVlnOcbEdMaJGw2+/phCqEYm4fJ9sqQgwayZIdThnSwhnBv0zpTlWm8abCpwNTb5Df5TJmmdFOS2W12mhPNdrPVbDYbzaqZ4xiTJM7LIXGKSzLKH2gaVfkDO8k7Ocmf1Mmf3XFm5nQ2RXooFbxicgle1ttmU8UsLfLN5EAHs06cHjEESljEXUEVlSWRoaGKDpM+KTIkVBExTTi3qoWxG6ohjfA1HYwqqzqYLkSr0sX/rXcSY65V16eL8oxV11dXkzfl4iJvkXukq3BU2c9AbRxPeft7T+MzI+sqJldFHsmsjhQIRs+sroj8Tvzneyf7kh0tL+tkX4iiuqpTGcm+LJ8k5MrIsurqig42VeqRxr6AHiLmC6lnxotZ6JFmzorprY/p5cIeejmigJ7FQrlSL9dikXoqE3otjTnlZS05OVLHo1Gj1Gn0aKfq7MqFTm6u1Elpol1SZ1dKk9CJjJQqGRlQycqQKiyNMqRKBkuTKlNPquTHVa49oXKtHElhJ3UyYjoJB7t0Eg5C59/PVb941ZfgFNY2vHr2DPGHi9pAeT2oNrL24gZvpGmWprXMro7/RSNYO2t2gyjr6iPVgfqyyOxAmdYyfMbPNM8QzcMDZS00o7yyqmVGuL6sdXh4eHmgrqy6bfSEgUNOG+vaE2MNnPAznU0QnQ0UY40e8jPNQ0TzaDHWEDHWEDHW6PBoORbJGJ9Q1WKmkmp8cMmyjdusiNfadH91SYpz0UgZvMP93ivTt+C0spFsoeqIPVASSQCJpj7FfYpFE54p0ZQo/joVb/JeOdyfvoVtjDc5IXYFSii0dFnjMvKWzyuL/WvEBdHSZcLhMQw1/tKFtvJIuK6scSnh5JyHk3MRTs4tJhOktWJJkWFdMputHF/dMWFfCIcJoaKcUBSyEUJmscQVf7r/y+Kl/Bxt4k+2sXAWW0qN1Uokq6KSIxVUxv8MsAVnKfF6aKzGAhtZiDV29RGfduxrVxRizV20dFmci/tiabyMWcKkscslJy7hrNAJjy1Fh+JSSGHiMigK4/IL6zPbNvrOrBNSoB4lC1n042Qlq/zNjA1oJzswgRKAiRId+OI+Tk584B4nF/BHHENdwB7kBiZRD2Ay8AdKoSSgh5KBXuAxfCF7wKdRKvh0SgNmSMykdGAWZejf4+grUKNMoB8H2+8pmzRgAPgd5ZAfmEvZwCDwW+pJAeAZlAPEdy4wT2KIeurfUG86A9hHYl/KA+ZTCNiP+gD7A7+mAuoLHED5wIHUT/+KBkkcTP2BQ2gAcCgN1P9FhRKH0SDgcIkjaDDwTBoCHElDgUVUqH+JL8xhwGIaDiyhEcBS4BdURmcCy2kkcBQV6UdpNIWBY6gYeBaVAM+WWEGlwHOoDDiWRulHaJzE8TQaOIHGACfSWfrnNEniZDobWEkV+mGaQmOBUyVOo3HAKhqvf0bVNAE4HXiYzqWJ4GfQZGANVQLPkziTpuj/pFqaCqyjacBZwE9pNlUD59B0YD2dCzyfZuif0FyJDVQDnEfn6R/TBVQL/kKJ86kOuIBmQX4RzQYulLiI5ugf0WKqBy6hucBGiUupQf+QltE84MV0AfAS4Ae0nC4ErqAFwEvpIuBlEi+nhcAraBHwSlqsv08rJTZRI/AqWgr8DS3TxW9BLgZeLXEVXaIfomtoOXA1rQCuoUuB19Jl+rvUTJcD19IVkFwHfJeupyuBN9BK4I10FfAm4EG6mX4DvIV+C/wdXa0foFsl/p5WAdfRauBttAattwMP0B10LXA9Nevv0B9oLfBOug74R4l30Q3ADXQj8G66CXgP8G26l24G3ke3AO+n3wEfoFv1t+hB+r3+Jj1E64Ab6TbgwxIfoduBj9IdwD/RH4CbJD5GdwIfpz8CI3QXsAX4BrXSBmAb3Q1sp3v11+kJuk9/jTZL/DPdD+ygB4Cd9CBwi8QnaSPwKXpYf5X+Qo8An5a4lR4FbqM/Af9Km4Db6THgDnpcf4V2UgT4N2rR/0HPSHyWWoHPUZu+n56nduAuegL4Am0G7qY/A/dQB/BF6gTulbiPtgD/Tk8BX6K/6C/Ty8CXaD89DfwHbQW+Qtv0v9OrEl+j7cDXaQfwDdoJfFPiW/Q34Nv0DPAdelbfRwckHqTn9b30Lu0CHqIXgO9JfJ92Az+gPcAP6UXgR7RPf5E+lvgJ/R34Kb2k76F/0svAzyQepv3Az+kVfTcdoVeBRyV+Qa8Bv6TXgf+iN4BfSfya3tJfoG/obeC39A7wO+Au+p4OAI/RQeAP9C7wR4nH6T39eYrS+0CdPgD+N6f/38/pX/zKc/o/u53TP/mFnP7JT3L6x7+Q0z/6SU7/sBs5/f0TOX3JaTn9vV/I6e/JnP7eT3L6IZnTD52S0w/JnH5I5vRDp+T0d3+S0w/KnH5Q5vSDv8Kc/vr/o5y+/785/b85/VeX03/t5/Rfb07/pXP6f3P6f3P6z+f05379Of1/ABquEH0KZW5kc3RyZWFtCmVuZG9iago5IDAgb2JqCjw8L1R5cGUgL0ZvbnREZXNjcmlwdG9yCi9Gb250TmFtZSAvQXJpYWxNVAovRmxhZ3MgNAovQXNjZW50IDkwNS4yNzM0NAovRGVzY2VudCAtMjExLjkxNDA2Ci9TdGVtViA0NS44OTg0MzgKL0NhcEhlaWdodCA3MTUuODIwMzEKL0l0YWxpY0FuZ2xlIDAKL0ZvbnRCQm94IFstNjY0LjU1MDc4IC0zMjQuNzA3MDMgMjAwMCAxMDA1Ljg1OTM4XQovRm9udEZpbGUyIDggMCBSPj4KZW5kb2JqCjEwIDAgb2JqCjw8L1R5cGUgL0ZvbnQKL0ZvbnREZXNjcmlwdG9yIDkgMCBSCi9CYXNlRm9udCAvQXJpYWxNVAovU3VidHlwZSAvQ0lERm9udFR5cGUyCi9DSURUb0dJRE1hcCAvSWRlbnRpdHkKL0NJRFN5c3RlbUluZm8gPDwvUmVnaXN0cnkgKEFkb2JlKQovT3JkZXJpbmcgKElkZW50aXR5KQovU3VwcGxlbWVudCAwPj4KL1cgWzAgWzc1MF0gMzkgWzcyMi4xNjc5NyA2NjYuOTkyMTkgMCAwIDcyMi4xNjc5NyAwIDAgMCA1NTYuMTUyMzQgMCAwIDc3Ny44MzIwMyAwIDAgNzIyLjE2Nzk3XSA1OCBbOTQzLjg0NzY2XV0KL0RXIDA+PgplbmRvYmoKMTEgMCBvYmoKPDwvRmlsdGVyIC9GbGF0ZURlY29kZQovTGVuZ3RoIDI2NT4+IHN0cmVhbQp4nF2RTWuEMBCG7/kVc9welmi6snsQYdcieOgHtf0Bmow2UJMQ48F/33xsLXQggYd538nMhNbtU6ukA/pmNe/QwSiVsLjo1XKEASepSM5ASO7uFG8+94ZQb+62xeHcqlGTsgSg7z67OLvB4Sr0gA+EvlqBVqoJDp9157lbjfnGGZWDjFQVCBx9pefevPQzAo22Yyt8Xrrt6D1/io/NILDIeeqGa4GL6TnaXk1IysxHBWXjoyKoxL98kVzDyL96G9Ts5tVZdrpUkZpEdaRHlqhJVEQqWKJronN85V4v/62+N8POUcYuqdLprk750F5Y4z47X631Y8ddx3nDpFLh/h1Gm+AK5wck/4erCmVuZHN0cmVhbQplbmRvYmoKNCAwIG9iago8PC9UeXBlIC9Gb250Ci9TdWJ0eXBlIC9UeXBlMAovQmFzZUZvbnQgL0FyaWFsTVQKL0VuY29kaW5nIC9JZGVudGl0eS1ICi9EZXNjZW5kYW50Rm9udHMgWzEwIDAgUl0KL1RvVW5pY29kZSAxMSAwIFI+PgplbmRvYmoKeHJlZgowIDEyCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwNDUwIDAwMDAwIG4gCjAwMDAwMDAxMDcgMDAwMDAgbiAKMDAwMDAxMDExMCAwMDAwMCBuIAowMDAwMDAwMTQ0IDAwMDAwIG4gCjAwMDAwMDA2NTggMDAwMDAgbiAKMDAwMDAwMDcxMyAwMDAwMCBuIAowMDAwMDAwNzYwIDAwMDAwIG4gCjAwMDAwMDkyMzkgMDAwMDAgbiAKMDAwMDAwOTQ2NiAwMDAwMCBuIAowMDAwMDA5Nzc0IDAwMDAwIG4gCnRyYWlsZXIKPDwvU2l6ZSAxMgovUm9vdCA3IDAgUgovSW5mbyAxIDAgUj4+CnN0YXJ0eHJlZgoxMDI0MgolJUVPRg==", +} +BINARY_IMAGE = ( + b'GIF89a=\x00D\x00\xf7\xa8\x00\x9a,3\xff\xc0\xc0\xef\xc0\xc0uXg\xfc\xf9\xf7\x993\x00\xff\xec\xec\xff\xa0\xa0\xe5\xcc\xbf\xcf\x9f\x87\x0f\xef\xef\x7f\x7f\x7f\xef\x0f\x0f\xdf\x1f\x1f\xff&&_\x9f\x9f\xffYY\xbf??5\xa5\xc2\xff\xff\xff\xac\x16\x19\xb2&\x00\xf8\x13\x10\xc2& \xdf`PP\x84\x9b\xf8\x03\x00\xb5\x0b\x0c\xdf\x0f\x00>\x9a\xb5\x87BM\x7f`P\xd2\xa5\x8f\xcc\x19\x00\xa5,\x00\xec\xd9\xcf\xe5\x0c\x00\xeb\t\x00\xff\xd9\xd9\xc7\x0c\x0c\x0f\x0f\x0f\xffyy~MZ\xfb\t\x08\xe5M@\xfb__\xff33\xcf\x90x\xf2\xe5\xdf\xc3\x06\x06\xbf\t\x08\xff\xb3\xb3\xd9\xb2\x9f\xff\x06\x06\xac)\x00\xff\xc6\xc6\x0c\t\x08\xf9\xf2\xef\xc9s`\xb8#\x00\x9f/\x00\xff__\xff\x8c\x8c\xc5\x1c\x00\xdf33\xffpp\xcf\x19\x19\xc0\x13\x10\xbf\x90x\xf7YY\xff\xf6\xf6\xe7??\xd7&&\xefLL2& \xdf\xbf\xaf\xbf\xbf\xbf???\xc5M@cn\x81_\x00\x00___\xcb00\xd8\x13\x00YC8\x80\x80\x80\xf3RRsVH\xc490\x10\x10\x10\x917@\xf2\x06\x00\xcf@@\xca\x86pooo\xa3!&\xc1\x1d\x18\xcf//\x1f\x1f\x1f\xdf\x00\x00\xd2\x16\x00\xcb\x90x\xbf\x1f\x00\x19\x13\x10\xf3\xd0\xd0\xe399&\x1d\x18Yy\x8e\x8f\x8f\x8f\xff\xa9\xa9\xcb\x13\x13\xbf00SF@\xb6& >\x1d\x18\xfb\xdd\xdd@@@\x99\x93\x90\xff\xbc\xbc\x7fPP\xaf\xaf\xaf\xc6VHzsp\x93& \xb7pp\xb3\x86ptPP|pp\xafOO\xd0\xd0\xd0\xef\xef\xefL90\xbc\xa9\xa0o0(\xeb\xb0\xb0\xff\xe0\xe0\xff\xd0\xd0\x870(K0(\xc9|h\x9f__lct\xebFF\xcf\xcf\xcf\xe0\xe0\xe0b& \xff },(@0(\xa9\x93\x88\xa6|h\x1f\xdf\xdf\xd5\xac\x97\xe2\xc5\xb7\xc7`POOO\x9cyhppp\xff\x80\x80\xff\x96\x96\xd7``\xcc\x99\x7f,\xb0\xcf\xbf\x00\x00\x00\x00\x00\x00\xff\xff\xff\x00\x00\xffff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\xf9\x04\x01\x00\x00\xa8\x00,\x00\x00\x00\x00=\x00D\x00\x00\x08\xff\x00Q\t\x1cH\xb0\xa0\xc1\x83\x08\x13*\\\xc8\xb0\xa1\xc0\x1b\x07\x0c8\x9cHq\xa1\x89\x14\xa72F\xac\xc8\xb1\xa2\t\x1f\x19Cj\x94\xd8\xb1$B\x03\x07D\xaa\x1ci\xb2%*#3V\xcad\xe9\xb2\xa2\x9d 3s\x9e\xdaX\x93!"\x8c:\x83\xf2\xeci\xf0c\xd0\xa3!\x87\x12E\x89\xb4iR\x92.a:\x9d\xfa\xb4\xe5\x0c\x9cT\xb3\xee\x84:\xf1\x06P\xad`\x95*4\n\xb6l\xd5\x84\x06>\x99]\x1b\xb2\xc5\x9c\x83F\xda\xb0\x9d{\xe4\x84\x00\x83W\xe7\xaeM\xe2f\xd4\xa8\xbb\x03\xbd\xea5kE\x88_\xbf\x80\x0fy\x1a\\\xb6\x08\x92\xc3\x87\x01\x070\xe5\x00\x02\xe3\xa9-\x80\xc4\x80\x1cY\xe0dS\x94-_\x0ezd3\xe7\xce\xa8>\x83\x0e=Zf\x92\x13\xa7Gm\x18 \xe1\xaf\xe7\xd5\xb8+\xb7\xceX8\xf6(\xda\xa2D\xd9N\x8d\xbb\xb8n\xc6\x8e}\x8f\xfa\x12<\xf8\xf0\xcf\x11\x1a\x14\x07}|mf\xdf\x00\x9elP\xd1\\\xb8dSaJ\x95\xffz }zu\xadiLs\xa6\xb0&8\x80\x01\xdd\x9f\x9b\x8a ^<\xf9\xe9\xac\xa9:\x82\x1d{\x83\x84\xe6\xef\xc5\xf7\x1d}\xf5\xd9W\x9eq\xa2\x1d\x95\x84a\xb1\xa9\xb0\x01\x00\xdd\x05\xd8\x9c|\x04\x16X\x8a\x02\x0b0\x80\x9f\x0b=\xe8\x94\\l\x1et \n\x00\x10\x02\x08\xdf\x84\x03ZX \x86\x1a\x16W\x03\x87+]\xe7[\x06\x00\x96\xe8\xde\x89\xce\xa5\xa8\xe2\x8a\x19N\xf7b\x87\x19\xa5\x17\x1b\x05\xa3P\x10\xa1\x8d#\xe2X\x9b\x8e;\xf2\xd8"n/\xd6\xd5\xdf\x13\xa2x\x80$\x89\x11\x9e\xd8\x81\x16\x146\xb9#\x8b\xd3\xf9\xe6\xc1\x7f\xa2\x0cp\xe5\x99\x12\xa8\x80\xdad\x15zi!\x98\xab\xf9Ff\x99gvG$g\xdf1\xa0\x80\x9bM\xc2\t\x19\x00\x19p\xd9\x9d\x99G6\xd7Hl\xdf\x99\xc2\xc8\x9e|~\t\x88)~Q@c\x99\xa3\x0cZg\x06\x00\xf8\x96\xa8)\x0c,\xc0h\xa3\x05^\x02\xe9(\x93Rji\x84\xcb)\'\x1fn\x9d~\nj)\xa3\x0e\xffZis\x84\x06\xd7\x81\xaak\xae\xc6\x01\x07\xa0\xb5\xfa*\xac~\xc9z\xaa\x04\x03l\x80+b\xb7\x81V@\x01$\xac\xd6\xe9\xab\xb1\xd2:kpj\x0ep\xe7\xb1\xab\x9aRA\x01!\x14\xd7\xc0\x03\x8dF\x1b\xdc\x00\xd3\x8ar-\xb6\xc8\x12\x07Z\t\x15\xf0:\xdd\xb7n\x8ak\xaa(\x1ddz\xac\x14\x86\x80\x92+~\xf8\xc1\xbb\xa3\xbc\xe4\xae\xe1\x01\xbaR\xfcAG\'\\\xa4\xab\x1a\xbf\xef\x82k\xa1\xbc\x03\xa3\xeb\xd7\x1d\xa4T\xcc\x87\xc2\xc5qP\x02\xc3\xab\xf9+\x9e\xb8OH\xec\xd7\x1bYTL\x8a\x1f~\xa1\x91\xecj"\xd8\xc01n\xfe\x8e\xdaA\x06\xe7\xa2;\t)Q\xb0AJ\x15\\\xa8\xbc2h!\x14\xe0\xee\xcb\xa05\x10\xc6\xa8"s&\x07\n\x13L\xb0sA\x0b\x9b\xa2\x81\x08"h\xf02\x0f\x15\xe0\x964g2\xa8\xd1D\xd3\xa4\xe8\x01\xf5t\x1c\x14`\xc6\xcb\xcbN\x11\xe7\xd6\x87]@\xca\xd7\x8f\x90\xf2\x01\x08#\x10t\x80$\xc5\x99\xc1-\xc7?\x14\xff@\xc6\xdal\x8f\xe2\x04)b0\xb1\t)}\x84\x12J&\x04\x05\x02\xc5\x18\xb8\xd9P\xc0\x0f\x1c\x93`5h\x81_\xb0H(j\x98\xacD( \xc0`P\xc5\x8f\x83\xa6\xc1\xb6;l1\x9d\x06\x1bk\x9d4\x18:(\x1e\n\x15&sR\xb7A9\xc0Q\xf1 \x18X\x00Z\xdf<\x84\xa0:h$H^\x1cgC\\\xa0\xdc\x10\x9a\xc8\xae8\x11gdQ\x07\x01\x07!\x10\n\x11W| {\xef\xa6\x90\xb0m\x01"T B\x01<\xa8\xed\xba_X|pE\x1e\xa7\xc9\xe0D\x19\xce\xcb\xbe\x04\xf5\x08\x11\x80@\x02\xf1+\xce}\t!\xecP\xc1\x0ed\xb8\xdc\xf9\x86\xa0\x88\x8aQA\x06\x90\xc1\x02\xfc\xf2G\x83\x1c4\xc4~\xf8\xcb\x1f\xf7^v\x98D\x98\x0c\x07\xca\x1b\xc5\x05\xba\x90\xbfP`Bt\x14\x81`\x07\'\xc8/\xbf\xc8@\toC\x01)\x9c\x00\xbb\x0e\xd2\xcd$"\x94\xa0\xef\xf0\xe3\x978\xe0l\x02^ \x05\x07\xf3\x97\x00\x04\xd0\xaf%1t\xde\x0b|X\xb0\x820\x8db\x0f\xa4`\xc2\x04\x16@\x8a\x0e\xce\x8f(\x02\t\xa2\xec\x86X\xc4\xb5\x15"\x898\xc4A\xfc\x1a\x08\xc5\x82HQqT\xc4\xdc("A\n<\x08\x02\x05\x94\x90\x1d\r@\xd8E\x83|1\x14T\xbc\x80\x0e>@\n\x14\x88An\xa0\xbb]\x1b\x13\xf2F\xd9Y\xc2dg\xe8\xe1\x1e\x1d\xd2\xc7P\xa0\x10\x07\x84\xf8\xe1 \x1fx\xbf\xfc\x11\xa1\x12\x90XdG\x82\xb8FI\x02q\t/\xb4\xa4&[\x12\x10\x00;', + "png", +) +ARRAY_TO_BASE64_IMAGE = ( + "data:image/png;base64," + "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" +) +BASE64_MODEL3D = { + "path": "Box.gltf", + "data": "data:;base64,ewogICAgImFzc2V0IjogewogICAgICAgICJnZW5lcmF0b3IiOiAiQ09MTEFEQTJHTFRGIiwKICAgICAgICAidmVyc2lvbiI6ICIyLjAiCiAgICB9LAogICAgInNjZW5lIjogMCwKICAgICJzY2VuZXMiOiBbCiAgICAgICAgewogICAgICAgICAgICAibm9kZXMiOiBbCiAgICAgICAgICAgICAgICAwCiAgICAgICAgICAgIF0KICAgICAgICB9CiAgICBdLAogICAgIm5vZGVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImNoaWxkcmVuIjogWwogICAgICAgICAgICAgICAgMQogICAgICAgICAgICBdLAogICAgICAgICAgICAibWF0cml4IjogWwogICAgICAgICAgICAgICAgMS4wLAogICAgICAgICAgICAgICAgMC4wLAogICAgICAgICAgICAgICAgMC4wLAogICAgICAgICAgICAgICAgMC4wLAogICAgICAgICAgICAgICAgMC4wLAogICAgICAgICAgICAgICAgMC4wLAogICAgICAgICAgICAgICAgLTEuMCwKICAgICAgICAgICAgICAgIDAuMCwKICAgICAgICAgICAgICAgIDAuMCwKICAgICAgICAgICAgICAgIDEuMCwKICAgICAgICAgICAgICAgIDAuMCwKICAgICAgICAgICAgICAgIDAuMCwKICAgICAgICAgICAgICAgIDAuMCwKICAgICAgICAgICAgICAgIDAuMCwKICAgICAgICAgICAgICAgIDAuMCwKICAgICAgICAgICAgICAgIDEuMAogICAgICAgICAgICBdCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgICJtZXNoIjogMAogICAgICAgIH0KICAgIF0sCiAgICAibWVzaGVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgInByaW1pdGl2ZXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgImF0dHJpYnV0ZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJOT1JNQUwiOiAxLAogICAgICAgICAgICAgICAgICAgICAgICAiUE9TSVRJT04iOiAyCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAiaW5kaWNlcyI6IDAsCiAgICAgICAgICAgICAgICAgICAgIm1vZGUiOiA0LAogICAgICAgICAgICAgICAgICAgICJtYXRlcmlhbCI6IDAKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgXSwKICAgICAgICAgICAgIm5hbWUiOiAiTWVzaCIKICAgICAgICB9CiAgICBdLAogICAgImFjY2Vzc29ycyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJidWZmZXJWaWV3IjogMCwKICAgICAgICAgICAgImJ5dGVPZmZzZXQiOiAwLAogICAgICAgICAgICAiY29tcG9uZW50VHlwZSI6IDUxMjMsCiAgICAgICAgICAgICJjb3VudCI6IDM2LAogICAgICAgICAgICAibWF4IjogWwogICAgICAgICAgICAgICAgMjMKICAgICAgICAgICAgXSwKICAgICAgICAgICAgIm1pbiI6IFsKICAgICAgICAgICAgICAgIDAKICAgICAgICAgICAgXSwKICAgICAgICAgICAgInR5cGUiOiAiU0NBTEFSIgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAiYnVmZmVyVmlldyI6IDEsCiAgICAgICAgICAgICJieXRlT2Zmc2V0IjogMCwKICAgICAgICAgICAgImNvbXBvbmVudFR5cGUiOiA1MTI2LAogICAgICAgICAgICAiY291bnQiOiAyNCwKICAgICAgICAgICAgIm1heCI6IFsKICAgICAgICAgICAgICAgIDEuMCwKICAgICAgICAgICAgICAgIDEuMCwKICAgICAgICAgICAgICAgIDEuMAogICAgICAgICAgICBdLAogICAgICAgICAgICAibWluIjogWwogICAgICAgICAgICAgICAgLTEuMCwKICAgICAgICAgICAgICAgIC0xLjAsCiAgICAgICAgICAgICAgICAtMS4wCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJ0eXBlIjogIlZFQzMiCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgICJidWZmZXJWaWV3IjogMSwKICAgICAgICAgICAgImJ5dGVPZmZzZXQiOiAyODgsCiAgICAgICAgICAgICJjb21wb25lbnRUeXBlIjogNTEyNiwKICAgICAgICAgICAgImNvdW50IjogMjQsCiAgICAgICAgICAgICJtYXgiOiBbCiAgICAgICAgICAgICAgICAwLjUsCiAgICAgICAgICAgICAgICAwLjUsCiAgICAgICAgICAgICAgICAwLjUKICAgICAgICAgICAgXSwKICAgICAgICAgICAgIm1pbiI6IFsKICAgICAgICAgICAgICAgIC0wLjUsCiAgICAgICAgICAgICAgICAtMC41LAogICAgICAgICAgICAgICAgLTAuNQogICAgICAgICAgICBdLAogICAgICAgICAgICAidHlwZSI6ICJWRUMzIgogICAgICAgIH0KICAgIF0sCiAgICAibWF0ZXJpYWxzIjogWwogICAgICAgIHsKICAgICAgICAgICAgInBick1ldGFsbGljUm91Z2huZXNzIjogewogICAgICAgICAgICAgICAgImJhc2VDb2xvckZhY3RvciI6IFsKICAgICAgICAgICAgICAgICAgICAwLjgwMDAwMDAxMTkyMDkyOSwKICAgICAgICAgICAgICAgICAgICAwLjAsCiAgICAgICAgICAgICAgICAgICAgMC4wLAogICAgICAgICAgICAgICAgICAgIDEuMAogICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgICJtZXRhbGxpY0ZhY3RvciI6IDAuMAogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJSZWQiCiAgICAgICAgfQogICAgXSwKICAgICJidWZmZXJWaWV3cyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJidWZmZXIiOiAwLAogICAgICAgICAgICAiYnl0ZU9mZnNldCI6IDU3NiwKICAgICAgICAgICAgImJ5dGVMZW5ndGgiOiA3MiwKICAgICAgICAgICAgInRhcmdldCI6IDM0OTYzCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgICJidWZmZXIiOiAwLAogICAgICAgICAgICAiYnl0ZU9mZnNldCI6IDAsCiAgICAgICAgICAgICJieXRlTGVuZ3RoIjogNTc2LAogICAgICAgICAgICAiYnl0ZVN0cmlkZSI6IDEyLAogICAgICAgICAgICAidGFyZ2V0IjogMzQ5NjIKICAgICAgICB9CiAgICBdLAogICAgImJ1ZmZlcnMiOiBbCiAgICAgICAgewogICAgICAgICAgICAiYnl0ZUxlbmd0aCI6IDY0OCwKICAgICAgICAgICAgInVyaSI6ICJkYXRhOmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTtiYXNlNjQsQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUNBUHdBQUFBQUFBQUFBQUFDQVB3QUFBQUFBQUFBQUFBQ0FQd0FBQUFBQUFBQUFBQUNBUHdBQUFBQUFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQ0F2d0FBQUFBQUFBQUFBQUNBdndBQUFBQUFBQUFBQUFDQXZ3QUFBQUFBQUFBQUFBQ0F2d0FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQXZ3QUFBTDhBQUFBL0FBQUFQd0FBQUw4QUFBQS9BQUFBdndBQUFEOEFBQUEvQUFBQVB3QUFBRDhBQUFBL0FBQUFQd0FBQUw4QUFBQS9BQUFBdndBQUFMOEFBQUEvQUFBQVB3QUFBTDhBQUFDL0FBQUF2d0FBQUw4QUFBQy9BQUFBUHdBQUFEOEFBQUEvQUFBQVB3QUFBTDhBQUFBL0FBQUFQd0FBQUQ4QUFBQy9BQUFBUHdBQUFMOEFBQUMvQUFBQXZ3QUFBRDhBQUFBL0FBQUFQd0FBQUQ4QUFBQS9BQUFBdndBQUFEOEFBQUMvQUFBQVB3QUFBRDhBQUFDL0FBQUF2d0FBQUw4QUFBQS9BQUFBdndBQUFEOEFBQUEvQUFBQXZ3QUFBTDhBQUFDL0FBQUF2d0FBQUQ4QUFBQy9BQUFBdndBQUFMOEFBQUMvQUFBQXZ3QUFBRDhBQUFDL0FBQUFQd0FBQUw4QUFBQy9BQUFBUHdBQUFEOEFBQUMvQUFBQkFBSUFBd0FDQUFFQUJBQUZBQVlBQndBR0FBVUFDQUFKQUFvQUN3QUtBQWtBREFBTkFBNEFEd0FPQUEwQUVBQVJBQklBRXdBU0FCRUFGQUFWQUJZQUZ3QVdBQlVBIgogICAgICAgIH0KICAgIF0KfQo=", +} +SUM_PIXELS_INTERPRETATION = { + "scores": [ + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.9217332561281606, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.8478093032233159, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + 0.7775525960239336, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.28228141285466124, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.7110596409959468, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.5717043041883806, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.17004439297432927, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.6232387569967188, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.349160393746381, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + 0.37415556842308434, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + [ + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.4147847905809689, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.21617448369040726, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.4393939393939394, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + 0.8667245705462266, + ], + ] + ], + "alternative_outputs": [ + [ + [1793106], + [1795539], + [1797837], + [1800021], + [1815417], + [1802088], + [1806420], + [1824192], + [1818906], + [1804818], + [1813338], + [1812561], + [1811298], + [1817472], + [1810533], + [1797249], + ] + ], +} +SUM_PIXELS_SHAP_INTERPRETATION = { + "scores": [ + [ + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.36599426908032084, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.9044030984144017, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.5780729041010304, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.03706410007949775, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.4724172299368354, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + 0.5148839775509372, + ], + ] + ], + "alternative_outputs": [[]], +} + +FILE_TEMPLATE_CONTEXT = { + "file_count": "single", + "value": { + "path": "sample_file.pdf", + "size": 10558, + "data": "data:application/pdf;base64,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", + }, + "path": "file", + "label": None, + "show_label": True, + "style": {}, + "elem_id": None, + "interactive": None, + "visible": True, +} +BASE64_MICROPHONE = { + "path": "/var/folders/t1/j7cmtcgd0mx43jh9nj_r9mmw0000gn/T/audiovb4gqjpc.wav", + "data": "data:audio/wav;base64,GkXfo59ChoEBQveBAULygQRC84EIQoKEd2VibUKHgQRChYECGFOAZwH/////////FUmpZpkq17GDD0JATYCGQ2hyb21lV0GGQ2hyb21lFlSua7+uvdeBAXPFh1upJLeC6SCDgQKGhkFfT1BVU2Oik09wdXNIZWFkAQEAAIC7AAAAAADhjbWERzuAAJ+BAWJkgSAfQ7Z1Af/////////ngQCjQdyBAACA+4PMpH/n1EPs4MPlDak5Fzh3pT23QOozrpMIemMucj6646WZTq/qWAjImUB4j/aEtJ08SjAyqjqFq+2zZ5BmqSKaDZJtE8pZRnh7pd/ez05WinXc/FkOyULyhFtAKY7v5MAAAAAAAAAAAAAAAAAAAKADzFGuPnjkNLV2iu/mGqmEkZOFkTDa9XGu/V+C8YKNhgXB0voRMsMX5rHf2WcKpFvpWqoiFsq5scEBbG0cNIjdGoU+Z3Scu5r9OMpyp0ETCKhFwi+D/g/ukqguM4i4rX7bjr3/IZCXAiOQ40t44c3thLsE9d7N/U6uePnhBMMh4hOCoQEL9bQcJHJpEL8EJsRPhIMhSZI9/aBmdmUAb56PS8k6qVyW57IMTYbCOJ9d0wjC1rwuLwUWeX6YCLfpX3T2QXdSsjThYFKwgsJm4i33Piwe/liwLaUeKfa4XjbkP5zsHX4C78gpFRf77q3Pg5bvCukbN416f+vQiBunXlcZ/RSdUXg9phF/TftxJ8NOk+sxY19g0TVRy2UMBV9uVxW9nFrQCLYxhOK50MLQDvEtRzEFGD8rvpc3cF7vKRFT9ObTh9vUx5pZ5Z0V7xngOWsz/DlxbzMBcRYOHeczi0aYAQZQqgnfAaNBO4EAPID7g2RpPsoN+j5Q9aclGv5D1s9CdoTT+mmvJ26cRh1bNNaI2isW9knZ3H+8hpVtpGfeLsG+6aQ8kkThDo84BlIX26mGsWfAaZlM0eJlPWlqxudzu2IFQXqLOzk819lC3X3zG4c+9EVLhEDepIDmRnjv6VCyjH6HmsJKeuZo/Lu0k/7RQww2vY/i9azLH5f0ew0XFNrHruB8MgFpwwzVxQttXpwhHTAl0B1zujsaaNX1+6vYSsv4DBORFKQiPYb69Nc+Sd46gbcItW11c6DcmdD0Jj8XOcNtjXKMryjRWdmEiYrAXVUTkZLsnIZJxpH3Dzs0V658BEWYfgNsrlVi2/8KaqOFpPXMyoZ4M1sWKtk13pRAk7xeQS0OqLKSkn8rzX1pPkKuONL0/vn8KKi9auAWZBE8+0u0JKNBe4EAeID7g3V/ImgFnHyflxJxgesfQU/hEw2cW/PTo6SRV89BxbmEbiiUEffK49yo3jalZn31EOX+GrVfONzQDcwz6+39msxgr7yRHJBXlCrGuDPhZn1yEg0nbQoC6cuaiocVGYivipU4B/cVG+SM/1JUZ1dOSMSi7IzUx/cIPxL9L329mCSn+d7e055zJthQaWzB35p0XbeLEmEDGf2xbm4Bt3eg0ROZMmKHC4tsVohbvjurVAhm31fk6KysYxJ3txAuMC6A6mpQMFmo9ADCLqwFP1rPFcR5+DNMCG+m4dvKSmF71lXvKi6kIVEP2U3KIsekd0GHY6W4QpybjUBlcIvjEwFMJcGpoeBpVZ5O+HEIONYCOJ8y4Z68uThakypsLKgqkPa4bvnATI6Hj9WLkg43nnLxWXFIobaw6mrpqR7+JuwtY4eL37PP1hTYv6ypROfDtonK6CtKUZbae3Atqgk8dsiYy6f7UXPmovQcgK2j6VCK+k24/T2rrkqjQYOBALSA+wM746KTKovZvocJZAogLOpprNkJuKrxFmMsLcdV/47iA8juYNVF2DA+W4KiFx6t7bflq2DELtamBLn4H/5wvv3LBStiTBgg1fgcO+p1iWuEg1RqSvLOVJE6oVZUrRxqtEWRewOCVDMNand7Exdc4rsjl+d8TMeMdalskYwKiDRTPxjIu7jr4sFGehIAL5bod1tiEOq7YyPdSliPnxRT4VbrICMoy80t5E6+2H01d2eReYzsRtuP4uqAudLvM4zL/2pWwH2wC1QGEEIiKkDFAbAYPFmwqKxMEzm+uXr5xnbMB69B6pyqsp+yq9cWoT96Oh+XMMu6DmtVN1Q/qzkUET8zrXOb0sJ817V2Zaj+0QVAlmhjFVGE1q72JcXE2+PN/KFXMooVaS2rXraiJYiXCsc9FcmRo/JVjf51LVKtyaxGp3syZghPwnyiNhGpbXCA0yDn+qsx7zItsxbmjL3eG6mwI0jkdxMhy55MpbCpqBESfIiZiw2IHXxQtI6KPaqjQYOBAO+A+wMaWBXecBWrz98jGAjM2LAvlKxUqbKiDsOE97P6bQkKXREtptUPWrrOVJzSgiTue5uAOfnKc3lHkixhmZiIC6M+hmmWc0NxW8OekQfhpmE+juG6BoUE3FTKuRPrmGytfqahopLAtWxxvNDgX4TaoqylsdgXpMaS3ZinkA1UvsYQPxc56FIj4lFeF3f8ea39rtA1JzZka1asIQJl8wor2zoRzCW6+jX6anhLKEBjCuPy7TwZ1ACCpU1tw68DvFN0nqNpAsb0QdYOst2y8CjU2QshwUQIPLMhws+PipOdCawbkX/VltWSl3DGmJGx88lRf1AsGvGmykCkfuqXkTbVuUPeuFwHYNKmkcUs99U8aYYZyiOv8BjJzo3vQmYNAIrb+EcjUIlSE3ecrAVZv2oBGY04Ntf9oFYPUGWLRvvd8UswScVxAFToUISFozdpgrfZwWtYikqw8sTkxZRI/YDXY2Epk2O8w9XMVYdxI4FojNsKQXpYFnolP5vyPdmN17OjQYOBASuA+wNPuyhaEA457BBCiSmcmDmjbP5UFKpdUvdWLRXtxNZpxos2I1ZK+f0xmwbZx4Oq5hBWsNBBwdsd9zReiOwY/nl/gUEUynWmfNvDMLRfwb47JQWL+kqgDLRN5WPJTXTpyXvVRoI4amc7Wjbesai+EG8PhcpuABFMJjNbcU+aGMJuT7rfb/PeAuapGwtQefLOeJG7ELIHjqe/Ehizufd2dhXL91M3E5syhmGzdrP5Qox/DKeQxt2f5QXr+S+YhpoHbzMI6hCSPBePzb3hdbbZ9kbabpnWBWZreAsINDgcwV4Yjx87NpZ6ThjvpqFL7GniPcqU3CAx5e35PXRwR1DgkSIqi4GEihWD4cKFWzDrxDAf4hSvvGLFBiVgu24oaJLNgqmBTunmozN3leeRDGK5RBq8CQ/1a/jPQxpKJqwP0HvfM62cutODtObEl6hOg9+MXSb5h9JYvABoo3oZa+WYiWCBl2z7WnAFN7fJsjteYtuvDUON/O9DW0v2YzNdTNOjQYOBAWeA+wNQbXIGz7NpKk31vLNIFhBPBHrdfP7xiV0usIfr3zJa4B+VymnG3ytGfixcorNxhKpbCs2H1cLrWjhSM9wcVdcRSWfQ1T12E5KV58cWTkfTEF9bW7H8cXhlcSvvgkjrWaQfIx0eA74JVzqFXx6BXdd9sZXRRmaOX8Ad+mz0fu5mIlwJW9KSk/M3g5W4ZGo/LslHWpPLfQo+7OPokpNR4WNCUdralfz7TBza7XMaWCGeYnUYFLf1POjtxvzdMgMMxZ2pDcW76i4k6roOCGKWtjAC1wAE52lir7r6YUeqQbT8QMDFeIWHSOlSVZnmrgMalzfW5HB8UEDMnWsXNYYMGSJKffDXXH2rBb0GXJg8mYatPspytQUu5xyQOWJddWkgonoTU4mFWUSohuUcW2cpKk1rpdJpNKod0fpH5RyoZnAZZYXzeQeLA7sJ4LwUZ6OGwj4ZhZlvWxJRkIQtGJX1jgsyKAVToAwrYr5lI4pTHnj4bA/yiDkCjD/q1jeZsuujQYOBAaOA+wM/NZhxY3E0H687M+siqrTCmh9MPREIILn/hrUqspKTCRXlMIJ/PZeUsDAcyrRgWHR7RM5ah/IvKdCsJKLU5Q1nMGESjH90HaNBSHf4V/Fs+PVHqZdKbA9tt2lZJ3TINcySP0sw+99rHZckGW51Re684SKYmIZm5+1vxKGrdGImUXBz0zG9xkr0kutLvq6RhzvvYhj9orQvovv3/mvt6yQAXZ+Pv2lgC8iQXN0Y4/HS98zUWoPOcZklWrCt6dUB7JI/P0xNsTExjF8/wnDe255TT2uR5NcFJI4clXPaDVcUApXdBa0H1NzIb07WHX2nHpi05c+PYN+c65UVf8FnND8gDjByXsYy7Iqz8aSmIKULKM6iPi8GbhqkamKHLsTXIhnFih30L8HIAjhnleY7FiOxrIukUt3K0fXHWVVpyXklL9J5u/nuRV3epKbtTncXQu1MRf2S8vkYW2GGgX5xCBwoOwkESScUf9xWDwYqVz+VR+Gs7DKQWWnarIsg5XqjQYOBAd+A+wNAhhKTNez6jmto2HjPkkOFDiSfmZnHDYtbOb1vTXN8Rbs9VbTdLYwHbw14DpEljDRsQCBpvaAQQix+iBWCixroQ/dJkTS/2KnYzFOhlKaIQEffrhpW44LQM0pTabthfXVQit1fGsCsdr7zPOR2mrlb5ccvVbHcriovtP6lGzuWPOBqqQnuXKLkyPs6Y0Qa+9gAujc+jripZJKFOYlA9MSwgliyTOJbTkfI2wlqqTKKoU1bcZDQpp5Ye2Er6GaZo7ZGVn1gvz9lDOSMCMyr4Oq5y6Xktzw3CGM6UGX7SXMAOtbt2RjPaHtuXrAq+0qoI4+WbXIiscQqeItSTn4ikSLFJqymv4xvxcJQRfJB06y7ZpT3tx5A98/F/qDo7unBCn7veNDgQGQLcmimpW9SX5oQraYkndGHvNlFDSDOAsKOK3IJD7uekmUcr/WYVqArzNBwTrZ5tFQuZ/8JQo4xwX5Az3aG1fSMtG0l8i7jlER7MCybZGkjIq6MT2A0NbGjQYOBAhuA+wNETRKRPUv0GQWKTjosJhcXb995F1P2wm2q2Ol6kvyTxdCbaQL8LszJISOeAUYQhoOfGPW02CnVbW91T8PMnnj7qEIxbO8RdQhqJsTb1Ssio7Tu3Pshvnendh68/uAuB6sJywkAtWlsQAhOspjcSb8w+WY7JoHJUml9yJ2IUDIvQIEBQ8u1w500gsyRVh5cwpTVtng7jW12zb+AUriGGLmO3ut72EuK3uYtFNSInpI63kW1+poJ3e9H0Ejy4CDRd/76/mtifMI0l3OuTR/a+IIoN5r89222HTkSKLS587VDvvfyoKoj7IAlgQsjY4OqQYKsOFH+dVjs/8KBkYU2/T+Ruv60j7K6zURZ1027AwH5Mzcaf0Vv22hzoIuVhUb0UwHP029fsJQnlqH8hWzzaPcBmPreenDXWsne0HLoKsB7OX7r4ns/IHscX+MVNWHCYRumXwrH6y4ZS+nSgZyG9iPoEfgEWEloE9Y8SZdWh/9OgMteGZqteivn2g4rPSejQYOBAleA+wNQHGwm4JvyZW23Pqd3njZ31QMzuGuZLxXuiRWl8JR0b3PfiNBBxRxv00xBhQS+VrpOCeMRA/YdnecYyI+6knzQTazpTHGxU6S3pAO6elaxcBswmYTl+hSlcg4QXIgYEwCDEdWTpSRi6ALl3vXyvsu5Km9/iZnXGlSv0jM0ho8UIuwzq5dXAUJPlrXg/hAYuZZc9wOkCNhpXdovJHXFnDzAs+fVYYBmghzjGCPXItR2w255cEWmnLy+U0Sg9IOLRGr5lvmyEXKaNXLKIWUdrF/rK91OSPrQay0Djis1tK2xdIZLTvDVlr8K3IEKoqJrBUzAGHZo7h7dm80vlTnBGU/21CfjaMi9JStWk4Ua7Q7b5qp6+5W2Bj9fpDZ2Ub1gZOoTn/rEUVameFjy6hbIdRt2U+XvAu8wKERAVzNRgaa2DhOL0UKzZg7HHI5IZSMIkExBT2ybFrDRog6lJsT1hAtcTtx5Psz+IF8UpjRi++WgvIr8iO2KhCA3AzvtpqajQYOBApOA+wOaoKR8kBqXC+u69TtLyz+S8831alq62o+0U1GEKnfJa9AtlUNR1nZJpw8DlA3QkaXVGagRdmsEKP/TKwyWdvkOMZbKPpr1Z/4mNfnjtkU7jWvs1q3kXzrnFlRFyjlmdoMt1A0TfhRxQA12VFHu2JJE2grGlKWSYKvcluKbJHE1JNagDp/qB+9lJvxMJA2kkDBQQfIR0mtpU1DTHEK9yE7fyHvCwOiyiveTCshlsSJ7WvlhHQx2Rtn7qjJlpb2SyOaNFJ297nllufOLenMk1kB4blxu4DnSg/g0zdmSGtwR8RVk9sQEiONuVJZubqKtiX/jpEG1CaUde6+FzNM/fyIvDhbjFIjqxPdDYLWZNl3l5gCD1E54kKXeUMe7eDToWhk+0dGI/4XDIp3pI6a0SbsWxNk09UulucwiCZaPl0MenCskrh26NQ+Zd6LJsW6JfD79si1E/GKhB3LX0YcYvY/2HD/WcOcZ9JzNdwG3KMf1zX0OxXBrORAg7J7pQnCjQYOBAs+A+wNAf/DMyDZlK6zqR28ylj2JXQzg9e4kK5/vL75PNSiMO1tdchiii4UVc6iTjfYJXXjqG73LpuuQ7T1HtWj4u6hVQNg6SZts3qxlTpIjuWXdVMaeKeYc7x/DGPG0S4DVmC9U+z9IF2icsvHHxF0BoV53aC2jdlTBcV+vw8xeafm7QOrKTmL7nglxbza94cJtcaD5gs5Vfrwgoij71pTNiyZ9iDt0I3oLbNCAZeqMtSbp+PFnK3Tv+zhx2JKtM7PrUyHTW3qo5LREn+G+7EBUKmCFmtStGBP72FBROCzkZH0TTv1U5Gqz4JnPj5YBfx+jkQx5jznc3p1ldEZz6ysYl1GXN1fI4CsGygqvFzrLQAn5x8o9WrgtaYQxEOAWTHK1Vp9x1+X9EgA7RZV+9yalHCaKjBjLx7iea7pju/muJ27jlKygb7W2t0rj2xXlVJxxU2KXSn8atgwt4aGQBJMEavLgDP1Z+Bmvlo57X9DnTLbxP82j2chb6T/TcafjRu+jQYOBAwuA+wM9aYQ8fhQxZZsS2xCi8dq5DrCTihUpnjchwR5VGlVhZqycrEkjLIsJe6nCBs7RdeOKxphz4n1KS5FtcYRUJeR7sQ2sDW/NC3G1h3qyRMIj9A38wP6FnnVZvHIy0jGzgUeh9X6s/6tlMscE3fN1+hZaeCq6jD147dSsrOS+YW+NPUEjw5WJ33BOp73DuqlxpXeegP/gPFS52aZ5hZ7uz/WQkJ4qAgmEUb/J0iVdRXzO8/0XK00qq+Rp+cWLZLbDuoYHqK/xg8aMq3ZN1iQ97/TLkpe6RX0BI0ddUoiMTiHtlbcSf1KUAwQfGsUgRTJNIxdelIDzHS17DbyG5COPSRpKYWC8f4zsxoS8jHzdZE/kKUA0KIUP8AYc3qrfrZiLPdkbmqKn4ixlJEdnbPTF6IVxmCoeR1sKjJGjwWrUxCIrKDiN8K3viGPgsbsHytbfffzf6EEeUYxkFROPx1SFMgODw5GsnOcMozYrg97DD80a+DMr//dEjV6jO+IujEijQYOBA0eA+wNAdJcvOohN2QTQF4F/DpVelPfdj8pYus9E31VBsUUGHNaHbhjBqeo+/D2MI6AQ1NOHUteCsYt7dF7NIWx5JqH/uL7whC2fOSjBwHT5oPw8ZKfXIUwGbk5J1RZrdbVVfaYwJViuAeqXs/WdUg/2PD4gT29h9Q5fpq+vhFI1BwPaPxEZFtEv1t/+K7fNrmhNBYG/30bsBKVHbw5AmrSim6Dhkd/pGE5RG4D8ecsUvGlB+rnqACTHzs7uxY0gdTYq2r4WH2P7DeXqVcMKMWBUG76hI6IGKW7vBXNbF43Ap2vlJEmZURzB35jl5QkSbE1owbFLDHOoyDb+YDt08HeSKkRFgxHjKVAbSWeGMQhFDP5v9kszHwCCUnKRkpK/CR2vIqna2IBO0QsE49PTjmFBQ2plpBuprVOOXymr3jVsqy7902HVHr7rUfE28Nz3/ikOuBtgGy2KBk/Yxa2ksK2rePpck18oI8h2uYpt0wnaurMeOB0X+hHVZE1O/kSIBvSjQYOBA4OA+wM/WaFrl20Ui032X9rmUgKVbM5pprwG4iPi6fxUJg3gmiRJDgFgneXHJplCRLCx+F8qZa885m/GPHCqot6MZN8BJDNdnquocrEBezXh0haYqkjxDx085K1fWwVJCkMyCRPMx+KUg4A1XgF3OqjgWx+VHHj66mq2F0k9otZ0UC5qRC2Qq51JhgRMAJqQLtU8cOb08hG+QX/Yter2qSR+lLoLAikjQ+QQUOO0hCJuXA/gP6SXXH1dqLNhkASFpvbKsosmT/QLiiRZidbJ/6Ct6lYyOG5eP0lYRjrP6mK6mnOaKuFw5tLG9qxKw6IoeEeY7WI+A8mr94Wrn8kl9bKTsjy+zA+C0SBq6aUzeZQn5OtzH5O7h4u9MPOnAylvIEjR+bdWoQlK7FJOuA77nR8NHrb5bEbKMDfR/aKB++XizUvI182P7M6AwP8Uhyi+Hajd2qmBzGeN/iays/z3hP3ZPd7z45r0LIXw7H9zZ0UcxkJgXPTFbg7FjGACIo3mtsKjQYOBA7+A+wNA8LZSgbInqd+Lz420l4sGZEKHpdRbYp5yK2MIkNvrRkZ6tJKIJIQnGKRoTHslyhhrKmuGqWAwT3PuL33CT3S2kjXU5JzvN/lJTK7clyJc1PunTG2+ipQtq73aW/YNNA4LvWPLL1FB62kooYZrrLNsFnF1k65HLRtPwqZP0fhKIj3V/eQ31fhNcF9ZqINrTnZy7pm620I5gqXWUykwFgJUJh5Lp5G0I3pJu9tsmTVBLs3ArDnvTc+aiWyVCQSwZwaMsMNpQMg9opB9aP9+mfa+fqM3uDqr2+a8c4m99ZCLLaqWlFZUi1uSy5bGgywJVbwAhYd7W5FU+7WVp5YLMEB0tP7qYg84kzz2tF3th7hQ5gMqJEMuSp3yOWiiqCFvC6k+ydaa0DNsJ3NnpdUn+hmow9CBLHREnz98RUQtm2UeiINGE6Yo7990Fil/jT14QAroZVgwYsATUGbFO0CktdifhlL4HmJKE/nVhVimji6WtLzevBmN2WDj32CfEaqjQYOBA/uA+wM/GMfyC+5QrcCefekrpbSeOkVMpX4wlR5dXuW2BEgceI0M/cUHWYLuDuS5B3FLerjXFoaPf/sm0zQJ543mF51/Hrl5b87/60bg9id822D8lhIt1Xi6ZhPJE0DiBP3Y0vFsvHhMvTyBfHHJaC8tRcZqj2yXkBcDZ8VsPW736sGiUZeUhHEj02jU4v1ZaVFhzsDcl2pd5EjcP3Gtw6hpwDongj6HAPvsbR0XV4zeCHSsKBEDhRL1Ct74hF/cfl8KP35Q46qnDsp6mNXnIHuKUYNHOcp/Tqhn1WjN35J/Hi0BnArFIMZutnohF3k+aEIu2H4i9XLPx6CBcNK0KRZe70A6SU22uucHcuWPCbjzRajRFJmmPHCO4/uKLzrClZu0xMnxu9OBiCcjIl7Cu125NthcX4nbGZeEcq2vS2lzKHQxUbhhtyf/OQs+ZLOoFaUw1lR3HHSA6Ksgh4WrpUElDOjkJjU5+eLzmcFj446vVazES2L0oKevLHuWc9ILB96jQYOBBDeA+wMiSCbZHA9+efZLryV1YiRqC/a6fq5QJR0NtSmHEk23ZblnXEWRZndLO0FAoLYJJx/5uQF8Zbf80zCs6bBiEZEXIv4c++XW2WnGLPgk2ytQ0RhQLLG5bL+864LO9eqJjsrk30BRZcNKndmbmiZxvZ1jjlZXEPREpMcPiqVrw2rpPznmy0Z1c3rfheURzpc5xstDcbb5y4cDG1K1orgPVrd/gg56lfV2IlmforFNn03Snjh8rblmoe9OHNDYE7xbMD9kNnnPApaWhnNrTM21Zz+1btJrWpRze4LamvAcibKO5TyDM6JPpGiQM4MUknWmYfeSx3nQMUT0r83s2zx6vURBIHZt6Fbp/te7HKM49nraW0aUIPUgavx8rpp+mbLxaYT9wjQizg8rQnWXLoDGbZotsMY1eVAS7gNEgDYSWs9JRQtkI+7W/+urYll0vwWHcQfQDyhid6AHNi4+ahH08V3uMzcHEuJOgT4eX5Lmjfi/KtCbSD7/Yz9UyAGy5rqjQYmBBHOA+4N/fz8RB8z3JXt7cuc6lRNqlHwU83zLL7Xg/9SG23471qkWDLgZ9j5chWZ0Lk5AdsjXtJhZ18zDp/js8JGokUvYIf69qM5M5+C525eMDYu5IgeAYCxCg6o8/IV011VGGJip/km+ABdL0p8Ge/fABmFhBgLrhhuRMMj2JVxhZ6oxwp88RM0y6EahYfTbxpnQf7fm6PW64BmszQN0fDzSvP+qwjiM4Qz61aPDWuIMJsGH+C/iZp0f0q4/7+/JilvwNZ2hpSmAvVLVe8V8vSRNuMTEws1kEIKl/wPtQiRuypz4NmT0ocfy8Pc3KagMHi6fhs5sfNutK0p2Xlh/XBtrepKchKMVB+7w81CHjEXgvLuII/bol3Aqnz3+3YtrTCusCOgIBQhbcso6mrWVO1XTW/3tAkd2qmj4mRdXNetG5bU32/eKUaIndB8188ePl5ospYfdaKwtcdWS0a4srFYd5ga5Ex6XHRhW8AdjJZf5cIt2WGrjctCgFYdKiiztpCd4FrbuwkCjQb+BBK+A+4ONlvDO7lzRoItQ5Rg5I0uSMCY9+7rEDz+fgSqZXUvkt6FaVBSh1X17J8+EBvOmrk+/5wfBNcFxDSohPxn9Ap/5NFum46nKJQbOSuy1dh1vURHujEVzQpj5GcKjuH1BeYin+Q8sTgbeV2+yCyTpjuoqRXOxqxBO5ZHD8mxhfVLkhTmfPWYNLH/w4ByBheCoO+snEBTcf2XuInUprKuDY/Br8axWAirmjcW8cqNzQiQMNoCn3seijnjZi6di6N4Ra31Sx24iGh3hka3ZQKZiaMlXsl29ZdqdTWOnTVaP0WUw4hIVO2h5X7k8ybRxU8+dufq95zxWG7330cUpzbQ+myMs3A4o7Bpr3VRBStmZifDde0oyO/u5mS9pepYkIYpc4rjmyZFGQurduRx6fBwyno4wlKbwH/bR4sGAkXiO0UuY9+aFDWunnnSt15n2THINrfVRZ00PDnGCVPnI5c2CGjqHkChNjHykoTybFQVPW0Xp/v9onsS7JmLMzi19aJwy0fbV8t9POxiaDujYvbyhM0PNx7qsFCtHExyZoxlu/KflZM+xeC0vgzssGfM/Yrx52WKFaXujfC0pCkGjQcSBBOyA+4OUle7V8d+del1dQ+AfX2kTEsQtBgsCeGfBhtAlF0j/UBtzzLI1WK3/zwNyN5smy5jewmtpVfEAxcauiYrCQN9nykXo2ZJ80bCRrDn6oDTmkZ88bU5DBEo0783DMLe3nOgm9VwPGVQAe4ufmY2GJWseAvhwS7oRYj4CluSmVi4o1JnzZD0qDNceFZGjjJUqVH3YLMAbmkLq/qU75EMUTjs1F7gbbOu4Q7i3ALoB/g5ojh4dxomJd4Tf3Jz1WYZ7nH1nVc5y19IipVH3XZygYOZ5Ortgxc3SiU07F2Kgzzb8vFDKbEX6EtUC+aalLmlJYfQiD7HZLfvbzZQ+buL3BeWy35dNXd7KODnKRhWjn9Fam2TdJJ17nLEV6msWYIlBfn8moLSbXQJxb6kKRe7Un7Z1wcvXx5TajXNp8kZCz+vlCAFuj2jeMuWVL6i/HsJH++CPopyAotLZ1hHyq3HoDYnQjI9aF2BktGJxs/M1W3xh3v3IvVvkgBlLyQaAZrokJ5AnJv8x+1u2dqTKo46Dbofs9SevpdiZtdmvLNmmhApg5sQXEpKCXTeOZeKsvFQGvmgOuWNaOPv5t793FQUKRqNBjIEFKID7g4WA6tXja5c1OytvkgwT63HOr7vajJ94r+F8YUrRSv+aZo1AVbFlO3iEHp81P7NR6Xg0lVwicDhBoCPfvjwDhw4gNtqXuSYdrg/oFdHcUYktX+9LgDRVV8EhQKkWfrq/O+uuXFYYdeTtJaM3LD3WK3jHFet5NE12aUw9aauVDaRTcS+Y5jp6Su7UXnZ3o8Zy9yWLTG+dka2kwzaKrnbkDYe8n0xz5v7JWUrNLhFo9AkKUuC6w+Vx8wIRmm73LsFpyJkuEFwF9STc0V1h8cjmm2mDp6oqEiWQdqXArDZpFPVJ41VMylcOI+lPY7MeYe7SrbRINClq8tVfVhEo5kjUKCs8CBj5B6RI7sLKPRapa5j5veLdkNwR0QXfE4HH9AXTHdlswAl9r0MRTjTVdkOhzF6SAwJ2+FxP3pTY2TKolhSchOx5Auxt/WQ+oG4CuqU9TLt7lfoDDOD7Qt9rOKJirGWN9SE1no5Z48pct7kHTm0u4jlFPFkgwemf8eR5v6gbdAOu3mWWS6NBh4EFZID7g4B/7pxmFStND6gEidN5ZQO6VnEyNe+JFaAH9OZNYG6G/52RcFcLpBVqElRkSDKvUE8kTeGCnkTSl7cvBvodt6nHq/Z80Ok1lcP5p/qUo2HQEufDbWLo+LjNxKv08PI3N/JvWb0fYwmVFZCZvvd4c8mT6Rifz7woVyMpd7mNZme/hkrqruPvni/vgDaTGwlFPtYOEUZLiE/Sfqg4DCC+2cpx+2zdriBe9/0zWviQ8FevnH1ycYoM+NMPo5D8DG26OHooDKgGI1k22yF4DPhFQJ7X7Nr0P1DwoaUUSMWFGrHbF//TRWHTdHw5zw6fYlDesCoef1JgoWt8Q7XcVAOoqzhP7f0lqs+1Eg7aGssS4Rbx7w0VCor0qeRYdNb/M6CG1qVVLRfl/VXUkaHXLovqie+Is9hwrxWDpk16ZY3irt2SBBnHlxBuLVNoed5GJhi88dnpEiOMYWyY+teE6q9EcoOjHvzDC7+Nff/zAx68fYvMiMm9egcm89RSNVSJgJjtGFejQYaBBaCA+4N/gOqup+c0l9fkaHVxu/bZ+V4EBVrSlZP6echgc7ERYfs2KaGXAjO7pzArdj52MNF29CJc9D52E5NNprs/U4ZkHRj6Mw3yua8PHZ3RNcjkU0hkW4g4GDRt/eInB2ZX1eq1j13algzi5iv79bHvxIlXQBeoKfFSkMyqFjl1k0tX5knuN0hx/Ifa3GbPMeBqFN4evxb03+8y3IWTTzSt39Tme/jnPopL/5JS38XHwq/5nUcYGai+yaN/rKN+2ANO9255DJzitbREO5XAFs5qzUgHpPvgm63cY6q33lsAtTYpZIdgMC6fZEIXLaogDZKFJ/uA6kt+/a/Uj6lCq7NHrXIWT+rpJocJmUo3n/uAb+pLHqE3wykjfdmT5yHCmWxNQzxKH2LCV8eKPwNtzHLjSJauWAplJTagql4Fk9BQ0p/JSztBM5Cnw9t+FONDNfMSFB7r+3Tacdv6PpNcZHb/wYjQXqONmAbxuy67c6TvVsf+XwRjMVnvDJ+rdpYVMyb/+lWjQYeBBdyA+4OAf+q18mBLjgEq+6p75VGkt7LcuPBEXVAptuRMteyUWfaMTVzp5gvO/uQDiW/0KrswPdgpSYdFqlbkRUgamIkWY4LN2vK0gnX7D5I0IMnItVatxQkgQL1zNVHSrgDlxgOlPp8ma+rsS74DHFH49bYl6p/WIiUR6ad4KRINx+8yK3pV9K6D7TFsE5ILROUEzhngW0JlnLPTeZb+4f+vyNDOF6C+ZYbZKoEx/64KfIw3sWOp5I2Oz9WDFXI+YGy04jYKeO3JoG8i2m/T88XYkffO1lImX6HrJsrK83CQI1n6XjSq7+HWzh6Kjt4OoDJ24K7pYwVNFjdEy8e5eCMKXD1qXfScOjcxpfOf1BHx8m1LsLU5wv27Y6Aj2wXA6oUHw+JiGjK6c911SE5He2R5leC7xbuEKEGymS+cfl4tgSHFcZY7PiUmNCe9IFRllH6oBfbuJkZZuBwVnnF0bDHRnXo62tE/Ku2Zqm5vPyWufbG/sUzDpD1XMbMCqo+m/4hpXKpfo0GGgQYYgPuDf4D0cktJTWSrDV0YJdBji87/cwaSvfyIUOdhgfGLZ87v4Po2+/doUWJxY/bm2CvNy27DI4UEJAisyalvwEe2ukEW93K71UO1zE2oQVGJn5qtKPmbkkyZnGaxXFyAlBovRm5XBtKKtvB0qjsCdvSJxnuZ2bfxSn/tV/6r5q40ywpf61i8jvrhANMtlq0Hr8JuHIOYAtzBohcHBOiQkNCpf2dgQG9HU10r3fKW+0EE+d2cV0FanuyZxQallDTh6pT69msMYw18gKKVDgugkS+a7bCShuuid7+toWdmqzZVuIcckm3LR2R1Lz017UAJt4UiROqoGVA9FyRVjYqtcVmX2mD0pJWU0gdBUxFsQTqES5GjYhR7eBeiV3wBAOCcq2kFZKbEzZ6tT6l3LTqPnuYF8hHHAl1CfTa2K/qJ9VUxUn6ilu3m0X0ywwXAPK+vnin8XAJPSOT5meY7gV/GtWhmJGgvGSMbBhqkv1oX7ydMeKXAUDBwFTZjB3Xvf6v+A2pko0GHgQZUgPuDgH/rS/Vxw0tdFvURGYP4KsErhCNQikuyU0g2dkhrDJglQKu8diGnIdoDX1cvV4L2my1ZJmEzZrcfSnYxjL6X5wHVNz6eH5n5YROxvAeI3gFhoPlgvVQOvygg3w22N6nAb7JQ0j0RkqyNQdC2nmrrSpasXfU9a8pmOqu1dVMYe7I6YerCO1O5OXTNsH8cyGdXe1d2lS7CwE60SfXywn/3stK3iBYvxWVIHA6SpVSk9HEDl2dleuFUl5DyJ0/au5KxJhTPQC/J3xY4Sw1hV43WNgHnlESTmGFndt7nvyVgET7/GPOX5mi9nlgm5BbQzT4iF9h9vUx9NpOL+s+rhE3I2GDqr2iofoW6TGp65hLCyR4TApzN/u8U+KV5oDqaqBpF1QA8Ur1Ye4HhggDSx9eOpnYM5Atm4VXePmVWrJv2VE1SZ94gUc1G19d6Ue124vHTtXyN2+oTDlhnTtH24T0tsLrG2rXejAhtQ5N62KLkR5KZEy6ViOrWeEZ9b6KbLLV4ZaNBhoEGkID7g3+A6ve9WfYcwIlWJZW4E7iKlf9pCNn+DPO/7SAae/M9XNAqfSF/6snUxltZk+HNTtetVuRfOCToIanz2tlXMbdj3nZg5dFpiEM5RrmEvIA3rmD54jGx8/wFg14bA2s3yh42Rb7EcZ0e0lI4JMBux8qFuPwaa69WGh/3jImklD1YZex9DN33dJCXZXcIw6n+JuI4DSwEkv1AiF5UvSLOXIhzMjHS3YCjPaOA0GF1RehpvvQGANBAe2fUxx/7fAZZy9jz585yVGWvf4s7DBiC4qIgFoKeWbjXiW6AGhLHEzIhQIkAsAWDIhJIam774GqBRt7PHI+mKzflVLSvhZ/Ugdhk7e7BViVbwFZzFKzFhsTScIKaVns6W8fTk95AbTOnULaUzR6kkI8O+fYYNroT7uk/+ZpvgRvLxSfbjutx7O/HGgOxTI0SlDfswJrnVznVCgtctyTHszpO1MTNDv55M9h0kGxIZjMlc+iCBuIXVL6wBkneBNRKi1UX4q8XFsIEYqNBh4EGzID7g4B/6rRpBLBG9xLgn5bP3hsSXip1jPm5u8P13LqMxJaUHl1Sqirn4Xupyj/O3bTncsVl8m/SwZNt94x8bwYSyzVxvPgyZPSi20HBDZ6gGKY8/7WpzkiXMe7/hrBVyrovOQaRYyQMOJUopfqwsr9C8YhzXDOUjNxyinVA0QJ/0LduiGMnWuKhmLApUPTwnqDAXg6ZD5ZtcMNSP2McBVNJ0CYhyNJa4BC5PgsfvxdcFbER55xGhkZ+gApruGcYNqKC7wWXOgpAeoltiu8oeL8WXWIov/Nd4Vkg1iOot3mG//4HcPgXwH5xNv3ZpT02X8v+CXQj9+34GzoRPbmZXSayJMMxCmB1m6pFb86GfyKaRwYoIycUCAEiSKUHqub9ijFO3ftQFad4iS3rCphPg4+l7k8XNqnXw9xaDVU9YAEBZUW0e5t54pdEeEBAbnXQabXrAAi4HZanhUfw9096oKO/3aSHbpAueZmD5IeGKoklFfZi71/vIl4SoJ/y4T/Kzw5824ejQX+BBwiA+4N/fe0gE9oDzk6pPWticJk/R5FTjvon2CHvSq3CR5SL4kJIDSwtYpPjzDCvNAmAdGGkKYRtYWF8l7GuIkcy7/S0cMqhKUrLVeiJm7AGVgLa8jK9JS79Jre8BDOsT5df93WB3s29/R5NRFRG+N8K0Hw9EOnxxEIeNUAREgLfMB1JVkvuss/QXJZ2+ZMBgO5Q6HxwWAIZacuc5DXGjtpb8dOS5Awx1445WwtgHItCQF4qh/TpOdZE8UbNv8MFdWk+Y9r5vDQ+IXHseOal2HpNoFBvw6XedhtL2ojBLgKS68Ov3P3tZvgbF9cSQu0sNVZwkitC1LCtI1P9z9oU9IyGTusuYXf8N4MdIq+wRyggQ250wd3FE6BDZJsAdEZCgw2WdT62Rki6nA5jo/tycZ5WF4z5dGpQKQv7RSaVmtCqaA1eZJbaMqJOq479Yr99l3oHjSpbQ+lErD1RdWkZeJUJyLNX5ZAdvkfRDUZxOP+MulWhINSlPwTneAsGUaNBYIEHRID7g3Vx7BWyG7DcH6AYG7Q459BzUJ2ZG4HEC4noLN2b1d5/SBZsKGcLn0/8pIv7OdNKYDz7rPLVgq1obd9qn40C6vNxSeNK80rbaqqZ1rud9KfBx/noFM0UBImUapGmCyOEIpUeDm4DJF3PrftupEjQaESe4h/CC3ZSFRTudVfq+V+BKHSr1z6BW6xyxzVX5uD52AJ5+lCN/mh+NN5Mf1X3AfNOsOqw5RfMXpFW4nzP6fAgbEoFWeJbDr+6xxa4IIq4i96/wWCB1oaZlYxU3VP4OMU/SjAsjvqeflmF3SlBALxFuntKp/Ta90HsXFzRNorF/tthsDuCKOgHqPC1IzgqZxMcwxwGXZHCQSvhFsvS9h85ruvmHOL5AewDFKxegrQPQ55I8SWF/pSkMTv4U1dKv13IkZSpizZ5aOLpJ8WbQp1MFvWWNxHO0cXbH283pHZLsKyQCrOw7cxcVD2jQWWBB4CA+4NzdexUs9YVJOPdr8Rja1mRLN/WQYwMCcarET9xjsD/nSC477CKcUfkhZG5xodOb+Rsz6K4TARyiY31BOaCZZxhOCDn0KCMLu9TndVasMHgetYNcaHDP6cSQ0p2eS4OHDogdAVG67D6WK0CA9T2ipy9veZRJFAbKiRvy2k4+7oHNGUGzu40/azOsKd87nfqN/J99yv+GYxQ2WZQeJ+vRbtFIYPa0YIwuwk7mEMug3eOjfqHTFNA51r5tMy5sZlxDMWmeh7x07wJcDdt3cTMolRLXmBb3jTG+t1UgiJ5Y7HWaFqHaJfiojj/46zs5FhU0GLeXe6TIN8HEJ5L8JYFwqHs+JI7L4UUUXzYaRQn+IkVZXTQat0VLqdbQJT/z7//WivKxtpsHxNKi6uKN/rZ9wRFXiCnsN/iVj1zXPcQfj3enO5sNtAVstcoJNRhQ5LAqHNmLxbafdwE8Z25O3O2A6ijQWiBB7yA+4NzdgmdFxOo3G3yaW+oSJaQ6Dmx75E2R3kCpEjOhRiybt20XRU4E35JeuQxMmYBYQwauGBwePUB5KvqAQjx4IaEdHNY9ntqsNciJa8cR0t4qZOgv9ppks30G56LIHtqvca87lShlaslIOFCn74I+VFBltnyFhAc9h5xoGdSDNqPSsgX2cCV/gCnGETS97oR1MDkYMiS3kzhXFhBofu6tE7Y7dCjgQe5gvuQ4c66Dpgpj11g1b84bvRGl5Qn+NAHcCctoY/WFNiixSDrh77ek210LoX2+RDjCQISDkKlI09ORqE/s3qAPE4rNn6hFoU3rUYbim6+DkTxhk9kNdiEYt/ia/z1IgzfNR4YwiHT1BI6AGg/VhGeuCW5+qEZbrakbBf+csfr4ZEhiR7L6nIO8jDKK/uzw39ygd5LVHY5I0wzJmwcDHrI8RPKrx6AW2Puz6EaFlCy3Xi9yfojW6Rt5FXs8pujQXSBB/iA+4N4dRZoFsbVzhOkjBoqBmi9lwGLu06T5uOEMvfrj7hkcD/A4IuEAWVrj3T5aL4BlKjn9K0pHYJ/DWz7eEXaNTIdAak1qgXtvK6lZohRIRIXzwHOQIcX2ME0hwl9o4HZm1hap6mhnJg2ZxNY2NlpF5prPPFUiTeyA+WXDRzuKEIF70ENSN3aMLaJYGoZfcZtzD71iqOgn+VWxiiPYzySy4SNBjDChpoa0cNISkirOUiLdodWw1+DB8XfkWCYPgEkFeH39VO/T/6OFJeI2z9ewOX/5Q68V9dFN6/kDciiDAduEJf+x6MbbA1BWPoVp1KuNgi6JcxdFZdXDs+974no+cXZibim3E3DrBXjZA9TIKplvB6/0fkZ+MFZEAuHYk65QyldcuW4zYZjHua7dQNRSuaTrVD1vH+xXoQ20kpAo07BwHLQ3F/OraCWG61EjH7kOKkTu38EGV3Tw+J5XtlFXT2C9E8A6eC2k+GvuOmbNrmjQYOBCDSA+wPsQ272UL59VaoycUbwyDZbtbXr4Yu9frjn24RzBqqeUfY8WaYJXmq2NxmjFlau6UlEfyDanjBR7F/OIVyzDHlyKNQ0qFXlnANZAiPHiLvcGdjhNqMdqlMwCaW/Yfs0tEKtNEaSC371RBSjCQuU6sf5jcGYEvfq0ZIdyJJHUIh5H0/sP1PJga482I9ZsLdb8hsPfTqkRgaUdWHcD0pozzmUngr9tQcrP1Eg/wOSI5lNSpXsmgjYXRz3xlnO8k49L82A++pkXPAVQfiIjKA6DIJfxMf08INrYkFCd504AAL+FTqxahYQlIkx9MIGbQdbeKVc5Z+I2iad/tfnkgTLTSAHATiKzQ/+D5d5OCaAdQenjjmeCWpb4L6hbHllxZCKfrvk5OBrn9e+WroJcG7xEn68/8p4F743/rPtrVg5lnkGpjJakyPHqv98t++X/BQlFsMy0NSqoTit+Z623X1Dg3gkhL7a10aF4PV5Gukjy4nGT+N17W4E0kK8kpnoC0yjQYOBCHCA+wPwJ1Okfe73ueLMAJzKSNWnOQsCIPmuiig7CLQ6ZSpB+f+YuUXxMDhyYhaWwO1IdVcA2sJnm78/yTxsZzKwZj6saIuwUM1MjRIjW0+N7QIuzLzgOFi2VlRTwa34kFCOov3K81HwORacZT2RJQ63DEmclWe30gTsXBXO4+CZv8iBAT2qFEn2GAEA6Cqb51X71lHUlj92J35feyOBb/hbt2A51FKVeR7Ob1d7gBfTrLmMG0Fbrm5sFo4abzJ1pk5WmDGTvKnXjQdIIp7B5kZuqYd0tOGH3B/H29OkdskcLFhk479hMlXog01qOTt9cEZXHRNhsY10RNmin4X5teAZofAnLpCuvUQ/7dgLfEm5DrM8Oz2rOZONXnLyuRYvXeVWCblzyy/Wtgdau1gbpE06g5f2jGBdF6P4tYEm2ikrWjiXmqeefsOgtYt0ZY+8sG/SPqhY51rRNvDZbXj2hXh6tb9TnrBZexz9aU0HAvOtfVFtCTAKzDioRNKTY+LOOn+jQYOBCKyA+wPsL2ujrX2dGycZl1Ww6f6T7nujYUAzTbifSe/Kn+G06wk+YFDGfjFAmI+z361/qQJMdfNxxIzu8KkfS4n9o5MZdr9LQOeNI+N1D4zBddwjN6iHUH6S/Z3pY0iZmdzc9N1j6jGk5BA1Ec3eTpG6Uul7DZMmPk4FY6EtrIXY/5p/wocvXKW7uGY84EFIFdGD2LM9VpBG7/3j3PG9t2HV1LX0yQ+6Ni25jGjltUVUYOqnIiajbWg53H4JToMk4bbDspPIn9ujLSQl9g846gABkdiTUEjiT5rqwUyux7Lmg8HjO7fLuV1Kt/JuC84eI+W+CDOgoFoEomgFj1TAb215gsAdmiYQ0sLmFHJfiZTdITSKl6bQn18RCvlomRAICuHC3zHJr2pfHEO4Flz356M8djkSkBBi/rVUWsprIDnRCWwjU2ZtFXtwATPx2rDlYw+6Dl8ttac+5/q/S3jzn1J7otzTg3rtwLxord/LGPrEPGOqT0r/ZY0ZFHbSoOl8hYKjQYOBCOiA+wPCh0FzRPu/G3YAzhX5NtLN1EPvPI+hP+dVsyYn6TXnmNi5TtUTR43PHxqksEHMXZkxDyxFePIXYwsa8gpobgFzu24Vh53zpz8CZ0q/YdNPIowf1Dnmp1aQaTDFNlUV/7+pXtAjas9nny3M5bGU589I/G+6zLBIT/h0jfMfoW2CwoZE0GyFe9ngEnoEz7t/5GDXwZXVDyRFo8IXSc8ol3cUQZIMALDqCrr8iLLcK8zBOJigXVkbZJDC25D1yLf7VKbGGgsvjqmDHxn/j3g+afDRMA0K1HoRoTIQrOjcv7w3w5zom6BSiRLkYqQhVOZNNl7A6gIpYlWVBPhjoQxZgK1LtGE3JO+4lZMwEM3mFjGMIJEIa1DFESJaQXO7UN/ovdgKDRsTamSHBehOPP8uJsRPze0o7mEEofsrNvkcij+7CexbTbgfiG3C3jmvNi/2orG2E10W4Az67vJ7LX1JKdbIhu7n0R2zRe5p/91P50ODrpONSmQk1Ce4QXKHOP+jQYOBCSSA+wPCprath4LyUHi28GXhCbZVV6+tBOFJGJT/vYikFeGCX5/oQfn6zsLIo7uWLYmoUPwy56qYAUlPNwYEqUJUKwrDHtX4AM4J28IIVzqBMME8SssRiam76gJQrdg6bbvGVTfJztZuFwRl8C8bMnDDngZxcmuvFM021J6oLNLOrnmArJmrlv0oEm1YhcCHWswUI95Q8yag6c8hhfDN9KdX+XC5cMJ6gNw9BCA2BMhOcQ0Y3hxZRt0JYh3DXhYGGNEdyQXaitDnRPIGcSCW3xzIvKHsIz6+m19dmymU5JRrECc6RGH4lMTuY9+dokZGKBWO+inPlPWw5WyEeVHJCdL+/qxTNMns+xwDwKCIAhWNDlNs3TAIQbPr+obRy9aMe2Ry6yfbdKMqWoQfdPRA19BGANvpRdPJgJ08ldz5H/8l5oNgTmsXQIzuCQPiHzqYVWfDznU8p+d34g5n9sA7yQxJr0r+COKCO8R1z0T0nKI+tCqW1KVhLm0ok5jC7HHLavyjQaOBCWCA+4N/fxNE0WW2c8ULBXMiz7ymtXi23KujT3leEQVHb2NHAE3xPHFFrUOfzstt+BYivh5bJ8AVEV8xe2Ck8dyAxy7g8gvy6K6gfvN/3pv2yeyEP1398i4plsfIETHcNqH1mTa4rXMrwX7S4umhBo9+U2Db0clQpg//0w9/o95GVRYEN5TvypwFr8veVbZeQ8+ka4vs4+Sv2Rc/2ZYGYqyp7iDsRv+yOozUhQkl6PAnkpimhWJ2fUsShH1LLTVsanN6rlZ9Re121xNPVi7OIAAgRm9BtZSmu+1WrSH3dJfkVznCDQk4tqywz28639OhRiv98uFo1StKOGTG83WA60a8KCR7PMCP/NYPM3FmSia5pk76wqH5NJ8Z9Y82rqKgI7HFTn/RtLJ/s53vHNrIq43jMWAQFTgv0SArWhGIjyLF+EUWawPg46vYVtgQl28KI45Un4MuAROKMMi38BKhYhBeLGiqyz5uyrnO7p/NRrrTWlgkxB7Xinah6vnpyOo2YFludtQyVAKx4gOoZj2CIzAftzmOswRkeVMy44hh31MMMaNBeoEJnID7g3l6772nIV7HCcwbA6junN9kxO+xQtxTQO4Y2ABBoaa/cNzE29kFgrT/Q2nwnO9zaw21nT78QnzGqRvwmIGjnR3X+iBp7N11v/UIfFKHZMXkTy/vtGUWeNkj4HIt2wpDxZsTpByWcekKGprrYbEn7ACSypLBEsqBzFFEck/V8j4TbI+35UFf1e4etoEvPNWAwVIsqwpWCua92fr+EjTnhicbShVe3zWW7m+7iFZysMkw+GNmQ8MD4Av3O3npbj/BNQPft1vBgcq41zyNxNxJP+p9h9QIsrrAJAiyFuC9Zpn+QGzXTgotOUiw8Efwmsur+ON4WJphGp4wo5asKL+hRbnk7k+NoyJSP002cTisRWXBtjR/s4DUBFKMkgO11dICOHn8+sEqAS65bIeYSiwP/WZfZOsFGedvHrM1jMYQpb8mV/3xZ5xs+yUa0PcIIdA4pYsn+L0yLoM0C5Ljrcy8RR6t+gdyWAm0R+WN+i4mmE2waWcwyKNBdYEJ2ID7g3l1Pys+XJJ7Qg8stQqvm37FLd1bwX8ZnTiONnavmvtK6p4MMcGgBWGRjbIMVQB7AqZUMDPNC2JXnESUun7S1nxmxMLkjvufqvCTylLJw3l8vWY053lYqxDgumVK0mYn/TCSVbow8bMupVQ69VHADKnzBurIGEylvXe39T+pei1cRPbh9edXg6bx87ktbKUjQlU9PgGs/VnzzAxx1xxVFwF9+s0YizfE3MIKtM2COoC1da4ATzg/xwbHhjAvbA9KLoJSqN4mQmLeCxkaiBUD8Z1roHk13Wlga034x1hCKH38yH37jfB18sg3Z7I6x1yPIlIv7AD5SJUThkDVs9eTeyeCkDD2t6ozY0oKq5vkyg1qO2JQUbWQyz3xCpO+vPu9rNQSVHVg0hPa3wY+pY598P0DgKuVICyja1yU+1VmxcPfNjhIbZgg0JMzK6LWp/+JtvCQUrTIO6XJat29s5eg2o1quXPVKAbrcK4nbZ1XrRSjQYOBChSA+wNAO3IfDg7FDTcOEF31BpIAPbZeUYsOXbcsem19bJnCaGdPhYNZxSTo5JyVpqr7281j6AKDJEVwtWfR8Wk2fuvlDm7PFITJITuEsL5Fo0DFs2UGvErLbT8elzSroZxDX/72PVCxPoXwLlg5MRVqjIwcNGg3aW8iZf5OX1/Ml+3jRDgiOFH7FF8/d0tQi0XNqhkEp6mEx1KcvABMpev69oTqlLXsutUcWN5KWGn/1xD3xkD8X3HHb0kwWLqsx5ltZelFDjxBufUDX7b0gCkSOE+Es9sZkaHIuhYkiTKH3SEwlfGnkkgSteqF9NVY6c7JQTcXKxFDMtrVnSW8RFHs2BpkMSgE+XNJFewyVim7YvEliS6VWQHbn44ZfA88oa3GqD99+S9TMTlz5lHdJMNpv6ICLJTWbin9ygixUIXaWUORSQbRcaHjTNki+Vq86Wty8gjK/TSYCUHMDeWCECjmltx9AE1L3rhX0uwZ8+Hoy1zibxlIQkJqenfgOybh0GWjQZOBClCA+4N/f0RG1ixyAluQZm9K34TaPbenX4ZmegKfFKA1wiNq+USjDk6bEhxznEngwQgmnLzmjAJVKQCSCHhSnBIQjUtdfV9bSgyT04kk7bqLrq7Huqzms7DVZdgt1xNgLZPUpQMQolAJr7AYNi+v1R0fRhemMvi1YJunKYpmNZD4TJ+dTz0WXVga2qBChcK/GUfj7rSZgfArYCMyQoCWBy9X7k5wCUxfHOI+iAbWLurZNjqYw+ls2bvkEdPXc5us4BMHM7OkrXDZ9nLR9O4meBDWmYwek2hKMWv9eFXE4lORK9V4MveU0pZU1vxzKSb3sMyyy2qCHHVJSe3yfRjssT8S5vVSq3l+8L6MAGT/T78p1P0ExYOMNDIBfHt1kNAn1UhBBOAXMFdY88fI85j02ZqZ+kxG6u/iZSrDp00+WQWkiGbEonSPoDwtMu9IYE7vLvKto+aK+uiNfeTZjwx7EbvaVjArfai6uNIwVUxQkakHP50IX91U/dyd/25dWaHTqqi9FvMh0g4zwhbHcsxiE/kmo0G/gQqMgPuDkZGrBRmesCoC5IEOj8oHaszhHMn8ANzrTfMOsi5sy1o5c3B02eTeADOq3PqYsTCuGy7R/T7BP55sCDOJSKhB7+NTjGYH4YV6TdHWodoNCT1gBFtU9cNsHPsozIM7QJtrVokziMEkBSEbtFtEoGWtuHvS8xj8JZTBLXKRXlaQGsEJZ62ZhyasmpcCXCD3sZV7zCakrJgvXOVmw5jCvpRLMhe9kVNiB3wtVnK/djl4eyyYNS/Be4TsjzSIuQCVrcL2C7vhxTd0E9WxLRI49VhG4eexeKLvwYy4OPhJE+ekfiPwd7aMzPQklyGnfbSGDbyB6ZQgLIKtE/BJ1viQUpSM8daZZ1KnyTsPRDV0Y4lv2Beab2hxbhuwczzQHlAJbE35uYd2oKyj6DohLD63NLBaKMTHf+ITsDzDFr4vJEW9+ccVKI2IW7eGm+LCuinQBMq0p0zAnT4r9oNH8vFOwbh6xPX1vcrDu/qugKXcfZUaJV19b0L1eDkdDncHQpluyTPhR26yh5NbiEtnRFKKIG5PKcK0F+W5M/rKgyNdK3VFJdSy/X3Am13xGxTqghMeKdRKQo4ASlnrZKEXo0G1gQrIgPuDkY2v6CDaq5pOBwokW/A//y3h7A4SyBfMCra1pFqEBzIVFnFRfrt8u15z9fUEIDxXDPArLJazHhCIX2JAONjkUskQgfBNEGtvnfGGVJYedwO31oE9GFKrVAQmJ6Zrp/SgKW9dYL1rNm9D47N9xQUDZGm0d84pUcQm3llo+npX0nTmeOU241KgijOwj6dNu9ilTD0VFpSToSVigLGIW/ZA5w1HfkgJCdO2hpnuo5pGTqqUsuADZDOyDJ5WyFh9eqcuuQjMOfdwWSbf/rhSVv6FhjIsFu+2QgCoHRQIOGGYKe8V9VnHETk1uq59qU+D0VBsTgZLU3NIeKvbtYV+ESemWixZ2VcycoN+w4Nhvo2JHTnlxHrrrf080QpMNkhbmb6Sr+cFr8z8AuQpvDL12Co3wo/d90mFn9pLEkb6iSH7eMFujUPMUsbOWkyr4WZnPl+AhMP2DUiPBwvOPtMymqRBkQJV4/5XRxolfHP5Ug9R7XEeq5LAXGaGKn4N396LRzDCm82hGJ8YU0d1nZHSjgnFNyqojYSCe1JYRWbx0Mi1bTCJ4VUp28UX/em+zuejPNmjQYaBCwSA+4N/frAhu7Se1Vk3EDYBgE6yYrQ9HjQSl0VpBO9+o3x9441pPQGyfSYZSOm2zadll1ivz/yUQPCaaqJBJux2AC74E/FCYDaD5ugqw9OXUQ0OhlziIBHPjL5OyXOk0Uy5qY+BGUphZi9yveQVihe+1IH/lLTgClOzTJNsI2QgPZCpWtZDgD/0ysO87mDVggB93rLElRncKWF/jXr7GkMhBwQCpkaJqJiIS03xUHXBYcm4vQCkGIoWpWUUDlo4hotQs0NRhQFMH8QzSDP+I00aG7gbk8TcoeHoUliyNsMhzmJ6w9WD7c8rdep0YqAQETY2KkOvyX/jUcZiGpFY2r9kaxdDOaj23Yj91+PuCPrgaBDNpbJkueydSa+duPl4fTxx0kNy7q2KDXm7pNVZPLso9JHrdnw4f9GI2Xo8Grykj1Ul9T633z/17Uf1A9LgkVtSVfCquIRUC5Yb1V4O4lmCCrTbIJLQYACW7VOAZSig6aEe8PCAIjTTM508ZCRLyXbq7NejQXqBC0CA+4OAfawq7rc+841xn7poaqevPFj1pLfxOGNchl9ciD+gGyzWxB/xsCID+nTVnIkD7D/GGN/rLQbZM8H/nBIAev7etcTF6lY9DHzLTbNcLhaCarJtahWNcISO0Q6H8KZ9tQMmWrsRuWKH97m+ktIn+W9VmjHOt0zTpl9vDEEghmDumuTbPih1BuT2XdpmdSFAkE0aL7c94+DmMh4ty1NCNe5U9XxGmAJE2X6SJ+/8RIwb0q2qi4cXGtErOJcs1iJIyzNY3sUfwwuhRgh5aoILHvb7op6CUSra6naxswSnyrUIf31ixyPM89TdWunmnNxCESOmc0dxr8YezmShtH9vMi4iK3xqp5loO8B3o1AJv1cmQXfmSFZSS6TlO9QNjm0IaTf4nkqKPIuJ7dJz00sBH5h9zUaMOwnWw7dBV7JtHFUtfuMt5ON3rWQDGOOOSNb4lbDRfb+NukSx6pQpe7Jhi1AZgldTrc0KiJN+e++k3oMeJi1TcOKjQWqBC3yA+4N6dDwMxHNO+IQBmpdfP0txPhVzIcgigTgvKU5Z5B1UsRKL9ntO264vpfXb5qIKZxsTL5gRb8cr9SYTeqZALPPTiPyGprMmcMYuymH6kpdtssAZlmkq4Fkqn0MpsUuusampz8fBVqvkLCLFskN9a3CSKYFYtq5xs2tOY4ZbQOZ233nmPWjtAdzO0TB8XKDJp0uSQqZL8Nxi8qDxe/jPJ3BsNvZ45GD/a1d586VN6+tJnhpq2kUi1JGbjYm748Pqn2jbshfpzO8yxTafKk8YdMTvOZUTJDspa9HGPxojq/Kre4L3WNpEFtsvcB9voh213Jgifb5VIHZtq4wfBeIRSdF2sI+CEpWGXpuLHN1oOiprwIrq5LpEHhHGxQIiDYSiIk/gYzGadEuyUOq8o2B1k5oULZE+dho02hlKtK0cCWv5QADlyz/QhXPZkiwqzgzCRJDGj/1y02xNbBb4ZFanAXgtm/l7fg==", +} diff --git a/.venv/lib/python3.13/site-packages/gradio_client/package.json b/.venv/lib/python3.13/site-packages/gradio_client/package.json new file mode 100644 index 0000000000000000000000000000000000000000..6206ae2475f5cdec954b4b06fd9b39b666497e17 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio_client/package.json @@ -0,0 +1,8 @@ +{ + "name": "gradio_client", + "version": "1.14.0", + "description": "", + "python": "true", + "main_changeset": true, + "private": true +} diff --git a/.venv/lib/python3.13/site-packages/gradio_client/serializing.py b/.venv/lib/python3.13/site-packages/gradio_client/serializing.py new file mode 100644 index 0000000000000000000000000000000000000000..bd0d98e6f65b41c87a7958d0ddc42113f38b8443 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio_client/serializing.py @@ -0,0 +1,602 @@ +"""Included for backwards compatibility with 3.x spaces/apps.""" + +from __future__ import annotations + +import json +import os +import secrets +import tempfile +import uuid +from pathlib import Path +from typing import Any + +from gradio_client import media_data, utils +from gradio_client.data_classes import FileData + +with open(Path(__file__).parent / "types.json") as f: + serializer_types = json.load(f) + + +class Serializable: + def serialized_info(self): + """ + The typing information for this component as a dictionary whose values are a list of 2 strings: [Python type, language-agnostic description]. + Keys of the dictionary are: raw_input, raw_output, serialized_input, serialized_output + """ + return self.api_info() + + def api_info(self) -> dict[str, list[str]]: + """ + The typing information for this component as a dictionary whose values are a list of 2 strings: [Python type, language-agnostic description]. + Keys of the dictionary are: raw_input, raw_output, serialized_input, serialized_output + """ + raise NotImplementedError() + + def example_inputs(self) -> dict[str, Any]: + """ + The example inputs for this component as a dictionary whose values are example inputs compatible with this component. + Keys of the dictionary are: raw, serialized + """ + raise NotImplementedError() + + # For backwards compatibility + def input_api_info(self) -> tuple[str, str]: + api_info = self.api_info() + types = api_info.get("serialized_input", [api_info["info"]["type"]] * 2) # type: ignore + return (types[0], types[1]) + + # For backwards compatibility + def output_api_info(self) -> tuple[str, str]: + api_info = self.api_info() + types = api_info.get("serialized_output", [api_info["info"]["type"]] * 2) # type: ignore + return (types[0], types[1]) + + def serialize(self, x: Any, load_dir: str | Path = "", allow_links: bool = False): + """ + Convert data from human-readable format to serialized format for a browser. + """ + return x + + def deserialize( + self, + x: Any, + save_dir: str | Path | None = None, + root_url: str | None = None, + hf_token: str | None = None, + ): + """ + Convert data from serialized format for a browser to human-readable format. + """ + return x + + +class SimpleSerializable(Serializable): + """General class that does not perform any serialization or deserialization.""" + + def api_info(self) -> dict[str, bool | dict]: + return { + "info": serializer_types["SimpleSerializable"], + "serialized_info": False, + } + + def example_inputs(self) -> dict[str, Any]: + return { + "raw": None, + "serialized": None, + } + + +class StringSerializable(Serializable): + """Expects a string as input/output but performs no serialization.""" + + def api_info(self) -> dict[str, bool | dict]: + return { + "info": serializer_types["StringSerializable"], + "serialized_info": False, + } + + def example_inputs(self) -> dict[str, Any]: + return { + "raw": "Howdy!", + "serialized": "Howdy!", + } + + +class ListStringSerializable(Serializable): + """Expects a list of strings as input/output but performs no serialization.""" + + def api_info(self) -> dict[str, bool | dict]: + return { + "info": serializer_types["ListStringSerializable"], + "serialized_info": False, + } + + def example_inputs(self) -> dict[str, Any]: + return { + "raw": ["Howdy!", "Merhaba"], + "serialized": ["Howdy!", "Merhaba"], + } + + +class BooleanSerializable(Serializable): + """Expects a boolean as input/output but performs no serialization.""" + + def api_info(self) -> dict[str, bool | dict]: + return { + "info": serializer_types["BooleanSerializable"], + "serialized_info": False, + } + + def example_inputs(self) -> dict[str, Any]: + return { + "raw": True, + "serialized": True, + } + + +class NumberSerializable(Serializable): + """Expects a number (int/float) as input/output but performs no serialization.""" + + def api_info(self) -> dict[str, bool | dict]: + return { + "info": serializer_types["NumberSerializable"], + "serialized_info": False, + } + + def example_inputs(self) -> dict[str, Any]: + return { + "raw": 5, + "serialized": 5, + } + + +class ImgSerializable(Serializable): + """Expects a base64 string as input/output which is serialized to a filepath.""" + + def serialized_info(self): + return { + "type": "string", + "description": "filepath on your computer (or URL) of image", + } + + def api_info(self) -> dict[str, bool | dict]: + return {"info": serializer_types["ImgSerializable"], "serialized_info": True} + + def example_inputs(self) -> dict[str, Any]: + return { + "raw": media_data.BASE64_IMAGE, + "serialized": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png", + } + + def serialize( + self, + x: str | None, + load_dir: str | Path = "", + allow_links: bool = False, + ) -> str | None: + """ + Convert from human-friendly version of a file (string filepath) to a serialized + representation (base64). + Parameters: + x: String path to file to serialize + load_dir: Path to directory containing x + """ + if not x: + return None + if utils.is_http_url_like(x): + return utils.encode_url_to_base64(x) + return utils.encode_file_to_base64(Path(load_dir) / x) + + def deserialize( + self, + x: str | None, + save_dir: str | Path | None = None, + root_url: str | None = None, + hf_token: str | None = None, + ) -> str | None: + """ + Convert from serialized representation of a file (base64) to a human-friendly + version (string filepath). Optionally, save the file to the directory specified by save_dir + Parameters: + x: Base64 representation of image to deserialize into a string filepath + save_dir: Path to directory to save the deserialized image to + root_url: Ignored + hf_token: Ignored + """ + if x is None or x == "": + return None + file = utils.decode_base64_to_file(x, dir=save_dir) + return file.name + + +class FileSerializable(Serializable): + """Expects a dict with base64 representation of object as input/output which is serialized to a filepath.""" + + def __init__(self) -> None: + self.stream = None + self.stream_name = None + super().__init__() + + def serialized_info(self): + return self._single_file_serialized_info() + + def _single_file_api_info(self): + return { + "info": serializer_types["SingleFileSerializable"], + "serialized_info": True, + } + + def _single_file_serialized_info(self): + return { + "type": "string", + "description": "filepath on your computer (or URL) of file", + } + + def _multiple_file_serialized_info(self): + return { + "type": "array", + "description": "List of filepath(s) or URL(s) to files", + "items": { + "type": "string", + "description": "filepath on your computer (or URL) of file", + }, + } + + def _multiple_file_api_info(self): + return { + "info": serializer_types["MultipleFileSerializable"], + "serialized_info": True, + } + + def api_info(self) -> dict[str, dict | bool]: + return self._single_file_api_info() + + def example_inputs(self) -> dict[str, Any]: + return self._single_file_example_inputs() + + def _single_file_example_inputs(self) -> dict[str, Any]: + return { + "raw": {"is_file": False, "data": media_data.BASE64_FILE}, + "serialized": "https://github.com/gradio-app/gradio/raw/main/test/test_files/sample_file.pdf", + } + + def _multiple_file_example_inputs(self) -> dict[str, Any]: + return { + "raw": [{"is_file": False, "data": media_data.BASE64_FILE}], + "serialized": [ + "https://github.com/gradio-app/gradio/raw/main/test/test_files/sample_file.pdf" + ], + } + + def _serialize_single( + self, + x: str | FileData | None, + load_dir: str | Path = "", + allow_links: bool = False, + ) -> FileData | None: + if x is None or isinstance(x, dict): + return x + if utils.is_http_url_like(x): + filename = x + size = None + else: + filename = str(Path(load_dir) / x) + size = Path(filename).stat().st_size + return { + "name": filename or None, + "data": None + if allow_links + else utils.encode_url_or_file_to_base64(filename), + "orig_name": Path(filename).name, + "size": size, + } + + def _setup_stream(self, url, hf_token): + return utils.download_byte_stream(url, hf_token) + + def _deserialize_single( + self, + x: str | FileData | None, + save_dir: str | None = None, + root_url: str | None = None, + hf_token: str | None = None, + ) -> str | None: + if x is None: + return None + if isinstance(x, str): + file_name = utils.decode_base64_to_file(x, dir=save_dir).name + elif isinstance(x, dict): + if x.get("is_file"): + filepath = x.get("name") + if filepath is None: + raise ValueError(f"The 'name' field is missing in {x}") + if root_url is not None: + file_name = utils.download_tmp_copy_of_file( + root_url + "file=" + filepath, + hf_token=hf_token, + dir=save_dir, + ) + else: + file_name = utils.create_tmp_copy_of_file(filepath, dir=save_dir) + elif x.get("is_stream"): + if not (x["name"] and root_url and save_dir): + raise ValueError( + "name and root_url and save_dir must all be present" + ) + if not self.stream or self.stream_name != x["name"]: + self.stream = self._setup_stream( + root_url + "stream/" + x["name"], hf_token=hf_token + ) + self.stream_name = x["name"] + chunk = next(self.stream) + path = Path(save_dir or tempfile.gettempdir()) / secrets.token_hex(20) + path.mkdir(parents=True, exist_ok=True) + path = path / x.get("orig_name", "output") + path.write_bytes(chunk) + file_name = str(path) + else: + data = x.get("data") + if data is None: + raise ValueError(f"The 'data' field is missing in {x}") + file_name = utils.decode_base64_to_file(data, dir=save_dir).name + else: + raise ValueError( + f"A FileSerializable component can only deserialize a string or a dict, not a {type(x)}: {x}" + ) + return file_name + + def serialize( + self, + x: str | FileData | None | list[str | FileData | None], + load_dir: str | Path = "", + allow_links: bool = False, + ) -> FileData | None | list[FileData | None]: + """ + Convert from human-friendly version of a file (string filepath) to a + serialized representation (base64) + Parameters: + x: String path to file to serialize + load_dir: Path to directory containing x + allow_links: Will allow path returns instead of raw file content + """ + if x is None or x == "": + return None + if isinstance(x, list): + return [self._serialize_single(f, load_dir, allow_links) for f in x] + else: + return self._serialize_single(x, load_dir, allow_links) + + def deserialize( + self, + x: str | FileData | None | list[str | FileData | None], + save_dir: Path | str | None = None, + root_url: str | None = None, + hf_token: str | None = None, + ) -> str | None | list[str | None]: + """ + Convert from serialized representation of a file (base64) to a human-friendly + version (string filepath). Optionally, save the file to the directory specified by `save_dir` + Parameters: + x: Base64 representation of file to deserialize into a string filepath + save_dir: Path to directory to save the deserialized file to + root_url: If this component is loaded from an external Space, this is the URL of the Space. + hf_token: If this component is loaded from an external private Space, this is the access token for the Space + """ + if x is None: + return None + if isinstance(save_dir, Path): + save_dir = str(save_dir) + if isinstance(x, list): + return [ + self._deserialize_single( + f, save_dir=save_dir, root_url=root_url, hf_token=hf_token + ) + for f in x + ] + else: + return self._deserialize_single( + x, save_dir=save_dir, root_url=root_url, hf_token=hf_token + ) + + +class VideoSerializable(FileSerializable): + def serialized_info(self): + return { + "type": "string", + "description": "filepath on your computer (or URL) of video file", + } + + def api_info(self) -> dict[str, dict | bool]: + return {"info": serializer_types["FileSerializable"], "serialized_info": True} + + def example_inputs(self) -> dict[str, Any]: + return { + "raw": {"is_file": False, "data": media_data.BASE64_VIDEO}, + "serialized": "https://github.com/gradio-app/gradio/raw/main/test/test_files/video_sample.mp4", + } + + def serialize( + self, x: str | None, load_dir: str | Path = "", allow_links: bool = False + ) -> tuple[FileData | None, None]: + return (super().serialize(x, load_dir, allow_links), None) # type: ignore + + def deserialize( + self, + x: tuple[FileData | None, FileData | None] | None, + save_dir: Path | str | None = None, + root_url: str | None = None, + hf_token: str | None = None, + ) -> str | tuple[str | None, str | None] | None: + """ + Convert from serialized representation of a file (base64) to a human-friendly + version (string filepath). Optionally, save the file to the directory specified by `save_dir` + """ + if isinstance(x, (tuple, list)): + if len(x) != 2: + raise ValueError(f"Expected tuple of length 2. Received: {x}") + x_as_list = [x[0], x[1]] + else: + raise ValueError(f"Expected tuple of length 2. Received: {x}") + deserialized_file = super().deserialize(x_as_list, save_dir, root_url, hf_token) # type: ignore + if isinstance(deserialized_file, list): + return deserialized_file[0] # ignore subtitles + + +class JSONSerializable(Serializable): + def serialized_info(self): + return {"type": "string", "description": "filepath to JSON file"} + + def api_info(self) -> dict[str, dict | bool]: + return {"info": serializer_types["JSONSerializable"], "serialized_info": True} + + def example_inputs(self) -> dict[str, Any]: + return { + "raw": {"a": 1, "b": 2}, + "serialized": None, + } + + def serialize( + self, + x: str | None, + load_dir: str | Path = "", + allow_links: bool = False, + ) -> dict | list | None: + """ + Convert from a a human-friendly version (string path to json file) to a + serialized representation (json string) + Parameters: + x: String path to json file to read to get json string + load_dir: Path to directory containing x + """ + if x is None or x == "": + return None + return utils.file_to_json(Path(load_dir) / x) + + def deserialize( + self, + x: str | dict | list, + save_dir: str | Path | None = None, + root_url: str | None = None, + hf_token: str | None = None, + ) -> str | None: + """ + Convert from serialized representation (json string) to a human-friendly + version (string path to json file). Optionally, save the file to the directory specified by `save_dir` + Parameters: + x: Json string + save_dir: Path to save the deserialized json file to + root_url: Ignored + hf_token: Ignored + """ + if x is None: + return None + return utils.dict_or_str_to_json_file(x, dir=save_dir).name + + +class GallerySerializable(Serializable): + def serialized_info(self): + return { + "type": "string", + "description": "path to directory with images and a file associating images with captions called captions.json", + } + + def api_info(self) -> dict[str, dict | bool]: + return { + "info": serializer_types["GallerySerializable"], + "serialized_info": True, + } + + def example_inputs(self) -> dict[str, Any]: + return { + "raw": [media_data.BASE64_IMAGE] * 2, + "serialized": [ + "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png", + ] + * 2, + } + + def serialize( + self, x: str | None, load_dir: str | Path = "", allow_links: bool = False + ) -> list[list[str | None]] | None: + if x is None or x == "": + return None + files = [] + captions_file = Path(x) / "captions.json" + with captions_file.open("r") as captions_json: + captions = json.load(captions_json) + for file_name, caption in captions.items(): + img = FileSerializable().serialize(file_name, allow_links=allow_links) + files.append([img, caption]) + return files + + def deserialize( + self, + x: list[list[str | None]] | None, + save_dir: str = "", + root_url: str | None = None, + hf_token: str | None = None, + ) -> None | str: + if x is None: + return None + gallery_path = Path(save_dir) / str(uuid.uuid4()) + gallery_path.mkdir(exist_ok=True, parents=True) + captions = {} + for img_data in x: + if isinstance(img_data, (list, tuple)): + img_data, caption = img_data + else: + caption = None + name = FileSerializable().deserialize( + img_data, gallery_path, root_url=root_url, hf_token=hf_token + ) + captions[name] = caption + captions_file = gallery_path / "captions.json" + with captions_file.open("w") as captions_json: + json.dump(captions, captions_json) + return os.path.abspath(gallery_path) + + +SERIALIZER_MAPPING = {} +for cls in Serializable.__subclasses__(): + SERIALIZER_MAPPING[cls.__name__] = cls + for subcls in cls.__subclasses__(): + SERIALIZER_MAPPING[subcls.__name__] = subcls + +SERIALIZER_MAPPING["Serializable"] = SimpleSerializable +SERIALIZER_MAPPING["File"] = FileSerializable +SERIALIZER_MAPPING["UploadButton"] = FileSerializable + +COMPONENT_MAPPING: dict[str, type] = { + "textbox": StringSerializable, + "number": NumberSerializable, + "slider": NumberSerializable, + "checkbox": BooleanSerializable, + "checkboxgroup": ListStringSerializable, + "radio": StringSerializable, + "dropdown": SimpleSerializable, + "image": ImgSerializable, + "video": FileSerializable, + "audio": FileSerializable, + "file": FileSerializable, + "dataframe": JSONSerializable, + "timeseries": JSONSerializable, + "fileexplorer": JSONSerializable, + "state": SimpleSerializable, + "button": StringSerializable, + "uploadbutton": FileSerializable, + "colorpicker": StringSerializable, + "label": JSONSerializable, + "highlightedtext": JSONSerializable, + "json": JSONSerializable, + "html": StringSerializable, + "gallery": GallerySerializable, + "chatbot": JSONSerializable, + "model3d": FileSerializable, + "plot": JSONSerializable, + "barplot": JSONSerializable, + "lineplot": JSONSerializable, + "scatterplot": JSONSerializable, + "markdown": StringSerializable, + "code": StringSerializable, + "annotatedimage": JSONSerializable, +} diff --git a/.venv/lib/python3.13/site-packages/gradio_client/templates/discord_chat.py b/.venv/lib/python3.13/site-packages/gradio_client/templates/discord_chat.py new file mode 100644 index 0000000000000000000000000000000000000000..747100d055413ea0170f9d77c06fd92be0b6d673 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio_client/templates/discord_chat.py @@ -0,0 +1,192 @@ +import asyncio +import os +import threading +from threading import Event + +import discord +import gradio as gr +from discord import Permissions +from discord.ext import commands +from discord.utils import oauth_url + +import gradio_client as grc +from gradio_client.utils import QueueError + +event = Event() + +DISCORD_TOKEN = os.getenv("DISCORD_TOKEN") + + +async def wait(job): + while not job.done(): + await asyncio.sleep(0.2) + + +def get_client(session: str | None = None) -> grc.Client: + client = grc.Client("<>", hf_token=os.getenv("HF_TOKEN")) + if session: + client.session_hash = session + return client + + +def truncate_response(response: str) -> str: + ending = "...\nTruncating response to 2000 characters due to discord api limits." + if len(response) > 2000: + return response[: 2000 - len(ending)] + ending + else: + return response + + +intents = discord.Intents.default() +intents.message_content = True +bot = commands.Bot(command_prefix="/", intents=intents) + + +@bot.event +async def on_ready(): + print(f"Logged in as {bot.user} (ID: {bot.user.id})") + synced = await bot.tree.sync() + print(f"Synced commands: {', '.join([s.name for s in synced])}.") + event.set() + print("------") + + +thread_to_client = {} +thread_to_user = {} + + +@bot.hybrid_command( + name="<>", + description="Enter some text to chat with the bot! Like this: /<> Hello, how are you?", +) +async def chat(ctx, prompt: str): + if ctx.author.id == bot.user.id: + return + try: + message = await ctx.send("Creating thread...") + + thread = await message.create_thread(name=prompt) + loop = asyncio.get_running_loop() + client = await loop.run_in_executor(None, get_client, None) + job = client.submit(prompt, api_name="/<>") + await wait(job) + + try: + job.result() + response = job.outputs()[-1] + await thread.send(truncate_response(response)) + thread_to_client[thread.id] = client + thread_to_user[thread.id] = ctx.author.id + except QueueError: + await thread.send( + "The gradio space powering this bot is really busy! Please try again later!" + ) + + except Exception as e: + print(f"{e}") + + +async def continue_chat(message): + """Continues a given conversation based on chathistory""" + try: + client = thread_to_client[message.channel.id] + prompt = message.content + job = client.submit(prompt, api_name="/<>") + await wait(job) + try: + job.result() + response = job.outputs()[-1] + await message.reply(truncate_response(response)) + except QueueError: + await message.reply( + "The gradio space powering this bot is really busy! Please try again later!" + ) + + except Exception as e: + print(f"Error: {e}") + + +@bot.event +async def on_message(message): + """Continue the chat""" + try: + if not message.author.bot: + if message.channel.id in thread_to_user: + if thread_to_user[message.channel.id] == message.author.id: + await continue_chat(message) + else: + await bot.process_commands(message) + + except Exception as e: + print(f"Error: {e}") + + +# running in thread +def run_bot(): + if not DISCORD_TOKEN: + print("DISCORD_TOKEN NOT SET") + event.set() + else: + bot.run(DISCORD_TOKEN) + + +threading.Thread(target=run_bot).start() + +event.wait() + +if not DISCORD_TOKEN: + welcome_message = """ + + ## You have not specified a DISCORD_TOKEN, which means you have not created a bot account. Please follow these steps: + + ### 1. Go to https://discord.com/developers/applications and click 'New Application' + + ### 2. Give your bot a name 🤖 + + ![](https://gradio-builds.s3.amazonaws.com/demo-files/discordbots/BotName.png) + + ## 3. In Settings > Bot, click the 'Reset Token' button to get a new token. Write it down and keep it safe 🔐 + + ![](https://gradio-builds.s3.amazonaws.com/demo-files/discordbots/ResetToken.png) + + ## 4. Optionally make the bot public if you want anyone to be able to add it to their servers + + ## 5. Scroll down and enable 'Message Content Intent' under 'Priviledged Gateway Intents' + + ![](https://gradio-builds.s3.amazonaws.com/demo-files/discordbots/MessageContentIntent.png) + + ## 6. Save your changes! + + ## 7. The token from step 3 is the DISCORD_TOKEN. Rerun the deploy_discord command, e.g client.deploy_discord(discord_bot_token=DISCORD_TOKEN, ...), or add the token as a space secret manually. +""" +else: + permissions = Permissions(326417525824) + url = oauth_url(bot.user.id, permissions=permissions) + welcome_message = f""" + ## Add this bot to your server by clicking this link: + + {url} + + ## How to use it? + + The bot can be triggered via `/<>` followed by your text prompt. + + This will create a thread with the bot's response to your text prompt. + You can reply in the thread (without `/<>`) to continue the conversation. + In the thread, the bot will only reply to the original author of the command. + + ⚠️ Note ⚠️: Please make sure this bot's command does have the same name as another command in your server. + + ⚠️ Note ⚠️: Bot commands do not work in DMs with the bot as of now. + """ + + +with gr.Blocks() as demo: + gr.Markdown( + f""" + # Discord bot of <> + {welcome_message} + """ + ) + +demo.launch() diff --git a/.venv/lib/python3.13/site-packages/gradio_client/types.json b/.venv/lib/python3.13/site-packages/gradio_client/types.json new file mode 100644 index 0000000000000000000000000000000000000000..2fc1d425b4568bb38def2517449b428858410759 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio_client/types.json @@ -0,0 +1,199 @@ +{ + "SimpleSerializable": { + "type": {}, + "description": "any valid value" + }, + "StringSerializable": { + "type": "string" + }, + "ListStringSerializable": { + "type": "array", + "items": { + "type": "string" + } + }, + "BooleanSerializable": { + "type": "boolean" + }, + "NumberSerializable": { + "type": "number" + }, + "ImgSerializable": { + "type": "string", + "description": "base64 representation of an image" + }, + "FileSerializable": { + "oneOf": [ + { + "type": "string", + "description": "filepath on your computer (or URL) of file" + }, + { + "type": "object", + "properties": { + "name": { "type": "string", "description": "name of file" }, + "data": { + "type": "string", + "description": "base64 representation of file" + }, + "size": { + "type": "integer", + "description": "size of image in bytes" + }, + "is_file": { + "type": "boolean", + "description": "true if the file has been uploaded to the server" + }, + "orig_name": { + "type": "string", + "description": "original name of the file" + } + }, + "required": ["name", "data"] + }, + { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string", + "description": "filepath on your computer (or URL) of file" + }, + { + "type": "object", + "properties": { + "name": { "type": "string", "description": "name of file" }, + "data": { + "type": "string", + "description": "base64 representation of file" + }, + "size": { + "type": "integer", + "description": "size of image in bytes" + }, + "is_file": { + "type": "boolean", + "description": "true if the file has been uploaded to the server" + }, + "orig_name": { + "type": "string", + "description": "original name of the file" + } + }, + "required": ["name", "data"] + } + ] + } + } + ] + }, + "SingleFileSerializable": { + "oneOf": [ + { + "type": "string", + "description": "filepath on your computer (or URL) of file" + }, + { + "type": "object", + "properties": { + "name": { "type": "string", "description": "name of file" }, + "data": { + "type": "string", + "description": "base64 representation of file" + }, + "size": { + "type": "integer", + "description": "size of image in bytes" + }, + "is_file": { + "type": "boolean", + "description": "true if the file has been uploaded to the server" + }, + "orig_name": { + "type": "string", + "description": "original name of the file" + } + }, + "required": ["name", "data"] + } + ] + }, + "MultipleFileSerializable": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string", + "description": "filepath on your computer (or URL) of file" + }, + { + "type": "object", + "properties": { + "name": { "type": "string", "description": "name of file" }, + "data": { + "type": "string", + "description": "base64 representation of file" + }, + "size": { + "type": "integer", + "description": "size of image in bytes" + }, + "is_file": { + "type": "boolean", + "description": "true if the file has been uploaded to the server" + }, + "orig_name": { + "type": "string", + "description": "original name of the file" + } + }, + "required": ["name", "data"] + } + ] + } + }, + "JSONSerializable": { + "type": {}, + "description": "any valid json" + }, + "GallerySerializable": { + "type": "array", + "items": { + "type": "array", + "items": false, + "maxSize": 2, + "minSize": 2, + "prefixItems": [ + { + "type": "object", + "properties": { + "name": { "type": "string", "description": "name of file" }, + "data": { + "type": "string", + "description": "base64 representation of file" + }, + "size": { + "type": "integer", + "description": "size of image in bytes" + }, + "is_file": { + "type": "boolean", + "description": "true if the file has been uploaded to the server" + }, + "orig_name": { + "type": "string", + "description": "original name of the file" + } + }, + "required": ["name", "data"] + }, + { + "oneOf": [ + { "type": "string", "description": "caption of image" }, + { "type": "null" } + ] + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/gradio_client/utils.py b/.venv/lib/python3.13/site-packages/gradio_client/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..7e4c6fabad33596067669e923183f1e49bb65036 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/gradio_client/utils.py @@ -0,0 +1,1373 @@ +from __future__ import annotations + +import asyncio +import base64 +import concurrent.futures +import copy +import inspect +import json +import mimetypes +import os +import pkgutil +import secrets +import shutil +import tempfile +import time +import warnings +from collections.abc import Callable, Coroutine +from dataclasses import dataclass, field +from datetime import datetime +from enum import Enum +from pathlib import Path +from threading import Lock +from typing import ( + TYPE_CHECKING, + Any, + Literal, + NewType, + TypedDict, + Union, + get_args, + get_origin, + get_type_hints, +) + +import fsspec.asyn +import httpx +import huggingface_hub +from huggingface_hub import SpaceStage +from websockets.asyncio.client import ClientConnection + +if TYPE_CHECKING: + from gradio_client.data_classes import ParameterInfo + +API_URL = "api/predict/" +SSE_URL_V0 = "queue/join" +SSE_DATA_URL_V0 = "queue/data" +SSE_URL = "queue/data" +SSE_DATA_URL = "queue/join" +WS_URL = "queue/join" +UPLOAD_URL = "upload" +LOGIN_URL = "login" +CONFIG_URL = "config" +API_INFO_URL = "info?all_endpoints=True" +RAW_API_INFO_URL = "info?serialize=False" +SPACE_FETCHER_URL = "https://gradio-space-api-fetcher-v2.hf.space/api" +RESET_URL = "reset" +SPACE_URL = "https://hf.space/{}" +HEARTBEAT_URL = "heartbeat/{session_hash}" +CANCEL_URL = "cancel" + +STATE_COMPONENT = "state" +INVALID_RUNTIME = [ + SpaceStage.NO_APP_FILE, + SpaceStage.CONFIG_ERROR, + SpaceStage.BUILD_ERROR, + SpaceStage.RUNTIME_ERROR, + SpaceStage.PAUSED, +] + + +class Message(TypedDict, total=False): + msg: str + output: dict[str, Any] + event_id: str + rank: int + rank_eta: float + queue_size: int + success: bool + progress_data: list[dict] + log: str + level: str + + +def get_package_version() -> str: + try: + package_json_data = ( + pkgutil.get_data(__name__, "package.json").decode("utf-8").strip() # type: ignore + ) + package_data = json.loads(package_json_data) + version = package_data.get("version", "") + return version + except Exception: + return "" + + +__version__ = get_package_version() + + +class TooManyRequestsError(Exception): + """Raised when the API returns a 429 status code.""" + + pass + + +class QueueError(Exception): + """Raised when the queue is full or there is an issue adding a job to the queue.""" + + pass + + +class InvalidAPIEndpointError(Exception): + """Raised when the API endpoint is invalid.""" + + pass + + +class SpaceDuplicationError(Exception): + """Raised when something goes wrong with a Space Duplication.""" + + pass + + +class ServerMessage(str, Enum): + send_hash = "send_hash" + queue_full = "queue_full" + estimation = "estimation" + send_data = "send_data" + process_starts = "process_starts" + process_generating = "process_generating" + process_completed = "process_completed" + log = "log" + progress = "progress" + heartbeat = "heartbeat" + server_stopped = "Server stopped unexpectedly." + unexpected_error = "unexpected_error" + close_stream = "close_stream" + process_streaming = "process_streaming" + + +class Status(Enum): + """Status codes presented to client users.""" + + STARTING = "STARTING" + JOINING_QUEUE = "JOINING_QUEUE" + QUEUE_FULL = "QUEUE_FULL" + IN_QUEUE = "IN_QUEUE" + SENDING_DATA = "SENDING_DATA" + PROCESSING = "PROCESSING" + ITERATING = "ITERATING" + PROGRESS = "PROGRESS" + FINISHED = "FINISHED" + CANCELLED = "CANCELLED" + LOG = "LOG" + + @staticmethod + def ordering(status: Status) -> int: + """Order of messages. Helpful for testing.""" + order = [ + Status.STARTING, + Status.JOINING_QUEUE, + Status.QUEUE_FULL, + Status.IN_QUEUE, + Status.SENDING_DATA, + Status.PROCESSING, + Status.PROGRESS, + Status.ITERATING, + Status.FINISHED, + Status.CANCELLED, + ] + return order.index(status) + + def __lt__(self, other: Status): + return self.ordering(self) < self.ordering(other) + + @staticmethod + def msg_to_status(msg: str) -> Status: + """Map the raw message from the backend to the status code presented to users.""" + return { + ServerMessage.send_hash: Status.JOINING_QUEUE, + ServerMessage.queue_full: Status.QUEUE_FULL, + ServerMessage.estimation: Status.IN_QUEUE, + ServerMessage.send_data: Status.SENDING_DATA, + ServerMessage.process_starts: Status.PROCESSING, + ServerMessage.process_generating: Status.ITERATING, + ServerMessage.process_completed: Status.FINISHED, + ServerMessage.progress: Status.PROGRESS, + ServerMessage.log: Status.LOG, + ServerMessage.server_stopped: Status.FINISHED, + }[msg] # type: ignore + + +@dataclass +class ProgressUnit: + index: int | None + length: int | None + unit: str | None + progress: float | None + desc: str | None + + @classmethod + def from_msg(cls, data: list[dict]) -> list[ProgressUnit]: + return [ + cls( + index=d.get("index"), + length=d.get("length"), + unit=d.get("unit"), + progress=d.get("progress"), + desc=d.get("desc"), + ) + for d in data + ] + + +@dataclass +class StatusUpdate: + """Update message sent from the worker thread to the Job on the main thread.""" + + code: Status + rank: int | None + queue_size: int | None + eta: float | None + success: bool | None + time: datetime | None + progress_data: list[ProgressUnit] | None + log: tuple[str, str] | None = None + type: Literal["status", "output"] = "status" + + +@dataclass +class OutputUpdate: + """Update message sent from the worker thread to the Job on the main thread.""" + + outputs: list[Any] + success: bool + type: Literal["output"] = "output" + final: bool = False + + +Update = NewType("Update", StatusUpdate | OutputUpdate) + + +def create_initial_status_update(): + return StatusUpdate( + code=Status.STARTING, + rank=None, + queue_size=None, + eta=None, + success=None, + time=datetime.now(), + progress_data=None, + ) + + +@dataclass +class JobStatus: + """The job status. + + Keeps track of the latest status update and intermediate outputs (not yet implements). + """ + + latest_status: StatusUpdate = field(default_factory=create_initial_status_update) + outputs: list[Any] = field(default_factory=list) + + +@dataclass +class Communicator: + """Helper class to help communicate between the worker thread and main thread.""" + + lock: Lock + job: JobStatus + prediction_processor: Callable[..., tuple] + reset_url: str + should_cancel: bool = False + event_id: str | None = None + thread_complete: bool = False + request_headers: dict[str, str] | None = None + updates: asyncio.Queue[Update] = field(default_factory=asyncio.Queue) + + +######################## +# Network utils +######################## + + +def is_http_url_like(possible_url) -> bool: + """ + Check if the given value is a string that looks like an HTTP(S) URL. + """ + if not isinstance(possible_url, str): + return False + return possible_url.startswith(("http://", "https://")) + + +def probe_url(possible_url: str) -> bool: + """ + Probe the given URL to see if it responds with a 200 status code (to HEAD, then to GET). + """ + headers = {"User-Agent": "gradio (https://gradio.app/; gradio-team@huggingface.co)"} + try: + with httpx.Client() as client: + head_request = httpx.head(possible_url, headers=headers) + if head_request.status_code == 405: + return client.get(possible_url, headers=headers).is_success + return head_request.is_success + except Exception: + return False + + +def is_valid_url(possible_url: str) -> bool: + """ + Check if the given string is a valid URL. + """ + warnings.warn( + "is_valid_url should not be used. " + "Use is_http_url_like() and probe_url(), as suitable, instead.", + ) + return is_http_url_like(possible_url) and probe_url(possible_url) + + +async def get_pred_from_ws( + websocket: ClientConnection, + data: str, + hash_data: str, + helper: Communicator | None = None, +) -> dict[str, Any]: + completed = False + resp = {} + while not completed: + # Receive message in the background so that we can + # cancel even while running a long pred + task = asyncio.create_task(websocket.recv()) + while not task.done(): + if helper: + with helper.lock: + if helper.should_cancel: + # Need to reset the iterator state since the client + # will not reset the session + async with httpx.AsyncClient() as http: + reset = http.post( + helper.reset_url, json=json.loads(hash_data) + ) + # Retrieve cancel exception from task + # otherwise will get nasty warning in console + task.cancel() + await asyncio.gather(task, reset, return_exceptions=True) + raise concurrent.futures.CancelledError() + # Need to suspend this coroutine so that task actually runs + await asyncio.sleep(0.01) + msg = task.result() + resp = json.loads(msg) + if helper: + with helper.lock: + has_progress = "progress_data" in resp + status_update = StatusUpdate( + code=Status.msg_to_status(resp["msg"]), + queue_size=resp.get("queue_size"), + rank=resp.get("rank", None), + success=resp.get("success"), + time=datetime.now(), + eta=resp.get("rank_eta"), + progress_data=ProgressUnit.from_msg(resp["progress_data"]) + if has_progress + else None, + ) + output = resp.get("output", {}).get("data", []) + if output and status_update.code != Status.FINISHED: + try: + result = helper.prediction_processor(*output) + except Exception as e: + result = [e] + helper.job.outputs.append(result) + helper.job.latest_status = status_update + if resp["msg"] == "queue_full": + raise QueueError("Queue is full! Please try again.") + if resp["msg"] == "send_hash": + await websocket.send(hash_data) + elif resp["msg"] == "send_data": + await websocket.send(data) + completed = resp["msg"] == "process_completed" + return resp["output"] + + +def get_pred_from_sse_v0( + client: httpx.Client, + data: dict, + hash_data: dict, + helper: Communicator, + sse_url: str, + sse_data_url: str, + headers: dict[str, str], + cookies: dict[str, str] | None, + ssl_verify: bool, + executor: concurrent.futures.ThreadPoolExecutor, +) -> dict[str, Any] | None: + helper.thread_complete = False + future_cancel = executor.submit( + check_for_cancel, helper, headers, cookies, ssl_verify + ) + future_sse = executor.submit( + stream_sse_v0, + client, + data, + hash_data, + helper, + sse_url, + sse_data_url, + headers, + cookies, + ) + done, _ = concurrent.futures.wait( + [future_cancel, future_sse], # type: ignore + return_when=concurrent.futures.FIRST_COMPLETED, + ) + helper.thread_complete = True + + if len(done) != 1: + raise ValueError(f"Did not expect {len(done)} tasks to be done.") + for future in done: + return future.result() + + +def get_pred_from_sse_v1plus( + helper: Communicator, + headers: dict[str, str], + cookies: dict[str, str] | None, + pending_messages_per_event: dict[str, list[Message | None]], + event_id: str, + protocol: Literal["sse_v1", "sse_v2", "sse_v2.1"], + ssl_verify: bool, + executor: concurrent.futures.ThreadPoolExecutor, +) -> dict[str, Any] | None: + helper.thread_complete = False + future_cancel = executor.submit( + check_for_cancel, helper, headers, cookies, ssl_verify + ) + future_sse = executor.submit( + stream_sse_v1plus, helper, pending_messages_per_event, event_id, protocol + ) + done, _ = concurrent.futures.wait( + [future_cancel, future_sse], # type: ignore + return_when=concurrent.futures.FIRST_COMPLETED, + ) + helper.thread_complete = True + + if len(done) != 1: + raise ValueError(f"Did not expect {len(done)} tasks to be done.") + for future in done: + exception = future.exception() + if exception: + raise exception + return future.result() + + +def check_for_cancel( + helper: Communicator, + headers: dict[str, str], + cookies: dict[str, str] | None, + ssl_verify: bool, +): + while True: + time.sleep(0.05) + with helper.lock: + if helper.should_cancel: + break + if helper.thread_complete: + raise concurrent.futures.CancelledError() + if helper.event_id: + httpx.post( + helper.reset_url, + json={"event_id": helper.event_id}, + headers=headers, + cookies=cookies, + verify=ssl_verify, + ) + raise concurrent.futures.CancelledError() + + +def stream_sse_v0( + client: httpx.Client, + data: dict, + hash_data: dict, + helper: Communicator, + sse_url: str, + sse_data_url: str, + headers: dict[str, str], + cookies: dict[str, str] | None, +) -> dict[str, Any]: + try: + with client.stream( + "GET", + sse_url, + params=hash_data, + headers=headers, + cookies=cookies, + ) as response: + for line in response.iter_lines(): + line = line.rstrip("\n") + if len(line) == 0: + continue + if line.startswith("data:"): + resp = json.loads(line[5:]) + if resp["msg"] in [ServerMessage.log, ServerMessage.heartbeat]: + continue + with helper.lock: + has_progress = "progress_data" in resp + status_update = StatusUpdate( + code=Status.msg_to_status(resp["msg"]), + queue_size=resp.get("queue_size"), + rank=resp.get("rank", None), + success=resp.get("success"), + time=datetime.now(), + eta=resp.get("rank_eta"), + progress_data=ProgressUnit.from_msg(resp["progress_data"]) + if has_progress + else None, + ) + output = resp.get("output", {}).get("data", []) + if output and status_update.code != Status.FINISHED: + try: + result = helper.prediction_processor(*output) + except Exception as e: + result = [e] + helper.job.outputs.append(result) + helper.job.latest_status = status_update + if helper.thread_complete: + raise concurrent.futures.CancelledError() + if resp["msg"] == "queue_full": + raise QueueError("Queue is full! Please try again.") + elif resp["msg"] == "send_data": + event_id = resp["event_id"] + helper.event_id = event_id + req = client.post( + sse_data_url, + json={"event_id": event_id, **data, **hash_data}, + headers=headers, + cookies=cookies, + ) + req.raise_for_status() + elif resp["msg"] == "process_completed": + return resp["output"] + else: + raise ValueError(f"Unexpected message: {line}") + raise ValueError("Did not receive process_completed message.") + except concurrent.futures.CancelledError: + raise + + +def stream_sse_v1plus( + helper: Communicator, + pending_messages_per_event: dict[str, list[Message | None]], + event_id: str, + protocol: Literal["sse_v1", "sse_v2", "sse_v2.1", "sse_v3"], +) -> dict[str, Any]: + try: + pending_messages = pending_messages_per_event[event_id] + pending_responses_for_diffs = None + + while True: + if len(pending_messages) > 0: + msg = pending_messages.pop(0) + else: + time.sleep(0.05) + continue + + if msg is None or helper.thread_complete: + raise concurrent.futures.CancelledError() + + with helper.lock: + log_message = None + if msg["msg"] == ServerMessage.log: + log = msg.get("log") + level = msg.get("level") + if log and level: + log_message = (log, level) + status_update = StatusUpdate( + code=Status.msg_to_status(msg["msg"]), + queue_size=msg.get("queue_size"), + rank=msg.get("rank", None), + success=msg.get("success"), + time=datetime.now(), + eta=msg.get("rank_eta"), + progress_data=ProgressUnit.from_msg(msg["progress_data"]) + if "progress_data" in msg + else None, + log=log_message, + ) + output = msg.get("output", {}).get("data", []) + if msg["msg"] == ServerMessage.process_generating and protocol in [ + "sse_v2", + "sse_v2.1", + "sse_v3", + ]: + if pending_responses_for_diffs is None: + pending_responses_for_diffs = list(output) + else: + for i, value in enumerate(output): + prev_output = pending_responses_for_diffs[i] + new_output = apply_diff(prev_output, value) + pending_responses_for_diffs[i] = new_output + output[i] = new_output + + if output and status_update.code != Status.FINISHED: + try: + result = helper.prediction_processor(*output) + except Exception as e: + result = [e] + helper.job.outputs.append(result) + helper.updates.put_nowait( + OutputUpdate(outputs=result, success=msg.get("success", True)) + ) + helper.job.latest_status = status_update + helper.updates.put_nowait(status_update) + if msg["msg"] == ServerMessage.process_completed: + del pending_messages_per_event[event_id] + if not msg.get("success", True): + # Create a new copy of the error dict so we + # can preserve the error message (it gets popped later) + output = dict(msg["output"].items()) + else: + output = msg["output"] + helper.updates.put_nowait( + OutputUpdate( + outputs=output, + final=True, + success=msg.get("success", True), + ) + ) + return msg["output"] + elif msg["msg"] == ServerMessage.server_stopped: + raise ValueError("Server stopped.") + + except concurrent.futures.CancelledError: + raise + + +def apply_diff(obj, diff): + obj = copy.deepcopy(obj) + + def apply_edit(target, path, action, value): + if len(path) == 0: + if action == "replace": + return value + elif action == "append": + return target + value + else: + raise ValueError(f"Unsupported action: {action}") + + current = target + for i in range(len(path) - 1): + current = current[path[i]] + + last_path = path[-1] + if action == "replace": + current[last_path] = value + elif action == "append": + current[last_path] += value + elif action == "add": + if isinstance(current, list): + current.insert(int(last_path), value) + else: + current[last_path] = value + elif action == "delete": + if isinstance(current, list): + del current[int(last_path)] + else: + del current[last_path] + else: + raise ValueError(f"Unknown action: {action}") + + return target + + for action, path, value in diff: + obj = apply_edit(obj, path, action, value) + + return obj + + +######################## +# Data processing utils +######################## + + +def create_tmp_copy_of_file(file_path: str, dir: str | None = None) -> str: + directory = Path(dir or tempfile.gettempdir()) / secrets.token_hex(20) + directory.mkdir(exist_ok=True, parents=True) + dest = directory / Path(file_path).name + shutil.copy2(file_path, dest) + return str(dest.resolve()) + + +def download_tmp_copy_of_file( + url_path: str, hf_token: str | None = None, dir: str | None = None +) -> str: + """Kept for backwards compatibility for 3.x spaces.""" + if dir is not None: + os.makedirs(dir, exist_ok=True) + headers = {"Authorization": "Bearer " + hf_token} if hf_token else {} + directory = Path(dir or tempfile.gettempdir()) / secrets.token_hex(20) + directory.mkdir(exist_ok=True, parents=True) + file_path = directory / Path(url_path).name + + with httpx.stream( + "GET", url_path, headers=headers, follow_redirects=True + ) as response: + response.raise_for_status() + with open(file_path, "wb") as f: + for chunk in response.iter_raw(): + f.write(chunk) + return str(file_path.resolve()) + + +def get_mimetype(filename: str) -> str | None: + if filename.endswith(".vtt"): + return "text/vtt" + mimetype = mimetypes.guess_type(filename)[0] + if mimetype is not None: + mimetype = mimetype.replace("x-wav", "wav").replace("x-flac", "flac") + return mimetype + + +def get_extension(encoding: str) -> str | None: + encoding = encoding.replace("audio/wav", "audio/x-wav") + type = mimetypes.guess_type(encoding)[0] + if type == "audio/flac": # flac is not supported by mimetypes + return "flac" + elif type is None: + return None + extension = mimetypes.guess_extension(type) + if extension is not None and extension.startswith("."): + extension = extension[1:] + return extension + + +def is_valid_file(file_path: str, file_types: list[str]) -> bool: + mime_type = get_mimetype(file_path) + for file_type in file_types: + if file_type == "file": + return True + if file_type.startswith("."): + file_type = file_type.lstrip(".").lower() + file_ext = Path(file_path).suffix.lstrip(".").lower() + if file_type == file_ext: + return True + elif mime_type is not None and mime_type.startswith(f"{file_type}/"): + return True + return False + + +def encode_file_to_base64(f: str | Path): + with open(f, "rb") as file: + encoded_string = base64.b64encode(file.read()) + base64_str = str(encoded_string, "utf-8") + mimetype = get_mimetype(str(f)) + return ( + "data:" + + (mimetype if mimetype is not None else "") + + ";base64," + + base64_str + ) + + +def encode_url_to_base64(url: str): + resp = httpx.get(url) + resp.raise_for_status() + encoded_string = base64.b64encode(resp.content) + base64_str = str(encoded_string, "utf-8") + mimetype = get_mimetype(url) + return ( + "data:" + (mimetype if mimetype is not None else "") + ";base64," + base64_str + ) + + +def encode_url_or_file_to_base64(path: str | Path): + path = str(path) + if is_http_url_like(path): + return encode_url_to_base64(path) + return encode_file_to_base64(path) + + +def download_byte_stream(url: str, hf_token=None): + arr = bytearray() + headers = {"Authorization": "Bearer " + hf_token} if hf_token else {} + with httpx.stream("GET", url, headers=headers) as r: + for data in r.iter_bytes(): + arr += data + yield data + yield arr + + +def decode_base64_to_binary(encoding: str) -> tuple[bytes, str | None]: + extension = get_extension(encoding) + data = encoding.rsplit(",", 1)[-1] + return base64.b64decode(data), extension + + +def strip_invalid_filename_characters(filename: str, max_bytes: int = 200) -> str: + """ + Strips invalid characters from a filename and ensures it does not exceed the maximum byte length + Invalid characters are any characters that are not alphanumeric or one of the following: . _ - , + The filename may include an extension (in which case it is preserved exactly as is), or could be just a name without an extension. + """ + name, ext = os.path.splitext(filename) + name = "".join([char for char in name if char.isalnum() or char in "._-, "]) + filename = name + ext + filename_len = len(filename.encode()) + if filename_len > max_bytes: + while filename_len > max_bytes: + if len(name) == 0: + break + name = name[:-1] + filename = name + ext + filename_len = len(filename.encode()) + return filename + + +def sanitize_parameter_names(original_name: str) -> str: + """Cleans up a Python parameter name to make the API info more readable.""" + return ( + "".join([char for char in original_name if char.isalnum() or char in " _"]) + .replace(" ", "_") + .lower() + ) + + +def decode_base64_to_file( + encoding: str, + file_path: str | None = None, + dir: str | Path | None = None, + prefix: str | None = None, +): + directory = Path(dir or tempfile.gettempdir()) / secrets.token_hex(20) + directory.mkdir(exist_ok=True, parents=True) + data, extension = decode_base64_to_binary(encoding) + if file_path is not None and prefix is None: + filename = Path(file_path).name + prefix = filename + if "." in filename: + prefix = filename[0 : filename.index(".")] + extension = filename[filename.index(".") + 1 :] + + if prefix is not None: + prefix = strip_invalid_filename_characters(prefix) + + if extension is None: + file_obj = tempfile.NamedTemporaryFile( + delete=False, prefix=prefix, dir=directory + ) + else: + file_obj = tempfile.NamedTemporaryFile( + delete=False, + prefix=prefix, + suffix="." + extension, + dir=directory, + ) + file_obj.write(data) + file_obj.flush() + return file_obj + + +def dict_or_str_to_json_file(jsn: str | dict | list, dir: str | Path | None = None): + if dir is not None: + os.makedirs(dir, exist_ok=True) + + file_obj = tempfile.NamedTemporaryFile( + delete=False, suffix=".json", dir=dir, mode="w+" + ) + if isinstance(jsn, str): + jsn = json.loads(jsn) + json.dump(jsn, file_obj) + file_obj.flush() + return file_obj + + +def file_to_json(file_path: str | Path) -> dict | list: + with open(file_path) as f: + return json.load(f) + + +########################### +# HuggingFace Hub API Utils +########################### +def set_space_timeout( + space_id: str, + hf_token: str | None = None, + timeout_in_seconds: int = 300, +): + headers = huggingface_hub.utils.build_hf_headers( + token=hf_token, + library_name="gradio_client", + library_version=__version__, + ) + try: + httpx.post( + f"https://huggingface.co/api/spaces/{space_id}/sleeptime", + json={"seconds": timeout_in_seconds}, + headers=headers, + ) + except httpx.HTTPStatusError as e: + raise SpaceDuplicationError( + f"Could not set sleep timeout on duplicated Space. Please visit {SPACE_URL.format(space_id)} " + "to set a timeout manually to reduce billing charges." + ) from e + + +######################## +# Misc utils +######################## + + +def synchronize_async(func: Callable, *args, **kwargs) -> Any: + """ + Runs async functions in sync scopes. Can be used in any scope. + + Example: + if inspect.iscoroutinefunction(block_fn.fn): + predictions = utils.synchronize_async(block_fn.fn, *processed_input) + + Args: + func: + *args: + **kwargs: + """ + return fsspec.asyn.sync(fsspec.asyn.get_loop(), func, *args, **kwargs) # type: ignore + + +class APIInfoParseError(ValueError): + pass + + +def get_type(schema: dict): + if "const" in schema: + return "const" + if "enum" in schema: + return "enum" + elif "type" in schema: + return schema["type"] + elif schema.get("$ref"): + return "$ref" + elif schema.get("oneOf"): + return "oneOf" + elif schema.get("anyOf"): + return "anyOf" + elif schema.get("allOf"): + return "allOf" + elif "type" not in schema: + return {} + else: + raise APIInfoParseError(f"Cannot parse type for {schema}") + + +FILE_DATA_FORMATS = [ + "Dict(path: str | None (Path to a local file), url: str | None (Publicly available url or base64 encoded image), size: int | None (Size of image in bytes), orig_name: str | None (Original filename), mime_type: str | None (mime type of image), is_stream: bool (Can always be set to False), meta: Dict())", + "dict(path: str | None (Path to a local file), url: str | None (Publicly available url or base64 encoded image), size: int | None (Size of image in bytes), orig_name: str | None (Original filename), mime_type: str | None (mime type of image), is_stream: bool (Can always be set to False), meta: dict())", + "Dict(path: str, url: str | None, size: int | None, orig_name: str | None, mime_type: str | None)", + "Dict(path: str, url: str | None, size: int | None, orig_name: str | None, mime_type: str | None, is_stream: bool)", + "Dict(path: str, url: str | None, size: int | None, orig_name: str | None, mime_type: str | None, is_stream: bool, meta: Dict())", + "dict(path: str, url: str | None, size: int | None, orig_name: str | None, mime_type: str | None, is_stream: bool, meta: dict())", + "dict(path: str, url: str | None, size: int | None, orig_name: str | None, mime_type: str | None, is_stream: bool, meta: dict(_type: Literal[gradio.FileData]))", +] + +CURRENT_FILE_DATA_FORMAT = FILE_DATA_FORMATS[-1] + + +def json_schema_to_python_type(schema: Any) -> str: + type_ = _json_schema_to_python_type(schema, schema.get("$defs")) + return type_.replace(CURRENT_FILE_DATA_FORMAT, "filepath") + + +def _json_schema_to_python_type(schema: Any, defs) -> str: + """Convert the json schema into a python type hint""" + if schema == {}: + return "Any" + type_ = get_type(schema) + if type_ == {}: + if "json" in schema.get("description", {}): + return "str | float | bool | list | dict" + else: + return "Any" + elif type_ == "$ref": + return _json_schema_to_python_type(defs[schema["$ref"].split("/")[-1]], defs) + elif type_ == "null": + return "None" + elif type_ == "const": + return f"Literal[{schema['const']}]" + elif type_ == "enum": + return ( + "Literal[" + ", ".join(["'" + str(v) + "'" for v in schema["enum"]]) + "]" + ) + elif type_ == "integer": + return "int" + elif type_ == "string": + return "str" + elif type_ == "boolean": + return "bool" + elif type_ == "number": + return "float" + elif type_ == "array": + items = schema.get("items", []) + if "prefixItems" in items: + elements = ", ".join( + [_json_schema_to_python_type(i, defs) for i in items["prefixItems"]] + ) + return f"tuple[{elements}]" + elif "prefixItems" in schema: + elements = ", ".join( + [_json_schema_to_python_type(i, defs) for i in schema["prefixItems"]] + ) + return f"tuple[{elements}]" + else: + elements = _json_schema_to_python_type(items, defs) + return f"list[{elements}]" + elif type_ == "object": + + def get_desc(v): + return f" ({v.get('description')})" if v.get("description") else "" + + props = schema.get("properties", {}) + + des = [ + f"{n}: {_json_schema_to_python_type(v, defs)}{get_desc(v)}" + for n, v in props.items() + if n != "$defs" + ] + + if "additionalProperties" in schema: + additional_properties = schema["additionalProperties"] + if isinstance(additional_properties, bool) and additional_properties: + des += ["str, Any"] + else: + des += [ + f"str, {_json_schema_to_python_type(additional_properties, defs)}" + ] + des = ", ".join(des) + return f"dict({des})" + elif type_ in ["oneOf", "anyOf"]: + desc = " | ".join([_json_schema_to_python_type(i, defs) for i in schema[type_]]) + return desc + elif type_ == "allOf": + data = ", ".join(_json_schema_to_python_type(i, defs) for i in schema[type_]) + desc = f"All[{data}]" + return desc + else: + raise APIInfoParseError(f"Cannot parse schema {schema}") + + +def python_type_to_json_schema(type_hint: Any) -> dict: + try: + return _python_type_to_json_schema(type_hint) + except Exception: + return {} + + +def _python_type_to_json_schema(type_hint: Any) -> dict: + """Convert a Python type hint to a JSON schema.""" + if type_hint is type(None): + return {"type": "null"} + if type_hint is Any: + return {} + if type_hint is str: + return {"type": "string"} + if type_hint is int: + return {"type": "integer"} + if type_hint is float: + return {"type": "number"} + if type_hint is bool: + return {"type": "boolean"} + if type_hint is dict: + return {"type": "object", "additionalProperties": {}} + if type_hint is list: + return {"type": "array", "items": {}} + if type_hint is tuple: + return {"type": "array"} + if type_hint is set or type_hint is frozenset: + return {"type": "array", "uniqueItems": True} + if type_hint is bytes or type_hint is bytearray: + return {"type": "string", "format": "byte"} + + origin = get_origin(type_hint) + + if origin is Literal: + literal_values = get_args(type_hint) + if len(literal_values) == 1: + return {"const": literal_values[0]} + return {"enum": list(literal_values)} + + if ( + origin is Union + or (hasattr(origin, "__name__") and origin.__name__ == "UnionType") + or str(origin) == "|" + ): + types = get_args(type_hint) + if len(types) == 2 and type(None) in types: + other_type = next(t for t in types if t is not type(None)) + schema = _python_type_to_json_schema(other_type) + return {"oneOf": [{"type": "null"}, schema]} + return {"anyOf": [_python_type_to_json_schema(t) for t in types]} + + if origin is list: + args = get_args(type_hint) + if not args: + return {"type": "array", "items": {}} + item_type = args[0] + return {"type": "array", "items": _python_type_to_json_schema(item_type)} + if origin is tuple: + types = get_args(type_hint) + if not types: + return {"type": "array"} + if len(types) == 2 and types[1] is ...: + return {"type": "array", "items": _python_type_to_json_schema(types[0])} + return { + "type": "array", + "prefixItems": [_python_type_to_json_schema(t) for t in types], + "minItems": len(types), + "maxItems": len(types), + } + if origin is set or origin is frozenset: + args = get_args(type_hint) + if not args: + return {"type": "array", "uniqueItems": True} + item_type = args[0] + return { + "type": "array", + "uniqueItems": True, + "items": _python_type_to_json_schema(item_type), + } + + if origin is dict: + args = get_args(type_hint) + if not args: + return {"type": "object", "additionalProperties": {}} + key_type, value_type = args + if key_type is not str: + raise ValueError("JSON Schema only supports string keys in objects") + schema = { + "type": "object", + "additionalProperties": _python_type_to_json_schema(value_type), + } + return schema + + if inspect.isclass(type_hint) and issubclass(type_hint, Enum): + enum_values = [item.value for item in type_hint] + return {"enum": enum_values} + + if inspect.isclass(type_hint) and hasattr(type_hint, "__annotations__"): + properties = {} + required = [] + + hints = get_type_hints(type_hint) + for field_name, field_type in hints.items(): + properties[field_name] = _python_type_to_json_schema(field_type) + if hasattr(type_hint, "__total__"): + if type_hint.__total__: + required.append(field_name) + elif ( + not hasattr(type_hint, "__dataclass_fields__") + or not type_hint.__dataclass_fields__[field_name].default + ): + required.append(field_name) + + schema = {"type": "object", "properties": properties} + if required: + schema["required"] = required + return schema + + return {} + + +def traverse(json_obj: Any, func: Callable, is_root: Callable[..., bool]) -> Any: + """ + Traverse a JSON object and apply a function to each element that satisfies the is_root condition. + """ + if is_root(json_obj): + return func(json_obj) + elif isinstance(json_obj, dict): + new_obj = {} + for key, value in json_obj.items(): + new_obj[key] = traverse(value, func, is_root) + return new_obj + elif isinstance(json_obj, (list, tuple)): + new_obj = [] + for item in json_obj: + new_obj.append(traverse(item, func, is_root)) + return new_obj + else: + return json_obj + + +async def async_traverse( + json_obj: Any, + func: Callable[..., Coroutine[Any, Any, Any]], + is_root: Callable[..., bool], +) -> Any: + """ + Traverse a JSON object and apply a async function to each element that satisfies the is_root condition. + """ + if is_root(json_obj): + return await func(json_obj) + elif isinstance(json_obj, dict): + new_obj = {} + for key, value in json_obj.items(): + new_obj[key] = await async_traverse(value, func, is_root) + return new_obj + elif isinstance(json_obj, (list, tuple)): + new_obj = [] + for item in json_obj: + new_obj.append(await async_traverse(item, func, is_root)) + return new_obj + else: + return json_obj + + +def value_is_file(api_info: dict) -> bool: + info = _json_schema_to_python_type(api_info, api_info.get("$defs")) + return any(file_data_format in info for file_data_format in FILE_DATA_FORMATS) + + +def is_filepath(s) -> bool: + """ + Check if the given value is a valid str or Path filepath on the local filesystem, e.g. "path/to/file". + """ + return isinstance(s, (str, Path)) and Path(s).exists() and Path(s).is_file() + + +def is_file_obj(d) -> bool: + """ + Check if the given value is a valid FileData object dictionary in versions of Gradio<=4.20, e.g. + { + "path": "path/to/file", + } + """ + return isinstance(d, dict) and "path" in d and isinstance(d["path"], str) + + +def is_file_obj_with_meta(d) -> bool: + """ + Check if the given value is a valid FileData object dictionary in newer versions of Gradio + where the file objects include a specific "meta" key, e.g. + { + "path": "path/to/file", + "meta": {"_type: "gradio.FileData"} + } + """ + return ( + isinstance(d, dict) + and "path" in d + and isinstance(d["path"], str) + and "meta" in d + and d["meta"].get("_type", "") == "gradio.FileData" + ) + + +def is_file_obj_with_url(d) -> bool: + """ + Check if the given value is a valid FileData object dictionary in newer versions of Gradio + where the file objects include a specific "meta" key, and ALSO include a "url" key, e.g. + { + "path": "path/to/file", + "url": "/file=path/to/file", + "meta": {"_type: "gradio.FileData"} + } + """ + return is_file_obj_with_meta(d) and "url" in d and isinstance(d["url"], str) + + +SKIP_COMPONENTS = { + "state", + "row", + "column", + "tabs", + "tab", + "tabitem", + "box", + "form", + "accordion", + "group", + "interpretation", + "dataset", + "sidebar", +} + + +def handle_file(filepath_or_url: str | Path): + s = str(filepath_or_url) + data = {"path": s, "meta": {"_type": "gradio.FileData"}} + if is_http_url_like(s): + return {**data, "orig_name": s.split("/")[-1], "url": s} + elif Path(s).exists(): + return {**data, "orig_name": Path(s).name} + else: + raise ValueError( + f"File {s} does not exist on local filesystem and is not a valid URL." + ) + + +def file(filepath_or_url: str | Path): + warnings.warn( + "file() is deprecated and will be removed in a future version. Use handle_file() instead." + ) + return handle_file(filepath_or_url) + + +def construct_args( + parameters_info: list[ParameterInfo] | None, args: tuple, kwargs: dict +) -> list: + class _Keywords(Enum): + NO_VALUE = "NO_VALUE" # Used as a sentinel to determine if nothing is provided as a parameter for an argument + + _args = list(args) + if parameters_info is None: + if kwargs: + raise ValueError( + "This endpoint does not support key-word arguments Please click on 'view API' in the footer of the Gradio app to see usage." + ) + return _args + num_args = len(args) + _args = _args + [_Keywords.NO_VALUE] * (len(parameters_info) - num_args) + + kwarg_arg_mapping = {} + kwarg_names = [] + for index, param_info in enumerate(parameters_info): + if "parameter_name" in param_info: + kwarg_arg_mapping[param_info["parameter_name"]] = index + kwarg_names.append(param_info["parameter_name"]) + else: + kwarg_names.append(f"argument {index}") + if ( + param_info.get("parameter_has_default", False) + and _args[index] == _Keywords.NO_VALUE + ): + _args[index] = param_info.get("parameter_default") + + for key, value in kwargs.items(): + if key in kwarg_arg_mapping: + if kwarg_arg_mapping[key] < num_args: + raise TypeError( + f"Parameter `{key}` is already set as a positional argument. Please click on 'view API' in the footer of the Gradio app to see usage." + ) + else: + _args[kwarg_arg_mapping[key]] = value + else: + raise TypeError( + f"Parameter `{key}` is not a valid key-word argument. Please click on 'view API' in the footer of the Gradio app to see usage." + ) + + if _Keywords.NO_VALUE in _args: + raise TypeError( + f"No value provided for required argument: {kwarg_names[_args.index(_Keywords.NO_VALUE)]}" + ) + + return _args + + +def extract_validation_message(req: httpx.Response) -> str | None: + """ + If the request is a 422 error and the detail contains a validation error message, return the message. Otherwise, return None. + """ + if req.status_code == 422: + detail = req.json().get("detail", []) + validation_messages = [] + for index, error_info in enumerate(detail): + if ( + error_info.get("__type__", "") == "validate" + and error_info.get("is_valid") is False + ): + param_name = error_info.get("parameter_name", f"parameter_{index}") + validation_messages.append( + f"- {param_name}: {error_info.get('message', '')}" + ) + validation_messages.insert( + 0, f"{len(validation_messages)} parameter(s) failed validation:" + ) + if validation_messages: + return "\n".join(validation_messages) diff --git a/.venv/lib/python3.13/site-packages/groovy-0.1.2.dist-info/INSTALLER b/.venv/lib/python3.13/site-packages/groovy-0.1.2.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/groovy-0.1.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.13/site-packages/groovy-0.1.2.dist-info/METADATA b/.venv/lib/python3.13/site-packages/groovy-0.1.2.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..3031e8244dfebcf2deb3b92a8d5dd9bd8741914a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/groovy-0.1.2.dist-info/METADATA @@ -0,0 +1,152 @@ +Metadata-Version: 2.4 +Name: groovy +Version: 0.1.2 +Summary: A small Python library created to help developers protect their applications from Server Side Request Forgery (SSRF) attacks. +Project-URL: homepage, https://github.com/gradio-app/groovy +Project-URL: repository, https://github.com/gradio-app/groovy +Author-email: Abubakar Abid +License-File: LICENSE +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python :: 3 +Requires-Python: >3.9 +Provides-Extra: dev +Requires-Dist: pytest; extra == 'dev' +Requires-Dist: ruff==0.9.3; extra == 'dev' +Description-Content-Type: text/markdown + +

+ PyPI + Python version + Format + Test +

+ + +

+ +

+ +Groovy is a Python-to-JavaScript transpiler, meaning that it converts Python functions to their JavaScript equivalents. It is used in the [Gradio](https://gradio.app) library, so that developers can write functions in Python and have them run as fast as client-side JavaScript ⚡. Instead of aiming for full coverage of Python features, groovy prioritizes **clear error reporting** for unsupported Python code, making it easier for developers to modify their functions accordingly. + +### 🚀 Features +- Converts simple Python functions into JavaScript equivalents. +- Supports a subset of the Python standard library along with some Gradio-specific classes. +- Provides **complete error reporting** when a function can't be transpiled (either due to no equivalent in JavaScript or ambiguity). + +### 📦 Installation +Install groovy via pip: +```bash +pip install groovy +``` + +### 🔧 Usage +```python +from groovy import transpile + +def sum_range(n: int): + total = 0 + for i in range(n): + total = total + i + return total + +js_code = transpile(sum) +print(js_code) +``` +produces: + +``` +function sum_range(n) { + let total = 0; + for (let i of Array.from({length: n}, (_, i) => i)) { + total = (total + i); + } + return total; +``` + +Note that the JavaScript function is not necessarily minimized or optimized (yet) but it should return exactly the same value when called with the same arguments. While the internal implementation of the transpiled JavaScript function may differ slightly from the Python version (e.g. Python tuples may get converted to JS arrays), groovy tries to guarantee that the return values will be identical for the same inputs. + +If groovy encounters unsupported syntax, it will **complain clearly** (throw a `TranspilationError` with all of the issues along with line numbers and the code that caused the issue, making it easy for developers to fix their code. + + +```python +def example_function(x, y): + z = x + y + if z > 10: + print(z) + else: + print(0) + +transpile(example_function) +``` + +raises: + +``` +TranspilerError: 2 issues found: + +* Line 4: Unsupported function "print()" +>> print(z) +* Line 6: Unsupported function "print()" +>> print(0) +``` + +### 🤔 Ambiguity +groovy takes a conservative approach when encountering ambiguous types. Instead of making assumptions about types, it will raise a `TranspilationError`. For example, a simple sum function without type hints will fail: + +```python +def sum(a, b): + return a + b + +transpile(sum) # Raises TranspilationError: Cannot determine types for parameters 'a' and 'b' +``` + +This is because `+` could mean different things in JavaScript depending on the types (string concatenation vs numeric addition vs. custom behavior for a custom class). Adding type hints (which is **strongly recommended** for all usage) resolves the ambiguity: + +```python +def sum(a: int, b: int): + return a + b + +transpile(sum) # Works! Produces: function sum(a, b) { return (a + b); } +``` + +### 🔥 Supported Syntax + +groovy supports the following Python syntax and built-in functions. Other functions will not be transpiled. + +**General** + +| Python Syntax | JavaScript Equivalent | +|--------------|----------------------| +| `def function(x: int)` | `function function(x)` | +| `x + y`, `x - y`, `x * y`, `x / y` | `(x + y)`, `(x - y)`, `(x * y)`, `(x / y)` | +| `x > y`, `x < y`, `x >= y`, `x <= y` | `(x > y)`, `(x < y)`, `(x >= y)`, `(x <= y)` | +| `x == y`, `x != y` | `(x === y)`, `(x !== y)` | +| `x in list`, `x not in list` | `list.includes(x)`, `!list.includes(x)` | +| `x = value` | `let x = value` | +| `if condition: ... elif: ... else: ...` | `if (condition) { ... } else if { ... } else { ... }` | +| `for x in range(n)` | `for (let x of Array.from({length: n}, (_, i) => i))` | +| `for x in list` | `for (let x of list)` | +| `while condition` | `while (condition)` | +| `[x for x in list if condition]` | `list.filter(x => condition).map(x => x)` | +| `len(list)` | `list.length` | +| `len(dict)` | `Object.keys(dict).length` | +| `[1, 2, 3]` | `[1, 2, 3]` | +| `(1, 2, 3)` | `[1, 2, 3]` | +| `{"key": "value"}` | `{"key": "value"}` | +| `x and y`, `x or y` | `(x && y)`, `(x || y)` | +| `None` | `null` | + + +**Gradio-specific syntax** + +| Python Syntax | JavaScript Equivalent | +|--------------|----------------------| +| `gr.Component(param=value)` | `{"param": "value", "__type__": "update"}` | + + +### 📜 License +groovy is open-source under the [MIT License](https://github.com/abidlabs/groovy/blob/main/LICENSE). + +--- +Contributions to increase coverage of the Python library that groovy can transpile are welcome! We welcome AI-generated PRs if the rationale is clear to follow, PRs are not too large in scope, and tests are included. diff --git a/.venv/lib/python3.13/site-packages/groovy-0.1.2.dist-info/RECORD b/.venv/lib/python3.13/site-packages/groovy-0.1.2.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..c6e737c46021834702311ae27dc534953133a941 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/groovy-0.1.2.dist-info/RECORD @@ -0,0 +1,10 @@ +groovy-0.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +groovy-0.1.2.dist-info/METADATA,sha256=TpSDwMDzyWn5ThLESEUhJgOHdCEyUgwj18jRniCplTQ,6115 +groovy-0.1.2.dist-info/RECORD,, +groovy-0.1.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87 +groovy-0.1.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357 +groovy/__init__.py,sha256=rnZLuZ4HpX8TzM58MUNWA6Gm8U3nmTRYzlhCwcfQRNM,223 +groovy/__pycache__/__init__.cpython-313.pyc,, +groovy/__pycache__/transpiler.cpython-313.pyc,, +groovy/transpiler.py,sha256=HZGbbtVk7z9-rmi4ecmXU5Z8_nfy0S0Rx3elB5N-tss,25664 +groovy/version.txt,sha256=VKRsZExOtvEo-Z9_CENJGGF7MbaAUi7UrLV8lCQ3KCc,5 diff --git a/.venv/lib/python3.13/site-packages/groovy-0.1.2.dist-info/WHEEL b/.venv/lib/python3.13/site-packages/groovy-0.1.2.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..12228d414b6cfed7c39d3781c85c63256a1d7fb5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/groovy-0.1.2.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.27.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/lib/python3.13/site-packages/groovy-0.1.2.dist-info/licenses/LICENSE b/.venv/lib/python3.13/site-packages/groovy-0.1.2.dist-info/licenses/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/groovy-0.1.2.dist-info/licenses/LICENSE @@ -0,0 +1,201 @@ + 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/python3.13/site-packages/groovy/__init__.py b/.venv/lib/python3.13/site-packages/groovy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c81119b02aa60b3ab8d1097d00ee90f31056b9e3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/groovy/__init__.py @@ -0,0 +1,7 @@ +from pathlib import Path + +from groovy.transpiler import TranspilerError, transpile + +__version__ = Path(__file__).parent.joinpath("version.txt").read_text().strip() + +__all__ = ["__version__", "transpile", "TranspilerError"] diff --git a/.venv/lib/python3.13/site-packages/groovy/transpiler.py b/.venv/lib/python3.13/site-packages/groovy/transpiler.py new file mode 100644 index 0000000000000000000000000000000000000000..c5fcf2966f4d406cc5c6bb8f02d518d7d86dfeb3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/groovy/transpiler.py @@ -0,0 +1,689 @@ +from __future__ import annotations + +import ast +import builtins +import inspect +import json +import textwrap +from collections.abc import Callable + + +class TranspilerError(Exception): + """Exception raised when transpilation fails or encounters ambiguous syntax.""" + + def __init__( + self, + issues: list[tuple[int, str, str]] | None = None, + message: str | None = None, + ): + self.issues = issues or [] + if message: + super().__init__(message) + else: + issue_count = len(self.issues) + issues_text = ( + f"{issue_count} issue{'s' if issue_count != 1 else ''} found:\n\n" + ) + for line_no, message, code in self.issues: + issues_text += f"* Line {line_no}: {message}\n>> {code}\n" + super().__init__(issues_text) + + +class PythonToJSVisitor(ast.NodeVisitor): + def __init__(self): + self.js_lines = [] # Accumulate lines of JavaScript code. + self.indent_level = 0 # Track current indent level for readability. + self.declared_vars = set() # Track declared variables + self.issues: list[tuple[int, str, str]] = [] # Track transpilation issues + self.source_lines: list[str] = [] # Store source code lines + self.var_types: dict[str, type | None] = {} # Track variable types + + # Map built-in functions to their transformation functions. + self.builtin_transforms = { + "range": self.transform_range, + "len": self.transform_len, + } + + def add_issue(self, node: ast.AST, message: str) -> None: + """Add a transpilation issue with source code context.""" + if hasattr(node, "lineno"): + line_no = node.lineno + line_text = self.source_lines[line_no - 1].strip() + self.issues.append((line_no, message, line_text)) + + def visit(self, node): + try: + return super().visit(node) + except TranspilerError as e: + if e.issues: + self.issues.extend(e.issues) + return "" # Return empty string for failed conversions + + def generic_visit(self, node): + self.add_issue(node, f"Unsupported syntax: {type(node).__name__}") + return "" + + def indent(self) -> str: + return " " * self.indent_level + + # === Function Definition === + def visit_FunctionDef(self, node: ast.FunctionDef): # noqa: N802 + # Extract parameter names and types from type hints + params = [] + for arg in node.args.args: + params.append(arg.arg) + if arg.annotation and isinstance(arg.annotation, ast.Name): + type_name = arg.annotation.id + type_obj = globals().get(type_name, getattr(builtins, type_name, None)) + if type_obj is not None: + self.var_types[arg.arg] = type_obj + + header = f"function {node.name}({', '.join(params)}) " + "{" + self.js_lines.append(header) + self.indent_level += 1 + + for stmt in node.body: + self.visit(stmt) + self.indent_level -= 1 + self.js_lines.append("}") + + # === Attribute === + def visit_Attribute(self, node: ast.Attribute): + # Simply return a dotted string: e.g., gr.Textbox + value = self.visit(node.value) + return f"{value}.{node.attr}" + + # === Return Statement === + def visit_Return(self, node: ast.Return): # noqa: N802 + ret_val = "" if node.value is None else self.visit(node.value) + self.js_lines.append(f"{self.indent()}return {ret_val};") + + # === Expression Statements === + def visit_Expr(self, node: ast.Expr): # noqa: N802 + expr = self.visit(node.value) + self.js_lines.append(f"{self.indent()}{expr};") + + # === Assignment === + def visit_Assign(self, node: ast.Assign): # noqa: N802 + if len(node.targets) != 1: + raise TranspilerError("Multiple assignment targets are not supported yet.") + target_node = node.targets[0] + target = self.visit(target_node) + value = self.visit(node.value) + + if ( + isinstance(target_node, ast.Name) + and target_node.id not in self.declared_vars + ): + self.declared_vars.add(target_node.id) + expr_type = self.get_expr_type(node.value) + if expr_type is not None: + self.var_types[target_node.id] = expr_type + self.js_lines.append(f"{self.indent()}let {target} = {value};") + else: + self.js_lines.append(f"{self.indent()}{target} = {value};") + + # === Binary Operations === + def check_type_safety(self, node: ast.AST, *exprs: ast.AST, context: str) -> None: + """ + Check if an operation is type-safe. + Raises TranspilerError if types are ambiguous or incompatible. + """ + types = [self.get_expr_type(expr) for expr in exprs] + + # Check for unknown types + if any(t is None for t in types): + self.add_issue( + node, + f"Ambiguous operation: Cannot determine types for {context}. " + "Operation behavior may differ in JavaScript based on types.", + ) + raise TranspilerError() + + # Check for type consistency if multiple expressions + if len(types) > 1 and not all(t == types[0] for t in types): + type_names = [t.__name__ for t in types] + self.add_issue( + node, + f"Ambiguous operation: Mixed types ({', '.join(type_names)}) in {context}. " + "Behavior may differ in JavaScript.", + ) + raise TranspilerError() + + def visit_BinOp(self, node: ast.BinOp): # noqa: N802 + left = self.visit(node.left) + right = self.visit(node.right) + op = self.visit(node.op) + + self.check_type_safety( + node, node.left, node.right, context=f"'{left} {op} {right}'" + ) + return f"({left} {op} {right})" + + def visit_Add(self, node: ast.Add): # noqa: N802, ARG002 + return "+" + + def visit_Sub(self, node: ast.Sub): # noqa: N802, ARG002 + return "-" + + def visit_Mult(self, node: ast.Mult): # noqa: N802, ARG002 + return "*" + + def visit_Div(self, node: ast.Div): # noqa: N802, ARG002 + return "/" + + # === Comparison Operations === + def visit_Compare(self, node: ast.Compare): # noqa: N802 + if len(node.ops) != 1 or len(node.comparators) != 1: + raise TranspilerError("Only single comparisons are supported") + op = node.ops[0] + left = self.visit(node.left) + right = self.visit(node.comparators[0]) + # Handle membership tests separately since types may differ. + if isinstance(op, ast.In): + # Translate Python "a in b" to JS "b.includes(a)" + return f"{right}.includes({left})" + elif isinstance(op, ast.NotIn): + # Translate Python "a not in b" to JS "!b.includes(a)" + return f"!{right}.includes({left})" + else: + # For other comparisons, check type safety. + self.check_type_safety( + node, + node.left, + node.comparators[0], + context=f"comparison {left} {self.visit(op)} {right}", + ) + op_str = self.visit(op) + return f"({left} {op_str} {right})" + + def visit_Gt(self, node: ast.Gt): # noqa: N802, ARG002 + return ">" + + def visit_Lt(self, node: ast.Lt): # noqa: N802, ARG002 + return "<" + + def visit_GtE(self, node: ast.GtE): # noqa: N802, ARG002 + return ">=" + + def visit_LtE(self, node: ast.LtE): # noqa: N802, ARG002 + return "<=" + + def visit_Eq(self, node: ast.Eq): # noqa: N802, ARG002 + return "===" + + def visit_NotEq(self, node: ast.NotEq): # noqa: N802, ARG002 + return "!==" + + # (Optional: in case In or NotIn are visited directly.) + def visit_In(self, node: ast.In): + return "in" + + def visit_NotIn(self, node: ast.NotIn): + return "not in" + + # === If Statement === + def visit_If(self, node: ast.If): # noqa: N802 + test = self.visit(node.test) + self.js_lines.append(f"{self.indent()}if ({test}) " + "{") + self.indent_level += 1 + for stmt in node.body: + self.visit(stmt) + self.indent_level -= 1 + self.js_lines.append(f"{self.indent()}" + "}") + + # Handle elif and else clauses + current = node + while ( + current.orelse + and len(current.orelse) == 1 + and isinstance(current.orelse[0], ast.If) + ): + current = current.orelse[0] + test = self.visit(current.test) + self.js_lines.append(f"{self.indent()}else if ({test}) " + "{") + self.indent_level += 1 + for stmt in current.body: + self.visit(stmt) + self.indent_level -= 1 + self.js_lines.append(f"{self.indent()}" + "}") + + # Handle final else clause if it exists + if current.orelse: + self.js_lines.append(f"{self.indent()}else " + "{") + self.indent_level += 1 + for stmt in current.orelse: + self.visit(stmt) + self.indent_level -= 1 + self.js_lines.append(f"{self.indent()}" + "}") + + # === Built-in Function Transformations === + def transform_range(self, node: ast.Call) -> str: + """Transform Python's range() to an equivalent JavaScript array expression.""" + args = [self.visit(arg) for arg in node.args] + for arg in node.args: + self.check_type_safety(arg, arg, context="range() argument") + if len(args) == 1: # range(stop) + return f"Array.from({{length: {args[0]}}}, (_, i) => i)" + elif len(args) == 2: # range(start, stop) + return f"Array.from({{length: {args[1]} - {args[0]}}}, (_, i) => i + {args[0]})" + elif len(args) == 3: # range(start, stop, step) + raise TranspilerError("range() with step argument is not supported yet") + else: + raise TranspilerError("Invalid number of arguments for range()") + + def transform_len(self, node: ast.Call) -> str: + """Transform Python's len() to the equivalent JavaScript property access.""" + if len(node.args) != 1: + raise TranspilerError("len() takes exactly one argument") + arg_code = self.visit(node.args[0]) + t = self.get_expr_type(node.args[0]) + # If the type is a dictionary, return Object.keys(...).length; + if t is dict: + return f"Object.keys({arg_code}).length" + else: + # For lists, tuples, and strings, use .length. + return f"{arg_code}.length" + + # === Function Calls === + def _handle_gradio_component_updates(self, node: ast.Call): + """Handle Gradio component calls and return JSON representation.""" + kwargs = {} + for kw in node.keywords: + if isinstance(kw.value, ast.Constant) and kw.value.value is None: + # None values should remain None in the kwargs dictionary + # so that they are converted to null, not "null" in json.dumps(). + kwargs[kw.arg] = None + continue + value = self.visit(kw.value) + try: + kwargs[kw.arg] = ast.literal_eval(value) + except Exception: + kwargs[kw.arg] = value + kwargs["__type__"] = "update" + return json.dumps(kwargs) + + def visit_Call(self, node: ast.Call): # noqa: N802 + try: + import gradio + + has_gradio = True + except ImportError: + has_gradio = False + + # Handle built-in functions via our transformation mapping. + if isinstance(node.func, ast.Name): + if node.func.id in self.builtin_transforms: + return self.builtin_transforms[node.func.id](node) + + # Try to resolve if this is a Gradio component. + if has_gradio: + try: + # Handle direct update() call + if node.func.id == "update": + return self._handle_gradio_component_updates(node) + + component_class = getattr(gradio, node.func.id, None) + if component_class and issubclass( + component_class, gradio.blocks.Block + ): + return self._handle_gradio_component_updates(node) + except Exception: + pass + + for arg in node.args: + self.check_type_safety( + arg, arg, context=f"argument in {node.func.id}() call" + ) + self.add_issue(node, f'Unsupported function "{node.func.id}()"') + return "" + + # Handle attribute access like gr.Textbox. (Note the updated check.) + if isinstance(node.func, ast.Attribute) and has_gradio: + try: + # Now allow for module aliases such as "gr" as well as "gradio" + if isinstance(node.func.value, ast.Name) and node.func.value.id in { + "gradio", + "gr", + }: + # Handle gr.update() call + if node.func.attr == "update": + return self._handle_gradio_component_updates(node) + + component_class = getattr(gradio, node.func.attr, None) + if component_class and issubclass( + component_class, gradio.blocks.Block + ): + return self._handle_gradio_component_updates(node) + except Exception: + pass + + # For other method calls (like obj.method()) + func = self.visit(node.func) + args = [self.visit(arg) for arg in node.args] + + if isinstance(node.func, ast.Attribute): + self.check_type_safety( + node.func, node.func.value, context=f"object in method call {func}" + ) + for arg in node.args: + self.check_type_safety( + arg, arg, context=f"argument in method call {func}" + ) + + return f"{func}({', '.join(args)})" + + # === Variable Name === + def visit_Name(self, node: ast.Name): # noqa: N802 + return node.id + + # === Constants === + def visit_Constant(self, node: ast.Constant): # noqa: N802 + if node.value is None: + return "null" + return repr(node.value) + + # === For Loop === + def visit_For(self, node: ast.For): # noqa: N802 + target = self.visit(node.target) + iter_expr = self.visit(node.iter) + + # If iterating over a range, record that the loop variable is an int. + if ( + isinstance(node.iter, ast.Call) + and isinstance(node.iter.func, ast.Name) + and node.iter.func.id == "range" + ): + if isinstance(node.target, ast.Name): + self.var_types[node.target.id] = int + + self.js_lines.append(f"{self.indent()}for (let {target} of {iter_expr}) " + "{") + self.indent_level += 1 + for stmt in node.body: + self.visit(stmt) + self.indent_level -= 1 + self.js_lines.append(f"{self.indent()}" + "}") + + # === While Loop === + def visit_While(self, node: ast.While): # noqa: N802 + test = self.visit(node.test) + self.js_lines.append(f"{self.indent()}while ({test}) " + "{") + self.indent_level += 1 + for stmt in node.body: + self.visit(stmt) + self.indent_level -= 1 + self.js_lines.append(f"{self.indent()}" + "}") + + # === List === + def visit_List(self, node: ast.List): # noqa: N802 + elements = [self.visit(elt) for elt in node.elts] + return f"[{', '.join(elements)}]" + + # === Tuple === + def visit_Tuple(self, node: ast.Tuple): # noqa: N802 + elements = [self.visit(elt) for elt in node.elts] + return f"[{', '.join(elements)}]" + + # === List Comprehension === + def visit_ListComp(self, node: ast.ListComp): + """ + Transform a Python list comprehension into a combination of filter and map calls. + For example: + [x * 2 for x in arr if x > 10] + becomes: + arr.filter(x => x > 10).map(x => x * 2) + """ + if len(node.generators) != 1: + self.add_issue( + node, "Only single generator list comprehensions are supported" + ) + raise TranspilerError() + gen = node.generators[0] + iter_js = self.visit(gen.iter) + target_js = self.visit(gen.target) + elt_js = self.visit(node.elt) + if gen.ifs: + # Join multiple ifs with logical AND. + conditions = " && ".join(self.visit(if_node) for if_node in gen.ifs) + result = f"{iter_js}.filter({target_js} => {conditions})" + # Only add a map step if the element expression is different from the loop variable. + if not (isinstance(node.elt, ast.Name) and node.elt.id == gen.target.id): + result += f".map({target_js} => {elt_js})" + else: + result = f"{iter_js}.map({target_js} => {elt_js})" + return result + + # === Subscript === + def visit_Subscript(self, node: ast.Subscript): # noqa: N802 + value = self.visit(node.value) + slice_value = self.visit(node.slice) + return f"{value}[{slice_value}]" + + # === Augmented Assignment === + def visit_AugAssign(self, node: ast.AugAssign): # noqa: N802 + target = self.visit(node.target) + op = self.visit(node.op).strip() + value = self.visit(node.value) + self.js_lines.append(f"{self.indent()}{target} {op}= {value};") + + # === Boolean Operations === + def visit_BoolOp(self, node: ast.BoolOp): # noqa: N802 + op = self.visit(node.op) + values = [self.visit(value) for value in node.values] + # Join the values with the operator. + return f"({f' {op} '.join(values)})" + + def visit_And(self, node: ast.And): # noqa: N802, ARG002 + return "&&" + + def visit_Or(self, node: ast.Or): # noqa: N802, ARG002 + return "||" + + # === Dictionary === + def visit_Dict(self, node: ast.Dict): # noqa: N802 + pairs = [] + for key, value in zip(node.keys, node.values): + if key is None: # Handle dict unpacking + continue + key_js = self.visit(key) + value_js = self.visit(value) + pairs.append(f"{key_js}: {value_js}") + return f"{{{', '.join(pairs)}}}" + + def get_expr_type(self, node: ast.AST) -> type | None: + """Determine the type of an expression if possible.""" + if isinstance(node, ast.Constant): + return type(node.value) + elif isinstance(node, ast.Name): + # First check if we have a stored type from type hints or assignments. + if node.id in self.var_types: + return self.var_types[node.id] + return None + elif isinstance(node, ast.BinOp): + left_type = self.get_expr_type(node.left) + right_type = self.get_expr_type(node.right) + if left_type == right_type and left_type is not None: + return left_type + return None + elif isinstance(node, ast.Call): + # We can't determine the return type of function calls yet. + return None + elif isinstance(node, ast.List): + return list + elif isinstance(node, ast.Dict): + return dict + elif isinstance(node, ast.Tuple): + return tuple + return None + + +def transpile(fn: Callable, validate: bool = False) -> str: + """ + Transpiles a Python function to JavaScript and returns the JavaScript code as a string. + + Parameters: + fn: The Python function to transpile. + validate: If True, the function will be validated to ensure it takes no arguments & only returns gradio component property updates. This is used when Groovy is used inside Gradio and `gradio` must be installed to use this. + + Returns: + The JavaScript code as a string. + + Raises: + TranspilerError: If the function cannot be transpiled or if the transpiled function is not valid. + """ + if validate: + sig = inspect.signature(fn) + if sig.parameters: + param_names = list(sig.parameters.keys()) + raise TranspilerError( + message=f"Function must take no arguments for client-side use, but got: {param_names}" + ) + + try: + source = inspect.getsource(fn) + source = textwrap.dedent(source) + except Exception as e: + raise TranspilerError( + message="Could not retrieve source code from the function." + ) from e + + try: + tree = ast.parse(source) + except SyntaxError as e: + raise TranspilerError(message="Could not parse function source.") from e + + if validate: + try: + import gradio # noqa: F401 + except ImportError: + raise TranspilerError(message="Gradio must be installed for validation.") + + func_node = None + for node in ast.walk(tree): + if isinstance(node, ast.FunctionDef) and node.name == fn.__name__: + func_node = node + break + + if func_node: + return_nodes = [] + for node in ast.walk(func_node): + if isinstance(node, ast.Return) and node.value is not None: + return_nodes.append(node) + + if not return_nodes: + raise TranspilerError( + message="Function must return Gradio component updates, but no return statement found." + ) + + for return_node in return_nodes: + if not _is_valid_gradio_return(return_node.value): + line_no = return_node.lineno + line_text = source.splitlines()[line_no - 1].strip() + raise TranspilerError( + message=f"Function must only return Gradio component updates. Invalid return at line {line_no}: {line_text}" + ) + + func_node = None + for node in ast.walk(tree): + if isinstance(node, (ast.FunctionDef, ast.Lambda)): + func_node = node + break + + if func_node is None: + raise TranspilerError( + message="No function or lambda definition found in the provided source." + ) + + visitor = PythonToJSVisitor() + visitor.source_lines = source.splitlines() + + if isinstance(func_node, ast.Lambda): + args = [arg.arg for arg in func_node.args.args] + visitor.js_lines.append(f"function ({', '.join(args)}) " + "{") + visitor.indent_level += 1 + visitor.js_lines.append( + f"{visitor.indent()}return {visitor.visit(func_node.body)};" + ) + visitor.indent_level -= 1 + visitor.js_lines.append("}") + else: + visitor.visit(func_node) + + if visitor.issues: + raise TranspilerError(issues=visitor.issues) + + return "\n".join(visitor.js_lines) + + +def _is_valid_gradio_return(node: ast.AST) -> bool: + """ + Check if a return value is a valid Gradio component or collection of components. + + Args: + node: The AST node representing the return value + + Returns: + bool: True if the return value is valid, False otherwise + """ + # Check for direct Gradio component call + if isinstance(node, ast.Call): + if isinstance(node.func, ast.Attribute) and isinstance( + node.func.value, ast.Name + ): + if node.func.value.id in {"gr", "gradio"}: + try: + import gradio + + if node.func.attr == "update": + return True + + component_class = getattr(gradio, node.func.attr, None) + if component_class and issubclass( + component_class, gradio.blocks.Block + ): + if node.args: + return False + for kw in node.keywords: + if kw.arg == "value": + return False + return True + except (ImportError, AttributeError): + pass + return False + elif isinstance(node.func, ast.Name): + try: + import gradio + + if node.func.id == "update": + return True + + component_class = getattr(gradio, node.func.id, None) + if component_class and issubclass(component_class, gradio.blocks.Block): + if node.args: + return False + for kw in node.keywords: + if kw.arg == "value": + return False + return True + except (ImportError, AttributeError): + pass + return False + + elif isinstance(node, (ast.Tuple, ast.List)): + if not node.elts: + return False + return all(_is_valid_gradio_return(elt) for elt in node.elts) + + return False + + +# === Example Usage === + +if __name__ == "__main__": + import gradio as gr + + def filter_rows_by_term(): + return gr.update(selected=2, visible=True, info=None) + + js_code = transpile(filter_rows_by_term, validate=True) + print(js_code) diff --git a/.venv/lib/python3.13/site-packages/groovy/version.txt b/.venv/lib/python3.13/site-packages/groovy/version.txt new file mode 100644 index 0000000000000000000000000000000000000000..8294c184368c0ec9f84fbcc80c6b36326940c770 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/groovy/version.txt @@ -0,0 +1 @@ +0.1.2 \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/INSTALLER b/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/METADATA b/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..8a2f639061cc4a203f7109d8335d28076442c61d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/METADATA @@ -0,0 +1,202 @@ +Metadata-Version: 2.4 +Name: h11 +Version: 0.16.0 +Summary: A pure-Python, bring-your-own-I/O implementation of HTTP/1.1 +Home-page: https://github.com/python-hyper/h11 +Author: Nathaniel J. Smith +Author-email: njs@pobox.com +License: MIT +Classifier: Development Status :: 3 - Alpha +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.8 +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: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: System :: Networking +Requires-Python: >=3.8 +License-File: LICENSE.txt +Dynamic: author +Dynamic: author-email +Dynamic: classifier +Dynamic: description +Dynamic: home-page +Dynamic: license +Dynamic: license-file +Dynamic: requires-python +Dynamic: summary + +h11 +=== + +.. image:: https://travis-ci.org/python-hyper/h11.svg?branch=master + :target: https://travis-ci.org/python-hyper/h11 + :alt: Automated test status + +.. image:: https://codecov.io/gh/python-hyper/h11/branch/master/graph/badge.svg + :target: https://codecov.io/gh/python-hyper/h11 + :alt: Test coverage + +.. image:: https://readthedocs.org/projects/h11/badge/?version=latest + :target: http://h11.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + +This is a little HTTP/1.1 library written from scratch in Python, +heavily inspired by `hyper-h2 `_. + +It's a "bring-your-own-I/O" library; h11 contains no IO code +whatsoever. This means you can hook h11 up to your favorite network +API, and that could be anything you want: synchronous, threaded, +asynchronous, or your own implementation of `RFC 6214 +`_ -- h11 won't judge you. +(Compare this to the current state of the art, where every time a `new +network API `_ comes along then someone +gets to start over reimplementing the entire HTTP protocol from +scratch.) Cory Benfield made an `excellent blog post describing the +benefits of this approach +`_, or if you like video +then here's his `PyCon 2016 talk on the same theme +`_. + +This also means that h11 is not immediately useful out of the box: +it's a toolkit for building programs that speak HTTP, not something +that could directly replace ``requests`` or ``twisted.web`` or +whatever. But h11 makes it much easier to implement something like +``requests`` or ``twisted.web``. + +At a high level, working with h11 goes like this: + +1) First, create an ``h11.Connection`` object to track the state of a + single HTTP/1.1 connection. + +2) When you read data off the network, pass it to + ``conn.receive_data(...)``; you'll get back a list of objects + representing high-level HTTP "events". + +3) When you want to send a high-level HTTP event, create the + corresponding "event" object and pass it to ``conn.send(...)``; + this will give you back some bytes that you can then push out + through the network. + +For example, a client might instantiate and then send a +``h11.Request`` object, then zero or more ``h11.Data`` objects for the +request body (e.g., if this is a POST), and then a +``h11.EndOfMessage`` to indicate the end of the message. Then the +server would then send back a ``h11.Response``, some ``h11.Data``, and +its own ``h11.EndOfMessage``. If either side violates the protocol, +you'll get a ``h11.ProtocolError`` exception. + +h11 is suitable for implementing both servers and clients, and has a +pleasantly symmetric API: the events you send as a client are exactly +the ones that you receive as a server and vice-versa. + +`Here's an example of a tiny HTTP client +`_ + +It also has `a fine manual `_. + +FAQ +--- + +*Whyyyyy?* + +I wanted to play with HTTP in `Curio +`__ and `Trio +`__, which at the time didn't have any +HTTP libraries. So I thought, no big deal, Python has, like, a dozen +different implementations of HTTP, surely I can find one that's +reusable. I didn't find one, but I did find Cory's call-to-arms +blog-post. So I figured, well, fine, if I have to implement HTTP from +scratch, at least I can make sure no-one *else* has to ever again. + +*Should I use it?* + +Maybe. You should be aware that it's a very young project. But, it's +feature complete and has an exhaustive test-suite and complete docs, +so the next step is for people to try using it and see how it goes +:-). If you do then please let us know -- if nothing else we'll want +to talk to you before making any incompatible changes! + +*What are the features/limitations?* + +Roughly speaking, it's trying to be a robust, complete, and non-hacky +implementation of the first "chapter" of the HTTP/1.1 spec: `RFC 7230: +HTTP/1.1 Message Syntax and Routing +`_. That is, it mostly focuses on +implementing HTTP at the level of taking bytes on and off the wire, +and the headers related to that, and tries to be anal about spec +conformance. It doesn't know about higher-level concerns like URL +routing, conditional GETs, cross-origin cookie policies, or content +negotiation. But it does know how to take care of framing, +cross-version differences in keep-alive handling, and the "obsolete +line folding" rule, so you can focus your energies on the hard / +interesting parts for your application, and it tries to support the +full specification in the sense that any useful HTTP/1.1 conformant +application should be able to use h11. + +It's pure Python, and has no dependencies outside of the standard +library. + +It has a test suite with 100.0% coverage for both statements and +branches. + +Currently it supports Python 3 (testing on 3.8-3.12) and PyPy 3. +The last Python 2-compatible version was h11 0.11.x. +(Originally it had a Cython wrapper for `http-parser +`_ and a beautiful nested state +machine implemented with ``yield from`` to postprocess the output. But +I had to take these out -- the new *parser* needs fewer lines-of-code +than the old *parser wrapper*, is written in pure Python, uses no +exotic language syntax, and has more features. It's sad, really; that +old state machine was really slick. I just need a few sentences here +to mourn that.) + +I don't know how fast it is. I haven't benchmarked or profiled it yet, +so it's probably got a few pointless hot spots, and I've been trying +to err on the side of simplicity and robustness instead of +micro-optimization. But at the architectural level I tried hard to +avoid fundamentally bad decisions, e.g., I believe that all the +parsing algorithms remain linear-time even in the face of pathological +input like slowloris, and there are no byte-by-byte loops. (I also +believe that it maintains bounded memory usage in the face of +arbitrary/pathological input.) + +The whole library is ~800 lines-of-code. You can read and understand +the whole thing in less than an hour. Most of the energy invested in +this so far has been spent on trying to keep things simple by +minimizing special-cases and ad hoc state manipulation; even though it +is now quite small and simple, I'm still annoyed that I haven't +figured out how to make it even smaller and simpler. (Unfortunately, +HTTP does not lend itself to simplicity.) + +The API is ~feature complete and I don't expect the general outlines +to change much, but you can't judge an API's ergonomics until you +actually document and use it, so I'd expect some changes in the +details. + +*How do I try it?* + +.. code-block:: sh + + $ pip install h11 + $ git clone git@github.com:python-hyper/h11 + $ cd h11/examples + $ python basic-client.py + +and go from there. + +*License?* + +MIT + +*Code of conduct?* + +Contributors are requested to follow our `code of conduct +`_ in +all project spaces. diff --git a/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/RECORD b/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..dee4864da26e11320bae425074d7c1b64dac1f95 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/RECORD @@ -0,0 +1,29 @@ +h11-0.16.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +h11-0.16.0.dist-info/METADATA,sha256=KPMmCYrAn8unm48YD5YIfIQf4kViFct7hyqcfVzRnWQ,8348 +h11-0.16.0.dist-info/RECORD,, +h11-0.16.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91 +h11-0.16.0.dist-info/licenses/LICENSE.txt,sha256=N9tbuFkm2yikJ6JYZ_ELEjIAOuob5pzLhRE4rbjm82E,1124 +h11-0.16.0.dist-info/top_level.txt,sha256=F7dC4jl3zeh8TGHEPaWJrMbeuoWbS379Gwdi-Yvdcis,4 +h11/__init__.py,sha256=iO1KzkSO42yZ6ffg-VMgbx_ZVTWGUY00nRYEWn-s3kY,1507 +h11/__pycache__/__init__.cpython-313.pyc,, +h11/__pycache__/_abnf.cpython-313.pyc,, +h11/__pycache__/_connection.cpython-313.pyc,, +h11/__pycache__/_events.cpython-313.pyc,, +h11/__pycache__/_headers.cpython-313.pyc,, +h11/__pycache__/_readers.cpython-313.pyc,, +h11/__pycache__/_receivebuffer.cpython-313.pyc,, +h11/__pycache__/_state.cpython-313.pyc,, +h11/__pycache__/_util.cpython-313.pyc,, +h11/__pycache__/_version.cpython-313.pyc,, +h11/__pycache__/_writers.cpython-313.pyc,, +h11/_abnf.py,sha256=ybixr0xsupnkA6GFAyMubuXF6Tc1lb_hF890NgCsfNc,4815 +h11/_connection.py,sha256=k9YRVf6koZqbttBW36xSWaJpWdZwa-xQVU9AHEo9DuI,26863 +h11/_events.py,sha256=I97aXoal1Wu7dkL548BANBUCkOIbe-x5CioYA9IBY14,11792 +h11/_headers.py,sha256=P7D-lBNxHwdLZPLimmYwrPG-9ZkjElvvJZJdZAgSP-4,10412 +h11/_readers.py,sha256=a4RypORUCC3d0q_kxPuBIM7jTD8iLt5X91TH0FsduN4,8590 +h11/_receivebuffer.py,sha256=xrspsdsNgWFxRfQcTXxR8RrdjRXXTK0Io5cQYWpJ1Ws,5252 +h11/_state.py,sha256=_5LG_BGR8FCcFQeBPH-TMHgm_-B-EUcWCnQof_9XjFE,13231 +h11/_util.py,sha256=LWkkjXyJaFlAy6Lt39w73UStklFT5ovcvo0TkY7RYuk,4888 +h11/_version.py,sha256=GVSsbPSPDcOuF6ptfIiXnVJoaEm3ygXbMnqlr_Giahw,686 +h11/_writers.py,sha256=oFKm6PtjeHfbj4RLX7VB7KDc1gIY53gXG3_HR9ltmTA,5081 +h11/py.typed,sha256=sow9soTwP9T_gEAQSVh7Gb8855h04Nwmhs2We-JRgZM,7 diff --git a/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/WHEEL b/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..1eb3c49d99559863120cfb8433fc8738fba43ba9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (78.1.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/licenses/LICENSE.txt b/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/licenses/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..8f080eae848f759c9173bfc0c79506357ebe5090 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/licenses/LICENSE.txt @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2016 Nathaniel J. Smith and other 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/python3.13/site-packages/h11-0.16.0.dist-info/top_level.txt b/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..0d24def711344ec6f4da2108f7d5c9261eb35f8b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/top_level.txt @@ -0,0 +1 @@ +h11 diff --git a/.venv/lib/python3.13/site-packages/h11/__init__.py b/.venv/lib/python3.13/site-packages/h11/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..989e92c3458681a6f0be72ae4105ea742750d328 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11/__init__.py @@ -0,0 +1,62 @@ +# A highish-level implementation of the HTTP/1.1 wire protocol (RFC 7230), +# containing no networking code at all, loosely modelled on hyper-h2's generic +# implementation of HTTP/2 (and in particular the h2.connection.H2Connection +# class). There's still a bunch of subtle details you need to get right if you +# want to make this actually useful, because it doesn't implement all the +# semantics to check that what you're asking to write to the wire is sensible, +# but at least it gets you out of dealing with the wire itself. + +from h11._connection import Connection, NEED_DATA, PAUSED +from h11._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from h11._state import ( + CLIENT, + CLOSED, + DONE, + ERROR, + IDLE, + MIGHT_SWITCH_PROTOCOL, + MUST_CLOSE, + SEND_BODY, + SEND_RESPONSE, + SERVER, + SWITCHED_PROTOCOL, +) +from h11._util import LocalProtocolError, ProtocolError, RemoteProtocolError +from h11._version import __version__ + +PRODUCT_ID = "python-h11/" + __version__ + + +__all__ = ( + "Connection", + "NEED_DATA", + "PAUSED", + "ConnectionClosed", + "Data", + "EndOfMessage", + "Event", + "InformationalResponse", + "Request", + "Response", + "CLIENT", + "CLOSED", + "DONE", + "ERROR", + "IDLE", + "MUST_CLOSE", + "SEND_BODY", + "SEND_RESPONSE", + "SERVER", + "SWITCHED_PROTOCOL", + "ProtocolError", + "LocalProtocolError", + "RemoteProtocolError", +) diff --git a/.venv/lib/python3.13/site-packages/h11/_abnf.py b/.venv/lib/python3.13/site-packages/h11/_abnf.py new file mode 100644 index 0000000000000000000000000000000000000000..933587fba22290d7eb7df4c88e12f1e61702b8ce --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11/_abnf.py @@ -0,0 +1,132 @@ +# We use native strings for all the re patterns, to take advantage of string +# formatting, and then convert to bytestrings when compiling the final re +# objects. + +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#whitespace +# OWS = *( SP / HTAB ) +# ; optional whitespace +OWS = r"[ \t]*" + +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#rule.token.separators +# token = 1*tchar +# +# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" +# / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" +# / DIGIT / ALPHA +# ; any VCHAR, except delimiters +token = r"[-!#$%&'*+.^_`|~0-9a-zA-Z]+" + +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#header.fields +# field-name = token +field_name = token + +# The standard says: +# +# field-value = *( field-content / obs-fold ) +# field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] +# field-vchar = VCHAR / obs-text +# obs-fold = CRLF 1*( SP / HTAB ) +# ; obsolete line folding +# ; see Section 3.2.4 +# +# https://tools.ietf.org/html/rfc5234#appendix-B.1 +# +# VCHAR = %x21-7E +# ; visible (printing) characters +# +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#rule.quoted-string +# obs-text = %x80-FF +# +# However, the standard definition of field-content is WRONG! It disallows +# fields containing a single visible character surrounded by whitespace, +# e.g. "foo a bar". +# +# See: https://www.rfc-editor.org/errata_search.php?rfc=7230&eid=4189 +# +# So our definition of field_content attempts to fix it up... +# +# Also, we allow lots of control characters, because apparently people assume +# that they're legal in practice (e.g., google analytics makes cookies with +# \x01 in them!): +# https://github.com/python-hyper/h11/issues/57 +# We still don't allow NUL or whitespace, because those are often treated as +# meta-characters and letting them through can lead to nasty issues like SSRF. +vchar = r"[\x21-\x7e]" +vchar_or_obs_text = r"[^\x00\s]" +field_vchar = vchar_or_obs_text +field_content = r"{field_vchar}+(?:[ \t]+{field_vchar}+)*".format(**globals()) + +# We handle obs-fold at a different level, and our fixed-up field_content +# already grows to swallow the whole value, so ? instead of * +field_value = r"({field_content})?".format(**globals()) + +# header-field = field-name ":" OWS field-value OWS +header_field = ( + r"(?P{field_name})" + r":" + r"{OWS}" + r"(?P{field_value})" + r"{OWS}".format(**globals()) +) + +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#request.line +# +# request-line = method SP request-target SP HTTP-version CRLF +# method = token +# HTTP-version = HTTP-name "/" DIGIT "." DIGIT +# HTTP-name = %x48.54.54.50 ; "HTTP", case-sensitive +# +# request-target is complicated (see RFC 7230 sec 5.3) -- could be path, full +# URL, host+port (for connect), or even "*", but in any case we are guaranteed +# that it contists of the visible printing characters. +method = token +request_target = r"{vchar}+".format(**globals()) +http_version = r"HTTP/(?P[0-9]\.[0-9])" +request_line = ( + r"(?P{method})" + r" " + r"(?P{request_target})" + r" " + r"{http_version}".format(**globals()) +) + +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#status.line +# +# status-line = HTTP-version SP status-code SP reason-phrase CRLF +# status-code = 3DIGIT +# reason-phrase = *( HTAB / SP / VCHAR / obs-text ) +status_code = r"[0-9]{3}" +reason_phrase = r"([ \t]|{vchar_or_obs_text})*".format(**globals()) +status_line = ( + r"{http_version}" + r" " + r"(?P{status_code})" + # However, there are apparently a few too many servers out there that just + # leave out the reason phrase: + # https://github.com/scrapy/scrapy/issues/345#issuecomment-281756036 + # https://github.com/seanmonstar/httparse/issues/29 + # so make it optional. ?: is a non-capturing group. + r"(?: (?P{reason_phrase}))?".format(**globals()) +) + +HEXDIG = r"[0-9A-Fa-f]" +# Actually +# +# chunk-size = 1*HEXDIG +# +# but we impose an upper-limit to avoid ridiculosity. len(str(2**64)) == 20 +chunk_size = r"({HEXDIG}){{1,20}}".format(**globals()) +# Actually +# +# chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) +# +# but we aren't parsing the things so we don't really care. +chunk_ext = r";.*" +chunk_header = ( + r"(?P{chunk_size})" + r"(?P{chunk_ext})?" + r"{OWS}\r\n".format( + **globals() + ) # Even though the specification does not allow for extra whitespaces, + # we are lenient with trailing whitespaces because some servers on the wild use it. +) diff --git a/.venv/lib/python3.13/site-packages/h11/_connection.py b/.venv/lib/python3.13/site-packages/h11/_connection.py new file mode 100644 index 0000000000000000000000000000000000000000..e37d82a82a882c072cb938a90eb4486b51cdad99 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11/_connection.py @@ -0,0 +1,659 @@ +# This contains the main Connection class. Everything in h11 revolves around +# this. +from typing import ( + Any, + Callable, + cast, + Dict, + List, + Optional, + overload, + Tuple, + Type, + Union, +) + +from ._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from ._headers import get_comma_header, has_expect_100_continue, set_comma_header +from ._readers import READERS, ReadersType +from ._receivebuffer import ReceiveBuffer +from ._state import ( + _SWITCH_CONNECT, + _SWITCH_UPGRADE, + CLIENT, + ConnectionState, + DONE, + ERROR, + MIGHT_SWITCH_PROTOCOL, + SEND_BODY, + SERVER, + SWITCHED_PROTOCOL, +) +from ._util import ( # Import the internal things we need + LocalProtocolError, + RemoteProtocolError, + Sentinel, +) +from ._writers import WRITERS, WritersType + +# Everything in __all__ gets re-exported as part of the h11 public API. +__all__ = ["Connection", "NEED_DATA", "PAUSED"] + + +class NEED_DATA(Sentinel, metaclass=Sentinel): + pass + + +class PAUSED(Sentinel, metaclass=Sentinel): + pass + + +# If we ever have this much buffered without it making a complete parseable +# event, we error out. The only time we really buffer is when reading the +# request/response line + headers together, so this is effectively the limit on +# the size of that. +# +# Some precedents for defaults: +# - node.js: 80 * 1024 +# - tomcat: 8 * 1024 +# - IIS: 16 * 1024 +# - Apache: <8 KiB per line> +DEFAULT_MAX_INCOMPLETE_EVENT_SIZE = 16 * 1024 + + +# RFC 7230's rules for connection lifecycles: +# - If either side says they want to close the connection, then the connection +# must close. +# - HTTP/1.1 defaults to keep-alive unless someone says Connection: close +# - HTTP/1.0 defaults to close unless both sides say Connection: keep-alive +# (and even this is a mess -- e.g. if you're implementing a proxy then +# sending Connection: keep-alive is forbidden). +# +# We simplify life by simply not supporting keep-alive with HTTP/1.0 peers. So +# our rule is: +# - If someone says Connection: close, we will close +# - If someone uses HTTP/1.0, we will close. +def _keep_alive(event: Union[Request, Response]) -> bool: + connection = get_comma_header(event.headers, b"connection") + if b"close" in connection: + return False + if getattr(event, "http_version", b"1.1") < b"1.1": + return False + return True + + +def _body_framing( + request_method: bytes, event: Union[Request, Response] +) -> Tuple[str, Union[Tuple[()], Tuple[int]]]: + # Called when we enter SEND_BODY to figure out framing information for + # this body. + # + # These are the only two events that can trigger a SEND_BODY state: + assert type(event) in (Request, Response) + # Returns one of: + # + # ("content-length", count) + # ("chunked", ()) + # ("http/1.0", ()) + # + # which are (lookup key, *args) for constructing body reader/writer + # objects. + # + # Reference: https://tools.ietf.org/html/rfc7230#section-3.3.3 + # + # Step 1: some responses always have an empty body, regardless of what the + # headers say. + if type(event) is Response: + if ( + event.status_code in (204, 304) + or request_method == b"HEAD" + or (request_method == b"CONNECT" and 200 <= event.status_code < 300) + ): + return ("content-length", (0,)) + # Section 3.3.3 also lists another case -- responses with status_code + # < 200. For us these are InformationalResponses, not Responses, so + # they can't get into this function in the first place. + assert event.status_code >= 200 + + # Step 2: check for Transfer-Encoding (T-E beats C-L): + transfer_encodings = get_comma_header(event.headers, b"transfer-encoding") + if transfer_encodings: + assert transfer_encodings == [b"chunked"] + return ("chunked", ()) + + # Step 3: check for Content-Length + content_lengths = get_comma_header(event.headers, b"content-length") + if content_lengths: + return ("content-length", (int(content_lengths[0]),)) + + # Step 4: no applicable headers; fallback/default depends on type + if type(event) is Request: + return ("content-length", (0,)) + else: + return ("http/1.0", ()) + + +################################################################ +# +# The main Connection class +# +################################################################ + + +class Connection: + """An object encapsulating the state of an HTTP connection. + + Args: + our_role: If you're implementing a client, pass :data:`h11.CLIENT`. If + you're implementing a server, pass :data:`h11.SERVER`. + + max_incomplete_event_size (int): + The maximum number of bytes we're willing to buffer of an + incomplete event. In practice this mostly sets a limit on the + maximum size of the request/response line + headers. If this is + exceeded, then :meth:`next_event` will raise + :exc:`RemoteProtocolError`. + + """ + + def __init__( + self, + our_role: Type[Sentinel], + max_incomplete_event_size: int = DEFAULT_MAX_INCOMPLETE_EVENT_SIZE, + ) -> None: + self._max_incomplete_event_size = max_incomplete_event_size + # State and role tracking + if our_role not in (CLIENT, SERVER): + raise ValueError(f"expected CLIENT or SERVER, not {our_role!r}") + self.our_role = our_role + self.their_role: Type[Sentinel] + if our_role is CLIENT: + self.their_role = SERVER + else: + self.their_role = CLIENT + self._cstate = ConnectionState() + + # Callables for converting data->events or vice-versa given the + # current state + self._writer = self._get_io_object(self.our_role, None, WRITERS) + self._reader = self._get_io_object(self.their_role, None, READERS) + + # Holds any unprocessed received data + self._receive_buffer = ReceiveBuffer() + # If this is true, then it indicates that the incoming connection was + # closed *after* the end of whatever's in self._receive_buffer: + self._receive_buffer_closed = False + + # Extra bits of state that don't fit into the state machine. + # + # These two are only used to interpret framing headers for figuring + # out how to read/write response bodies. their_http_version is also + # made available as a convenient public API. + self.their_http_version: Optional[bytes] = None + self._request_method: Optional[bytes] = None + # This is pure flow-control and doesn't at all affect the set of legal + # transitions, so no need to bother ConnectionState with it: + self.client_is_waiting_for_100_continue = False + + @property + def states(self) -> Dict[Type[Sentinel], Type[Sentinel]]: + """A dictionary like:: + + {CLIENT: , SERVER: } + + See :ref:`state-machine` for details. + + """ + return dict(self._cstate.states) + + @property + def our_state(self) -> Type[Sentinel]: + """The current state of whichever role we are playing. See + :ref:`state-machine` for details. + """ + return self._cstate.states[self.our_role] + + @property + def their_state(self) -> Type[Sentinel]: + """The current state of whichever role we are NOT playing. See + :ref:`state-machine` for details. + """ + return self._cstate.states[self.their_role] + + @property + def they_are_waiting_for_100_continue(self) -> bool: + return self.their_role is CLIENT and self.client_is_waiting_for_100_continue + + def start_next_cycle(self) -> None: + """Attempt to reset our connection state for a new request/response + cycle. + + If both client and server are in :data:`DONE` state, then resets them + both to :data:`IDLE` state in preparation for a new request/response + cycle on this same connection. Otherwise, raises a + :exc:`LocalProtocolError`. + + See :ref:`keepalive-and-pipelining`. + + """ + old_states = dict(self._cstate.states) + self._cstate.start_next_cycle() + self._request_method = None + # self.their_http_version gets left alone, since it presumably lasts + # beyond a single request/response cycle + assert not self.client_is_waiting_for_100_continue + self._respond_to_state_changes(old_states) + + def _process_error(self, role: Type[Sentinel]) -> None: + old_states = dict(self._cstate.states) + self._cstate.process_error(role) + self._respond_to_state_changes(old_states) + + def _server_switch_event(self, event: Event) -> Optional[Type[Sentinel]]: + if type(event) is InformationalResponse and event.status_code == 101: + return _SWITCH_UPGRADE + if type(event) is Response: + if ( + _SWITCH_CONNECT in self._cstate.pending_switch_proposals + and 200 <= event.status_code < 300 + ): + return _SWITCH_CONNECT + return None + + # All events go through here + def _process_event(self, role: Type[Sentinel], event: Event) -> None: + # First, pass the event through the state machine to make sure it + # succeeds. + old_states = dict(self._cstate.states) + if role is CLIENT and type(event) is Request: + if event.method == b"CONNECT": + self._cstate.process_client_switch_proposal(_SWITCH_CONNECT) + if get_comma_header(event.headers, b"upgrade"): + self._cstate.process_client_switch_proposal(_SWITCH_UPGRADE) + server_switch_event = None + if role is SERVER: + server_switch_event = self._server_switch_event(event) + self._cstate.process_event(role, type(event), server_switch_event) + + # Then perform the updates triggered by it. + + if type(event) is Request: + self._request_method = event.method + + if role is self.their_role and type(event) in ( + Request, + Response, + InformationalResponse, + ): + event = cast(Union[Request, Response, InformationalResponse], event) + self.their_http_version = event.http_version + + # Keep alive handling + # + # RFC 7230 doesn't really say what one should do if Connection: close + # shows up on a 1xx InformationalResponse. I think the idea is that + # this is not supposed to happen. In any case, if it does happen, we + # ignore it. + if type(event) in (Request, Response) and not _keep_alive( + cast(Union[Request, Response], event) + ): + self._cstate.process_keep_alive_disabled() + + # 100-continue + if type(event) is Request and has_expect_100_continue(event): + self.client_is_waiting_for_100_continue = True + if type(event) in (InformationalResponse, Response): + self.client_is_waiting_for_100_continue = False + if role is CLIENT and type(event) in (Data, EndOfMessage): + self.client_is_waiting_for_100_continue = False + + self._respond_to_state_changes(old_states, event) + + def _get_io_object( + self, + role: Type[Sentinel], + event: Optional[Event], + io_dict: Union[ReadersType, WritersType], + ) -> Optional[Callable[..., Any]]: + # event may be None; it's only used when entering SEND_BODY + state = self._cstate.states[role] + if state is SEND_BODY: + # Special case: the io_dict has a dict of reader/writer factories + # that depend on the request/response framing. + framing_type, args = _body_framing( + cast(bytes, self._request_method), cast(Union[Request, Response], event) + ) + return io_dict[SEND_BODY][framing_type](*args) # type: ignore[index] + else: + # General case: the io_dict just has the appropriate reader/writer + # for this state + return io_dict.get((role, state)) # type: ignore[return-value] + + # This must be called after any action that might have caused + # self._cstate.states to change. + def _respond_to_state_changes( + self, + old_states: Dict[Type[Sentinel], Type[Sentinel]], + event: Optional[Event] = None, + ) -> None: + # Update reader/writer + if self.our_state != old_states[self.our_role]: + self._writer = self._get_io_object(self.our_role, event, WRITERS) + if self.their_state != old_states[self.their_role]: + self._reader = self._get_io_object(self.their_role, event, READERS) + + @property + def trailing_data(self) -> Tuple[bytes, bool]: + """Data that has been received, but not yet processed, represented as + a tuple with two elements, where the first is a byte-string containing + the unprocessed data itself, and the second is a bool that is True if + the receive connection was closed. + + See :ref:`switching-protocols` for discussion of why you'd want this. + """ + return (bytes(self._receive_buffer), self._receive_buffer_closed) + + def receive_data(self, data: bytes) -> None: + """Add data to our internal receive buffer. + + This does not actually do any processing on the data, just stores + it. To trigger processing, you have to call :meth:`next_event`. + + Args: + data (:term:`bytes-like object`): + The new data that was just received. + + Special case: If *data* is an empty byte-string like ``b""``, + then this indicates that the remote side has closed the + connection (end of file). Normally this is convenient, because + standard Python APIs like :meth:`file.read` or + :meth:`socket.recv` use ``b""`` to indicate end-of-file, while + other failures to read are indicated using other mechanisms + like raising :exc:`TimeoutError`. When using such an API you + can just blindly pass through whatever you get from ``read`` + to :meth:`receive_data`, and everything will work. + + But, if you have an API where reading an empty string is a + valid non-EOF condition, then you need to be aware of this and + make sure to check for such strings and avoid passing them to + :meth:`receive_data`. + + Returns: + Nothing, but after calling this you should call :meth:`next_event` + to parse the newly received data. + + Raises: + RuntimeError: + Raised if you pass an empty *data*, indicating EOF, and then + pass a non-empty *data*, indicating more data that somehow + arrived after the EOF. + + (Calling ``receive_data(b"")`` multiple times is fine, + and equivalent to calling it once.) + + """ + if data: + if self._receive_buffer_closed: + raise RuntimeError("received close, then received more data?") + self._receive_buffer += data + else: + self._receive_buffer_closed = True + + def _extract_next_receive_event( + self, + ) -> Union[Event, Type[NEED_DATA], Type[PAUSED]]: + state = self.their_state + # We don't pause immediately when they enter DONE, because even in + # DONE state we can still process a ConnectionClosed() event. But + # if we have data in our buffer, then we definitely aren't getting + # a ConnectionClosed() immediately and we need to pause. + if state is DONE and self._receive_buffer: + return PAUSED + if state is MIGHT_SWITCH_PROTOCOL or state is SWITCHED_PROTOCOL: + return PAUSED + assert self._reader is not None + event = self._reader(self._receive_buffer) + if event is None: + if not self._receive_buffer and self._receive_buffer_closed: + # In some unusual cases (basically just HTTP/1.0 bodies), EOF + # triggers an actual protocol event; in that case, we want to + # return that event, and then the state will change and we'll + # get called again to generate the actual ConnectionClosed(). + if hasattr(self._reader, "read_eof"): + event = self._reader.read_eof() + else: + event = ConnectionClosed() + if event is None: + event = NEED_DATA + return event # type: ignore[no-any-return] + + def next_event(self) -> Union[Event, Type[NEED_DATA], Type[PAUSED]]: + """Parse the next event out of our receive buffer, update our internal + state, and return it. + + This is a mutating operation -- think of it like calling :func:`next` + on an iterator. + + Returns: + : One of three things: + + 1) An event object -- see :ref:`events`. + + 2) The special constant :data:`NEED_DATA`, which indicates that + you need to read more data from your socket and pass it to + :meth:`receive_data` before this method will be able to return + any more events. + + 3) The special constant :data:`PAUSED`, which indicates that we + are not in a state where we can process incoming data (usually + because the peer has finished their part of the current + request/response cycle, and you have not yet called + :meth:`start_next_cycle`). See :ref:`flow-control` for details. + + Raises: + RemoteProtocolError: + The peer has misbehaved. You should close the connection + (possibly after sending some kind of 4xx response). + + Once this method returns :class:`ConnectionClosed` once, then all + subsequent calls will also return :class:`ConnectionClosed`. + + If this method raises any exception besides :exc:`RemoteProtocolError` + then that's a bug -- if it happens please file a bug report! + + If this method raises any exception then it also sets + :attr:`Connection.their_state` to :data:`ERROR` -- see + :ref:`error-handling` for discussion. + + """ + + if self.their_state is ERROR: + raise RemoteProtocolError("Can't receive data when peer state is ERROR") + try: + event = self._extract_next_receive_event() + if event not in [NEED_DATA, PAUSED]: + self._process_event(self.their_role, cast(Event, event)) + if event is NEED_DATA: + if len(self._receive_buffer) > self._max_incomplete_event_size: + # 431 is "Request header fields too large" which is pretty + # much the only situation where we can get here + raise RemoteProtocolError( + "Receive buffer too long", error_status_hint=431 + ) + if self._receive_buffer_closed: + # We're still trying to complete some event, but that's + # never going to happen because no more data is coming + raise RemoteProtocolError("peer unexpectedly closed connection") + return event + except BaseException as exc: + self._process_error(self.their_role) + if isinstance(exc, LocalProtocolError): + exc._reraise_as_remote_protocol_error() + else: + raise + + @overload + def send(self, event: ConnectionClosed) -> None: + ... + + @overload + def send( + self, event: Union[Request, InformationalResponse, Response, Data, EndOfMessage] + ) -> bytes: + ... + + @overload + def send(self, event: Event) -> Optional[bytes]: + ... + + def send(self, event: Event) -> Optional[bytes]: + """Convert a high-level event into bytes that can be sent to the peer, + while updating our internal state machine. + + Args: + event: The :ref:`event ` to send. + + Returns: + If ``type(event) is ConnectionClosed``, then returns + ``None``. Otherwise, returns a :term:`bytes-like object`. + + Raises: + LocalProtocolError: + Sending this event at this time would violate our + understanding of the HTTP/1.1 protocol. + + If this method raises any exception then it also sets + :attr:`Connection.our_state` to :data:`ERROR` -- see + :ref:`error-handling` for discussion. + + """ + data_list = self.send_with_data_passthrough(event) + if data_list is None: + return None + else: + return b"".join(data_list) + + def send_with_data_passthrough(self, event: Event) -> Optional[List[bytes]]: + """Identical to :meth:`send`, except that in situations where + :meth:`send` returns a single :term:`bytes-like object`, this instead + returns a list of them -- and when sending a :class:`Data` event, this + list is guaranteed to contain the exact object you passed in as + :attr:`Data.data`. See :ref:`sendfile` for discussion. + + """ + if self.our_state is ERROR: + raise LocalProtocolError("Can't send data when our state is ERROR") + try: + if type(event) is Response: + event = self._clean_up_response_headers_for_sending(event) + # We want to call _process_event before calling the writer, + # because if someone tries to do something invalid then this will + # give a sensible error message, while our writers all just assume + # they will only receive valid events. But, _process_event might + # change self._writer. So we have to do a little dance: + writer = self._writer + self._process_event(self.our_role, event) + if type(event) is ConnectionClosed: + return None + else: + # In any situation where writer is None, process_event should + # have raised ProtocolError + assert writer is not None + data_list: List[bytes] = [] + writer(event, data_list.append) + return data_list + except: + self._process_error(self.our_role) + raise + + def send_failed(self) -> None: + """Notify the state machine that we failed to send the data it gave + us. + + This causes :attr:`Connection.our_state` to immediately become + :data:`ERROR` -- see :ref:`error-handling` for discussion. + + """ + self._process_error(self.our_role) + + # When sending a Response, we take responsibility for a few things: + # + # - Sometimes you MUST set Connection: close. We take care of those + # times. (You can also set it yourself if you want, and if you do then + # we'll respect that and close the connection at the right time. But you + # don't have to worry about that unless you want to.) + # + # - The user has to set Content-Length if they want it. Otherwise, for + # responses that have bodies (e.g. not HEAD), then we will automatically + # select the right mechanism for streaming a body of unknown length, + # which depends on depending on the peer's HTTP version. + # + # This function's *only* responsibility is making sure headers are set up + # right -- everything downstream just looks at the headers. There are no + # side channels. + def _clean_up_response_headers_for_sending(self, response: Response) -> Response: + assert type(response) is Response + + headers = response.headers + need_close = False + + # HEAD requests need some special handling: they always act like they + # have Content-Length: 0, and that's how _body_framing treats + # them. But their headers are supposed to match what we would send if + # the request was a GET. (Technically there is one deviation allowed: + # we're allowed to leave out the framing headers -- see + # https://tools.ietf.org/html/rfc7231#section-4.3.2 . But it's just as + # easy to get them right.) + method_for_choosing_headers = cast(bytes, self._request_method) + if method_for_choosing_headers == b"HEAD": + method_for_choosing_headers = b"GET" + framing_type, _ = _body_framing(method_for_choosing_headers, response) + if framing_type in ("chunked", "http/1.0"): + # This response has a body of unknown length. + # If our peer is HTTP/1.1, we use Transfer-Encoding: chunked + # If our peer is HTTP/1.0, we use no framing headers, and close the + # connection afterwards. + # + # Make sure to clear Content-Length (in principle user could have + # set both and then we ignored Content-Length b/c + # Transfer-Encoding overwrote it -- this would be naughty of them, + # but the HTTP spec says that if our peer does this then we have + # to fix it instead of erroring out, so we'll accord the user the + # same respect). + headers = set_comma_header(headers, b"content-length", []) + if self.their_http_version is None or self.their_http_version < b"1.1": + # Either we never got a valid request and are sending back an + # error (their_http_version is None), so we assume the worst; + # or else we did get a valid HTTP/1.0 request, so we know that + # they don't understand chunked encoding. + headers = set_comma_header(headers, b"transfer-encoding", []) + # This is actually redundant ATM, since currently we + # unconditionally disable keep-alive when talking to HTTP/1.0 + # peers. But let's be defensive just in case we add + # Connection: keep-alive support later: + if self._request_method != b"HEAD": + need_close = True + else: + headers = set_comma_header(headers, b"transfer-encoding", [b"chunked"]) + + if not self._cstate.keep_alive or need_close: + # Make sure Connection: close is set + connection = set(get_comma_header(headers, b"connection")) + connection.discard(b"keep-alive") + connection.add(b"close") + headers = set_comma_header(headers, b"connection", sorted(connection)) + + return Response( + headers=headers, + status_code=response.status_code, + http_version=response.http_version, + reason=response.reason, + ) diff --git a/.venv/lib/python3.13/site-packages/h11/_events.py b/.venv/lib/python3.13/site-packages/h11/_events.py new file mode 100644 index 0000000000000000000000000000000000000000..ca1c3adbde2c4e7710482a18e3471f91f1da610e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11/_events.py @@ -0,0 +1,369 @@ +# High level events that make up HTTP/1.1 conversations. Loosely inspired by +# the corresponding events in hyper-h2: +# +# http://python-hyper.org/h2/en/stable/api.html#events +# +# Don't subclass these. Stuff will break. + +import re +from abc import ABC +from dataclasses import dataclass +from typing import List, Tuple, Union + +from ._abnf import method, request_target +from ._headers import Headers, normalize_and_validate +from ._util import bytesify, LocalProtocolError, validate + +# Everything in __all__ gets re-exported as part of the h11 public API. +__all__ = [ + "Event", + "Request", + "InformationalResponse", + "Response", + "Data", + "EndOfMessage", + "ConnectionClosed", +] + +method_re = re.compile(method.encode("ascii")) +request_target_re = re.compile(request_target.encode("ascii")) + + +class Event(ABC): + """ + Base class for h11 events. + """ + + __slots__ = () + + +@dataclass(init=False, frozen=True) +class Request(Event): + """The beginning of an HTTP request. + + Fields: + + .. attribute:: method + + An HTTP method, e.g. ``b"GET"`` or ``b"POST"``. Always a byte + string. :term:`Bytes-like objects ` and native + strings containing only ascii characters will be automatically + converted to byte strings. + + .. attribute:: target + + The target of an HTTP request, e.g. ``b"/index.html"``, or one of the + more exotic formats described in `RFC 7320, section 5.3 + `_. Always a byte + string. :term:`Bytes-like objects ` and native + strings containing only ascii characters will be automatically + converted to byte strings. + + .. attribute:: headers + + Request headers, represented as a list of (name, value) pairs. See + :ref:`the header normalization rules ` for details. + + .. attribute:: http_version + + The HTTP protocol version, represented as a byte string like + ``b"1.1"``. See :ref:`the HTTP version normalization rules + ` for details. + + """ + + __slots__ = ("method", "headers", "target", "http_version") + + method: bytes + headers: Headers + target: bytes + http_version: bytes + + def __init__( + self, + *, + method: Union[bytes, str], + headers: Union[Headers, List[Tuple[bytes, bytes]], List[Tuple[str, str]]], + target: Union[bytes, str], + http_version: Union[bytes, str] = b"1.1", + _parsed: bool = False, + ) -> None: + super().__init__() + if isinstance(headers, Headers): + object.__setattr__(self, "headers", headers) + else: + object.__setattr__( + self, "headers", normalize_and_validate(headers, _parsed=_parsed) + ) + if not _parsed: + object.__setattr__(self, "method", bytesify(method)) + object.__setattr__(self, "target", bytesify(target)) + object.__setattr__(self, "http_version", bytesify(http_version)) + else: + object.__setattr__(self, "method", method) + object.__setattr__(self, "target", target) + object.__setattr__(self, "http_version", http_version) + + # "A server MUST respond with a 400 (Bad Request) status code to any + # HTTP/1.1 request message that lacks a Host header field and to any + # request message that contains more than one Host header field or a + # Host header field with an invalid field-value." + # -- https://tools.ietf.org/html/rfc7230#section-5.4 + host_count = 0 + for name, value in self.headers: + if name == b"host": + host_count += 1 + if self.http_version == b"1.1" and host_count == 0: + raise LocalProtocolError("Missing mandatory Host: header") + if host_count > 1: + raise LocalProtocolError("Found multiple Host: headers") + + validate(method_re, self.method, "Illegal method characters") + validate(request_target_re, self.target, "Illegal target characters") + + # This is an unhashable type. + __hash__ = None # type: ignore + + +@dataclass(init=False, frozen=True) +class _ResponseBase(Event): + __slots__ = ("headers", "http_version", "reason", "status_code") + + headers: Headers + http_version: bytes + reason: bytes + status_code: int + + def __init__( + self, + *, + headers: Union[Headers, List[Tuple[bytes, bytes]], List[Tuple[str, str]]], + status_code: int, + http_version: Union[bytes, str] = b"1.1", + reason: Union[bytes, str] = b"", + _parsed: bool = False, + ) -> None: + super().__init__() + if isinstance(headers, Headers): + object.__setattr__(self, "headers", headers) + else: + object.__setattr__( + self, "headers", normalize_and_validate(headers, _parsed=_parsed) + ) + if not _parsed: + object.__setattr__(self, "reason", bytesify(reason)) + object.__setattr__(self, "http_version", bytesify(http_version)) + if not isinstance(status_code, int): + raise LocalProtocolError("status code must be integer") + # Because IntEnum objects are instances of int, but aren't + # duck-compatible (sigh), see gh-72. + object.__setattr__(self, "status_code", int(status_code)) + else: + object.__setattr__(self, "reason", reason) + object.__setattr__(self, "http_version", http_version) + object.__setattr__(self, "status_code", status_code) + + self.__post_init__() + + def __post_init__(self) -> None: + pass + + # This is an unhashable type. + __hash__ = None # type: ignore + + +@dataclass(init=False, frozen=True) +class InformationalResponse(_ResponseBase): + """An HTTP informational response. + + Fields: + + .. attribute:: status_code + + The status code of this response, as an integer. For an + :class:`InformationalResponse`, this is always in the range [100, + 200). + + .. attribute:: headers + + Request headers, represented as a list of (name, value) pairs. See + :ref:`the header normalization rules ` for + details. + + .. attribute:: http_version + + The HTTP protocol version, represented as a byte string like + ``b"1.1"``. See :ref:`the HTTP version normalization rules + ` for details. + + .. attribute:: reason + + The reason phrase of this response, as a byte string. For example: + ``b"OK"``, or ``b"Not Found"``. + + """ + + def __post_init__(self) -> None: + if not (100 <= self.status_code < 200): + raise LocalProtocolError( + "InformationalResponse status_code should be in range " + "[100, 200), not {}".format(self.status_code) + ) + + # This is an unhashable type. + __hash__ = None # type: ignore + + +@dataclass(init=False, frozen=True) +class Response(_ResponseBase): + """The beginning of an HTTP response. + + Fields: + + .. attribute:: status_code + + The status code of this response, as an integer. For an + :class:`Response`, this is always in the range [200, + 1000). + + .. attribute:: headers + + Request headers, represented as a list of (name, value) pairs. See + :ref:`the header normalization rules ` for details. + + .. attribute:: http_version + + The HTTP protocol version, represented as a byte string like + ``b"1.1"``. See :ref:`the HTTP version normalization rules + ` for details. + + .. attribute:: reason + + The reason phrase of this response, as a byte string. For example: + ``b"OK"``, or ``b"Not Found"``. + + """ + + def __post_init__(self) -> None: + if not (200 <= self.status_code < 1000): + raise LocalProtocolError( + "Response status_code should be in range [200, 1000), not {}".format( + self.status_code + ) + ) + + # This is an unhashable type. + __hash__ = None # type: ignore + + +@dataclass(init=False, frozen=True) +class Data(Event): + """Part of an HTTP message body. + + Fields: + + .. attribute:: data + + A :term:`bytes-like object` containing part of a message body. Or, if + using the ``combine=False`` argument to :meth:`Connection.send`, then + any object that your socket writing code knows what to do with, and for + which calling :func:`len` returns the number of bytes that will be + written -- see :ref:`sendfile` for details. + + .. attribute:: chunk_start + + A marker that indicates whether this data object is from the start of a + chunked transfer encoding chunk. This field is ignored when when a Data + event is provided to :meth:`Connection.send`: it is only valid on + events emitted from :meth:`Connection.next_event`. You probably + shouldn't use this attribute at all; see + :ref:`chunk-delimiters-are-bad` for details. + + .. attribute:: chunk_end + + A marker that indicates whether this data object is the last for a + given chunked transfer encoding chunk. This field is ignored when when + a Data event is provided to :meth:`Connection.send`: it is only valid + on events emitted from :meth:`Connection.next_event`. You probably + shouldn't use this attribute at all; see + :ref:`chunk-delimiters-are-bad` for details. + + """ + + __slots__ = ("data", "chunk_start", "chunk_end") + + data: bytes + chunk_start: bool + chunk_end: bool + + def __init__( + self, data: bytes, chunk_start: bool = False, chunk_end: bool = False + ) -> None: + object.__setattr__(self, "data", data) + object.__setattr__(self, "chunk_start", chunk_start) + object.__setattr__(self, "chunk_end", chunk_end) + + # This is an unhashable type. + __hash__ = None # type: ignore + + +# XX FIXME: "A recipient MUST ignore (or consider as an error) any fields that +# are forbidden to be sent in a trailer, since processing them as if they were +# present in the header section might bypass external security filters." +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#chunked.trailer.part +# Unfortunately, the list of forbidden fields is long and vague :-/ +@dataclass(init=False, frozen=True) +class EndOfMessage(Event): + """The end of an HTTP message. + + Fields: + + .. attribute:: headers + + Default value: ``[]`` + + Any trailing headers attached to this message, represented as a list of + (name, value) pairs. See :ref:`the header normalization rules + ` for details. + + Must be empty unless ``Transfer-Encoding: chunked`` is in use. + + """ + + __slots__ = ("headers",) + + headers: Headers + + def __init__( + self, + *, + headers: Union[ + Headers, List[Tuple[bytes, bytes]], List[Tuple[str, str]], None + ] = None, + _parsed: bool = False, + ) -> None: + super().__init__() + if headers is None: + headers = Headers([]) + elif not isinstance(headers, Headers): + headers = normalize_and_validate(headers, _parsed=_parsed) + + object.__setattr__(self, "headers", headers) + + # This is an unhashable type. + __hash__ = None # type: ignore + + +@dataclass(frozen=True) +class ConnectionClosed(Event): + """This event indicates that the sender has closed their outgoing + connection. + + Note that this does not necessarily mean that they can't *receive* further + data, because TCP connections are composed to two one-way channels which + can be closed independently. See :ref:`closing` for details. + + No fields. + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/h11/_headers.py b/.venv/lib/python3.13/site-packages/h11/_headers.py new file mode 100644 index 0000000000000000000000000000000000000000..31da3e2b23b55a624b36f105e62a6902e63286aa --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11/_headers.py @@ -0,0 +1,282 @@ +import re +from typing import AnyStr, cast, List, overload, Sequence, Tuple, TYPE_CHECKING, Union + +from ._abnf import field_name, field_value +from ._util import bytesify, LocalProtocolError, validate + +if TYPE_CHECKING: + from ._events import Request + +try: + from typing import Literal +except ImportError: + from typing_extensions import Literal # type: ignore + +CONTENT_LENGTH_MAX_DIGITS = 20 # allow up to 1 billion TB - 1 + + +# Facts +# ----- +# +# Headers are: +# keys: case-insensitive ascii +# values: mixture of ascii and raw bytes +# +# "Historically, HTTP has allowed field content with text in the ISO-8859-1 +# charset [ISO-8859-1], supporting other charsets only through use of +# [RFC2047] encoding. In practice, most HTTP header field values use only a +# subset of the US-ASCII charset [USASCII]. Newly defined header fields SHOULD +# limit their field values to US-ASCII octets. A recipient SHOULD treat other +# octets in field content (obs-text) as opaque data." +# And it deprecates all non-ascii values +# +# Leading/trailing whitespace in header names is forbidden +# +# Values get leading/trailing whitespace stripped +# +# Content-Disposition actually needs to contain unicode semantically; to +# accomplish this it has a terrifically weird way of encoding the filename +# itself as ascii (and even this still has lots of cross-browser +# incompatibilities) +# +# Order is important: +# "a proxy MUST NOT change the order of these field values when forwarding a +# message" +# (and there are several headers where the order indicates a preference) +# +# Multiple occurences of the same header: +# "A sender MUST NOT generate multiple header fields with the same field name +# in a message unless either the entire field value for that header field is +# defined as a comma-separated list [or the header is Set-Cookie which gets a +# special exception]" - RFC 7230. (cookies are in RFC 6265) +# +# So every header aside from Set-Cookie can be merged by b", ".join if it +# occurs repeatedly. But, of course, they can't necessarily be split by +# .split(b","), because quoting. +# +# Given all this mess (case insensitive, duplicates allowed, order is +# important, ...), there doesn't appear to be any standard way to handle +# headers in Python -- they're almost like dicts, but... actually just +# aren't. For now we punt and just use a super simple representation: headers +# are a list of pairs +# +# [(name1, value1), (name2, value2), ...] +# +# where all entries are bytestrings, names are lowercase and have no +# leading/trailing whitespace, and values are bytestrings with no +# leading/trailing whitespace. Searching and updating are done via naive O(n) +# methods. +# +# Maybe a dict-of-lists would be better? + +_content_length_re = re.compile(rb"[0-9]+") +_field_name_re = re.compile(field_name.encode("ascii")) +_field_value_re = re.compile(field_value.encode("ascii")) + + +class Headers(Sequence[Tuple[bytes, bytes]]): + """ + A list-like interface that allows iterating over headers as byte-pairs + of (lowercased-name, value). + + Internally we actually store the representation as three-tuples, + including both the raw original casing, in order to preserve casing + over-the-wire, and the lowercased name, for case-insensitive comparisions. + + r = Request( + method="GET", + target="/", + headers=[("Host", "example.org"), ("Connection", "keep-alive")], + http_version="1.1", + ) + assert r.headers == [ + (b"host", b"example.org"), + (b"connection", b"keep-alive") + ] + assert r.headers.raw_items() == [ + (b"Host", b"example.org"), + (b"Connection", b"keep-alive") + ] + """ + + __slots__ = "_full_items" + + def __init__(self, full_items: List[Tuple[bytes, bytes, bytes]]) -> None: + self._full_items = full_items + + def __bool__(self) -> bool: + return bool(self._full_items) + + def __eq__(self, other: object) -> bool: + return list(self) == list(other) # type: ignore + + def __len__(self) -> int: + return len(self._full_items) + + def __repr__(self) -> str: + return "" % repr(list(self)) + + def __getitem__(self, idx: int) -> Tuple[bytes, bytes]: # type: ignore[override] + _, name, value = self._full_items[idx] + return (name, value) + + def raw_items(self) -> List[Tuple[bytes, bytes]]: + return [(raw_name, value) for raw_name, _, value in self._full_items] + + +HeaderTypes = Union[ + List[Tuple[bytes, bytes]], + List[Tuple[bytes, str]], + List[Tuple[str, bytes]], + List[Tuple[str, str]], +] + + +@overload +def normalize_and_validate(headers: Headers, _parsed: Literal[True]) -> Headers: + ... + + +@overload +def normalize_and_validate(headers: HeaderTypes, _parsed: Literal[False]) -> Headers: + ... + + +@overload +def normalize_and_validate( + headers: Union[Headers, HeaderTypes], _parsed: bool = False +) -> Headers: + ... + + +def normalize_and_validate( + headers: Union[Headers, HeaderTypes], _parsed: bool = False +) -> Headers: + new_headers = [] + seen_content_length = None + saw_transfer_encoding = False + for name, value in headers: + # For headers coming out of the parser, we can safely skip some steps, + # because it always returns bytes and has already run these regexes + # over the data: + if not _parsed: + name = bytesify(name) + value = bytesify(value) + validate(_field_name_re, name, "Illegal header name {!r}", name) + validate(_field_value_re, value, "Illegal header value {!r}", value) + assert isinstance(name, bytes) + assert isinstance(value, bytes) + + raw_name = name + name = name.lower() + if name == b"content-length": + lengths = {length.strip() for length in value.split(b",")} + if len(lengths) != 1: + raise LocalProtocolError("conflicting Content-Length headers") + value = lengths.pop() + validate(_content_length_re, value, "bad Content-Length") + if len(value) > CONTENT_LENGTH_MAX_DIGITS: + raise LocalProtocolError("bad Content-Length") + if seen_content_length is None: + seen_content_length = value + new_headers.append((raw_name, name, value)) + elif seen_content_length != value: + raise LocalProtocolError("conflicting Content-Length headers") + elif name == b"transfer-encoding": + # "A server that receives a request message with a transfer coding + # it does not understand SHOULD respond with 501 (Not + # Implemented)." + # https://tools.ietf.org/html/rfc7230#section-3.3.1 + if saw_transfer_encoding: + raise LocalProtocolError( + "multiple Transfer-Encoding headers", error_status_hint=501 + ) + # "All transfer-coding names are case-insensitive" + # -- https://tools.ietf.org/html/rfc7230#section-4 + value = value.lower() + if value != b"chunked": + raise LocalProtocolError( + "Only Transfer-Encoding: chunked is supported", + error_status_hint=501, + ) + saw_transfer_encoding = True + new_headers.append((raw_name, name, value)) + else: + new_headers.append((raw_name, name, value)) + return Headers(new_headers) + + +def get_comma_header(headers: Headers, name: bytes) -> List[bytes]: + # Should only be used for headers whose value is a list of + # comma-separated, case-insensitive values. + # + # The header name `name` is expected to be lower-case bytes. + # + # Connection: meets these criteria (including cast insensitivity). + # + # Content-Length: technically is just a single value (1*DIGIT), but the + # standard makes reference to implementations that do multiple values, and + # using this doesn't hurt. Ditto, case insensitivity doesn't things either + # way. + # + # Transfer-Encoding: is more complex (allows for quoted strings), so + # splitting on , is actually wrong. For example, this is legal: + # + # Transfer-Encoding: foo; options="1,2", chunked + # + # and should be parsed as + # + # foo; options="1,2" + # chunked + # + # but this naive function will parse it as + # + # foo; options="1 + # 2" + # chunked + # + # However, this is okay because the only thing we are going to do with + # any Transfer-Encoding is reject ones that aren't just "chunked", so + # both of these will be treated the same anyway. + # + # Expect: the only legal value is the literal string + # "100-continue". Splitting on commas is harmless. Case insensitive. + # + out: List[bytes] = [] + for _, found_name, found_raw_value in headers._full_items: + if found_name == name: + found_raw_value = found_raw_value.lower() + for found_split_value in found_raw_value.split(b","): + found_split_value = found_split_value.strip() + if found_split_value: + out.append(found_split_value) + return out + + +def set_comma_header(headers: Headers, name: bytes, new_values: List[bytes]) -> Headers: + # The header name `name` is expected to be lower-case bytes. + # + # Note that when we store the header we use title casing for the header + # names, in order to match the conventional HTTP header style. + # + # Simply calling `.title()` is a blunt approach, but it's correct + # here given the cases where we're using `set_comma_header`... + # + # Connection, Content-Length, Transfer-Encoding. + new_headers: List[Tuple[bytes, bytes]] = [] + for found_raw_name, found_name, found_raw_value in headers._full_items: + if found_name != name: + new_headers.append((found_raw_name, found_raw_value)) + for new_value in new_values: + new_headers.append((name.title(), new_value)) + return normalize_and_validate(new_headers) + + +def has_expect_100_continue(request: "Request") -> bool: + # https://tools.ietf.org/html/rfc7231#section-5.1.1 + # "A server that receives a 100-continue expectation in an HTTP/1.0 request + # MUST ignore that expectation." + if request.http_version < b"1.1": + return False + expect = get_comma_header(request.headers, b"expect") + return b"100-continue" in expect diff --git a/.venv/lib/python3.13/site-packages/h11/_readers.py b/.venv/lib/python3.13/site-packages/h11/_readers.py new file mode 100644 index 0000000000000000000000000000000000000000..576804cc282032526e0a932c9853d586a094bad0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11/_readers.py @@ -0,0 +1,250 @@ +# Code to read HTTP data +# +# Strategy: each reader is a callable which takes a ReceiveBuffer object, and +# either: +# 1) consumes some of it and returns an Event +# 2) raises a LocalProtocolError (for consistency -- e.g. we call validate() +# and it might raise a LocalProtocolError, so simpler just to always use +# this) +# 3) returns None, meaning "I need more data" +# +# If they have a .read_eof attribute, then this will be called if an EOF is +# received -- but this is optional. Either way, the actual ConnectionClosed +# event will be generated afterwards. +# +# READERS is a dict describing how to pick a reader. It maps states to either: +# - a reader +# - or, for body readers, a dict of per-framing reader factories + +import re +from typing import Any, Callable, Dict, Iterable, NoReturn, Optional, Tuple, Type, Union + +from ._abnf import chunk_header, header_field, request_line, status_line +from ._events import Data, EndOfMessage, InformationalResponse, Request, Response +from ._receivebuffer import ReceiveBuffer +from ._state import ( + CLIENT, + CLOSED, + DONE, + IDLE, + MUST_CLOSE, + SEND_BODY, + SEND_RESPONSE, + SERVER, +) +from ._util import LocalProtocolError, RemoteProtocolError, Sentinel, validate + +__all__ = ["READERS"] + +header_field_re = re.compile(header_field.encode("ascii")) +obs_fold_re = re.compile(rb"[ \t]+") + + +def _obsolete_line_fold(lines: Iterable[bytes]) -> Iterable[bytes]: + it = iter(lines) + last: Optional[bytes] = None + for line in it: + match = obs_fold_re.match(line) + if match: + if last is None: + raise LocalProtocolError("continuation line at start of headers") + if not isinstance(last, bytearray): + # Cast to a mutable type, avoiding copy on append to ensure O(n) time + last = bytearray(last) + last += b" " + last += line[match.end() :] + else: + if last is not None: + yield last + last = line + if last is not None: + yield last + + +def _decode_header_lines( + lines: Iterable[bytes], +) -> Iterable[Tuple[bytes, bytes]]: + for line in _obsolete_line_fold(lines): + matches = validate(header_field_re, line, "illegal header line: {!r}", line) + yield (matches["field_name"], matches["field_value"]) + + +request_line_re = re.compile(request_line.encode("ascii")) + + +def maybe_read_from_IDLE_client(buf: ReceiveBuffer) -> Optional[Request]: + lines = buf.maybe_extract_lines() + if lines is None: + if buf.is_next_line_obviously_invalid_request_line(): + raise LocalProtocolError("illegal request line") + return None + if not lines: + raise LocalProtocolError("no request line received") + matches = validate( + request_line_re, lines[0], "illegal request line: {!r}", lines[0] + ) + return Request( + headers=list(_decode_header_lines(lines[1:])), _parsed=True, **matches + ) + + +status_line_re = re.compile(status_line.encode("ascii")) + + +def maybe_read_from_SEND_RESPONSE_server( + buf: ReceiveBuffer, +) -> Union[InformationalResponse, Response, None]: + lines = buf.maybe_extract_lines() + if lines is None: + if buf.is_next_line_obviously_invalid_request_line(): + raise LocalProtocolError("illegal request line") + return None + if not lines: + raise LocalProtocolError("no response line received") + matches = validate(status_line_re, lines[0], "illegal status line: {!r}", lines[0]) + http_version = ( + b"1.1" if matches["http_version"] is None else matches["http_version"] + ) + reason = b"" if matches["reason"] is None else matches["reason"] + status_code = int(matches["status_code"]) + class_: Union[Type[InformationalResponse], Type[Response]] = ( + InformationalResponse if status_code < 200 else Response + ) + return class_( + headers=list(_decode_header_lines(lines[1:])), + _parsed=True, + status_code=status_code, + reason=reason, + http_version=http_version, + ) + + +class ContentLengthReader: + def __init__(self, length: int) -> None: + self._length = length + self._remaining = length + + def __call__(self, buf: ReceiveBuffer) -> Union[Data, EndOfMessage, None]: + if self._remaining == 0: + return EndOfMessage() + data = buf.maybe_extract_at_most(self._remaining) + if data is None: + return None + self._remaining -= len(data) + return Data(data=data) + + def read_eof(self) -> NoReturn: + raise RemoteProtocolError( + "peer closed connection without sending complete message body " + "(received {} bytes, expected {})".format( + self._length - self._remaining, self._length + ) + ) + + +chunk_header_re = re.compile(chunk_header.encode("ascii")) + + +class ChunkedReader: + def __init__(self) -> None: + self._bytes_in_chunk = 0 + # After reading a chunk, we have to throw away the trailing \r\n. + # This tracks the bytes that we need to match and throw away. + self._bytes_to_discard = b"" + self._reading_trailer = False + + def __call__(self, buf: ReceiveBuffer) -> Union[Data, EndOfMessage, None]: + if self._reading_trailer: + lines = buf.maybe_extract_lines() + if lines is None: + return None + return EndOfMessage(headers=list(_decode_header_lines(lines))) + if self._bytes_to_discard: + data = buf.maybe_extract_at_most(len(self._bytes_to_discard)) + if data is None: + return None + if data != self._bytes_to_discard[: len(data)]: + raise LocalProtocolError( + f"malformed chunk footer: {data!r} (expected {self._bytes_to_discard!r})" + ) + self._bytes_to_discard = self._bytes_to_discard[len(data) :] + if self._bytes_to_discard: + return None + # else, fall through and read some more + assert self._bytes_to_discard == b"" + if self._bytes_in_chunk == 0: + # We need to refill our chunk count + chunk_header = buf.maybe_extract_next_line() + if chunk_header is None: + return None + matches = validate( + chunk_header_re, + chunk_header, + "illegal chunk header: {!r}", + chunk_header, + ) + # XX FIXME: we discard chunk extensions. Does anyone care? + self._bytes_in_chunk = int(matches["chunk_size"], base=16) + if self._bytes_in_chunk == 0: + self._reading_trailer = True + return self(buf) + chunk_start = True + else: + chunk_start = False + assert self._bytes_in_chunk > 0 + data = buf.maybe_extract_at_most(self._bytes_in_chunk) + if data is None: + return None + self._bytes_in_chunk -= len(data) + if self._bytes_in_chunk == 0: + self._bytes_to_discard = b"\r\n" + chunk_end = True + else: + chunk_end = False + return Data(data=data, chunk_start=chunk_start, chunk_end=chunk_end) + + def read_eof(self) -> NoReturn: + raise RemoteProtocolError( + "peer closed connection without sending complete message body " + "(incomplete chunked read)" + ) + + +class Http10Reader: + def __call__(self, buf: ReceiveBuffer) -> Optional[Data]: + data = buf.maybe_extract_at_most(999999999) + if data is None: + return None + return Data(data=data) + + def read_eof(self) -> EndOfMessage: + return EndOfMessage() + + +def expect_nothing(buf: ReceiveBuffer) -> None: + if buf: + raise LocalProtocolError("Got data when expecting EOF") + return None + + +ReadersType = Dict[ + Union[Type[Sentinel], Tuple[Type[Sentinel], Type[Sentinel]]], + Union[Callable[..., Any], Dict[str, Callable[..., Any]]], +] + +READERS: ReadersType = { + (CLIENT, IDLE): maybe_read_from_IDLE_client, + (SERVER, IDLE): maybe_read_from_SEND_RESPONSE_server, + (SERVER, SEND_RESPONSE): maybe_read_from_SEND_RESPONSE_server, + (CLIENT, DONE): expect_nothing, + (CLIENT, MUST_CLOSE): expect_nothing, + (CLIENT, CLOSED): expect_nothing, + (SERVER, DONE): expect_nothing, + (SERVER, MUST_CLOSE): expect_nothing, + (SERVER, CLOSED): expect_nothing, + SEND_BODY: { + "chunked": ChunkedReader, + "content-length": ContentLengthReader, + "http/1.0": Http10Reader, + }, +} diff --git a/.venv/lib/python3.13/site-packages/h11/_receivebuffer.py b/.venv/lib/python3.13/site-packages/h11/_receivebuffer.py new file mode 100644 index 0000000000000000000000000000000000000000..e5c4e08a56f5081e87103f38b4add6ce1b730204 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11/_receivebuffer.py @@ -0,0 +1,153 @@ +import re +import sys +from typing import List, Optional, Union + +__all__ = ["ReceiveBuffer"] + + +# Operations we want to support: +# - find next \r\n or \r\n\r\n (\n or \n\n are also acceptable), +# or wait until there is one +# - read at-most-N bytes +# Goals: +# - on average, do this fast +# - worst case, do this in O(n) where n is the number of bytes processed +# Plan: +# - store bytearray, offset, how far we've searched for a separator token +# - use the how-far-we've-searched data to avoid rescanning +# - while doing a stream of uninterrupted processing, advance offset instead +# of constantly copying +# WARNING: +# - I haven't benchmarked or profiled any of this yet. +# +# Note that starting in Python 3.4, deleting the initial n bytes from a +# bytearray is amortized O(n), thanks to some excellent work by Antoine +# Martin: +# +# https://bugs.python.org/issue19087 +# +# This means that if we only supported 3.4+, we could get rid of the code here +# involving self._start and self.compress, because it's doing exactly the same +# thing that bytearray now does internally. +# +# BUT unfortunately, we still support 2.7, and reading short segments out of a +# long buffer MUST be O(bytes read) to avoid DoS issues, so we can't actually +# delete this code. Yet: +# +# https://pythonclock.org/ +# +# (Two things to double-check first though: make sure PyPy also has the +# optimization, and benchmark to make sure it's a win, since we do have a +# slightly clever thing where we delay calling compress() until we've +# processed a whole event, which could in theory be slightly more efficient +# than the internal bytearray support.) +blank_line_regex = re.compile(b"\n\r?\n", re.MULTILINE) + + +class ReceiveBuffer: + def __init__(self) -> None: + self._data = bytearray() + self._next_line_search = 0 + self._multiple_lines_search = 0 + + def __iadd__(self, byteslike: Union[bytes, bytearray]) -> "ReceiveBuffer": + self._data += byteslike + return self + + def __bool__(self) -> bool: + return bool(len(self)) + + def __len__(self) -> int: + return len(self._data) + + # for @property unprocessed_data + def __bytes__(self) -> bytes: + return bytes(self._data) + + def _extract(self, count: int) -> bytearray: + # extracting an initial slice of the data buffer and return it + out = self._data[:count] + del self._data[:count] + + self._next_line_search = 0 + self._multiple_lines_search = 0 + + return out + + def maybe_extract_at_most(self, count: int) -> Optional[bytearray]: + """ + Extract a fixed number of bytes from the buffer. + """ + out = self._data[:count] + if not out: + return None + + return self._extract(count) + + def maybe_extract_next_line(self) -> Optional[bytearray]: + """ + Extract the first line, if it is completed in the buffer. + """ + # Only search in buffer space that we've not already looked at. + search_start_index = max(0, self._next_line_search - 1) + partial_idx = self._data.find(b"\r\n", search_start_index) + + if partial_idx == -1: + self._next_line_search = len(self._data) + return None + + # + 2 is to compensate len(b"\r\n") + idx = partial_idx + 2 + + return self._extract(idx) + + def maybe_extract_lines(self) -> Optional[List[bytearray]]: + """ + Extract everything up to the first blank line, and return a list of lines. + """ + # Handle the case where we have an immediate empty line. + if self._data[:1] == b"\n": + self._extract(1) + return [] + + if self._data[:2] == b"\r\n": + self._extract(2) + return [] + + # Only search in buffer space that we've not already looked at. + match = blank_line_regex.search(self._data, self._multiple_lines_search) + if match is None: + self._multiple_lines_search = max(0, len(self._data) - 2) + return None + + # Truncate the buffer and return it. + idx = match.span(0)[-1] + out = self._extract(idx) + lines = out.split(b"\n") + + for line in lines: + if line.endswith(b"\r"): + del line[-1] + + assert lines[-2] == lines[-1] == b"" + + del lines[-2:] + + return lines + + # In theory we should wait until `\r\n` before starting to validate + # incoming data. However it's interesting to detect (very) invalid data + # early given they might not even contain `\r\n` at all (hence only + # timeout will get rid of them). + # This is not a 100% effective detection but more of a cheap sanity check + # allowing for early abort in some useful cases. + # This is especially interesting when peer is messing up with HTTPS and + # sent us a TLS stream where we were expecting plain HTTP given all + # versions of TLS so far start handshake with a 0x16 message type code. + def is_next_line_obviously_invalid_request_line(self) -> bool: + try: + # HTTP header line must not contain non-printable characters + # and should not start with a space + return self._data[0] < 0x21 + except IndexError: + return False diff --git a/.venv/lib/python3.13/site-packages/h11/_state.py b/.venv/lib/python3.13/site-packages/h11/_state.py new file mode 100644 index 0000000000000000000000000000000000000000..3ad444b043e3f3d6c05c2d9d84d5119312bfaa34 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11/_state.py @@ -0,0 +1,365 @@ +################################################################ +# The core state machine +################################################################ +# +# Rule 1: everything that affects the state machine and state transitions must +# live here in this file. As much as possible goes into the table-based +# representation, but for the bits that don't quite fit, the actual code and +# state must nonetheless live here. +# +# Rule 2: this file does not know about what role we're playing; it only knows +# about HTTP request/response cycles in the abstract. This ensures that we +# don't cheat and apply different rules to local and remote parties. +# +# +# Theory of operation +# =================== +# +# Possibly the simplest way to think about this is that we actually have 5 +# different state machines here. Yes, 5. These are: +# +# 1) The client state, with its complicated automaton (see the docs) +# 2) The server state, with its complicated automaton (see the docs) +# 3) The keep-alive state, with possible states {True, False} +# 4) The SWITCH_CONNECT state, with possible states {False, True} +# 5) The SWITCH_UPGRADE state, with possible states {False, True} +# +# For (3)-(5), the first state listed is the initial state. +# +# (1)-(3) are stored explicitly in member variables. The last +# two are stored implicitly in the pending_switch_proposals set as: +# (state of 4) == (_SWITCH_CONNECT in pending_switch_proposals) +# (state of 5) == (_SWITCH_UPGRADE in pending_switch_proposals) +# +# And each of these machines has two different kinds of transitions: +# +# a) Event-triggered +# b) State-triggered +# +# Event triggered is the obvious thing that you'd think it is: some event +# happens, and if it's the right event at the right time then a transition +# happens. But there are somewhat complicated rules for which machines can +# "see" which events. (As a rule of thumb, if a machine "sees" an event, this +# means two things: the event can affect the machine, and if the machine is +# not in a state where it expects that event then it's an error.) These rules +# are: +# +# 1) The client machine sees all h11.events objects emitted by the client. +# +# 2) The server machine sees all h11.events objects emitted by the server. +# +# It also sees the client's Request event. +# +# And sometimes, server events are annotated with a _SWITCH_* event. For +# example, we can have a (Response, _SWITCH_CONNECT) event, which is +# different from a regular Response event. +# +# 3) The keep-alive machine sees the process_keep_alive_disabled() event +# (which is derived from Request/Response events), and this event +# transitions it from True -> False, or from False -> False. There's no way +# to transition back. +# +# 4&5) The _SWITCH_* machines transition from False->True when we get a +# Request that proposes the relevant type of switch (via +# process_client_switch_proposals), and they go from True->False when we +# get a Response that has no _SWITCH_* annotation. +# +# So that's event-triggered transitions. +# +# State-triggered transitions are less standard. What they do here is couple +# the machines together. The way this works is, when certain *joint* +# configurations of states are achieved, then we automatically transition to a +# new *joint* state. So, for example, if we're ever in a joint state with +# +# client: DONE +# keep-alive: False +# +# then the client state immediately transitions to: +# +# client: MUST_CLOSE +# +# This is fundamentally different from an event-based transition, because it +# doesn't matter how we arrived at the {client: DONE, keep-alive: False} state +# -- maybe the client transitioned SEND_BODY -> DONE, or keep-alive +# transitioned True -> False. Either way, once this precondition is satisfied, +# this transition is immediately triggered. +# +# What if two conflicting state-based transitions get enabled at the same +# time? In practice there's only one case where this arises (client DONE -> +# MIGHT_SWITCH_PROTOCOL versus DONE -> MUST_CLOSE), and we resolve it by +# explicitly prioritizing the DONE -> MIGHT_SWITCH_PROTOCOL transition. +# +# Implementation +# -------------- +# +# The event-triggered transitions for the server and client machines are all +# stored explicitly in a table. Ditto for the state-triggered transitions that +# involve just the server and client state. +# +# The transitions for the other machines, and the state-triggered transitions +# that involve the other machines, are written out as explicit Python code. +# +# It'd be nice if there were some cleaner way to do all this. This isn't +# *too* terrible, but I feel like it could probably be better. +# +# WARNING +# ------- +# +# The script that generates the state machine diagrams for the docs knows how +# to read out the EVENT_TRIGGERED_TRANSITIONS and STATE_TRIGGERED_TRANSITIONS +# tables. But it can't automatically read the transitions that are written +# directly in Python code. So if you touch those, you need to also update the +# script to keep it in sync! +from typing import cast, Dict, Optional, Set, Tuple, Type, Union + +from ._events import * +from ._util import LocalProtocolError, Sentinel + +# Everything in __all__ gets re-exported as part of the h11 public API. +__all__ = [ + "CLIENT", + "SERVER", + "IDLE", + "SEND_RESPONSE", + "SEND_BODY", + "DONE", + "MUST_CLOSE", + "CLOSED", + "MIGHT_SWITCH_PROTOCOL", + "SWITCHED_PROTOCOL", + "ERROR", +] + + +class CLIENT(Sentinel, metaclass=Sentinel): + pass + + +class SERVER(Sentinel, metaclass=Sentinel): + pass + + +# States +class IDLE(Sentinel, metaclass=Sentinel): + pass + + +class SEND_RESPONSE(Sentinel, metaclass=Sentinel): + pass + + +class SEND_BODY(Sentinel, metaclass=Sentinel): + pass + + +class DONE(Sentinel, metaclass=Sentinel): + pass + + +class MUST_CLOSE(Sentinel, metaclass=Sentinel): + pass + + +class CLOSED(Sentinel, metaclass=Sentinel): + pass + + +class ERROR(Sentinel, metaclass=Sentinel): + pass + + +# Switch types +class MIGHT_SWITCH_PROTOCOL(Sentinel, metaclass=Sentinel): + pass + + +class SWITCHED_PROTOCOL(Sentinel, metaclass=Sentinel): + pass + + +class _SWITCH_UPGRADE(Sentinel, metaclass=Sentinel): + pass + + +class _SWITCH_CONNECT(Sentinel, metaclass=Sentinel): + pass + + +EventTransitionType = Dict[ + Type[Sentinel], + Dict[ + Type[Sentinel], + Dict[Union[Type[Event], Tuple[Type[Event], Type[Sentinel]]], Type[Sentinel]], + ], +] + +EVENT_TRIGGERED_TRANSITIONS: EventTransitionType = { + CLIENT: { + IDLE: {Request: SEND_BODY, ConnectionClosed: CLOSED}, + SEND_BODY: {Data: SEND_BODY, EndOfMessage: DONE}, + DONE: {ConnectionClosed: CLOSED}, + MUST_CLOSE: {ConnectionClosed: CLOSED}, + CLOSED: {ConnectionClosed: CLOSED}, + MIGHT_SWITCH_PROTOCOL: {}, + SWITCHED_PROTOCOL: {}, + ERROR: {}, + }, + SERVER: { + IDLE: { + ConnectionClosed: CLOSED, + Response: SEND_BODY, + # Special case: server sees client Request events, in this form + (Request, CLIENT): SEND_RESPONSE, + }, + SEND_RESPONSE: { + InformationalResponse: SEND_RESPONSE, + Response: SEND_BODY, + (InformationalResponse, _SWITCH_UPGRADE): SWITCHED_PROTOCOL, + (Response, _SWITCH_CONNECT): SWITCHED_PROTOCOL, + }, + SEND_BODY: {Data: SEND_BODY, EndOfMessage: DONE}, + DONE: {ConnectionClosed: CLOSED}, + MUST_CLOSE: {ConnectionClosed: CLOSED}, + CLOSED: {ConnectionClosed: CLOSED}, + SWITCHED_PROTOCOL: {}, + ERROR: {}, + }, +} + +StateTransitionType = Dict[ + Tuple[Type[Sentinel], Type[Sentinel]], Dict[Type[Sentinel], Type[Sentinel]] +] + +# NB: there are also some special-case state-triggered transitions hard-coded +# into _fire_state_triggered_transitions below. +STATE_TRIGGERED_TRANSITIONS: StateTransitionType = { + # (Client state, Server state) -> new states + # Protocol negotiation + (MIGHT_SWITCH_PROTOCOL, SWITCHED_PROTOCOL): {CLIENT: SWITCHED_PROTOCOL}, + # Socket shutdown + (CLOSED, DONE): {SERVER: MUST_CLOSE}, + (CLOSED, IDLE): {SERVER: MUST_CLOSE}, + (ERROR, DONE): {SERVER: MUST_CLOSE}, + (DONE, CLOSED): {CLIENT: MUST_CLOSE}, + (IDLE, CLOSED): {CLIENT: MUST_CLOSE}, + (DONE, ERROR): {CLIENT: MUST_CLOSE}, +} + + +class ConnectionState: + def __init__(self) -> None: + # Extra bits of state that don't quite fit into the state model. + + # If this is False then it enables the automatic DONE -> MUST_CLOSE + # transition. Don't set this directly; call .keep_alive_disabled() + self.keep_alive = True + + # This is a subset of {UPGRADE, CONNECT}, containing the proposals + # made by the client for switching protocols. + self.pending_switch_proposals: Set[Type[Sentinel]] = set() + + self.states: Dict[Type[Sentinel], Type[Sentinel]] = {CLIENT: IDLE, SERVER: IDLE} + + def process_error(self, role: Type[Sentinel]) -> None: + self.states[role] = ERROR + self._fire_state_triggered_transitions() + + def process_keep_alive_disabled(self) -> None: + self.keep_alive = False + self._fire_state_triggered_transitions() + + def process_client_switch_proposal(self, switch_event: Type[Sentinel]) -> None: + self.pending_switch_proposals.add(switch_event) + self._fire_state_triggered_transitions() + + def process_event( + self, + role: Type[Sentinel], + event_type: Type[Event], + server_switch_event: Optional[Type[Sentinel]] = None, + ) -> None: + _event_type: Union[Type[Event], Tuple[Type[Event], Type[Sentinel]]] = event_type + if server_switch_event is not None: + assert role is SERVER + if server_switch_event not in self.pending_switch_proposals: + raise LocalProtocolError( + "Received server _SWITCH_UPGRADE event without a pending proposal" + ) + _event_type = (event_type, server_switch_event) + if server_switch_event is None and _event_type is Response: + self.pending_switch_proposals = set() + self._fire_event_triggered_transitions(role, _event_type) + # Special case: the server state does get to see Request + # events. + if _event_type is Request: + assert role is CLIENT + self._fire_event_triggered_transitions(SERVER, (Request, CLIENT)) + self._fire_state_triggered_transitions() + + def _fire_event_triggered_transitions( + self, + role: Type[Sentinel], + event_type: Union[Type[Event], Tuple[Type[Event], Type[Sentinel]]], + ) -> None: + state = self.states[role] + try: + new_state = EVENT_TRIGGERED_TRANSITIONS[role][state][event_type] + except KeyError: + event_type = cast(Type[Event], event_type) + raise LocalProtocolError( + "can't handle event type {} when role={} and state={}".format( + event_type.__name__, role, self.states[role] + ) + ) from None + self.states[role] = new_state + + def _fire_state_triggered_transitions(self) -> None: + # We apply these rules repeatedly until converging on a fixed point + while True: + start_states = dict(self.states) + + # It could happen that both these special-case transitions are + # enabled at the same time: + # + # DONE -> MIGHT_SWITCH_PROTOCOL + # DONE -> MUST_CLOSE + # + # For example, this will always be true of a HTTP/1.0 client + # requesting CONNECT. If this happens, the protocol switch takes + # priority. From there the client will either go to + # SWITCHED_PROTOCOL, in which case it's none of our business when + # they close the connection, or else the server will deny the + # request, in which case the client will go back to DONE and then + # from there to MUST_CLOSE. + if self.pending_switch_proposals: + if self.states[CLIENT] is DONE: + self.states[CLIENT] = MIGHT_SWITCH_PROTOCOL + + if not self.pending_switch_proposals: + if self.states[CLIENT] is MIGHT_SWITCH_PROTOCOL: + self.states[CLIENT] = DONE + + if not self.keep_alive: + for role in (CLIENT, SERVER): + if self.states[role] is DONE: + self.states[role] = MUST_CLOSE + + # Tabular state-triggered transitions + joint_state = (self.states[CLIENT], self.states[SERVER]) + changes = STATE_TRIGGERED_TRANSITIONS.get(joint_state, {}) + self.states.update(changes) + + if self.states == start_states: + # Fixed point reached + return + + def start_next_cycle(self) -> None: + if self.states != {CLIENT: DONE, SERVER: DONE}: + raise LocalProtocolError( + f"not in a reusable state. self.states={self.states}" + ) + # Can't reach DONE/DONE with any of these active, but still, let's be + # sure. + assert self.keep_alive + assert not self.pending_switch_proposals + self.states = {CLIENT: IDLE, SERVER: IDLE} diff --git a/.venv/lib/python3.13/site-packages/h11/_util.py b/.venv/lib/python3.13/site-packages/h11/_util.py new file mode 100644 index 0000000000000000000000000000000000000000..6718445290770e028ea2f1f662026c9a0b0991db --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11/_util.py @@ -0,0 +1,135 @@ +from typing import Any, Dict, NoReturn, Pattern, Tuple, Type, TypeVar, Union + +__all__ = [ + "ProtocolError", + "LocalProtocolError", + "RemoteProtocolError", + "validate", + "bytesify", +] + + +class ProtocolError(Exception): + """Exception indicating a violation of the HTTP/1.1 protocol. + + This as an abstract base class, with two concrete base classes: + :exc:`LocalProtocolError`, which indicates that you tried to do something + that HTTP/1.1 says is illegal, and :exc:`RemoteProtocolError`, which + indicates that the remote peer tried to do something that HTTP/1.1 says is + illegal. See :ref:`error-handling` for details. + + In addition to the normal :exc:`Exception` features, it has one attribute: + + .. attribute:: error_status_hint + + This gives a suggestion as to what status code a server might use if + this error occurred as part of a request. + + For a :exc:`RemoteProtocolError`, this is useful as a suggestion for + how you might want to respond to a misbehaving peer, if you're + implementing a server. + + For a :exc:`LocalProtocolError`, this can be taken as a suggestion for + how your peer might have responded to *you* if h11 had allowed you to + continue. + + The default is 400 Bad Request, a generic catch-all for protocol + violations. + + """ + + def __init__(self, msg: str, error_status_hint: int = 400) -> None: + if type(self) is ProtocolError: + raise TypeError("tried to directly instantiate ProtocolError") + Exception.__init__(self, msg) + self.error_status_hint = error_status_hint + + +# Strategy: there are a number of public APIs where a LocalProtocolError can +# be raised (send(), all the different event constructors, ...), and only one +# public API where RemoteProtocolError can be raised +# (receive_data()). Therefore we always raise LocalProtocolError internally, +# and then receive_data will translate this into a RemoteProtocolError. +# +# Internally: +# LocalProtocolError is the generic "ProtocolError". +# Externally: +# LocalProtocolError is for local errors and RemoteProtocolError is for +# remote errors. +class LocalProtocolError(ProtocolError): + def _reraise_as_remote_protocol_error(self) -> NoReturn: + # After catching a LocalProtocolError, use this method to re-raise it + # as a RemoteProtocolError. This method must be called from inside an + # except: block. + # + # An easy way to get an equivalent RemoteProtocolError is just to + # modify 'self' in place. + self.__class__ = RemoteProtocolError # type: ignore + # But the re-raising is somewhat non-trivial -- you might think that + # now that we've modified the in-flight exception object, that just + # doing 'raise' to re-raise it would be enough. But it turns out that + # this doesn't work, because Python tracks the exception type + # (exc_info[0]) separately from the exception object (exc_info[1]), + # and we only modified the latter. So we really do need to re-raise + # the new type explicitly. + # On py3, the traceback is part of the exception object, so our + # in-place modification preserved it and we can just re-raise: + raise self + + +class RemoteProtocolError(ProtocolError): + pass + + +def validate( + regex: Pattern[bytes], data: bytes, msg: str = "malformed data", *format_args: Any +) -> Dict[str, bytes]: + match = regex.fullmatch(data) + if not match: + if format_args: + msg = msg.format(*format_args) + raise LocalProtocolError(msg) + return match.groupdict() + + +# Sentinel values +# +# - Inherit identity-based comparison and hashing from object +# - Have a nice repr +# - Have a *bonus property*: type(sentinel) is sentinel +# +# The bonus property is useful if you want to take the return value from +# next_event() and do some sort of dispatch based on type(event). + +_T_Sentinel = TypeVar("_T_Sentinel", bound="Sentinel") + + +class Sentinel(type): + def __new__( + cls: Type[_T_Sentinel], + name: str, + bases: Tuple[type, ...], + namespace: Dict[str, Any], + **kwds: Any + ) -> _T_Sentinel: + assert bases == (Sentinel,) + v = super().__new__(cls, name, bases, namespace, **kwds) + v.__class__ = v # type: ignore + return v + + def __repr__(self) -> str: + return self.__name__ + + +# Used for methods, request targets, HTTP versions, header names, and header +# values. Accepts ascii-strings, or bytes/bytearray/memoryview/..., and always +# returns bytes. +def bytesify(s: Union[bytes, bytearray, memoryview, int, str]) -> bytes: + # Fast-path: + if type(s) is bytes: + return s + if isinstance(s, str): + s = s.encode("ascii") + if isinstance(s, int): + raise TypeError("expected bytes-like object, not int") + return bytes(s) diff --git a/.venv/lib/python3.13/site-packages/h11/_version.py b/.venv/lib/python3.13/site-packages/h11/_version.py new file mode 100644 index 0000000000000000000000000000000000000000..76e7327b8617c9d12236f511414d5eb58e98a44b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11/_version.py @@ -0,0 +1,16 @@ +# This file must be kept very simple, because it is consumed from several +# places -- it is imported by h11/__init__.py, execfile'd by setup.py, etc. + +# We use a simple scheme: +# 1.0.0 -> 1.0.0+dev -> 1.1.0 -> 1.1.0+dev +# where the +dev versions are never released into the wild, they're just what +# we stick into the VCS in between releases. +# +# This is compatible with PEP 440: +# http://legacy.python.org/dev/peps/pep-0440/ +# via the use of the "local suffix" "+dev", which is disallowed on index +# servers and causes 1.0.0+dev to sort after plain 1.0.0, which is what we +# want. (Contrast with the special suffix 1.0.0.dev, which sorts *before* +# 1.0.0.) + +__version__ = "0.16.0" diff --git a/.venv/lib/python3.13/site-packages/h11/_writers.py b/.venv/lib/python3.13/site-packages/h11/_writers.py new file mode 100644 index 0000000000000000000000000000000000000000..939cdb912a9debaea07fbf3a9ac04549c44d077c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11/_writers.py @@ -0,0 +1,145 @@ +# Code to read HTTP data +# +# Strategy: each writer takes an event + a write-some-bytes function, which is +# calls. +# +# WRITERS is a dict describing how to pick a reader. It maps states to either: +# - a writer +# - or, for body writers, a dict of framin-dependent writer factories + +from typing import Any, Callable, Dict, List, Tuple, Type, Union + +from ._events import Data, EndOfMessage, Event, InformationalResponse, Request, Response +from ._headers import Headers +from ._state import CLIENT, IDLE, SEND_BODY, SEND_RESPONSE, SERVER +from ._util import LocalProtocolError, Sentinel + +__all__ = ["WRITERS"] + +Writer = Callable[[bytes], Any] + + +def write_headers(headers: Headers, write: Writer) -> None: + # "Since the Host field-value is critical information for handling a + # request, a user agent SHOULD generate Host as the first header field + # following the request-line." - RFC 7230 + raw_items = headers._full_items + for raw_name, name, value in raw_items: + if name == b"host": + write(b"%s: %s\r\n" % (raw_name, value)) + for raw_name, name, value in raw_items: + if name != b"host": + write(b"%s: %s\r\n" % (raw_name, value)) + write(b"\r\n") + + +def write_request(request: Request, write: Writer) -> None: + if request.http_version != b"1.1": + raise LocalProtocolError("I only send HTTP/1.1") + write(b"%s %s HTTP/1.1\r\n" % (request.method, request.target)) + write_headers(request.headers, write) + + +# Shared between InformationalResponse and Response +def write_any_response( + response: Union[InformationalResponse, Response], write: Writer +) -> None: + if response.http_version != b"1.1": + raise LocalProtocolError("I only send HTTP/1.1") + status_bytes = str(response.status_code).encode("ascii") + # We don't bother sending ascii status messages like "OK"; they're + # optional and ignored by the protocol. (But the space after the numeric + # status code is mandatory.) + # + # XX FIXME: could at least make an effort to pull out the status message + # from stdlib's http.HTTPStatus table. Or maybe just steal their enums + # (either by import or copy/paste). We already accept them as status codes + # since they're of type IntEnum < int. + write(b"HTTP/1.1 %s %s\r\n" % (status_bytes, response.reason)) + write_headers(response.headers, write) + + +class BodyWriter: + def __call__(self, event: Event, write: Writer) -> None: + if type(event) is Data: + self.send_data(event.data, write) + elif type(event) is EndOfMessage: + self.send_eom(event.headers, write) + else: # pragma: no cover + assert False + + def send_data(self, data: bytes, write: Writer) -> None: + pass + + def send_eom(self, headers: Headers, write: Writer) -> None: + pass + + +# +# These are all careful not to do anything to 'data' except call len(data) and +# write(data). This allows us to transparently pass-through funny objects, +# like placeholder objects referring to files on disk that will be sent via +# sendfile(2). +# +class ContentLengthWriter(BodyWriter): + def __init__(self, length: int) -> None: + self._length = length + + def send_data(self, data: bytes, write: Writer) -> None: + self._length -= len(data) + if self._length < 0: + raise LocalProtocolError("Too much data for declared Content-Length") + write(data) + + def send_eom(self, headers: Headers, write: Writer) -> None: + if self._length != 0: + raise LocalProtocolError("Too little data for declared Content-Length") + if headers: + raise LocalProtocolError("Content-Length and trailers don't mix") + + +class ChunkedWriter(BodyWriter): + def send_data(self, data: bytes, write: Writer) -> None: + # if we encoded 0-length data in the naive way, it would look like an + # end-of-message. + if not data: + return + write(b"%x\r\n" % len(data)) + write(data) + write(b"\r\n") + + def send_eom(self, headers: Headers, write: Writer) -> None: + write(b"0\r\n") + write_headers(headers, write) + + +class Http10Writer(BodyWriter): + def send_data(self, data: bytes, write: Writer) -> None: + write(data) + + def send_eom(self, headers: Headers, write: Writer) -> None: + if headers: + raise LocalProtocolError("can't send trailers to HTTP/1.0 client") + # no need to close the socket ourselves, that will be taken care of by + # Connection: close machinery + + +WritersType = Dict[ + Union[Tuple[Type[Sentinel], Type[Sentinel]], Type[Sentinel]], + Union[ + Dict[str, Type[BodyWriter]], + Callable[[Union[InformationalResponse, Response], Writer], None], + Callable[[Request, Writer], None], + ], +] + +WRITERS: WritersType = { + (CLIENT, IDLE): write_request, + (SERVER, IDLE): write_any_response, + (SERVER, SEND_RESPONSE): write_any_response, + SEND_BODY: { + "chunked": ChunkedWriter, + "content-length": ContentLengthWriter, + "http/1.0": Http10Writer, + }, +} diff --git a/.venv/lib/python3.13/site-packages/h11/py.typed b/.venv/lib/python3.13/site-packages/h11/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..f5642f79f21d872f010979dcf6f0c4a415acc19d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/h11/py.typed @@ -0,0 +1 @@ +Marker diff --git a/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/INSTALLER b/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/METADATA b/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..1d0a6947a9e9362d8d32d5ad3b6ff4999a90342f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/METADATA @@ -0,0 +1,87 @@ +Metadata-Version: 2.4 +Name: hf-xet +Version: 1.5.1 +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Programming Language :: Rust +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.8 +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 :: 3.14 +Classifier: Programming Language :: Python :: Free Threading +Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta +Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence +Requires-Dist: pytest ; extra == 'tests' +Provides-Extra: tests +License-File: LICENSE +Summary: Fast transfer of large files with the Hugging Face Hub. +Maintainer-email: Rajat Arya , Jared Sulzdorf , Di Xiao , Assaf Vayner , Hoyt Koepke +License-Expression: Apache-2.0 +Requires-Python: >=3.8 +Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM +Project-URL: Documentation, https://huggingface.co/docs/hub/xet/index +Project-URL: Homepage, https://github.com/huggingface/xet-core +Project-URL: Issues, https://github.com/huggingface/xet-core/issues +Project-URL: Repository, https://github.com/huggingface/xet-core.git + + +

+ License + GitHub release + Contributor Covenant +

+ +

+

🤗 hf-xet - xet client tech, used in huggingface_hub

+

+ +## Welcome + +`hf-xet` enables `huggingface_hub` to utilize xet storage for uploading and downloading to HF Hub. Xet storage provides chunk-based deduplication, efficient storage/retrieval with local disk caching, and backwards compatibility with Git LFS. This library is not meant to be used directly, and is instead intended to be used from [huggingface_hub](https://pypi.org/project/huggingface-hub). + +## Key features + +♻ **chunk-based deduplication implementation**: avoid transferring and storing chunks that are shared across binary files (models, datasets, etc). + +🤗 **Python bindings**: bindings for [huggingface_hub](https://github.com/huggingface/huggingface_hub/) package. + +↔ **network communications**: concurrent communication to HF Hub Xet backend services (CAS). + +🔖 **local disk caching**: chunk-based cache that sits alongside the existing [huggingface_hub disk cache](https://huggingface.co/docs/huggingface_hub/guides/manage-cache). + +## Installation + +Install the `hf_xet` package with [pip](https://pypi.org/project/hf-xet/): + +```bash +pip install hf_xet +``` + +## Quick Start + +`hf_xet` is not intended to be run independently as it is expected to be used from `huggingface_hub`, so to get started with `huggingface_hub` check out the documentation [here]("https://hf.co/docs/huggingface_hub"). + +## Contributions (feature requests, bugs, etc.) are encouraged & appreciated 💙💚💛💜🧡❤️ + +Please join us in making hf-xet better. We value everyone's contributions. Code is not the only way to help. Answering questions, helping each other, improving documentation, filing issues all help immensely. If you are interested in contributing (please do!), check out the [contribution guide](https://github.com/huggingface/xet-core/blob/main/CONTRIBUTING.md) for this repository. diff --git a/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/RECORD b/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..dd0c7c997dc63a93afad9d9e69f6a93d6d3cb586 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/RECORD @@ -0,0 +1,9 @@ +hf_xet-1.5.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +hf_xet-1.5.1.dist-info/METADATA,sha256=Ng3NIurLVmsxfHrQzB0hVplUWdfDjyPgOB1vV43zU9s,4882 +hf_xet-1.5.1.dist-info/RECORD,, +hf_xet-1.5.1.dist-info/WHEEL,sha256=OkX4wPsZin6E8CKOzxYqaTQ7om8YEJGkDJxzf2dJ9DM,143 +hf_xet-1.5.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357 +hf_xet-1.5.1.dist-info/sboms/hf_xet.cyclonedx.json,sha256=qwtR4a6GgW2Y-ybzx9ThgMyHXF11N79IyEWcWf1CeBw,304991 +hf_xet/__init__.py,sha256=E8UDdyQ8glZ_nve9hHEf22bPang8-RKx4VuApXYeQUo,107 +hf_xet/__pycache__/__init__.cpython-313.pyc,, +hf_xet/hf_xet.abi3.so,sha256=67AVYfNTLATTgxnYRWZSV5vBoS_6j1FFDErdBM-hhTY,11601472 diff --git a/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/WHEEL b/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..47ba96185f16b33e1d135b1d1ac1b9d7be9ddfbd --- /dev/null +++ b/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: maturin (1.13.3) +Root-Is-Purelib: false +Tag: cp37-abi3-manylinux_2_17_x86_64 +Tag: cp37-abi3-manylinux2014_x86_64 diff --git a/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/licenses/LICENSE b/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/licenses/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/licenses/LICENSE @@ -0,0 +1,201 @@ + 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/python3.13/site-packages/hf_xet-1.5.1.dist-info/sboms/hf_xet.cyclonedx.json b/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/sboms/hf_xet.cyclonedx.json new file mode 100644 index 0000000000000000000000000000000000000000..0fc3ee19e170627aec1ff9e81f75be4d63d4c963 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/hf_xet-1.5.1.dist-info/sboms/hf_xet.cyclonedx.json @@ -0,0 +1,9387 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "version": 1, + "serialNumber": "urn:uuid:80a47879-2909-4049-b9ad-942e737a7962", + "metadata": { + "timestamp": "2026-06-08T22:47:15.676232212Z", + "tools": [ + { + "vendor": "CycloneDX", + "name": "cargo-cyclonedx", + "version": "0.5.9" + } + ], + "component": { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/hf_xet#1.5.1", + "name": "hf_xet", + "version": "1.5.1", + "scope": "required", + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/hf_xet@1.5.1?download_url=file://.", + "components": [ + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/hf_xet#1.5.1 bin-target-0", + "name": "hf_xet", + "version": "1.5.1", + "purl": "pkg:cargo/hf_xet@1.5.1?download_url=file://.#src/lib.rs" + } + ] + }, + "properties": [ + { + "name": "cdx:rustc:sbom:target:all_targets", + "value": "true" + } + ] + }, + "components": [ + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/xet_client#xet-client@1.5.2", + "name": "xet-client", + "version": "1.5.2", + "description": "Client library for communicating with Hugging Face Xet storage servers. Use through the hf-xet crate.", + "scope": "required", + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/xet-client@1.5.2?download_url=file:///home/runner/work/xet-core/xet-core/xet_client", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/huggingface/xet-core" + }, + { + "type": "vcs", + "url": "https://github.com/huggingface/xet-core" + } + ] + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/xet_core_structures#xet-core-structures@1.5.2", + "name": "xet-core-structures", + "version": "1.5.2", + "description": "Core data structures including MerkleHash, metadata shards, and Xorb objects.", + "scope": "required", + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/xet-core-structures@1.5.2?download_url=file:///home/runner/work/xet-core/xet-core/xet_core_structures", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/huggingface/xet-core" + }, + { + "type": "vcs", + "url": "https://github.com/huggingface/xet-core" + } + ] + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/xet_data#xet-data@1.5.2", + "name": "xet-data", + "version": "1.5.2", + "description": "Data processing pipeline for chunking, deduplication, and file reconstruction; used in the Hugging Face Xet client tools. Intended to be used through the API in the hf-xet package.", + "scope": "required", + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/xet-data@1.5.2?download_url=file:///home/runner/work/xet-core/xet-core/xet_data", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/huggingface/xet-core" + }, + { + "type": "vcs", + "url": "https://github.com/huggingface/xet-core" + } + ] + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/xet_pkg#hf-xet@1.5.2", + "name": "hf-xet", + "version": "1.5.2", + "description": "Client library and tooling for the Hugging Face Xet data storage system.", + "scope": "required", + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/hf-xet@1.5.2?download_url=file:///home/runner/work/xet-core/xet-core/xet_pkg", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/huggingface/xet-core" + }, + { + "type": "vcs", + "url": "https://github.com/huggingface/xet-core" + } + ] + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#xet-runtime@1.5.2", + "name": "xet-runtime", + "version": "1.5.2", + "description": "Async runtime, configuration, logging, and utility infrastructure for the Hugging Face Xet client tools.", + "scope": "required", + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/xet-runtime@1.5.2?download_url=file:///home/runner/work/xet-core/xet-core/xet_runtime", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/huggingface/xet-core" + }, + { + "type": "vcs", + "url": "https://github.com/huggingface/xet-core" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#aho-corasick@1.1.4", + "author": "Andrew Gallant ", + "name": "aho-corasick", + "version": "1.1.4", + "description": "Fast multiple substring searching.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" + } + ], + "licenses": [ + { + "expression": "Unlicense OR MIT" + } + ], + "purl": "pkg:cargo/aho-corasick@1.1.4", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/BurntSushi/aho-corasick" + }, + { + "type": "vcs", + "url": "https://github.com/BurntSushi/aho-corasick" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#anstream@1.0.0", + "name": "anstream", + "version": "1.0.0", + "description": "IO stream adapters for writing colored text that will gracefully degrade according to your terminal's capabilities.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/anstream@1.0.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-cli/anstyle.git" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#anstyle-parse@1.0.0", + "name": "anstyle-parse", + "version": "1.0.0", + "description": "Parse ANSI Style Escapes", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/anstyle-parse@1.0.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-cli/anstyle.git" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#anstyle-query@1.1.5", + "name": "anstyle-query", + "version": "1.1.5", + "description": "Look up colored console capabilities", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/anstyle-query@1.1.5", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-cli/anstyle.git" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#anstyle@1.0.14", + "name": "anstyle", + "version": "1.0.14", + "description": "ANSI text styling", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/anstyle@1.0.14", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-cli/anstyle.git" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.102", + "author": "David Tolnay ", + "name": "anyhow", + "version": "1.0.102", + "description": "Flexible concrete Error type built on std::error::Error", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/anyhow@1.0.102", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/anyhow" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/anyhow" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#approx@0.5.1", + "author": "Brendan Zabarauskas ", + "name": "approx", + "version": "0.5.1", + "description": "Approximate floating point equality comparisons and assertions.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" + } + ], + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/approx@0.5.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/approx" + }, + { + "type": "website", + "url": "https://github.com/brendanzab/approx" + }, + { + "type": "vcs", + "url": "https://github.com/brendanzab/approx" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#arrayref@0.3.9", + "author": "David Roundy ", + "name": "arrayref", + "version": "0.3.9", + "description": "Macros to take array references of slices", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + } + ], + "licenses": [ + { + "expression": "BSD-2-Clause" + } + ], + "purl": "pkg:cargo/arrayref@0.3.9", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/arrayref" + }, + { + "type": "vcs", + "url": "https://github.com/droundy/arrayref" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#arrayvec@0.7.6", + "author": "bluss", + "name": "arrayvec", + "version": "0.7.6", + "description": "A vector with fixed capacity, backed by an array (it can be stored on the stack too). Implements fixed capacity ArrayVec and ArrayString.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/arrayvec@0.7.6", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/arrayvec/" + }, + { + "type": "vcs", + "url": "https://github.com/bluss/arrayvec" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "author": "David Tolnay ", + "name": "async-trait", + "version": "0.1.89", + "description": "Type erasure for async trait methods", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/async-trait@0.1.89", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/async-trait" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/async-trait" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#atomic-waker@1.1.2", + "author": "Stjepan Glavina , Contributors to futures-rs", + "name": "atomic-waker", + "version": "1.1.2", + "description": "A synchronization primitive for task wakeup", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/atomic-waker@1.1.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/smol-rs/atomic-waker" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#autocfg@1.5.0", + "author": "Josh Stone ", + "name": "autocfg", + "version": "1.5.0", + "description": "Automatic cfg for Rust compiler features", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/autocfg@1.5.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/autocfg/" + }, + { + "type": "vcs", + "url": "https://github.com/cuviper/autocfg" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#aws-lc-rs@1.16.2", + "author": "AWS-LibCrypto", + "name": "aws-lc-rs", + "version": "1.16.2", + "description": "aws-lc-rs is a cryptographic library using AWS-LC for its cryptographic operations. This library strives to be API-compatible with the popular Rust library named ring.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc" + } + ], + "licenses": [ + { + "expression": "ISC AND (Apache-2.0 OR ISC)" + } + ], + "purl": "pkg:cargo/aws-lc-rs@1.16.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/crate/aws-lc-rs" + }, + { + "type": "website", + "url": "https://github.com/aws/aws-lc-rs" + }, + { + "type": "other", + "url": "aws_lc_rs_1_16_2_sys" + }, + { + "type": "vcs", + "url": "https://github.com/aws/aws-lc-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#aws-lc-sys@0.39.0", + "author": "AWS-LC", + "name": "aws-lc-sys", + "version": "0.39.0", + "description": "AWS-LC is a general-purpose cryptographic library maintained by the AWS Cryptography team for AWS and their customers. It іs based on code from the Google BoringSSL project and the OpenSSL project.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1fa7e52a4c5c547c741610a2c6f123f3881e409b714cd27e6798ef020c514f0a" + } + ], + "licenses": [ + { + "expression": "ISC AND (Apache-2.0 OR ISC) AND Apache-2.0 AND MIT AND BSD-3-Clause AND (Apache-2.0 OR ISC OR MIT) AND (Apache-2.0 OR ISC OR MIT-0)" + } + ], + "purl": "pkg:cargo/aws-lc-sys@0.39.0", + "externalReferences": [ + { + "type": "other", + "url": "aws_lc_0_39_0" + }, + { + "type": "vcs", + "url": "https://github.com/aws/aws-lc-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1", + "author": "Marshall Pierce ", + "name": "base64", + "version": "0.22.1", + "description": "encodes and decodes base64 as bytes or utf8", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/base64@0.22.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/base64" + }, + { + "type": "vcs", + "url": "https://github.com/marshallpierce/rust-base64" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#bitflags@2.11.0", + "author": "The Rust Project Developers", + "name": "bitflags", + "version": "2.11.0", + "description": "A macro to generate structures which behave like bitflags. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/bitflags@2.11.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/bitflags" + }, + { + "type": "website", + "url": "https://github.com/bitflags/bitflags" + }, + { + "type": "vcs", + "url": "https://github.com/bitflags/bitflags" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#blake3@1.8.3", + "author": "Jack O'Connor , Samuel Neves", + "name": "blake3", + "version": "1.8.3", + "description": "the BLAKE3 hash function", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2468ef7d57b3fb7e16b576e8377cdbde2320c60e1491e961d11da40fc4f02a2d" + } + ], + "licenses": [ + { + "expression": "CC0-1.0 OR Apache-2.0 OR Apache-2.0 WITH LLVM-exception" + } + ], + "purl": "pkg:cargo/blake3@1.8.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/blake3" + }, + { + "type": "vcs", + "url": "https://github.com/BLAKE3-team/BLAKE3" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#block-buffer@0.10.4", + "author": "RustCrypto Developers", + "name": "block-buffer", + "version": "0.10.4", + "description": "Buffer type for block processing of data", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/block-buffer@0.10.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/block-buffer" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/utils" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#bstr@1.12.1", + "author": "Andrew Gallant ", + "name": "bstr", + "version": "1.12.1", + "description": "A string type that is not required to be valid UTF-8.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/bstr@1.12.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/bstr" + }, + { + "type": "website", + "url": "https://github.com/BurntSushi/bstr" + }, + { + "type": "vcs", + "url": "https://github.com/BurntSushi/bstr" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#bytemuck@1.25.0", + "author": "Lokathor ", + "name": "bytemuck", + "version": "1.25.0", + "description": "A crate for mucking around with piles of bytes.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" + } + ], + "licenses": [ + { + "expression": "Zlib OR Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/bytemuck@1.25.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Lokathor/bytemuck" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "author": "Carl Lerche , Sean McArthur ", + "name": "bytes", + "version": "1.11.1", + "description": "Types and traits for working with bytes", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/bytes@1.11.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/tokio-rs/bytes" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.57", + "author": "Alex Crichton ", + "name": "cc", + "version": "1.2.57", + "description": "A build-time dependency for Cargo build scripts to assist in invoking the native C compiler to compile native C code into a static archive to be linked into Rust code. ", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/cc@1.2.57", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/cc" + }, + { + "type": "website", + "url": "https://github.com/rust-lang/cc-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/cc-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cfg-if@0.1.10", + "author": "Alex Crichton ", + "name": "cfg-if", + "version": "0.1.10", + "description": "A macro to ergonomically define an item depending on a large number of #[cfg] parameters. Structured like an if-else chain, the first matching branch is the item that gets emitted. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/cfg-if@0.1.10", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/cfg-if" + }, + { + "type": "website", + "url": "https://github.com/alexcrichton/cfg-if" + }, + { + "type": "vcs", + "url": "https://github.com/alexcrichton/cfg-if" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "author": "Alex Crichton ", + "name": "cfg-if", + "version": "1.0.4", + "description": "A macro to ergonomically define an item depending on a large number of #[cfg] parameters. Structured like an if-else chain, the first matching branch is the item that gets emitted. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/cfg-if@1.0.4", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-lang/cfg-if" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cfg_aliases@0.2.1", + "author": "Zicklag ", + "name": "cfg_aliases", + "version": "0.2.1", + "description": "A tiny utility to help save you a lot of effort with long winded `#[cfg()]` checks.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/cfg_aliases@0.2.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/cfg_aliases" + }, + { + "type": "website", + "url": "https://github.com/katharostech/cfg_aliases" + }, + { + "type": "vcs", + "url": "https://github.com/katharostech/cfg_aliases" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#chacha20@0.10.0", + "author": "RustCrypto Developers", + "name": "chacha20", + "version": "0.10.0", + "description": "The ChaCha20 stream cipher (RFC 8439) implemented in pure Rust using traits from the RustCrypto `cipher` crate, with optional architecture-specific hardware acceleration (AVX2, SSE2). Additionally provides the ChaCha8, ChaCha12, XChaCha20, XChaCha12 and XChaCha8 stream ciphers, and also optional rand_core-compatible RNGs based on those ciphers. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/chacha20@0.10.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/chacha20" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/stream-ciphers" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.44", + "name": "chrono", + "version": "0.4.44", + "description": "Date and time library for Rust", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/chrono@0.4.44", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/chrono/" + }, + { + "type": "website", + "url": "https://github.com/chronotope/chrono" + }, + { + "type": "vcs", + "url": "https://github.com/chronotope/chrono" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#clap@4.6.0", + "name": "clap", + "version": "4.6.0", + "description": "A simple to use, efficient, and full-featured Command Line Argument Parser", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/clap@4.6.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/clap-rs/clap" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#clap_builder@4.6.0", + "name": "clap_builder", + "version": "4.6.0", + "description": "A simple to use, efficient, and full-featured Command Line Argument Parser", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/clap_builder@4.6.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/clap-rs/clap" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#clap_derive@4.6.0", + "name": "clap_derive", + "version": "4.6.0", + "description": "Parse command line argument by defining a struct, derive crate.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/clap_derive@4.6.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/clap-rs/clap" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#clap_lex@1.1.0", + "name": "clap_lex", + "version": "1.1.0", + "description": "Minimal, flexible command line parser", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/clap_lex@1.1.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/clap-rs/clap" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cmake@0.1.57", + "author": "Alex Crichton ", + "name": "cmake", + "version": "0.1.57", + "description": "A build dependency for running `cmake` to build a native library ", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/cmake@0.1.57", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/cmake" + }, + { + "type": "website", + "url": "https://github.com/rust-lang/cmake-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/cmake-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#colorchoice@1.0.5", + "name": "colorchoice", + "version": "1.0.5", + "description": "Global override of color control", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/colorchoice@1.0.5", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-cli/anstyle.git" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#colored@3.1.1", + "author": "Thomas Wickham ", + "name": "colored", + "version": "3.1.1", + "description": "The most simple way to add colors in your terminal", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" + } + ], + "licenses": [ + { + "expression": "MPL-2.0" + } + ], + "purl": "pkg:cargo/colored@3.1.1", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/mackwic/colored" + }, + { + "type": "vcs", + "url": "https://github.com/mackwic/colored" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#const-str@1.1.0", + "author": "Nugine ", + "name": "const-str", + "version": "1.1.0", + "description": "compile-time string operations", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "18f12cc9948ed9604230cdddc7c86e270f9401ccbe3c2e98a4378c5e7632212f" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/const-str@1.1.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Nugine/const-str" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#const_panic@0.2.15", + "author": "rodrimati1992 ", + "name": "const_panic", + "version": "0.2.15", + "description": "const panic with formatting", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e262cdaac42494e3ae34c43969f9cdeb7da178bdb4b66fa6a1ea2edb4c8ae652" + } + ], + "licenses": [ + { + "expression": "Zlib" + } + ], + "purl": "pkg:cargo/const_panic@0.2.15", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rodrimati1992/const_panic/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#constant_time_eq@0.4.2", + "author": "Cesar Eduardo Barros ", + "name": "constant_time_eq", + "version": "0.4.2", + "description": "Compares two equal-sized byte strings in constant time.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" + } + ], + "licenses": [ + { + "expression": "CC0-1.0 OR MIT-0 OR Apache-2.0" + } + ], + "purl": "pkg:cargo/constant_time_eq@0.4.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/constant_time_eq" + }, + { + "type": "vcs", + "url": "https://github.com/cesarb/constant_time_eq" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#countio@0.3.0", + "author": "Oleh Martsokha ", + "name": "countio", + "version": "0.3.0", + "description": "Byte counting for std::io::{Read, Write, Seek} and its async variants from futures and tokio. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b9702aee5d1d744c01d82f6915644f950f898e014903385464c773b96fefdecb" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/countio@0.3.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/countio" + }, + { + "type": "website", + "url": "https://github.com/spire-rs/countio" + }, + { + "type": "vcs", + "url": "https://github.com/spire-rs/countio" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.17", + "author": "RustCrypto Developers", + "name": "cpufeatures", + "version": "0.2.17", + "description": "Lightweight runtime CPU feature detection for aarch64, loongarch64, and x86/x86_64 targets, with no_std support and support for mobile targets including Android and iOS ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/cpufeatures@0.2.17", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/cpufeatures" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/utils" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.3.0", + "author": "RustCrypto Developers", + "name": "cpufeatures", + "version": "0.3.0", + "description": "Lightweight runtime CPU feature detection for aarch64, loongarch64, and x86/x86_64 targets, with no_std support and support for mobile targets including Android and iOS ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/cpufeatures@0.3.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/cpufeatures" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/utils" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#crc32fast@1.5.0", + "author": "Sam Rijs , Alex Crichton ", + "name": "crc32fast", + "version": "1.5.0", + "description": "Fast, SIMD-accelerated CRC32 (IEEE) checksum computation", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/crc32fast@1.5.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/srijs/rust-crc32fast" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#crossbeam-channel@0.5.15", + "name": "crossbeam-channel", + "version": "0.5.15", + "description": "Multi-producer multi-consumer channels for message passing", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/crossbeam-channel@0.5.15", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel" + }, + { + "type": "vcs", + "url": "https://github.com/crossbeam-rs/crossbeam" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.21", + "name": "crossbeam-utils", + "version": "0.8.21", + "description": "Utilities for concurrent programming", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/crossbeam-utils@0.8.21", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-utils" + }, + { + "type": "vcs", + "url": "https://github.com/crossbeam-rs/crossbeam" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#crypto-common@0.1.7", + "author": "RustCrypto Developers", + "name": "crypto-common", + "version": "0.1.7", + "description": "Common cryptographic traits", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/crypto-common@0.1.7", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/crypto-common" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/traits" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#csv-core@0.1.13", + "author": "Andrew Gallant ", + "name": "csv-core", + "version": "0.1.13", + "description": "Bare bones CSV parsing with no_std support.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" + } + ], + "licenses": [ + { + "expression": "Unlicense OR MIT" + } + ], + "purl": "pkg:cargo/csv-core@0.1.13", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/csv-core" + }, + { + "type": "website", + "url": "https://github.com/BurntSushi/rust-csv" + }, + { + "type": "vcs", + "url": "https://github.com/BurntSushi/rust-csv" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#csv@1.4.0", + "author": "Andrew Gallant ", + "name": "csv", + "version": "1.4.0", + "description": "Fast CSV parsing with support for serde.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" + } + ], + "licenses": [ + { + "expression": "Unlicense OR MIT" + } + ], + "purl": "pkg:cargo/csv@1.4.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/csv" + }, + { + "type": "website", + "url": "https://github.com/BurntSushi/rust-csv" + }, + { + "type": "vcs", + "url": "https://github.com/BurntSushi/rust-csv" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ctor@1.0.3", + "author": "Matt Mastracci ", + "name": "ctor", + "version": "1.0.3", + "description": "Global, no_std-compatible constructors for all platforms that run before main (like C/C++ __attribute__((constructor)))", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "5c24d2b2b7c12a2fffb7c5c8fd0dcda7ca14b4600fa2d3701b6079aefb6fa180" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/ctor@1.0.3", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/mmastrac/linktime" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#deranged@0.5.8", + "author": "Jacob Pratt ", + "name": "deranged", + "version": "0.5.8", + "description": "Ranged integers", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/deranged@0.5.8", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/jhpratt/deranged" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#digest@0.10.7", + "author": "RustCrypto Developers", + "name": "digest", + "version": "0.10.7", + "description": "Traits for cryptographic hash functions and message authentication codes", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/digest@0.10.7", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/digest" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/traits" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#dirs-sys@0.5.0", + "author": "Simon Ochsenreither ", + "name": "dirs-sys", + "version": "0.5.0", + "description": "System-level helper functions for the dirs and directories crates.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/dirs-sys@0.5.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/dirs-dev/dirs-sys-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#dirs@6.0.0", + "author": "Simon Ochsenreither ", + "name": "dirs", + "version": "6.0.0", + "description": "A tiny low-level library that provides platform-specific standard locations of directories for config, cache and other data on Linux, Windows, macOS and Redox by leveraging the mechanisms defined by the XDG base/user directory specifications on Linux, the Known Folder API on Windows, and the Standard Directory guidelines on macOS.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/dirs@6.0.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/soc/dirs-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5", + "author": "Jane Lusby ", + "name": "displaydoc", + "version": "0.2.5", + "description": "A derive macro for implementing the display Trait via a doc comment and string interpolation ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/displaydoc@0.2.5", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/displaydoc" + }, + { + "type": "website", + "url": "https://github.com/yaahc/displaydoc" + }, + { + "type": "vcs", + "url": "https://github.com/yaahc/displaydoc" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#dunce@1.0.5", + "author": "Kornel ", + "name": "dunce", + "version": "1.0.5", + "description": "Normalize Windows paths to the most compatible format, avoiding UNC where possible", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + } + ], + "licenses": [ + { + "expression": "CC0-1.0 OR MIT-0 OR Apache-2.0" + } + ], + "purl": "pkg:cargo/dunce@1.0.5", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/dunce" + }, + { + "type": "website", + "url": "https://lib.rs/crates/dunce" + }, + { + "type": "vcs", + "url": "https://gitlab.com/kornelski/dunce" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#either@1.15.0", + "author": "bluss", + "name": "either", + "version": "1.15.0", + "description": "The enum `Either` with variants `Left` and `Right` is a general purpose sum type with two cases. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/either@1.15.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/either/1/" + }, + { + "type": "vcs", + "url": "https://github.com/rayon-rs/either" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#errno@0.3.14", + "author": "Chris Wong , Dan Gohman ", + "name": "errno", + "version": "0.3.14", + "description": "Cross-platform interface to the `errno` variable.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/errno@0.3.14", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/errno" + }, + { + "type": "vcs", + "url": "https://github.com/lambda-fairy/rust-errno" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#fastrand@2.3.0", + "author": "Stjepan Glavina ", + "name": "fastrand", + "version": "2.3.0", + "description": "A simple and fast random number generator", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/fastrand@2.3.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/smol-rs/fastrand" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#find-msvc-tools@0.1.9", + "name": "find-msvc-tools", + "version": "0.1.9", + "description": "Find windows-specific tools, read MSVC versions from the registry and from COM interfaces", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/find-msvc-tools@0.1.9", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/find-msvc-tools" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/cc-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#form_urlencoded@1.2.2", + "author": "The rust-url developers", + "name": "form_urlencoded", + "version": "1.2.2", + "description": "Parser and serializer for the application/x-www-form-urlencoded syntax, as used by HTML forms.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/form_urlencoded@1.2.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/servo/rust-url" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#fs_extra@1.3.0", + "author": "Denis Kurilenko ", + "name": "fs_extra", + "version": "1.3.0", + "description": "Expanding std::fs and std::io. Recursively copy folders with information about process and much more.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/fs_extra@1.3.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/fs_extra" + }, + { + "type": "website", + "url": "https://github.com/webdesus/fs_extra" + }, + { + "type": "vcs", + "url": "https://github.com/webdesus/fs_extra" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-channel@0.3.32", + "name": "futures-channel", + "version": "0.3.32", + "description": "Channels for asynchronous communication using futures-rs. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-channel@0.3.32", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.32", + "name": "futures-core", + "version": "0.3.32", + "description": "The core traits and types in for the `futures` library. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-core@0.3.32", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-executor@0.3.32", + "name": "futures-executor", + "version": "0.3.32", + "description": "Executors for asynchronous tasks based on the futures-rs library. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-executor@0.3.32", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-io@0.3.32", + "name": "futures-io", + "version": "0.3.32", + "description": "The `AsyncRead`, `AsyncWrite`, `AsyncSeek`, and `AsyncBufRead` traits for the futures-rs library. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-io@0.3.32", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-macro@0.3.32", + "name": "futures-macro", + "version": "0.3.32", + "description": "The futures-rs procedural macro implementations. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-macro@0.3.32", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-sink@0.3.32", + "name": "futures-sink", + "version": "0.3.32", + "description": "The asynchronous `Sink` trait for the futures-rs library. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-sink@0.3.32", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-task@0.3.32", + "name": "futures-task", + "version": "0.3.32", + "description": "Tools for working with tasks. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-task@0.3.32", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.32", + "name": "futures-util", + "version": "0.3.32", + "description": "Common utilities and extension traits for the futures-rs library. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-util@0.3.32", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures@0.3.32", + "name": "futures", + "version": "0.3.32", + "description": "An implementation of futures and streams featuring zero allocations, composability, and iterator-like interfaces. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures@0.3.32", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#gearhash@0.1.3", + "author": "Sam Rijs ", + "name": "gearhash", + "version": "0.1.3", + "description": "Fast, SIMD-accelerated hash function for content-defined chunking", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "c8cf82cf76cd16485e56295a1377c775ce708c9f1a0be6b029076d60a245d213" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/gearhash@0.1.3", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/srijs/rust-gearhash" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#generic-array@0.14.7", + "author": "Bartłomiej Kamiński , Aaron Trent ", + "name": "generic-array", + "version": "0.14.7", + "description": "Generic types implementing functionality of arrays", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/generic-array@0.14.7", + "externalReferences": [ + { + "type": "documentation", + "url": "http://fizyk20.github.io/generic-array/generic_array/" + }, + { + "type": "vcs", + "url": "https://github.com/fizyk20/generic-array.git" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.2.17", + "author": "The Rand Project Developers", + "name": "getrandom", + "version": "0.2.17", + "description": "A small cross-platform library for retrieving random data from system source", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/getrandom@0.2.17", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/getrandom" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/getrandom" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.3.4", + "author": "The Rand Project Developers", + "name": "getrandom", + "version": "0.3.4", + "description": "A small cross-platform library for retrieving random data from system source", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/getrandom@0.3.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/getrandom" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/getrandom" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.4.2", + "author": "The Rand Project Developers", + "name": "getrandom", + "version": "0.4.2", + "description": "A small cross-platform library for retrieving random data from system source", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/getrandom@0.4.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/getrandom" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/getrandom" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#git-version-macro@0.3.9", + "author": "David Roundy , Maarten de Vries , Mara Bos ", + "name": "git-version-macro", + "version": "0.3.9", + "description": "Internal macro crate for git-version.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" + } + ], + "licenses": [ + { + "expression": "BSD-2-Clause" + } + ], + "purl": "pkg:cargo/git-version-macro@0.3.9", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/fusion-engineering/rust-git-version" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#git-version@0.3.9", + "author": "Mara Bos , Maarten de Vries , David Roundy ", + "name": "git-version", + "version": "0.3.9", + "description": "Compile the git version (tag name, or hash otherwise) and dirty state into your program.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1ad568aa3db0fcbc81f2f116137f263d7304f512a1209b35b85150d3ef88ad19" + } + ], + "licenses": [ + { + "expression": "BSD-2-Clause" + } + ], + "purl": "pkg:cargo/git-version@0.3.9", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/git-version/" + }, + { + "type": "vcs", + "url": "https://github.com/fusion-engineering/rust-git-version" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#heapify@0.2.0", + "name": "heapify", + "version": "0.2.0", + "description": "Convenience functions to turn slices into max-heaps.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "0049b265b7f201ca9ab25475b22b47fe444060126a51abe00f77d986fc5cc52e" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/heapify@0.2.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/ethereal-sheep/heapify" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#heck@0.5.0", + "name": "heck", + "version": "0.5.0", + "description": "heck is a case conversion library.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/heck@0.5.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/withoutboats/heck" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#http-body-util@0.1.3", + "author": "Carl Lerche , Lucio Franco , Sean McArthur ", + "name": "http-body-util", + "version": "0.1.3", + "description": "Combinators and adapters for HTTP request or response bodies. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/http-body-util@0.1.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/http-body-util" + }, + { + "type": "vcs", + "url": "https://github.com/hyperium/http-body" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "author": "Carl Lerche , Lucio Franco , Sean McArthur ", + "name": "http-body", + "version": "1.0.1", + "description": "Trait representing an asynchronous, streaming, HTTP request or response body. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/http-body@1.0.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/http-body" + }, + { + "type": "vcs", + "url": "https://github.com/hyperium/http-body" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "author": "Alex Crichton , Carl Lerche , Sean McArthur ", + "name": "http", + "version": "1.4.0", + "description": "A set of types for representing HTTP requests and responses. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/http@1.4.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/http" + }, + { + "type": "vcs", + "url": "https://github.com/hyperium/http" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#httparse@1.10.1", + "author": "Sean McArthur ", + "name": "httparse", + "version": "1.10.1", + "description": "A tiny, safe, speedy, zero-copy HTTP/1.x parser.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/httparse@1.10.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/httparse" + }, + { + "type": "vcs", + "url": "https://github.com/seanmonstar/httparse" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#humantime@2.3.0", + "name": "humantime", + "version": "2.3.0", + "description": "A parser and formatter for std::time::{Duration, SystemTime}", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/humantime@2.3.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/humantime" + }, + { + "type": "website", + "url": "https://github.com/chronotope/humantime" + }, + { + "type": "vcs", + "url": "https://github.com/chronotope/humantime" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#hyper-rustls@0.27.7", + "name": "hyper-rustls", + "version": "0.27.7", + "description": "Rustls+hyper integration for pure rust HTTPS", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR ISC OR MIT" + } + ], + "purl": "pkg:cargo/hyper-rustls@0.27.7", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/hyper-rustls/" + }, + { + "type": "website", + "url": "https://github.com/rustls/hyper-rustls" + }, + { + "type": "vcs", + "url": "https://github.com/rustls/hyper-rustls" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#hyper-util@0.1.20", + "author": "Sean McArthur ", + "name": "hyper-util", + "version": "0.1.20", + "description": "hyper utilities", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/hyper-util@0.1.20", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/hyper-util" + }, + { + "type": "website", + "url": "https://hyper.rs" + }, + { + "type": "vcs", + "url": "https://github.com/hyperium/hyper-util" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1", + "author": "Sean McArthur ", + "name": "hyper", + "version": "1.8.1", + "description": "A protective and efficient HTTP library for all.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/hyper@1.8.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/hyper" + }, + { + "type": "website", + "url": "https://hyper.rs" + }, + { + "type": "vcs", + "url": "https://github.com/hyperium/hyper" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#iana-time-zone@0.1.65", + "author": "Andrew Straw , René Kijewski , Ryan Lopopolo ", + "name": "iana-time-zone", + "version": "0.1.65", + "description": "get the IANA time zone for the current system", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/iana-time-zone@0.1.65", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/strawlab/iana-time-zone" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_collections@2.1.1", + "author": "The ICU4X Project Developers", + "name": "icu_collections", + "version": "2.1.1", + "description": "Collection of API for use in ICU libraries.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/icu_collections@2.1.1", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_locale_core@2.1.1", + "author": "The ICU4X Project Developers", + "name": "icu_locale_core", + "version": "2.1.1", + "description": "API for managing Unicode Language and Locale Identifiers", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/icu_locale_core@2.1.1", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_normalizer@2.1.1", + "author": "The ICU4X Project Developers", + "name": "icu_normalizer", + "version": "2.1.1", + "description": "API for normalizing text into Unicode Normalization Forms", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/icu_normalizer@2.1.1", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_normalizer_data@2.1.1", + "author": "The ICU4X Project Developers", + "name": "icu_normalizer_data", + "version": "2.1.1", + "description": "Data for the icu_normalizer crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/icu_normalizer_data@2.1.1", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_properties@2.1.2", + "author": "The ICU4X Project Developers", + "name": "icu_properties", + "version": "2.1.2", + "description": "Definitions for Unicode properties", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/icu_properties@2.1.2", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_properties_data@2.1.2", + "author": "The ICU4X Project Developers", + "name": "icu_properties_data", + "version": "2.1.2", + "description": "Data for the icu_properties crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/icu_properties_data@2.1.2", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_provider@2.1.1", + "author": "The ICU4X Project Developers", + "name": "icu_provider", + "version": "2.1.1", + "description": "Trait and struct definitions for the ICU data provider", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/icu_provider@2.1.1", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#idna@1.1.0", + "author": "The rust-url developers", + "name": "idna", + "version": "1.1.0", + "description": "IDNA (Internationalizing Domain Names in Applications) and Punycode.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/idna@1.1.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/servo/rust-url/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#idna_adapter@1.2.1", + "author": "The rust-url developers", + "name": "idna_adapter", + "version": "1.2.1", + "description": "Back end adapter for idna", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/idna_adapter@1.2.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/idna_adapter/latest/idna_adapter/" + }, + { + "type": "website", + "url": "https://docs.rs/crate/idna_adapter/latest" + }, + { + "type": "vcs", + "url": "https://github.com/hsivonen/idna_adapter" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#indoc@2.0.7", + "author": "David Tolnay ", + "name": "indoc", + "version": "2.0.7", + "description": "Indented document literals", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/indoc@2.0.7", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/indoc" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/indoc" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#inventory@0.3.22", + "author": "David Tolnay ", + "name": "inventory", + "version": "0.3.22", + "description": "Typed distributed plugin registration", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "009ae045c87e7082cb72dab0ccd01ae075dd00141ddc108f43a0ea150a9e7227" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/inventory@0.3.22", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/inventory" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/inventory" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ipnet@2.12.0", + "author": "Kris Price ", + "name": "ipnet", + "version": "2.12.0", + "description": "Provides types and useful methods for working with IPv4 and IPv6 network addresses, commonly called IP prefixes. The new `IpNet`, `Ipv4Net`, and `Ipv6Net` types build on the existing `IpAddr`, `Ipv4Addr`, and `Ipv6Addr` types already provided in Rust's standard library and align to their design to stay consistent. The module also provides useful traits that extend `Ipv4Addr` and `Ipv6Addr` with methods for `Add`, `Sub`, `BitAnd`, and `BitOr` operations. The module only uses stable feature so it is guaranteed to compile using the stable toolchain.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/ipnet@2.12.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/ipnet" + }, + { + "type": "vcs", + "url": "https://github.com/krisprice/ipnet" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#iri-string@0.7.11", + "author": "YOSHIOKA Takuma ", + "name": "iri-string", + "version": "0.7.11", + "description": "IRI as string types", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d8e7418f59cc01c88316161279a7f665217ae316b388e58a0d10e29f54f1e5eb" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/iri-string@0.7.11", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/lo48576/iri-string" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#is_terminal_polyfill@1.70.2", + "name": "is_terminal_polyfill", + "version": "1.70.2", + "description": "Polyfill for `is_terminal` stdlib feature for use with older MSRVs", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/is_terminal_polyfill@1.70.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/polyfill-rs/is_terminal_polyfill" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#itertools@0.14.0", + "author": "bluss", + "name": "itertools", + "version": "0.14.0", + "description": "Extra iterator adaptors, iterator methods, free functions, and macros.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/itertools@0.14.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/itertools/" + }, + { + "type": "vcs", + "url": "https://github.com/rust-itertools/itertools" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.18", + "author": "David Tolnay ", + "name": "itoa", + "version": "1.0.18", + "description": "Fast integer primitive to string conversion", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/itoa@1.0.18", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/itoa" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/itoa" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#jobserver@0.1.34", + "author": "Alex Crichton ", + "name": "jobserver", + "version": "0.1.34", + "description": "An implementation of the GNU Make jobserver for Rust. ", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/jobserver@0.1.34", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/jobserver" + }, + { + "type": "website", + "url": "https://github.com/rust-lang/jobserver-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/jobserver-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#konst@0.4.3", + "author": "rodrimati1992 ", + "name": "konst", + "version": "0.4.3", + "description": "Const equivalents of std features: comparison, destructuring, iteration, and parsing", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f660d5f887e3562f9ab6f4a14988795b694099d66b4f5dedc02d197ba9becb1d" + } + ], + "licenses": [ + { + "expression": "Zlib" + } + ], + "purl": "pkg:cargo/konst@0.4.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/konst/" + }, + { + "type": "vcs", + "url": "https://github.com/rodrimati1992/konst/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#konst_proc_macros@0.4.1", + "author": "rodrimati1992 ", + "name": "konst_proc_macros", + "version": "0.4.1", + "description": "Implementation detail of the `konst` crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e037a2e1d8d5fdbd49b16a4ea09d5d6401c1f29eca5ff29d03d3824dba16256a" + } + ], + "licenses": [ + { + "expression": "Zlib" + } + ], + "purl": "pkg:cargo/konst_proc_macros@0.4.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/konst/" + }, + { + "type": "vcs", + "url": "https://github.com/rodrimati1992/konst/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "author": "Marvin Löbel ", + "name": "lazy_static", + "version": "1.5.0", + "description": "A macro for declaring lazily evaluated statics in Rust.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/lazy_static@1.5.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/lazy_static" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang-nursery/lazy-static.rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183", + "author": "The Rust Project Developers", + "name": "libc", + "version": "0.2.183", + "description": "Raw FFI bindings to platform libraries like libc.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/libc@0.2.183", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-lang/libc" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#link-section@0.15.0", + "author": "Matt Mastracci ", + "name": "link-section", + "version": "0.15.0", + "description": "Link-time initialized slices for Rust, with full support for Linux, macOS, Windows, WASM and many more platforms.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "4641b91711debb59c61b07eb5e30521ed6d9e2bdd9fd04f934e7da3a5bc386d4" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/link-section@0.15.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/mmastrac/linktime" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#linktime-proc-macro@0.1.0", + "author": "Matt Mastracci ", + "name": "linktime-proc-macro", + "version": "0.1.0", + "description": "proc-macro support for the linktime crates", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a44cd706ff0d503ee32b2071166510ca27e281228de10cd3aa8d35ff94560f81" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/linktime-proc-macro@0.1.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/mmastrac/rust-ctor" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#linux-raw-sys@0.12.1", + "author": "Dan Gohman ", + "name": "linux-raw-sys", + "version": "0.12.1", + "description": "Generated bindings for Linux's userspace API", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/linux-raw-sys@0.12.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/linux-raw-sys" + }, + { + "type": "vcs", + "url": "https://github.com/sunfishcode/linux-raw-sys" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#litemap@0.8.1", + "author": "The ICU4X Project Developers", + "name": "litemap", + "version": "0.8.1", + "description": "A key-value Map implementation based on a flat, sorted Vec.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/litemap@0.8.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/litemap" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#log@0.4.29", + "author": "The Rust Project Developers", + "name": "log", + "version": "0.4.29", + "description": "A lightweight logging facade for Rust ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/log@0.4.29", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/log" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/log" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#lru-slab@0.1.2", + "author": "Benjamin Saunders ", + "name": "lru-slab", + "version": "0.1.2", + "description": "Pre-allocated storage with constant-time LRU tracking", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0 OR Zlib" + } + ], + "purl": "pkg:cargo/lru-slab@0.1.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Ralith/lru-slab" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#lz4_flex@0.13.0", + "author": "Pascal Seitz , Arthur Silva , ticki ", + "name": "lz4_flex", + "version": "0.13.0", + "description": "Fastest LZ4 implementation in Rust, no unsafe by default.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "db9a0d582c2874f68138a16ce1867e0ffde6c0bb0a0df85e1f36d04146db488a" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/lz4_flex@0.13.0", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/pseitz/lz4_flex" + }, + { + "type": "vcs", + "url": "https://github.com/pseitz/lz4_flex" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#matchers@0.2.0", + "author": "Eliza Weisman ", + "name": "matchers", + "version": "0.2.0", + "description": "Regex matching on character and byte streams. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/matchers@0.2.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/matchers/" + }, + { + "type": "website", + "url": "https://github.com/hawkw/matchers" + }, + { + "type": "vcs", + "url": "https://github.com/hawkw/matchers" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "author": "Andrew Gallant , bluss", + "name": "memchr", + "version": "2.8.0", + "description": "Provides extremely fast (uses SIMD on x86_64, aarch64 and wasm32) routines for 1, 2 or 3 byte search and single substring search. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + } + ], + "licenses": [ + { + "expression": "Unlicense OR MIT" + } + ], + "purl": "pkg:cargo/memchr@2.8.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/memchr/" + }, + { + "type": "website", + "url": "https://github.com/BurntSushi/memchr" + }, + { + "type": "vcs", + "url": "https://github.com/BurntSushi/memchr" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#memoffset@0.9.1", + "author": "Gilad Naaman ", + "name": "memoffset", + "version": "0.9.1", + "description": "offset_of functionality for Rust structs.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/memoffset@0.9.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Gilnaa/memoffset" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#mio@1.1.1", + "author": "Carl Lerche , Thomas de Zeeuw , Tokio Contributors ", + "name": "mio", + "version": "1.1.1", + "description": "Lightweight non-blocking I/O.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/mio@1.1.1", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/tokio-rs/mio" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/mio" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1", + "author": "Thom Chiovoloni ", + "name": "more-asserts", + "version": "0.3.1", + "description": "Small library providing additional assert_* and debug_assert_* macros.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1fafa6961cabd9c63bcd77a45d7e3b7f3b552b70417831fb0f56db717e72407e" + } + ], + "licenses": [ + { + "expression": "Unlicense OR MIT OR Apache-2.0 OR CC0-1.0" + } + ], + "purl": "pkg:cargo/more-asserts@0.3.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/more-asserts" + }, + { + "type": "website", + "url": "https://github.com/thomcc/rust-more-asserts" + }, + { + "type": "vcs", + "url": "https://github.com/thomcc/rust-more-asserts" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#nu-ansi-term@0.50.3", + "author": "ogham@bsago.me, Ryan Scheel (Havvy) , Josh Triplett , The Nushell Project Developers", + "name": "nu-ansi-term", + "version": "0.50.3", + "description": "Library for ANSI terminal colors and styles (bold, underline)", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/nu-ansi-term@0.50.3", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/nushell/nu-ansi-term" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#num-conv@0.2.0", + "author": "Jacob Pratt ", + "name": "num-conv", + "version": "0.2.0", + "description": "`num_conv` is a crate to convert between integer types without using `as` casts. This provides better certainty when refactoring, makes the exact behavior of code more explicit, and allows using turbofish syntax. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/num-conv@0.2.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/jhpratt/num-conv" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19", + "author": "The Rust Project Developers", + "name": "num-traits", + "version": "0.2.19", + "description": "Numeric traits for generic mathematics", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/num-traits@0.2.19", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/num-traits" + }, + { + "type": "website", + "url": "https://github.com/rust-num/num-traits" + }, + { + "type": "vcs", + "url": "https://github.com/rust-num/num-traits" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.4", + "author": "Aleksey Kladov ", + "name": "once_cell", + "version": "1.21.4", + "description": "Single assignment cells and lazy values.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/once_cell@1.21.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/once_cell" + }, + { + "type": "vcs", + "url": "https://github.com/matklad/once_cell" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#oneshot@0.1.13", + "author": "Linus Färnstrand ", + "name": "oneshot", + "version": "0.1.13", + "description": "Oneshot spsc channel with (potentially) lock-free non-blocking send, and a receiver supporting both thread blocking receive operations as well as Future based async polling. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "269bca4c2591a28585d6bf10d9ed0332b7d76900a1b02bec41bdc3a2cdcda107" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/oneshot@0.1.13", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/faern/oneshot" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#openssl-probe@0.2.1", + "author": "Alex Crichton ", + "name": "openssl-probe", + "version": "0.2.1", + "description": "A library for helping to find system-wide trust anchor (\"root\") certificate locations based on paths typically used by `openssl`. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/openssl-probe@0.2.1", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/rustls/openssl-probe" + }, + { + "type": "vcs", + "url": "https://github.com/rustls/openssl-probe" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#option-ext@0.2.0", + "author": "Simon Ochsenreither ", + "name": "option-ext", + "version": "0.2.0", + "description": "Extends `Option` with additional operations", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + } + ], + "licenses": [ + { + "expression": "MPL-2.0" + } + ], + "purl": "pkg:cargo/option-ext@0.2.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/option-ext/" + }, + { + "type": "website", + "url": "https://github.com/soc/option-ext" + }, + { + "type": "vcs", + "url": "https://github.com/soc/option-ext.git" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#os_str_bytes@6.6.1", + "author": "dylni", + "name": "os_str_bytes", + "version": "6.6.1", + "description": "Convert between byte sequences and platform-native strings ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/os_str_bytes@6.6.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/dylni/os_str_bytes" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2", + "author": "The rust-url developers", + "name": "percent-encoding", + "version": "2.3.2", + "description": "Percent encoding and decoding", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/percent-encoding@2.3.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/servo/rust-url/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pin-project-internal@1.1.11", + "name": "pin-project-internal", + "version": "1.1.11", + "description": "Implementation detail of the `pin-project` crate. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/pin-project-internal@1.1.11", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/taiki-e/pin-project" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.17", + "name": "pin-project-lite", + "version": "0.2.17", + "description": "A lightweight version of pin-project written with declarative macros. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/pin-project-lite@0.2.17", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/taiki-e/pin-project-lite" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pin-project@1.1.11", + "name": "pin-project", + "version": "1.1.11", + "description": "A crate for safe and ergonomic pin-projection. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/pin-project@1.1.11", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/taiki-e/pin-project" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pin-utils@0.1.0", + "author": "Josef Brandl ", + "name": "pin-utils", + "version": "0.1.0", + "description": "Utilities for pinning ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/pin-utils@0.1.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/pin-utils" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang-nursery/pin-utils" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#potential_utf@0.1.4", + "author": "The ICU4X Project Developers", + "name": "potential_utf", + "version": "0.1.4", + "description": "Unvalidated string and character types", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/potential_utf@0.1.4", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#powerfmt@0.2.0", + "author": "Jacob Pratt ", + "name": "powerfmt", + "version": "0.2.0", + "description": " `powerfmt` is a library that provides utilities for formatting values. This crate makes it significantly easier to support filling to a minimum width with alignment, avoid heap allocation, and avoid repetitive calculations. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/powerfmt@0.2.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/jhpratt/powerfmt" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ppv-lite86@0.2.21", + "author": "The CryptoCorrosion Contributors", + "name": "ppv-lite86", + "version": "0.2.21", + "description": "Cross-platform cryptography-oriented low-level SIMD library.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/ppv-lite86@0.2.21", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/cryptocorrosion/cryptocorrosion" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "author": "David Tolnay , Alex Crichton ", + "name": "proc-macro2", + "version": "1.0.106", + "description": "A substitute implementation of the compiler's `proc_macro` API to decouple token-based libraries from the procedural macro use case.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/proc-macro2@1.0.106", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/proc-macro2" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/proc-macro2" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-build-config@0.26.0", + "author": "PyO3 Project and Contributors ", + "name": "pyo3-build-config", + "version": "0.26.0", + "description": "Build configuration for the PyO3 ecosystem", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "4fc6ddaf24947d12a9aa31ac65431fb1b851b8f4365426e182901eabfb87df5f" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/pyo3-build-config@0.26.0", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/pyo3/pyo3" + }, + { + "type": "vcs", + "url": "https://github.com/pyo3/pyo3" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-ffi@0.26.0", + "author": "PyO3 Project and Contributors ", + "name": "pyo3-ffi", + "version": "0.26.0", + "description": "Python-API bindings for the PyO3 ecosystem", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "025474d3928738efb38ac36d4744a74a400c901c7596199e20e45d98eb194105" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/pyo3-ffi@0.26.0", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/pyo3/pyo3" + }, + { + "type": "other", + "url": "python" + }, + { + "type": "vcs", + "url": "https://github.com/pyo3/pyo3" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-macros-backend@0.26.0", + "author": "PyO3 Project and Contributors ", + "name": "pyo3-macros-backend", + "version": "0.26.0", + "description": "Code generation for PyO3 package", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "100246c0ecf400b475341b8455a9213344569af29a3c841d29270e53102e0fcf" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/pyo3-macros-backend@0.26.0", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/pyo3/pyo3" + }, + { + "type": "vcs", + "url": "https://github.com/pyo3/pyo3" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-macros@0.26.0", + "author": "PyO3 Project and Contributors ", + "name": "pyo3-macros", + "version": "0.26.0", + "description": "Proc macros for PyO3 package", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2e64eb489f22fe1c95911b77c44cc41e7c19f3082fc81cce90f657cdc42ffded" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/pyo3-macros@0.26.0", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/pyo3/pyo3" + }, + { + "type": "vcs", + "url": "https://github.com/pyo3/pyo3" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3@0.26.0", + "author": "PyO3 Project and Contributors ", + "name": "pyo3", + "version": "0.26.0", + "description": "Bindings to Python interpreter", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7ba0117f4212101ee6544044dae45abe1083d30ce7b29c4b5cbdfa2354e07383" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/pyo3@0.26.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/crate/pyo3/" + }, + { + "type": "website", + "url": "https://github.com/pyo3/pyo3" + }, + { + "type": "vcs", + "url": "https://github.com/pyo3/pyo3" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#quinn-proto@0.11.14", + "name": "quinn-proto", + "version": "0.11.14", + "description": "State machine for the QUIC transport protocol", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/quinn-proto@0.11.14", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/quinn-rs/quinn" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#quinn-udp@0.5.14", + "name": "quinn-udp", + "version": "0.5.14", + "description": "UDP sockets with ECN information for the QUIC transport protocol", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/quinn-udp@0.5.14", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/quinn-rs/quinn" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#quinn@0.11.9", + "name": "quinn", + "version": "0.11.9", + "description": "Versatile QUIC transport protocol implementation", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/quinn@0.11.9", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/quinn-rs/quinn" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "author": "David Tolnay ", + "name": "quote", + "version": "1.0.45", + "description": "Quasi-quoting macro quote!(...)", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/quote@1.0.45", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/quote/" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/quote" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand@0.10.1", + "author": "The Rand Project Developers, The Rust Project Developers", + "name": "rand", + "version": "0.10.1", + "description": "Random number generators and other randomness functionality. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rand@0.10.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rand" + }, + { + "type": "website", + "url": "https://rust-random.github.io/book" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/rand" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2", + "author": "The Rand Project Developers, The Rust Project Developers", + "name": "rand", + "version": "0.9.2", + "description": "Random number generators and other randomness functionality. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rand@0.9.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rand" + }, + { + "type": "website", + "url": "https://rust-random.github.io/book" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/rand" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand_chacha@0.9.0", + "author": "The Rand Project Developers, The Rust Project Developers, The CryptoCorrosion Contributors", + "name": "rand_chacha", + "version": "0.9.0", + "description": "ChaCha random number generator ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rand_chacha@0.9.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rand_chacha" + }, + { + "type": "website", + "url": "https://rust-random.github.io/book" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/rand" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.10.1", + "author": "The Rand Project Developers", + "name": "rand_core", + "version": "0.10.1", + "description": "Core random number generation traits and tools for implementation.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rand_core@0.10.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rand_core" + }, + { + "type": "website", + "url": "https://rust-random.github.io/book" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/rand_core" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.9.5", + "author": "The Rand Project Developers, The Rust Project Developers", + "name": "rand_core", + "version": "0.9.5", + "description": "Core random number generator traits and tools for implementation. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rand_core@0.9.5", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rand_core" + }, + { + "type": "website", + "url": "https://rust-random.github.io/book" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/rand" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#redb@3.1.1", + "author": "Christopher Berner ", + "name": "redb", + "version": "3.1.1", + "description": "Rust Embedded DataBase", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ef99362319c782aa4639ad3a306b64c3bb90e12874e99b8df124cb679d988611" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/redb@3.1.1", + "externalReferences": [ + { + "type": "website", + "url": "https://www.redb.org" + }, + { + "type": "vcs", + "url": "https://github.com/cberner/redb" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.14", + "author": "The Rust Project Developers, Andrew Gallant ", + "name": "regex-automata", + "version": "0.4.14", + "description": "Automata construction and matching using regular expressions.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/regex-automata@0.4.14", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/regex-automata" + }, + { + "type": "website", + "url": "https://github.com/rust-lang/regex/tree/master/regex-automata" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/regex" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#regex-syntax@0.8.10", + "author": "The Rust Project Developers, Andrew Gallant ", + "name": "regex-syntax", + "version": "0.8.10", + "description": "A regular expression parser.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/regex-syntax@0.8.10", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/regex-syntax" + }, + { + "type": "website", + "url": "https://github.com/rust-lang/regex/tree/master/regex-syntax" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/regex" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#regex@1.12.3", + "author": "The Rust Project Developers, Andrew Gallant ", + "name": "regex", + "version": "1.12.3", + "description": "An implementation of regular expressions for Rust. This implementation uses finite automata and guarantees linear time matching on all inputs. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/regex@1.12.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/regex" + }, + { + "type": "website", + "url": "https://github.com/rust-lang/regex" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/regex" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#reqwest-middleware@0.5.1", + "author": "Rodrigo Gryzinski ", + "name": "reqwest-middleware", + "version": "0.5.1", + "description": "Wrapper around reqwest to allow for client middleware chains.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "199dda04a536b532d0cc04d7979e39b1c763ea749bf91507017069c00b96056f" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/reqwest-middleware@0.5.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/TrueLayer/reqwest-middleware" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#reqwest@0.13.2", + "author": "Sean McArthur ", + "name": "reqwest", + "version": "0.13.2", + "description": "higher level HTTP client library", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/reqwest@0.13.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/reqwest" + }, + { + "type": "vcs", + "url": "https://github.com/seanmonstar/reqwest" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ring@0.17.14", + "name": "ring", + "version": "0.17.14", + "description": "An experiment.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 AND ISC" + } + ], + "purl": "pkg:cargo/ring@0.17.14", + "externalReferences": [ + { + "type": "other", + "url": "ring_core_0_17_14_" + }, + { + "type": "vcs", + "url": "https://github.com/briansmith/ring" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustc-hash@2.1.1", + "author": "The Rust Project Developers", + "name": "rustc-hash", + "version": "2.1.1", + "description": "A speedy, non-cryptographic hashing algorithm used by rustc", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/rustc-hash@2.1.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-lang/rustc-hash" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.4", + "author": "Dan Gohman , Jakub Konka ", + "name": "rustix", + "version": "1.1.4", + "description": "Safe Rust bindings to POSIX/Unix/Linux/Winsock-like syscalls", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/rustix@1.1.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rustix" + }, + { + "type": "vcs", + "url": "https://github.com/bytecodealliance/rustix" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-native-certs@0.8.3", + "name": "rustls-native-certs", + "version": "0.8.3", + "description": "rustls-native-certs allows rustls to use the platform native certificate store", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR ISC OR MIT" + } + ], + "purl": "pkg:cargo/rustls-native-certs@0.8.3", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/rustls/rustls-native-certs" + }, + { + "type": "vcs", + "url": "https://github.com/rustls/rustls-native-certs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.14.0", + "name": "rustls-pki-types", + "version": "1.14.0", + "description": "Shared types for the rustls PKI ecosystem", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rustls-pki-types@1.14.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rustls-pki-types" + }, + { + "type": "website", + "url": "https://github.com/rustls/pki-types" + }, + { + "type": "vcs", + "url": "https://github.com/rustls/pki-types" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-platform-verifier@0.6.2", + "name": "rustls-platform-verifier", + "version": "0.6.2", + "description": "rustls-platform-verifier supports verifying TLS certificates in rustls with the operating system verifier", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rustls-platform-verifier@0.6.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rustls/rustls-platform-verifier" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-webpki@0.103.13", + "name": "rustls-webpki", + "version": "0.103.13", + "description": "Web PKI X.509 Certificate Verification.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" + } + ], + "licenses": [ + { + "expression": "ISC" + } + ], + "purl": "pkg:cargo/rustls-webpki@0.103.13", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rustls/webpki" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.37", + "name": "rustls", + "version": "0.23.37", + "description": "Rustls is a modern TLS library written in Rust.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR ISC OR MIT" + } + ], + "purl": "pkg:cargo/rustls@0.23.37", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/rustls/rustls" + }, + { + "type": "vcs", + "url": "https://github.com/rustls/rustls" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustversion@1.0.22", + "author": "David Tolnay ", + "name": "rustversion", + "version": "1.0.22", + "description": "Conditional compilation according to rustc compiler version", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rustversion@1.0.22", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rustversion" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/rustversion" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ryu@1.0.23", + "author": "David Tolnay ", + "name": "ryu", + "version": "1.0.23", + "description": "Fast floating point to string conversion", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR BSL-1.0" + } + ], + "purl": "pkg:cargo/ryu@1.0.23", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/ryu" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/ryu" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#safe-transmute@0.11.3", + "author": "наб , Eduardo Pinho , Lukas Kalbertodt , Philipp Tessenow , Marijn Suijten ", + "name": "safe-transmute", + "version": "0.11.3", + "description": "A safeguarded transmute() for Rust", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3944826ff8fa8093089aba3acb4ef44b9446a99a16f3bf4e74af3f77d340ab7d" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/safe-transmute@0.11.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://rawcdn.githack.com/nabijaczleweli/safe-transmute-rs/doc/safe_transmute/index.html" + }, + { + "type": "vcs", + "url": "https://github.com/nabijaczleweli/safe-transmute-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#same-file@1.0.6", + "author": "Andrew Gallant ", + "name": "same-file", + "version": "1.0.6", + "description": "A simple crate for determining whether two file paths point to the same file. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" + } + ], + "licenses": [ + { + "expression": "Unlicense OR MIT" + } + ], + "purl": "pkg:cargo/same-file@1.0.6", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/same-file" + }, + { + "type": "website", + "url": "https://github.com/BurntSushi/same-file" + }, + { + "type": "vcs", + "url": "https://github.com/BurntSushi/same-file" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "author": "Erick Tryzelaar , David Tolnay ", + "name": "serde", + "version": "1.0.228", + "description": "A generic serialization/deserialization framework", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/serde@1.0.228", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/serde" + }, + { + "type": "website", + "url": "https://serde.rs" + }, + { + "type": "vcs", + "url": "https://github.com/serde-rs/serde" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228", + "author": "Erick Tryzelaar , David Tolnay ", + "name": "serde_core", + "version": "1.0.228", + "description": "Serde traits only, with no support for derive -- use the `serde` crate instead", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/serde_core@1.0.228", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/serde_core" + }, + { + "type": "website", + "url": "https://serde.rs" + }, + { + "type": "vcs", + "url": "https://github.com/serde-rs/serde" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.228", + "author": "Erick Tryzelaar , David Tolnay ", + "name": "serde_derive", + "version": "1.0.228", + "description": "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/serde_derive@1.0.228", + "externalReferences": [ + { + "type": "documentation", + "url": "https://serde.rs/derive.html" + }, + { + "type": "website", + "url": "https://serde.rs" + }, + { + "type": "vcs", + "url": "https://github.com/serde-rs/serde" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149", + "author": "Erick Tryzelaar , David Tolnay ", + "name": "serde_json", + "version": "1.0.149", + "description": "A JSON serialization file format", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/serde_json@1.0.149", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/serde_json" + }, + { + "type": "vcs", + "url": "https://github.com/serde-rs/json" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_repr@0.1.20", + "author": "David Tolnay ", + "name": "serde_repr", + "version": "0.1.20", + "description": "Derive Serialize and Deserialize that delegates to the underlying repr of a C-like enum.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/serde_repr@0.1.20", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/serde_repr" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/serde-repr" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sha2-asm@0.6.4", + "author": "RustCrypto Developers", + "name": "sha2-asm", + "version": "0.6.4", + "description": "Assembly implementation of SHA-2 compression functions", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b845214d6175804686b2bd482bcffe96651bb2d1200742b712003504a2dac1ab" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/sha2-asm@0.6.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/sha2-asm" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/asm-hashes" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sha2@0.10.9", + "author": "RustCrypto Developers", + "name": "sha2", + "version": "0.10.9", + "description": "Pure Rust implementation of the SHA-2 hash function family including SHA-224, SHA-256, SHA-384, and SHA-512. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/sha2@0.10.9", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/sha2" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/hashes" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sharded-slab@0.1.7", + "author": "Eliza Weisman ", + "name": "sharded-slab", + "version": "0.1.7", + "description": "A lock-free concurrent slab. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/sharded-slab@0.1.7", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/sharded-slab/" + }, + { + "type": "website", + "url": "https://github.com/hawkw/sharded-slab" + }, + { + "type": "vcs", + "url": "https://github.com/hawkw/sharded-slab" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#shellexpand@3.1.2", + "author": "Vladimir Matveev , Ian Jackson ", + "name": "shellexpand", + "version": "3.1.2", + "description": "Shell-like expansions in strings", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "32824fab5e16e6c4d86dc1ba84489390419a39f97699852b66480bb87d297ed8" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/shellexpand@3.1.2", + "externalReferences": [ + { + "type": "documentation", + "url": "http://docs.rs/shellexpand/" + }, + { + "type": "vcs", + "url": "https://gitlab.com/ijackson/rust-shellexpand" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#shlex@1.3.0", + "author": "comex , Fenhl , Adrian Taylor , Alex Touchet , Daniel Parks , Garrett Berg ", + "name": "shlex", + "version": "1.3.0", + "description": "Split a string into shell words, like Python's shlex.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/shlex@1.3.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/comex/rust-shlex" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#signal-hook-registry@1.4.8", + "author": "Michal 'vorner' Vaner , Masaki Hara ", + "name": "signal-hook-registry", + "version": "1.4.8", + "description": "Backend crate for signal-hook", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/signal-hook-registry@1.4.8", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/signal-hook-registry" + }, + { + "type": "vcs", + "url": "https://github.com/vorner/signal-hook" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#signal-hook@0.3.18", + "author": "Michal 'vorner' Vaner , Thomas Himmelstoss ", + "name": "signal-hook", + "version": "0.3.18", + "description": "Unix signal handling", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/signal-hook@0.3.18", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/signal-hook" + }, + { + "type": "vcs", + "url": "https://github.com/vorner/signal-hook" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#slab@0.4.12", + "author": "Carl Lerche ", + "name": "slab", + "version": "0.4.12", + "description": "Pre-allocated storage for a uniform data type", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/slab@0.4.12", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/tokio-rs/slab" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#smallvec@1.15.1", + "author": "The Servo Project Developers", + "name": "smallvec", + "version": "1.15.1", + "description": "'Small vector' optimization: store up to a small number of items on the stack", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/smallvec@1.15.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/smallvec/" + }, + { + "type": "vcs", + "url": "https://github.com/servo/rust-smallvec" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#socket2@0.6.3", + "author": "Alex Crichton , Thomas de Zeeuw ", + "name": "socket2", + "version": "0.6.3", + "description": "Utilities for handling networking sockets with a maximal amount of configuration possible intended. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/socket2@0.6.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/socket2" + }, + { + "type": "website", + "url": "https://github.com/rust-lang/socket2" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/socket2" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#stable_deref_trait@1.2.1", + "author": "Robert Grosse ", + "name": "stable_deref_trait", + "version": "1.2.1", + "description": "An unsafe marker trait for types like Box and Rc that dereference to a stable address even when moved, and hence can be used with libraries such as owning_ref and rental. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/stable_deref_trait@1.2.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/stable_deref_trait/1.2.1/stable_deref_trait" + }, + { + "type": "vcs", + "url": "https://github.com/storyyeller/stable_deref_trait" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#static_assertions@1.1.0", + "author": "Nikolai Vazquez", + "name": "static_assertions", + "version": "1.1.0", + "description": "Compile-time assertions to ensure that invariants are met.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/static_assertions@1.1.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/static_assertions/" + }, + { + "type": "website", + "url": "https://github.com/nvzqz/static-assertions-rs" + }, + { + "type": "vcs", + "url": "https://github.com/nvzqz/static-assertions-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#statrs@0.18.0", + "author": "Michael Ma", + "name": "statrs", + "version": "0.18.0", + "description": "Statistical computing library for Rust", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2a3fe7c28c6512e766b0874335db33c94ad7b8f9054228ae1c2abd47ce7d335e" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/statrs@0.18.0", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/statrs-dev/statrs" + }, + { + "type": "vcs", + "url": "https://github.com/statrs-dev/statrs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#strsim@0.11.1", + "author": "Danny Guo , maxbachmann ", + "name": "strsim", + "version": "0.11.1", + "description": "Implementations of string similarity metrics. Includes Hamming, Levenshtein, OSA, Damerau-Levenshtein, Jaro, Jaro-Winkler, and Sørensen-Dice. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/strsim@0.11.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/strsim/" + }, + { + "type": "website", + "url": "https://github.com/rapidfuzz/strsim-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rapidfuzz/strsim-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#subtle@2.6.1", + "author": "Isis Lovecruft , Henry de Valence ", + "name": "subtle", + "version": "2.6.1", + "description": "Pure-Rust traits and utilities for constant-time cryptographic implementations.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + } + ], + "licenses": [ + { + "expression": "BSD-3-Clause" + } + ], + "purl": "pkg:cargo/subtle@2.6.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/subtle" + }, + { + "type": "website", + "url": "https://dalek.rs/" + }, + { + "type": "vcs", + "url": "https://github.com/dalek-cryptography/subtle" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117", + "author": "David Tolnay ", + "name": "syn", + "version": "2.0.117", + "description": "Parser for Rust source code", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/syn@2.0.117", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/syn" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/syn" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sync_wrapper@1.0.2", + "author": "Actyx AG ", + "name": "sync_wrapper", + "version": "1.0.2", + "description": "A tool for enlisting the compiler's help in proving the absence of concurrency", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" + } + ], + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/sync_wrapper@1.0.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/sync_wrapper" + }, + { + "type": "website", + "url": "https://docs.rs/sync_wrapper" + }, + { + "type": "vcs", + "url": "https://github.com/Actyx/sync_wrapper" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#synstructure@0.13.2", + "author": "Nika Layzell ", + "name": "synstructure", + "version": "0.13.2", + "description": "Helper methods and macros for custom derives", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/synstructure@0.13.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/synstructure" + }, + { + "type": "vcs", + "url": "https://github.com/mystor/synstructure" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sysinfo@0.38.4", + "author": "Guillaume Gomez ", + "name": "sysinfo", + "version": "0.38.4", + "description": "Library to get system information such as processes, CPUs, disks, components and networks", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "92ab6a2f8bfe508deb3c6406578252e491d299cbbf3bc0529ecc3313aee4a52f" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/sysinfo@0.38.4", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/GuillaumeGomez/sysinfo" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#target-lexicon@0.13.5", + "author": "Dan Gohman ", + "name": "target-lexicon", + "version": "0.13.5", + "description": "LLVM target triple types", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 WITH LLVM-exception" + } + ], + "purl": "pkg:cargo/target-lexicon@0.13.5", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/target-lexicon/" + }, + { + "type": "vcs", + "url": "https://github.com/bytecodealliance/target-lexicon" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.27.0", + "author": "Steven Allen , The Rust Project Developers, Ashley Mannix , Jason White ", + "name": "tempfile", + "version": "3.27.0", + "description": "A library for managing temporary files and directories.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/tempfile@3.27.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/tempfile" + }, + { + "type": "website", + "url": "https://stebalien.com/projects/tempfile-rs/" + }, + { + "type": "vcs", + "url": "https://github.com/Stebalien/tempfile" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@2.0.18", + "author": "David Tolnay ", + "name": "thiserror-impl", + "version": "2.0.18", + "description": "Implementation detail of the `thiserror` crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/thiserror-impl@2.0.18", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/dtolnay/thiserror" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "author": "David Tolnay ", + "name": "thiserror", + "version": "2.0.18", + "description": "derive(Error)", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/thiserror@2.0.18", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/thiserror" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/thiserror" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#thread_local@1.1.9", + "author": "Amanieu d'Antras ", + "name": "thread_local", + "version": "1.1.9", + "description": "Per-object thread-local storage", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/thread_local@1.1.9", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/thread_local/" + }, + { + "type": "vcs", + "url": "https://github.com/Amanieu/thread_local-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#time-core@0.1.8", + "author": "Jacob Pratt , Time contributors", + "name": "time-core", + "version": "0.1.8", + "description": "This crate is an implementation detail and should not be relied upon directly.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/time-core@0.1.8", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/time-rs/time" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#time-macros@0.2.27", + "author": "Jacob Pratt , Time contributors", + "name": "time-macros", + "version": "0.2.27", + "description": " Procedural macros for the time crate. This crate is an implementation detail and should not be relied upon directly. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/time-macros@0.2.27", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/time-rs/time" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#time@0.3.47", + "author": "Jacob Pratt , Time contributors", + "name": "time", + "version": "0.3.47", + "description": "Date and time library. Fully interoperable with the standard library. Mostly compatible with #![no_std].", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/time@0.3.47", + "externalReferences": [ + { + "type": "website", + "url": "https://time-rs.github.io" + }, + { + "type": "vcs", + "url": "https://github.com/time-rs/time" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tinystr@0.8.2", + "author": "The ICU4X Project Developers", + "name": "tinystr", + "version": "0.8.2", + "description": "A small ASCII-only bounded length string representation.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/tinystr@0.8.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tinyvec@1.11.0", + "author": "Lokathor ", + "name": "tinyvec", + "version": "1.11.0", + "description": "`tinyvec` provides 100% safe vec-like data structures.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" + } + ], + "licenses": [ + { + "expression": "Zlib OR Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/tinyvec@1.11.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Lokathor/tinyvec" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tinyvec_macros@0.1.1", + "author": "Soveu ", + "name": "tinyvec_macros", + "version": "0.1.1", + "description": "Some macros for tiny containers", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0 OR Zlib" + } + ], + "purl": "pkg:cargo/tinyvec_macros@0.1.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Soveu/tinyvec_macros" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-macros@2.6.1", + "author": "Tokio Contributors ", + "name": "tokio-macros", + "version": "2.6.1", + "description": "Tokio's proc macros. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tokio-macros@2.6.1", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tokio" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-retry@0.3.1", + "name": "tokio-retry", + "version": "0.3.1", + "description": "Extensible, asynchronous retry behaviours for futures/tokio", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "40f644c762e9d396831ae2f8935c954b0d758c4532e924bead0f666d0c1c8640" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tokio-retry@0.3.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/tokio-retry" + }, + { + "type": "vcs", + "url": "https://github.com/djc/tokio-retry" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-rustls@0.26.4", + "name": "tokio-rustls", + "version": "0.26.4", + "description": "Asynchronous TLS/SSL streams for Tokio using Rustls.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/tokio-rustls@0.26.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/tokio-rustls" + }, + { + "type": "website", + "url": "https://github.com/rustls/tokio-rustls" + }, + { + "type": "vcs", + "url": "https://github.com/rustls/tokio-rustls" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.18", + "author": "Tokio Contributors ", + "name": "tokio-util", + "version": "0.7.18", + "description": "Additional utilities for working with Tokio. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tokio-util@0.7.18", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tokio" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0", + "author": "Tokio Contributors ", + "name": "tokio", + "version": "1.50.0", + "description": "An event-driven, non-blocking I/O platform for writing asynchronous I/O backed applications. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tokio@1.50.0", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tokio" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tower-http@0.6.8", + "author": "Tower Maintainers ", + "name": "tower-http", + "version": "0.6.8", + "description": "Tower middleware and utilities for HTTP clients and servers", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tower-http@0.6.8", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/tower-rs/tower-http" + }, + { + "type": "vcs", + "url": "https://github.com/tower-rs/tower-http" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tower-layer@0.3.3", + "author": "Tower Maintainers ", + "name": "tower-layer", + "version": "0.3.3", + "description": "Decorates a `Service` to allow easy composition between `Service`s. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tower-layer@0.3.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/tower-layer/0.3.3" + }, + { + "type": "website", + "url": "https://github.com/tower-rs/tower" + }, + { + "type": "vcs", + "url": "https://github.com/tower-rs/tower" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3", + "author": "Tower Maintainers ", + "name": "tower-service", + "version": "0.3.3", + "description": "Trait representing an asynchronous, request / response based, client or server. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tower-service@0.3.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/tower-service/0.3.3" + }, + { + "type": "website", + "url": "https://github.com/tower-rs/tower" + }, + { + "type": "vcs", + "url": "https://github.com/tower-rs/tower" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tower@0.5.3", + "author": "Tower Maintainers ", + "name": "tower", + "version": "0.5.3", + "description": "Tower is a library of modular and reusable components for building robust clients and servers. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tower@0.5.3", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/tower-rs/tower" + }, + { + "type": "vcs", + "url": "https://github.com/tower-rs/tower" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-appender@0.2.4", + "author": "Zeki Sherif , Tokio Contributors ", + "name": "tracing-appender", + "version": "0.2.4", + "description": "Provides utilities for file appenders and making non-blocking writers. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tracing-appender@0.2.4", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tracing" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-attributes@0.1.31", + "author": "Tokio Contributors , Eliza Weisman , David Barsky ", + "name": "tracing-attributes", + "version": "0.1.31", + "description": "Procedural macro attributes for automatically instrumenting functions. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tracing-attributes@0.1.31", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tracing" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.36", + "author": "Tokio Contributors ", + "name": "tracing-core", + "version": "0.1.36", + "description": "Core primitives for application-level tracing. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tracing-core@0.1.36", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tracing" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-log@0.2.0", + "author": "Tokio Contributors ", + "name": "tracing-log", + "version": "0.2.0", + "description": "Provides compatibility between `tracing` and the `log` crate. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tracing-log@0.2.0", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tracing" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-serde@0.2.0", + "author": "Tokio Contributors ", + "name": "tracing-serde", + "version": "0.2.0", + "description": "A compatibility layer for serializing trace data with `serde` ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tracing-serde@0.2.0", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tracing" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-subscriber@0.3.23", + "author": "Eliza Weisman , David Barsky , Tokio Contributors ", + "name": "tracing-subscriber", + "version": "0.3.23", + "description": "Utilities for implementing and composing `tracing` subscribers. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tracing-subscriber@0.3.23", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tracing" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "author": "Eliza Weisman , Tokio Contributors ", + "name": "tracing", + "version": "0.1.44", + "description": "Application-level tracing for Rust. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tracing@0.1.44", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tracing" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#try-lock@0.2.5", + "author": "Sean McArthur ", + "name": "try-lock", + "version": "0.2.5", + "description": "A lightweight atomic lock.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/try-lock@0.2.5", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/try-lock" + }, + { + "type": "website", + "url": "https://github.com/seanmonstar/try-lock" + }, + { + "type": "vcs", + "url": "https://github.com/seanmonstar/try-lock" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#twox-hash@2.1.2", + "author": "Jake Goulding ", + "name": "twox-hash", + "version": "2.1.2", + "description": "A Rust implementation of the XXHash and XXH3 algorithms", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/twox-hash@2.1.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/twox-hash/" + }, + { + "type": "vcs", + "url": "https://github.com/shepmaster/twox-hash" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#typenum@1.19.0", + "author": "Paho Lurie-Gregg , Andre Bogus ", + "name": "typenum", + "version": "1.19.0", + "description": "Typenum is a Rust library for type-level numbers evaluated at compile time. It currently supports bits, unsigned integers, and signed integers. It also provides a type-level array of type-level numbers, but its implementation is incomplete.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/typenum@1.19.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/typenum" + }, + { + "type": "vcs", + "url": "https://github.com/paholg/typenum" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#typewit@1.14.2", + "author": "rodrimati1992 ", + "name": "typewit", + "version": "1.14.2", + "description": "type-witness-based abstractions, mostly for emulating polymorphism in const fns", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f8c1ae7cc0fdb8b842d65d127cb981574b0d2b249b74d1c7a2986863dc134f71" + } + ], + "licenses": [ + { + "expression": "Zlib" + } + ], + "purl": "pkg:cargo/typewit@1.14.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/typewit/" + }, + { + "type": "vcs", + "url": "https://github.com/rodrimati1992/typewit/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.24", + "author": "David Tolnay ", + "name": "unicode-ident", + "version": "1.0.24", + "description": "Determine whether characters have the XID_Start or XID_Continue properties according to Unicode Standard Annex #31", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + } + ], + "licenses": [ + { + "expression": "(MIT OR Apache-2.0) AND Unicode-3.0" + } + ], + "purl": "pkg:cargo/unicode-ident@1.0.24", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/unicode-ident" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/unicode-ident" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#unindent@0.2.4", + "author": "David Tolnay ", + "name": "unindent", + "version": "0.2.4", + "description": "Remove a column of leading whitespace from a string", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/unindent@0.2.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/unindent" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/indoc" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#untrusted@0.9.0", + "author": "Brian Smith ", + "name": "untrusted", + "version": "0.9.0", + "description": "Safe, fast, zero-panic, zero-crashing, zero-allocation parsing of untrusted inputs in Rust.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + } + ], + "licenses": [ + { + "expression": "ISC" + } + ], + "purl": "pkg:cargo/untrusted@0.9.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://briansmith.org/rustdoc/untrusted/" + }, + { + "type": "vcs", + "url": "https://github.com/briansmith/untrusted" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#url@2.5.8", + "author": "The rust-url developers", + "name": "url", + "version": "2.5.8", + "description": "URL library for Rust, based on the WHATWG URL Standard", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/url@2.5.8", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/url" + }, + { + "type": "vcs", + "url": "https://github.com/servo/rust-url" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#urlencoding@2.1.3", + "author": "Kornel , Bertram Truong ", + "name": "urlencoding", + "version": "2.1.3", + "description": "A Rust library for doing URL percentage encoding.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/urlencoding@2.1.3", + "externalReferences": [ + { + "type": "website", + "url": "https://lib.rs/urlencoding" + }, + { + "type": "vcs", + "url": "https://github.com/kornelski/rust_urlencoding" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#utf8_iter@1.0.4", + "author": "Henri Sivonen ", + "name": "utf8_iter", + "version": "1.0.4", + "description": "Iterator by char over potentially-invalid UTF-8 in &[u8]", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/utf8_iter@1.0.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/utf8_iter/" + }, + { + "type": "website", + "url": "https://docs.rs/utf8_iter/" + }, + { + "type": "vcs", + "url": "https://github.com/hsivonen/utf8_iter" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#utf8parse@0.2.2", + "author": "Joe Wilm , Christian Duerr ", + "name": "utf8parse", + "version": "0.2.2", + "description": "Table-driven UTF-8 parser", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/utf8parse@0.2.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/utf8parse/" + }, + { + "type": "vcs", + "url": "https://github.com/alacritty/vte" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#uuid@1.22.0", + "author": "Ashley Mannix, Dylan DPC, Hunar Roop Kahlon", + "name": "uuid", + "version": "1.22.0", + "description": "A library to generate and parse UUIDs.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/uuid@1.22.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/uuid" + }, + { + "type": "website", + "url": "https://github.com/uuid-rs/uuid" + }, + { + "type": "vcs", + "url": "https://github.com/uuid-rs/uuid" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#version_check@0.9.5", + "author": "Sergio Benitez ", + "name": "version_check", + "version": "0.9.5", + "description": "Tiny crate to check the version of the installed/running rustc.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/version_check@0.9.5", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/version_check/" + }, + { + "type": "vcs", + "url": "https://github.com/SergioBenitez/version_check" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#walkdir@2.5.0", + "author": "Andrew Gallant ", + "name": "walkdir", + "version": "2.5.0", + "description": "Recursively walk a directory.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" + } + ], + "licenses": [ + { + "expression": "Unlicense OR MIT" + } + ], + "purl": "pkg:cargo/walkdir@2.5.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/walkdir/" + }, + { + "type": "website", + "url": "https://github.com/BurntSushi/walkdir" + }, + { + "type": "vcs", + "url": "https://github.com/BurntSushi/walkdir" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#want@0.3.1", + "author": "Sean McArthur ", + "name": "want", + "version": "0.3.1", + "description": "Detect when another Future wants a result.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/want@0.3.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/want" + }, + { + "type": "vcs", + "url": "https://github.com/seanmonstar/want" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#whoami@2.1.1", + "name": "whoami", + "version": "2.1.1", + "description": "Rust library for getting information about the current user and environment", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d6a5b12f9df4f978d2cfdb1bd3bac52433f44393342d7ee9c25f5a1c14c0f45d" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR BSL-1.0 OR MIT" + } + ], + "purl": "pkg:cargo/whoami@2.1.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/whoami" + }, + { + "type": "website", + "url": "https://github.com/ardaku/whoami/releases" + }, + { + "type": "vcs", + "url": "https://github.com/ardaku/whoami" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#writeable@0.6.2", + "author": "The ICU4X Project Developers", + "name": "writeable", + "version": "0.6.2", + "description": "A more efficient alternative to fmt::Display", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/writeable@0.6.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#yoke-derive@0.8.1", + "author": "Manish Goregaokar ", + "name": "yoke-derive", + "version": "0.8.1", + "description": "Custom derive for the yoke crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/yoke-derive@0.8.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#yoke@0.8.1", + "author": "Manish Goregaokar ", + "name": "yoke", + "version": "0.8.1", + "description": "Abstraction allowing borrowed data to be carried along with the backing data it borrows from", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/yoke@0.8.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zerocopy@0.8.47", + "author": "Joshua Liebow-Feeser , Jack Wrenn ", + "name": "zerocopy", + "version": "0.8.47", + "description": "Zerocopy makes zero-cost memory manipulation effortless. We write \"unsafe\" so you don't have to.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" + } + ], + "licenses": [ + { + "expression": "BSD-2-Clause OR Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/zerocopy@0.8.47", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/google/zerocopy" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zerofrom-derive@0.1.6", + "author": "Manish Goregaokar ", + "name": "zerofrom-derive", + "version": "0.1.6", + "description": "Custom derive for the zerofrom crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/zerofrom-derive@0.1.6", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6", + "author": "Manish Goregaokar ", + "name": "zerofrom", + "version": "0.1.6", + "description": "ZeroFrom trait for constructing", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/zerofrom@0.1.6", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zeroize@1.8.2", + "author": "The RustCrypto Project Developers", + "name": "zeroize", + "version": "1.8.2", + "description": "Securely clear secrets from memory with a simple trait built on stable Rust primitives which guarantee memory is zeroed using an operation will not be 'optimized away' by the compiler. Uses a portable pure Rust implementation that works everywhere, even WASM! ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/zeroize@1.8.2", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/RustCrypto/utils/tree/master/zeroize" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/utils" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zerotrie@0.2.3", + "author": "The ICU4X Project Developers", + "name": "zerotrie", + "version": "0.2.3", + "description": "A data structure that efficiently maps strings to integers", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/zerotrie@0.2.3", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zerovec-derive@0.11.2", + "author": "Manish Goregaokar ", + "name": "zerovec-derive", + "version": "0.11.2", + "description": "Custom derive for the zerovec crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/zerovec-derive@0.11.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5", + "author": "The ICU4X Project Developers", + "name": "zerovec", + "version": "0.11.5", + "description": "Zero-copy vector backed by a byte array", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/zerovec@0.11.5", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zmij@1.0.21", + "author": "David Tolnay ", + "name": "zmij", + "version": "1.0.21", + "description": "A double-to-string conversion algorithm based on Schubfach and yy", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/zmij@1.0.21", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/zmij" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/zmij" + } + ] + } + ], + "dependencies": [ + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/hf_xet#1.5.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "path+file:///home/runner/work/xet-core/xet-core/xet_pkg#hf-xet@1.5.2", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#itertools@0.14.0", + "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "registry+https://github.com/rust-lang/crates.io-index#pyo3@0.26.0", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.10.1", + "registry+https://github.com/rust-lang/crates.io-index#signal-hook@0.3.18", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "path+file:///home/runner/work/xet-core/xet-core/xet_client#xet-client@1.5.2", + "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#xet-runtime@1.5.2" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/xet_client#xet-client@1.5.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.102", + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#clap@4.6.0", + "registry+https://github.com/rust-lang/crates.io-index#crc32fast@1.5.0", + "registry+https://github.com/rust-lang/crates.io-index#futures@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1", + "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.10.1", + "registry+https://github.com/rust-lang/crates.io-index#redb@3.1.1", + "registry+https://github.com/rust-lang/crates.io-index#reqwest@0.13.2", + "registry+https://github.com/rust-lang/crates.io-index#reqwest-middleware@0.5.1", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149", + "registry+https://github.com/rust-lang/crates.io-index#serde_repr@0.1.20", + "registry+https://github.com/rust-lang/crates.io-index#statrs@0.18.0", + "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.27.0", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0", + "registry+https://github.com/rust-lang/crates.io-index#tokio-retry@0.3.1", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "registry+https://github.com/rust-lang/crates.io-index#tracing-subscriber@0.3.23", + "registry+https://github.com/rust-lang/crates.io-index#url@2.5.8", + "registry+https://github.com/rust-lang/crates.io-index#urlencoding@2.1.3", + "path+file:///home/runner/work/xet-core/xet-core/xet_core_structures#xet-core-structures@1.5.2", + "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#xet-runtime@1.5.2" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/xet_core_structures#xet-core-structures@1.5.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1", + "registry+https://github.com/rust-lang/crates.io-index#blake3@1.8.3", + "registry+https://github.com/rust-lang/crates.io-index#bytemuck@1.25.0", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#clap@4.6.0", + "registry+https://github.com/rust-lang/crates.io-index#countio@0.3.0", + "registry+https://github.com/rust-lang/crates.io-index#csv@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#futures@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#heapify@0.2.0", + "registry+https://github.com/rust-lang/crates.io-index#itertools@0.14.0", + "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "registry+https://github.com/rust-lang/crates.io-index#lz4_flex@0.13.0", + "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.10.1", + "registry+https://github.com/rust-lang/crates.io-index#regex@1.12.3", + "registry+https://github.com/rust-lang/crates.io-index#safe-transmute@0.11.3", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#static_assertions@1.1.0", + "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.27.0", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0", + "registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.18", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "registry+https://github.com/rust-lang/crates.io-index#uuid@1.22.0", + "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#xet-runtime@1.5.2" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/xet_data#xet-data@1.5.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.102", + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.44", + "registry+https://github.com/rust-lang/crates.io-index#clap@4.6.0", + "registry+https://github.com/rust-lang/crates.io-index#gearhash@0.1.3", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#itertools@0.14.0", + "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1", + "registry+https://github.com/rust-lang/crates.io-index#pyo3@0.26.0", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.10.1", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149", + "registry+https://github.com/rust-lang/crates.io-index#sha2@0.10.9", + "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.27.0", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0", + "registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.18", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "registry+https://github.com/rust-lang/crates.io-index#url@2.5.8", + "registry+https://github.com/rust-lang/crates.io-index#uuid@1.22.0", + "registry+https://github.com/rust-lang/crates.io-index#walkdir@2.5.0", + "path+file:///home/runner/work/xet-core/xet-core/xet_client#xet-client@1.5.2", + "path+file:///home/runner/work/xet-core/xet-core/xet_core_structures#xet-core-structures@1.5.2", + "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#xet-runtime@1.5.2" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/xet_pkg#hf-xet@1.5.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1", + "registry+https://github.com/rust-lang/crates.io-index#pyo3@0.26.0", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0", + "registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.18", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "registry+https://github.com/rust-lang/crates.io-index#uuid@1.22.0", + "path+file:///home/runner/work/xet-core/xet-core/xet_client#xet-client@1.5.2", + "path+file:///home/runner/work/xet-core/xet-core/xet_core_structures#xet-core-structures@1.5.2", + "path+file:///home/runner/work/xet-core/xet-core/xet_data#xet-data@1.5.2", + "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#xet-runtime@1.5.2" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#xet-runtime@1.5.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.102", + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.44", + "registry+https://github.com/rust-lang/crates.io-index#colored@3.1.1", + "registry+https://github.com/rust-lang/crates.io-index#const-str@1.1.0", + "registry+https://github.com/rust-lang/crates.io-index#ctor@1.0.3", + "registry+https://github.com/rust-lang/crates.io-index#dirs@6.0.0", + "registry+https://github.com/rust-lang/crates.io-index#futures@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#git-version@0.3.9", + "registry+https://github.com/rust-lang/crates.io-index#humantime@2.3.0", + "registry+https://github.com/rust-lang/crates.io-index#konst@0.4.3", + "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183", + "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1", + "registry+https://github.com/rust-lang/crates.io-index#oneshot@0.1.13", + "registry+https://github.com/rust-lang/crates.io-index#pin-project@1.1.11", + "registry+https://github.com/rust-lang/crates.io-index#pyo3@0.26.0", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.10.1", + "registry+https://github.com/rust-lang/crates.io-index#reqwest@0.13.2", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149", + "registry+https://github.com/rust-lang/crates.io-index#shellexpand@3.1.2", + "registry+https://github.com/rust-lang/crates.io-index#sysinfo@0.38.4", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0", + "registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.18", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "registry+https://github.com/rust-lang/crates.io-index#tracing-appender@0.2.4", + "registry+https://github.com/rust-lang/crates.io-index#tracing-subscriber@0.3.23", + "registry+https://github.com/rust-lang/crates.io-index#whoami@2.1.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#aho-corasick@1.1.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#anstream@1.0.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#anstyle@1.0.14", + "registry+https://github.com/rust-lang/crates.io-index#anstyle-parse@1.0.0", + "registry+https://github.com/rust-lang/crates.io-index#anstyle-query@1.1.5", + "registry+https://github.com/rust-lang/crates.io-index#colorchoice@1.0.5", + "registry+https://github.com/rust-lang/crates.io-index#is_terminal_polyfill@1.70.2", + "registry+https://github.com/rust-lang/crates.io-index#utf8parse@0.2.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#anstyle-parse@1.0.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#utf8parse@0.2.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#anstyle-query@1.1.5" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#anstyle@1.0.14" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.102" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#approx@0.5.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#arrayref@0.3.9" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#arrayvec@0.7.6" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#atomic-waker@1.1.2" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#autocfg@1.5.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#aws-lc-rs@1.16.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#aws-lc-sys@0.39.0", + "registry+https://github.com/rust-lang/crates.io-index#zeroize@1.8.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#aws-lc-sys@0.39.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.57", + "registry+https://github.com/rust-lang/crates.io-index#cmake@0.1.57", + "registry+https://github.com/rust-lang/crates.io-index#dunce@1.0.5", + "registry+https://github.com/rust-lang/crates.io-index#fs_extra@1.3.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#bitflags@2.11.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#blake3@1.8.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#arrayref@0.3.9", + "registry+https://github.com/rust-lang/crates.io-index#arrayvec@0.7.6", + "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.57", + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#constant_time_eq@0.4.2", + "registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.17" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#block-buffer@0.10.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#generic-array@0.14.7" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#bstr@1.12.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.14", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#bytemuck@1.25.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.57", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#find-msvc-tools@0.1.9", + "registry+https://github.com/rust-lang/crates.io-index#jobserver@0.1.34", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183", + "registry+https://github.com/rust-lang/crates.io-index#shlex@1.3.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#cfg-if@0.1.10" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#cfg_aliases@0.2.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#chacha20@0.10.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.3.0", + "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.10.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.44", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#iana-time-zone@0.1.65", + "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#clap@4.6.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#clap_builder@4.6.0", + "registry+https://github.com/rust-lang/crates.io-index#clap_derive@4.6.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#clap_builder@4.6.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#anstream@1.0.0", + "registry+https://github.com/rust-lang/crates.io-index#anstyle@1.0.14", + "registry+https://github.com/rust-lang/crates.io-index#clap_lex@1.1.0", + "registry+https://github.com/rust-lang/crates.io-index#strsim@0.11.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#clap_derive@4.6.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#heck@0.5.0", + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#clap_lex@1.1.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#cmake@0.1.57", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.57" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#colorchoice@1.0.5" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#colored@3.1.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#const-str@1.1.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#const_panic@0.2.15", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#typewit@1.14.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#constant_time_eq@0.4.2" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#countio@0.3.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#futures-io@0.3.32" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.17" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.3.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#crc32fast@1.5.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#crossbeam-channel@0.5.15", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.21" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.21" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#crypto-common@0.1.7", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#generic-array@0.14.7", + "registry+https://github.com/rust-lang/crates.io-index#typenum@1.19.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#csv-core@0.1.13", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#csv@1.4.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#csv-core@0.1.13", + "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.18", + "registry+https://github.com/rust-lang/crates.io-index#ryu@1.0.23", + "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#ctor@1.0.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#link-section@0.15.0", + "registry+https://github.com/rust-lang/crates.io-index#linktime-proc-macro@0.1.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#deranged@0.5.8", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#powerfmt@0.2.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#digest@0.10.7", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#block-buffer@0.10.4", + "registry+https://github.com/rust-lang/crates.io-index#crypto-common@0.1.7" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#dirs-sys@0.5.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183", + "registry+https://github.com/rust-lang/crates.io-index#option-ext@0.2.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#dirs@6.0.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#dirs-sys@0.5.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#dunce@1.0.5" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#either@1.15.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#errno@0.3.14", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#fastrand@2.3.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#find-msvc-tools@0.1.9" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#form_urlencoded@1.2.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#fs_extra@1.3.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-channel@0.3.32", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-sink@0.3.32" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.32" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-executor@0.3.32", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-task@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.32" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-io@0.3.32" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-macro@0.3.32", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-sink@0.3.32" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-task@0.3.32" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.32", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#futures-channel@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-io@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-macro@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-sink@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-task@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#slab@0.4.12" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures@0.3.32", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#futures-channel@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-executor@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-io@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-sink@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-task@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.32" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#gearhash@0.1.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@0.1.10" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#generic-array@0.14.7", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#typenum@1.19.0", + "registry+https://github.com/rust-lang/crates.io-index#version_check@0.9.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.2.17", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.3.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.4.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183", + "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.10.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#git-version-macro@0.3.9", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#git-version@0.3.9", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#git-version-macro@0.3.9" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#heapify@0.2.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#heck@0.5.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#http-body-util@0.1.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.17" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.18" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#httparse@1.10.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#humantime@2.3.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#hyper-rustls@0.27.7", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1", + "registry+https://github.com/rust-lang/crates.io-index#hyper-util@0.1.20", + "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.37", + "registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.14.0", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0", + "registry+https://github.com/rust-lang/crates.io-index#tokio-rustls@0.26.4", + "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#hyper-util@0.1.20", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#futures-channel@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1", + "registry+https://github.com/rust-lang/crates.io-index#ipnet@2.12.0", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183", + "registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#socket2@0.6.3", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0", + "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#atomic-waker@1.1.2", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#futures-channel@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "registry+https://github.com/rust-lang/crates.io-index#httparse@1.10.1", + "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.18", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#pin-utils@0.1.0", + "registry+https://github.com/rust-lang/crates.io-index#smallvec@1.15.1", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0", + "registry+https://github.com/rust-lang/crates.io-index#want@0.3.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#iana-time-zone@0.1.65" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#icu_collections@2.1.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5", + "registry+https://github.com/rust-lang/crates.io-index#potential_utf@0.1.4", + "registry+https://github.com/rust-lang/crates.io-index#yoke@0.8.1", + "registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6", + "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#icu_locale_core@2.1.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5", + "registry+https://github.com/rust-lang/crates.io-index#litemap@0.8.1", + "registry+https://github.com/rust-lang/crates.io-index#tinystr@0.8.2", + "registry+https://github.com/rust-lang/crates.io-index#writeable@0.6.2", + "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#icu_normalizer@2.1.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#icu_collections@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#icu_normalizer_data@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#icu_properties@2.1.2", + "registry+https://github.com/rust-lang/crates.io-index#icu_provider@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#smallvec@1.15.1", + "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#icu_normalizer_data@2.1.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#icu_properties@2.1.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#icu_collections@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#icu_locale_core@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#icu_properties_data@2.1.2", + "registry+https://github.com/rust-lang/crates.io-index#icu_provider@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#zerotrie@0.2.3", + "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#icu_properties_data@2.1.2" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#icu_provider@2.1.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5", + "registry+https://github.com/rust-lang/crates.io-index#icu_locale_core@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#writeable@0.6.2", + "registry+https://github.com/rust-lang/crates.io-index#yoke@0.8.1", + "registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6", + "registry+https://github.com/rust-lang/crates.io-index#zerotrie@0.2.3", + "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#idna@1.1.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#idna_adapter@1.2.1", + "registry+https://github.com/rust-lang/crates.io-index#smallvec@1.15.1", + "registry+https://github.com/rust-lang/crates.io-index#utf8_iter@1.0.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#idna_adapter@1.2.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#icu_normalizer@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#icu_properties@2.1.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#indoc@2.0.7", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#rustversion@1.0.22" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#inventory@0.3.22" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#ipnet@2.12.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#iri-string@0.7.11", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#is_terminal_polyfill@1.70.2" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#itertools@0.14.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#either@1.15.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.18" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#jobserver@0.1.34", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#konst@0.4.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#const_panic@0.2.15", + "registry+https://github.com/rust-lang/crates.io-index#konst_proc_macros@0.4.1", + "registry+https://github.com/rust-lang/crates.io-index#typewit@1.14.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#konst_proc_macros@0.4.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#link-section@0.15.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#linktime-proc-macro@0.1.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#linux-raw-sys@0.12.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#litemap@0.8.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#log@0.4.29" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#lru-slab@0.1.2" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#lz4_flex@0.13.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#twox-hash@2.1.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#matchers@0.2.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.14" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#memoffset@0.9.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#autocfg@1.5.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#mio@1.1.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#nu-ansi-term@0.50.3" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#num-conv@0.2.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#autocfg@1.5.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.4" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#oneshot@0.1.13" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#openssl-probe@0.2.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#option-ext@0.2.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#os_str_bytes@6.6.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pin-project-internal@1.1.11", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.17" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pin-project@1.1.11", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#pin-project-internal@1.1.11" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pin-utils@0.1.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#potential_utf@0.1.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#powerfmt@0.2.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#ppv-lite86@0.2.21", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#zerocopy@0.8.47" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.24" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-build-config@0.26.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#target-lexicon@0.13.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-ffi@0.26.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183", + "registry+https://github.com/rust-lang/crates.io-index#pyo3-build-config@0.26.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-macros-backend@0.26.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#heck@0.5.0", + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#pyo3-build-config@0.26.0", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-macros@0.26.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#pyo3-macros-backend@0.26.0", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3@0.26.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#indoc@2.0.7", + "registry+https://github.com/rust-lang/crates.io-index#inventory@0.3.22", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183", + "registry+https://github.com/rust-lang/crates.io-index#memoffset@0.9.1", + "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.4", + "registry+https://github.com/rust-lang/crates.io-index#pyo3-build-config@0.26.0", + "registry+https://github.com/rust-lang/crates.io-index#pyo3-ffi@0.26.0", + "registry+https://github.com/rust-lang/crates.io-index#pyo3-macros@0.26.0", + "registry+https://github.com/rust-lang/crates.io-index#unindent@0.2.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#quinn-proto@0.11.14", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#aws-lc-rs@1.16.2", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#lru-slab@0.1.2", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2", + "registry+https://github.com/rust-lang/crates.io-index#rustc-hash@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.37", + "registry+https://github.com/rust-lang/crates.io-index#slab@0.4.12", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tinyvec@1.11.0", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#quinn-udp@0.5.14", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg_aliases@0.2.1", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183", + "registry+https://github.com/rust-lang/crates.io-index#socket2@0.6.3", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#quinn@0.11.9", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#cfg_aliases@0.2.1", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#quinn-proto@0.11.14", + "registry+https://github.com/rust-lang/crates.io-index#quinn-udp@0.5.14", + "registry+https://github.com/rust-lang/crates.io-index#rustc-hash@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.37", + "registry+https://github.com/rust-lang/crates.io-index#socket2@0.6.3", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rand@0.10.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#chacha20@0.10.0", + "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.4.2", + "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.10.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#rand_chacha@0.9.0", + "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.9.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rand_chacha@0.9.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#ppv-lite86@0.2.21", + "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.9.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.10.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.9.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.3.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#redb@3.1.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.14", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#aho-corasick@1.1.4", + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "registry+https://github.com/rust-lang/crates.io-index#regex-syntax@0.8.10" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#regex-syntax@0.8.10" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#regex@1.12.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#aho-corasick@1.1.4", + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.14", + "registry+https://github.com/rust-lang/crates.io-index#regex-syntax@0.8.10" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#reqwest-middleware@0.5.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.102", + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#reqwest@0.13.2", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#reqwest@0.13.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "registry+https://github.com/rust-lang/crates.io-index#http-body-util@0.1.3", + "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1", + "registry+https://github.com/rust-lang/crates.io-index#hyper-rustls@0.27.7", + "registry+https://github.com/rust-lang/crates.io-index#hyper-util@0.1.20", + "registry+https://github.com/rust-lang/crates.io-index#log@0.4.29", + "registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#quinn@0.11.9", + "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.37", + "registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.14.0", + "registry+https://github.com/rust-lang/crates.io-index#rustls-platform-verifier@0.6.2", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149", + "registry+https://github.com/rust-lang/crates.io-index#sync_wrapper@1.0.2", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0", + "registry+https://github.com/rust-lang/crates.io-index#tokio-rustls@0.26.4", + "registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.18", + "registry+https://github.com/rust-lang/crates.io-index#tower@0.5.3", + "registry+https://github.com/rust-lang/crates.io-index#tower-http@0.6.8", + "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3", + "registry+https://github.com/rust-lang/crates.io-index#url@2.5.8" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#ring@0.17.14", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.57", + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#untrusted@0.9.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustc-hash@2.1.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bitflags@2.11.0", + "registry+https://github.com/rust-lang/crates.io-index#errno@0.3.14", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183", + "registry+https://github.com/rust-lang/crates.io-index#linux-raw-sys@0.12.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-native-certs@0.8.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#openssl-probe@0.2.1", + "registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.14.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.14.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#zeroize@1.8.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-platform-verifier@0.6.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#log@0.4.29", + "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.37", + "registry+https://github.com/rust-lang/crates.io-index#rustls-native-certs@0.8.3", + "registry+https://github.com/rust-lang/crates.io-index#rustls-webpki@0.103.13" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-webpki@0.103.13", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#aws-lc-rs@1.16.2", + "registry+https://github.com/rust-lang/crates.io-index#ring@0.17.14", + "registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.14.0", + "registry+https://github.com/rust-lang/crates.io-index#untrusted@0.9.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.37", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#aws-lc-rs@1.16.2", + "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.4", + "registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.14.0", + "registry+https://github.com/rust-lang/crates.io-index#rustls-webpki@0.103.13", + "registry+https://github.com/rust-lang/crates.io-index#subtle@2.6.1", + "registry+https://github.com/rust-lang/crates.io-index#zeroize@1.8.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustversion@1.0.22" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#ryu@1.0.23" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#safe-transmute@0.11.3" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#same-file@1.0.6" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.228" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.228", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.18", + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#zmij@1.0.21" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#serde_repr@0.1.20", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#sha2-asm@0.6.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.57" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#sha2@0.10.9", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#digest@0.10.7", + "registry+https://github.com/rust-lang/crates.io-index#sha2-asm@0.6.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#sharded-slab@0.1.7", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#shellexpand@3.1.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bstr@1.12.1", + "registry+https://github.com/rust-lang/crates.io-index#dirs@6.0.0", + "registry+https://github.com/rust-lang/crates.io-index#os_str_bytes@6.6.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#shlex@1.3.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#signal-hook-registry@1.4.8", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#errno@0.3.14", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#signal-hook@0.3.18", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183", + "registry+https://github.com/rust-lang/crates.io-index#signal-hook-registry@1.4.8" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#slab@0.4.12" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#smallvec@1.15.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#socket2@0.6.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#stable_deref_trait@1.2.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#static_assertions@1.1.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#statrs@0.18.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#approx@0.5.1", + "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#strsim@0.11.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#subtle@2.6.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.24" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#sync_wrapper@1.0.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.32" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#synstructure@0.13.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#sysinfo@0.38.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183", + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#target-lexicon@0.13.5" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.27.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#fastrand@2.3.0", + "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.4.2", + "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.4", + "registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@2.0.18", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@2.0.18" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#thread_local@1.1.9", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#time-core@0.1.8" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#time-macros@0.2.27", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#num-conv@0.2.0", + "registry+https://github.com/rust-lang/crates.io-index#time-core@0.1.8" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#time@0.3.47", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#deranged@0.5.8", + "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.18", + "registry+https://github.com/rust-lang/crates.io-index#num-conv@0.2.0", + "registry+https://github.com/rust-lang/crates.io-index#powerfmt@0.2.0", + "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#time-core@0.1.8", + "registry+https://github.com/rust-lang/crates.io-index#time-macros@0.2.27" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tinystr@0.8.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5", + "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tinyvec@1.11.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#tinyvec_macros@0.1.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tinyvec_macros@0.1.1" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-macros@2.6.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-retry@0.3.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.10.1", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-rustls@0.26.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.37", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.18", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-sink@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183", + "registry+https://github.com/rust-lang/crates.io-index#mio@1.1.1", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#socket2@0.6.3", + "registry+https://github.com/rust-lang/crates.io-index#tokio-macros@2.6.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tower-http@0.6.8", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bitflags@2.11.0", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "registry+https://github.com/rust-lang/crates.io-index#iri-string@0.7.11", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#tower@0.5.3", + "registry+https://github.com/rust-lang/crates.io-index#tower-layer@0.3.3", + "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tower-layer@0.3.3" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tower@0.5.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.32", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#sync_wrapper@1.0.2", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.50.0", + "registry+https://github.com/rust-lang/crates.io-index#tower-layer@0.3.3", + "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-appender@0.2.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#crossbeam-channel@0.5.15", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#time@0.3.47", + "registry+https://github.com/rust-lang/crates.io-index#tracing-subscriber@0.3.23" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-attributes@0.1.31", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.36", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-log@0.2.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#log@0.4.29", + "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.4", + "registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.36" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-serde@0.2.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.36" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-subscriber@0.3.23", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#matchers@0.2.0", + "registry+https://github.com/rust-lang/crates.io-index#nu-ansi-term@0.50.3", + "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.4", + "registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.14", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149", + "registry+https://github.com/rust-lang/crates.io-index#sharded-slab@0.1.7", + "registry+https://github.com/rust-lang/crates.io-index#smallvec@1.15.1", + "registry+https://github.com/rust-lang/crates.io-index#thread_local@1.1.9", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.36", + "registry+https://github.com/rust-lang/crates.io-index#tracing-log@0.2.0", + "registry+https://github.com/rust-lang/crates.io-index#tracing-serde@0.2.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#tracing-attributes@0.1.31", + "registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.36" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#try-lock@0.2.5" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#twox-hash@2.1.2" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#typenum@1.19.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#typewit@1.14.2" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.24" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#unindent@0.2.4" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#untrusted@0.9.0" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#url@2.5.8", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#form_urlencoded@1.2.2", + "registry+https://github.com/rust-lang/crates.io-index#idna@1.1.0", + "registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#urlencoding@2.1.3" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#utf8_iter@1.0.4" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#utf8parse@0.2.2" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#uuid@1.22.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.4.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#version_check@0.9.5" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#walkdir@2.5.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#same-file@1.0.6" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#want@0.3.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#try-lock@0.2.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#whoami@2.1.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.183" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#writeable@0.6.2" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#yoke-derive@0.8.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117", + "registry+https://github.com/rust-lang/crates.io-index#synstructure@0.13.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#yoke@0.8.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#stable_deref_trait@1.2.1", + "registry+https://github.com/rust-lang/crates.io-index#yoke-derive@0.8.1", + "registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zerocopy@0.8.47" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zerofrom-derive@0.1.6", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117", + "registry+https://github.com/rust-lang/crates.io-index#synstructure@0.13.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#zerofrom-derive@0.1.6" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zeroize@1.8.2" + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zerotrie@0.2.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5", + "registry+https://github.com/rust-lang/crates.io-index#yoke@0.8.1", + "registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zerovec-derive@0.11.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.45", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.117" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#yoke@0.8.1", + "registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6", + "registry+https://github.com/rust-lang/crates.io-index#zerovec-derive@0.11.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zmij@1.0.21" + } + ] +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/hf_xet/__init__.py b/.venv/lib/python3.13/site-packages/hf_xet/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..96ed54a8a066d681e4973e5841a0f5577b619698 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/hf_xet/__init__.py @@ -0,0 +1,5 @@ +from .hf_xet import * + +__doc__ = hf_xet.__doc__ +if hasattr(hf_xet, "__all__"): + __all__ = hf_xet.__all__ \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/hf_xet/hf_xet.abi3.so b/.venv/lib/python3.13/site-packages/hf_xet/hf_xet.abi3.so new file mode 100644 index 0000000000000000000000000000000000000000..4784b83e0a585fb07481fb09d472fd8f7cda51a6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/hf_xet/hf_xet.abi3.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ebb01561f3532c04d38319d8456652579bc1a12ffa8f51450c4add04cfa18536 +size 11601472 diff --git a/.venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/INSTALLER b/.venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/METADATA b/.venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..8056834e6714b089ef49847820064a1ae4b041fd --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/METADATA @@ -0,0 +1,625 @@ +Metadata-Version: 2.4 +Name: httpcore +Version: 1.0.9 +Summary: A minimal low-level HTTP client. +Project-URL: Documentation, https://www.encode.io/httpcore +Project-URL: Homepage, https://www.encode.io/httpcore/ +Project-URL: Source, https://github.com/encode/httpcore +Author-email: Tom Christie +License-Expression: BSD-3-Clause +License-File: LICENSE.md +Classifier: Development Status :: 3 - Alpha +Classifier: Environment :: Web Environment +Classifier: Framework :: AsyncIO +Classifier: Framework :: Trio +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.8 +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: Topic :: Internet :: WWW/HTTP +Requires-Python: >=3.8 +Requires-Dist: certifi +Requires-Dist: h11>=0.16 +Provides-Extra: asyncio +Requires-Dist: anyio<5.0,>=4.0; extra == 'asyncio' +Provides-Extra: http2 +Requires-Dist: h2<5,>=3; extra == 'http2' +Provides-Extra: socks +Requires-Dist: socksio==1.*; extra == 'socks' +Provides-Extra: trio +Requires-Dist: trio<1.0,>=0.22.0; extra == 'trio' +Description-Content-Type: text/markdown + +# HTTP Core + +[![Test Suite](https://github.com/encode/httpcore/workflows/Test%20Suite/badge.svg)](https://github.com/encode/httpcore/actions) +[![Package version](https://badge.fury.io/py/httpcore.svg)](https://pypi.org/project/httpcore/) + +> *Do one thing, and do it well.* + +The HTTP Core package provides a minimal low-level HTTP client, which does +one thing only. Sending HTTP requests. + +It does not provide any high level model abstractions over the API, +does not handle redirects, multipart uploads, building authentication headers, +transparent HTTP caching, URL parsing, session cookie handling, +content or charset decoding, handling JSON, environment based configuration +defaults, or any of that Jazz. + +Some things HTTP Core does do: + +* Sending HTTP requests. +* Thread-safe / task-safe connection pooling. +* HTTP(S) proxy & SOCKS proxy support. +* Supports HTTP/1.1 and HTTP/2. +* Provides both sync and async interfaces. +* Async backend support for `asyncio` and `trio`. + +## Requirements + +Python 3.8+ + +## Installation + +For HTTP/1.1 only support, install with: + +```shell +$ pip install httpcore +``` + +There are also a number of optional extras available... + +```shell +$ pip install httpcore['asyncio,trio,http2,socks'] +``` + +## Sending requests + +Send an HTTP request: + +```python +import httpcore + +response = httpcore.request("GET", "https://www.example.com/") + +print(response) +# +print(response.status) +# 200 +print(response.headers) +# [(b'Accept-Ranges', b'bytes'), (b'Age', b'557328'), (b'Cache-Control', b'max-age=604800'), ...] +print(response.content) +# b'\n\n\nExample Domain\n\n\n ...' +``` + +The top-level `httpcore.request()` function is provided for convenience. In practice whenever you're working with `httpcore` you'll want to use the connection pooling functionality that it provides. + +```python +import httpcore + +http = httpcore.ConnectionPool() +response = http.request("GET", "https://www.example.com/") +``` + +Once you're ready to get going, [head over to the documentation](https://www.encode.io/httpcore/). + +## Motivation + +You *probably* don't want to be using HTTP Core directly. It might make sense if +you're writing something like a proxy service in Python, and you just want +something at the lowest possible level, but more typically you'll want to use +a higher level client library, such as `httpx`. + +The motivation for `httpcore` is: + +* To provide a reusable low-level client library, that other packages can then build on top of. +* To provide a *really clear interface split* between the networking code and client logic, + so that each is easier to understand and reason about in isolation. + +## Dependencies + +The `httpcore` package has the following dependencies... + +* `h11` +* `certifi` + +And the following optional extras... + +* `anyio` - Required by `pip install httpcore['asyncio']`. +* `trio` - Required by `pip install httpcore['trio']`. +* `h2` - Required by `pip install httpcore['http2']`. +* `socksio` - Required by `pip install httpcore['socks']`. + +## Versioning + +We use [SEMVER for our versioning policy](https://semver.org/). + +For changes between package versions please see our [project changelog](CHANGELOG.md). + +We recommend pinning your requirements either the most current major version, or a more specific version range: + +```python +pip install 'httpcore==1.*' +``` +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +## Version 1.0.9 (April 24th, 2025) + +- Resolve https://github.com/advisories/GHSA-vqfr-h8mv-ghfj with h11 dependency update. (#1008) + +## Version 1.0.8 (April 11th, 2025) + +- Fix `AttributeError` when importing on Python 3.14. (#1005) + +## Version 1.0.7 (November 15th, 2024) + +- Support `proxy=…` configuration on `ConnectionPool()`. (#974) + +## Version 1.0.6 (October 1st, 2024) + +- Relax `trio` dependency pinning. (#956) +- Handle `trio` raising `NotImplementedError` on unsupported platforms. (#955) +- Handle mapping `ssl.SSLError` to `httpcore.ConnectError`. (#918) + +## 1.0.5 (March 27th, 2024) + +- Handle `EndOfStream` exception for anyio backend. (#899) +- Allow trio `0.25.*` series in package dependancies. (#903) + +## 1.0.4 (February 21st, 2024) + +- Add `target` request extension. (#888) +- Fix support for connection `Upgrade` and `CONNECT` when some data in the stream has been read. (#882) + +## 1.0.3 (February 13th, 2024) + +- Fix support for async cancellations. (#880) +- Fix trace extension when used with socks proxy. (#849) +- Fix SSL context for connections using the "wss" scheme (#869) + +## 1.0.2 (November 10th, 2023) + +- Fix `float("inf")` timeouts in `Event.wait` function. (#846) + +## 1.0.1 (November 3rd, 2023) + +- Fix pool timeout to account for the total time spent retrying. (#823) +- Raise a neater RuntimeError when the correct async deps are not installed. (#826) +- Add support for synchronous TLS-in-TLS streams. (#840) + +## 1.0.0 (October 6th, 2023) + +From version 1.0 our async support is now optional, as the package has minimal dependencies by default. + +For async support use either `pip install 'httpcore[asyncio]'` or `pip install 'httpcore[trio]'`. + +The project versioning policy is now explicitly governed by SEMVER. See https://semver.org/. + +- Async support becomes fully optional. (#809) +- Add support for Python 3.12. (#807) + +## 0.18.0 (September 8th, 2023) + +- Add support for HTTPS proxies. (#745, #786) +- Drop Python 3.7 support. (#727) +- Handle `sni_hostname` extension with SOCKS proxy. (#774) +- Handle HTTP/1.1 half-closed connections gracefully. (#641) +- Change the type of `Extensions` from `Mapping[Str, Any]` to `MutableMapping[Str, Any]`. (#762) + +## 0.17.3 (July 5th, 2023) + +- Support async cancellations, ensuring that the connection pool is left in a clean state when cancellations occur. (#726) +- The networking backend interface has [been added to the public API](https://www.encode.io/httpcore/network-backends). Some classes which were previously private implementation detail are now part of the top-level public API. (#699) +- Graceful handling of HTTP/2 GoAway frames, with requests being transparently retried on a new connection. (#730) +- Add exceptions when a synchronous `trace callback` is passed to an asynchronous request or an asynchronous `trace callback` is passed to a synchronous request. (#717) +- Drop Python 3.7 support. (#727) + +## 0.17.2 (May 23th, 2023) + +- Add `socket_options` argument to `ConnectionPool` and `HTTProxy` classes. (#668) +- Improve logging with per-module logger names. (#690) +- Add `sni_hostname` request extension. (#696) +- Resolve race condition during import of `anyio` package. (#692) +- Enable TCP_NODELAY for all synchronous sockets. (#651) + +## 0.17.1 (May 17th, 2023) + +- If 'retries' is set, then allow retries if an SSL handshake error occurs. (#669) +- Improve correctness of tracebacks on network exceptions, by raising properly chained exceptions. (#678) +- Prevent connection-hanging behaviour when HTTP/2 connections are closed by a server-sent 'GoAway' frame. (#679) +- Fix edge-case exception when removing requests from the connection pool. (#680) +- Fix pool timeout edge-case. (#688) + +## 0.17.0 (March 16th, 2023) + +- Add DEBUG level logging. (#648) +- Respect HTTP/2 max concurrent streams when settings updates are sent by server. (#652) +- Increase the allowable HTTP header size to 100kB. (#647) +- Add `retries` option to SOCKS proxy classes. (#643) + +## 0.16.3 (December 20th, 2022) + +- Allow `ws` and `wss` schemes. Allows us to properly support websocket upgrade connections. (#625) +- Forwarding HTTP proxies use a connection-per-remote-host. Required by some proxy implementations. (#637) +- Don't raise `RuntimeError` when closing a connection pool with active connections. Removes some error cases when cancellations are used. (#631) +- Lazy import `anyio`, so that it's no longer a hard dependancy, and isn't imported if unused. (#639) + +## 0.16.2 (November 25th, 2022) + +- Revert 'Fix async cancellation behaviour', which introduced race conditions. (#627) +- Raise `RuntimeError` if attempting to us UNIX domain sockets on Windows. (#619) + +## 0.16.1 (November 17th, 2022) + +- Fix HTTP/1.1 interim informational responses, such as "100 Continue". (#605) + +## 0.16.0 (October 11th, 2022) + +- Support HTTP/1.1 informational responses. (#581) +- Fix async cancellation behaviour. (#580) +- Support `h11` 0.14. (#579) + +## 0.15.0 (May 17th, 2022) + +- Drop Python 3.6 support (#535) +- Ensure HTTP proxy CONNECT requests include `timeout` configuration. (#506) +- Switch to explicit `typing.Optional` for type hints. (#513) +- For `trio` map OSError exceptions to `ConnectError`. (#543) + +## 0.14.7 (February 4th, 2022) + +- Requests which raise a PoolTimeout need to be removed from the pool queue. (#502) +- Fix AttributeError that happened when Socks5Connection were terminated. (#501) + +## 0.14.6 (February 1st, 2022) + +- Fix SOCKS support for `http://` URLs. (#492) +- Resolve race condition around exceptions during streaming a response. (#491) + +## 0.14.5 (January 18th, 2022) + +- SOCKS proxy support. (#478) +- Add proxy_auth argument to HTTPProxy. (#481) +- Improve error message on 'RemoteProtocolError' exception when server disconnects without sending a response. (#479) + +## 0.14.4 (January 5th, 2022) + +- Support HTTP/2 on HTTPS tunnelling proxies. (#468) +- Fix proxy headers missing on HTTP forwarding. (#456) +- Only instantiate SSL context if required. (#457) +- More robust HTTP/2 handling. (#253, #439, #440, #441) + +## 0.14.3 (November 17th, 2021) + +- Fix race condition when removing closed connections from the pool. (#437) + +## 0.14.2 (November 16th, 2021) + +- Failed connections no longer remain in the pool. (Pull #433) + +## 0.14.1 (November 12th, 2021) + +- `max_connections` becomes optional. (Pull #429) +- `certifi` is now included in the install dependancies. (Pull #428) +- `h2` is now strictly optional. (Pull #428) + +## 0.14.0 (November 11th, 2021) + +The 0.14 release is a complete reworking of `httpcore`, comprehensively addressing some underlying issues in the connection pooling, as well as substantially redesigning the API to be more user friendly. + +Some of the lower-level API design also makes the components more easily testable in isolation, and the package now has 100% test coverage. + +See [discussion #419](https://github.com/encode/httpcore/discussions/419) for a little more background. + +There's some other neat bits in there too, such as the "trace" extension, which gives a hook into inspecting the internal events that occur during the request/response cycle. This extension is needed for the HTTPX cli, in order to... + +* Log the point at which the connection is established, and the IP/port on which it is made. +* Determine if the outgoing request should log as HTTP/1.1 or HTTP/2, rather than having to assume it's HTTP/2 if the --http2 flag was passed. (Which may not actually be true.) +* Log SSL version info / certificate info. + +Note that `curio` support is not currently available in 0.14.0. If you're using `httpcore` with `curio` please get in touch, so we can assess if we ought to prioritize it as a feature or not. + +## 0.13.7 (September 13th, 2021) + +- Fix broken error messaging when URL scheme is missing, or a non HTTP(S) scheme is used. (Pull #403) + +## 0.13.6 (June 15th, 2021) + +### Fixed + +- Close sockets when read or write timeouts occur. (Pull #365) + +## 0.13.5 (June 14th, 2021) + +### Fixed + +- Resolved niggles with AnyIO EOF behaviours. (Pull #358, #362) + +## 0.13.4 (June 9th, 2021) + +### Added + +- Improved error messaging when URL scheme is missing, or a non HTTP(S) scheme is used. (Pull #354) + +### Fixed + +- Switched to `anyio` as the default backend implementation when running with `asyncio`. Resolves some awkward [TLS timeout issues](https://github.com/encode/httpx/discussions/1511). + +## 0.13.3 (May 6th, 2021) + +### Added + +- Support HTTP/2 prior knowledge, using `httpcore.SyncConnectionPool(http1=False)`. (Pull #333) + +### Fixed + +- Handle cases where environment does not provide `select.poll` support. (Pull #331) + +## 0.13.2 (April 29th, 2021) + +### Added + +- Improve error message for specific case of `RemoteProtocolError` where server disconnects without sending a response. (Pull #313) + +## 0.13.1 (April 28th, 2021) + +### Fixed + +- More resiliant testing for closed connections. (Pull #311) +- Don't raise exceptions on ungraceful connection closes. (Pull #310) + +## 0.13.0 (April 21st, 2021) + +The 0.13 release updates the core API in order to match the HTTPX Transport API, +introduced in HTTPX 0.18 onwards. + +An example of making requests with the new interface is: + +```python +with httpcore.SyncConnectionPool() as http: + status_code, headers, stream, extensions = http.handle_request( + method=b'GET', + url=(b'https', b'example.org', 443, b'/'), + headers=[(b'host', b'example.org'), (b'user-agent', b'httpcore')] + stream=httpcore.ByteStream(b''), + extensions={} + ) + body = stream.read() + print(status_code, body) +``` + +### Changed + +- The `.request()` method is now `handle_request()`. (Pull #296) +- The `.arequest()` method is now `.handle_async_request()`. (Pull #296) +- The `headers` argument is no longer optional. (Pull #296) +- The `stream` argument is no longer optional. (Pull #296) +- The `ext` argument is now named `extensions`, and is no longer optional. (Pull #296) +- The `"reason"` extension keyword is now named `"reason_phrase"`. (Pull #296) +- The `"reason_phrase"` and `"http_version"` extensions now use byte strings for their values. (Pull #296) +- The `httpcore.PlainByteStream()` class becomes `httpcore.ByteStream()`. (Pull #296) + +### Added + +- Streams now support a `.read()` interface. (Pull #296) + +### Fixed + +- Task cancellation no longer leaks connections from the connection pool. (Pull #305) + +## 0.12.3 (December 7th, 2020) + +### Fixed + +- Abort SSL connections on close rather than waiting for remote EOF when using `asyncio`. (Pull #167) +- Fix exception raised in case of connect timeouts when using the `anyio` backend. (Pull #236) +- Fix `Host` header precedence for `:authority` in HTTP/2. (Pull #241, #243) +- Handle extra edge case when detecting for socket readability when using `asyncio`. (Pull #242, #244) +- Fix `asyncio` SSL warning when using proxy tunneling. (Pull #249) + +## 0.12.2 (November 20th, 2020) + +### Fixed + +- Properly wrap connect errors on the asyncio backend. (Pull #235) +- Fix `ImportError` occurring on Python 3.9 when using the HTTP/1.1 sync client in a multithreaded context. (Pull #237) + +## 0.12.1 (November 7th, 2020) + +### Added + +- Add connect retries. (Pull #221) + +### Fixed + +- Tweak detection of dropped connections, resolving an issue with open files limits on Linux. (Pull #185) +- Avoid leaking connections when establishing an HTTP tunnel to a proxy has failed. (Pull #223) +- Properly wrap OS errors when using `trio`. (Pull #225) + +## 0.12.0 (October 6th, 2020) + +### Changed + +- HTTP header casing is now preserved, rather than always sent in lowercase. (#216 and python-hyper/h11#104) + +### Added + +- Add Python 3.9 to officially supported versions. + +### Fixed + +- Gracefully handle a stdlib asyncio bug when a connection is closed while it is in a paused-for-reading state. (#201) + +## 0.11.1 (September 28nd, 2020) + +### Fixed + +- Add await to async semaphore release() coroutine (#197) +- Drop incorrect curio classifier (#192) + +## 0.11.0 (September 22nd, 2020) + +The Transport API with 0.11.0 has a couple of significant changes. + +Firstly we've moved changed the request interface in order to allow extensions, which will later enable us to support features +such as trailing headers, HTTP/2 server push, and CONNECT/Upgrade connections. + +The interface changes from: + +```python +def request(method, url, headers, stream, timeout): + return (http_version, status_code, reason, headers, stream) +``` + +To instead including an optional dictionary of extensions on the request and response: + +```python +def request(method, url, headers, stream, ext): + return (status_code, headers, stream, ext) +``` + +Having an open-ended extensions point will allow us to add later support for various optional features, that wouldn't otherwise be supported without these API changes. + +In particular: + +* Trailing headers support. +* HTTP/2 Server Push +* sendfile. +* Exposing raw connection on CONNECT, Upgrade, HTTP/2 bi-di streaming. +* Exposing debug information out of the API, including template name, template context. + +Currently extensions are limited to: + +* request: `timeout` - Optional. Timeout dictionary. +* response: `http_version` - Optional. Include the HTTP version used on the response. +* response: `reason` - Optional. Include the reason phrase used on the response. Only valid with HTTP/1.*. + +See https://github.com/encode/httpx/issues/1274#issuecomment-694884553 for the history behind this. + +Secondly, the async version of `request` is now namespaced as `arequest`. + +This allows concrete transports to support both sync and async implementations on the same class. + +### Added + +- Add curio support. (Pull #168) +- Add anyio support, with `backend="anyio"`. (Pull #169) + +### Changed + +- Update the Transport API to use 'ext' for optional extensions. (Pull #190) +- Update the Transport API to use `.request` and `.arequest` so implementations can support both sync and async. (Pull #189) + +## 0.10.2 (August 20th, 2020) + +### Added + +- Added Unix Domain Socket support. (Pull #139) + +### Fixed + +- Always include the port on proxy CONNECT requests. (Pull #154) +- Fix `max_keepalive_connections` configuration. (Pull #153) +- Fixes behaviour in HTTP/1.1 where server disconnects can be used to signal the end of the response body. (Pull #164) + +## 0.10.1 (August 7th, 2020) + +- Include `max_keepalive_connections` on `AsyncHTTPProxy`/`SyncHTTPProxy` classes. + +## 0.10.0 (August 7th, 2020) + +The most notable change in the 0.10.0 release is that HTTP/2 support is now fully optional. + +Use either `pip install httpcore` for HTTP/1.1 support only, or `pip install httpcore[http2]` for HTTP/1.1 and HTTP/2 support. + +### Added + +- HTTP/2 support becomes optional. (Pull #121, #130) +- Add `local_address=...` support. (Pull #100, #134) +- Add `PlainByteStream`, `IteratorByteStream`, `AsyncIteratorByteStream`. The `AsyncByteSteam` and `SyncByteStream` classes are now pure interface classes. (#133) +- Add `LocalProtocolError`, `RemoteProtocolError` exceptions. (Pull #129) +- Add `UnsupportedProtocol` exception. (Pull #128) +- Add `.get_connection_info()` method. (Pull #102, #137) +- Add better TRACE logs. (Pull #101) + +### Changed + +- `max_keepalive` is deprecated in favour of `max_keepalive_connections`. (Pull #140) + +### Fixed + +- Improve handling of server disconnects. (Pull #112) + +## 0.9.1 (May 27th, 2020) + +### Fixed + +- Proper host resolution for sync case, including IPv6 support. (Pull #97) +- Close outstanding connections when connection pool is closed. (Pull #98) + +## 0.9.0 (May 21th, 2020) + +### Changed + +- URL port becomes an `Optional[int]` instead of `int`. (Pull #92) + +### Fixed + +- Honor HTTP/2 max concurrent streams settings. (Pull #89, #90) +- Remove incorrect debug log. (Pull #83) + +## 0.8.4 (May 11th, 2020) + +### Added + +- Logging via HTTPCORE_LOG_LEVEL and HTTPX_LOG_LEVEL environment variables +and TRACE level logging. (Pull #79) + +### Fixed + +- Reuse of connections on HTTP/2 in close concurrency situations. (Pull #81) + +## 0.8.3 (May 6rd, 2020) + +### Fixed + +- Include `Host` and `Accept` headers on proxy "CONNECT" requests. +- De-duplicate any headers also contained in proxy_headers. +- HTTP/2 flag not being passed down to proxy connections. + +## 0.8.2 (May 3rd, 2020) + +### Fixed + +- Fix connections using proxy forwarding requests not being added to the +connection pool properly. (Pull #70) + +## 0.8.1 (April 30th, 2020) + +### Changed + +- Allow inherintance of both `httpcore.AsyncByteStream`, `httpcore.SyncByteStream` without type conflicts. + +## 0.8.0 (April 30th, 2020) + +### Fixed + +- Fixed tunnel proxy support. + +### Added + +- New `TimeoutException` base class. + +## 0.7.0 (March 5th, 2020) + +- First integration with HTTPX. diff --git a/.venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/RECORD b/.venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..2721ed2f4e591feebbb740ca2352ba08f70bb689 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/RECORD @@ -0,0 +1,68 @@ +httpcore-1.0.9.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +httpcore-1.0.9.dist-info/METADATA,sha256=_i1P2mGZEol4d54M8n88BFxTGGP83Zh-rMdPOhjUHCE,21529 +httpcore-1.0.9.dist-info/RECORD,, +httpcore-1.0.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87 +httpcore-1.0.9.dist-info/licenses/LICENSE.md,sha256=_ctZFUx0y6uhahEkL3dAvqnyPW_rVUeRfYxflKgDkqU,1518 +httpcore/__init__.py,sha256=9kT_kqChCCJUTHww24ZmR_ezcdbpRYWksD-gYNzkZP8,3445 +httpcore/__pycache__/__init__.cpython-313.pyc,, +httpcore/__pycache__/_api.cpython-313.pyc,, +httpcore/__pycache__/_exceptions.cpython-313.pyc,, +httpcore/__pycache__/_models.cpython-313.pyc,, +httpcore/__pycache__/_ssl.cpython-313.pyc,, +httpcore/__pycache__/_synchronization.cpython-313.pyc,, +httpcore/__pycache__/_trace.cpython-313.pyc,, +httpcore/__pycache__/_utils.cpython-313.pyc,, +httpcore/_api.py,sha256=unZmeDschBWCGCPCwkS3Wot9euK6bg_kKxLtGTxw214,3146 +httpcore/_async/__init__.py,sha256=EWdl2v4thnAHzJpqjU4h2a8DUiGAvNiWrkii9pfhTf0,1221 +httpcore/_async/__pycache__/__init__.cpython-313.pyc,, +httpcore/_async/__pycache__/connection.cpython-313.pyc,, +httpcore/_async/__pycache__/connection_pool.cpython-313.pyc,, +httpcore/_async/__pycache__/http11.cpython-313.pyc,, +httpcore/_async/__pycache__/http2.cpython-313.pyc,, +httpcore/_async/__pycache__/http_proxy.cpython-313.pyc,, +httpcore/_async/__pycache__/interfaces.cpython-313.pyc,, +httpcore/_async/__pycache__/socks_proxy.cpython-313.pyc,, +httpcore/_async/connection.py,sha256=6OcPXqMEfc0BU38_-iHUNDd1vKSTc2UVT09XqNb_BOk,8449 +httpcore/_async/connection_pool.py,sha256=DOIQ2s2ZCf9qfwxhzMprTPLqCL8OxGXiKF6qRHxvVyY,17307 +httpcore/_async/http11.py,sha256=-qM9bV7PjSQF5vxs37-eUXOIFwbIjPcZbNliuX9TtBw,13880 +httpcore/_async/http2.py,sha256=azX1fcmtXaIwjputFlZ4vd92J8xwjGOa9ax9QIv4394,23936 +httpcore/_async/http_proxy.py,sha256=2zVkrlv-Ds-rWGaqaXlrhEJiAQFPo23BT3Gq_sWoBXU,14701 +httpcore/_async/interfaces.py,sha256=jTiaWL83pgpGC9ziv90ZfwaKNMmHwmOalzaKiuTxATo,4455 +httpcore/_async/socks_proxy.py,sha256=lLKgLlggPfhFlqi0ODeBkOWvt9CghBBUyqsnsU1tx6Q,13841 +httpcore/_backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +httpcore/_backends/__pycache__/__init__.cpython-313.pyc,, +httpcore/_backends/__pycache__/anyio.cpython-313.pyc,, +httpcore/_backends/__pycache__/auto.cpython-313.pyc,, +httpcore/_backends/__pycache__/base.cpython-313.pyc,, +httpcore/_backends/__pycache__/mock.cpython-313.pyc,, +httpcore/_backends/__pycache__/sync.cpython-313.pyc,, +httpcore/_backends/__pycache__/trio.cpython-313.pyc,, +httpcore/_backends/anyio.py,sha256=x8PgEhXRC8bVqsdzk_YJx8Y6d9Tub06CuUSwnbmtqoY,5252 +httpcore/_backends/auto.py,sha256=zO136PKZmsaTDK-HRk84eA-MUg8_2wJf4NvmK432Aio,1662 +httpcore/_backends/base.py,sha256=aShgRdZnMmRhFWHetjumlM73f8Kz1YOAyCUP_4kHslA,3042 +httpcore/_backends/mock.py,sha256=er9T436uSe7NLrfiLa4x6Nuqg5ivQ693CxWYCWsgbH4,4077 +httpcore/_backends/sync.py,sha256=bhE4d9iK9Umxdsdsgm2EfKnXaBms2WggGYU-7jmUujU,7977 +httpcore/_backends/trio.py,sha256=LHu4_Mr5MswQmmT3yE4oLgf9b_JJfeVS4BjDxeJc7Ro,5996 +httpcore/_exceptions.py,sha256=looCKga3_YVYu3s-d3L9RMPRJyhsY7fiuuGxvkOD0c0,1184 +httpcore/_models.py,sha256=IO2CcXcdpovRcLTdGFGB6RyBZdEm2h_TOmoCc4rEKho,17623 +httpcore/_ssl.py,sha256=srqmSNU4iOUvWF-SrJvb8G_YEbHFELOXQOwdDIBTS9c,187 +httpcore/_sync/__init__.py,sha256=JBDIgXt5la1LCJ1sLQeKhjKFpLnpNr8Svs6z2ni3fgg,1141 +httpcore/_sync/__pycache__/__init__.cpython-313.pyc,, +httpcore/_sync/__pycache__/connection.cpython-313.pyc,, +httpcore/_sync/__pycache__/connection_pool.cpython-313.pyc,, +httpcore/_sync/__pycache__/http11.cpython-313.pyc,, +httpcore/_sync/__pycache__/http2.cpython-313.pyc,, +httpcore/_sync/__pycache__/http_proxy.cpython-313.pyc,, +httpcore/_sync/__pycache__/interfaces.cpython-313.pyc,, +httpcore/_sync/__pycache__/socks_proxy.cpython-313.pyc,, +httpcore/_sync/connection.py,sha256=9exGOb3PB-Mp2T1-sckSeL2t-tJ_9-NXomV8ihmWCgU,8238 +httpcore/_sync/connection_pool.py,sha256=a-T8LTsUxc7r0Ww1atfHSDoWPjQ0fA8Ul7S3-F0Mj70,16955 +httpcore/_sync/http11.py,sha256=IFobD1Md5JFlJGKWnh1_Q3epikUryI8qo09v8MiJIEA,13476 +httpcore/_sync/http2.py,sha256=AxU4yhcq68Bn5vqdJYtiXKYUj7nvhYbxz3v4rT4xnvA,23400 +httpcore/_sync/http_proxy.py,sha256=_al_6crKuEZu2wyvu493RZImJdBJnj5oGKNjLOJL2Zo,14463 +httpcore/_sync/interfaces.py,sha256=snXON42vUDHO5JBJvo8D4VWk2Wat44z2OXXHDrjbl94,4344 +httpcore/_sync/socks_proxy.py,sha256=zegZW9Snqj2_992DFJa8_CppOVBkVL4AgwduRkStakQ,13614 +httpcore/_synchronization.py,sha256=zSi13mAColBnknjZBknUC6hKNDQT4C6ijnezZ-r0T2s,9434 +httpcore/_trace.py,sha256=ck6ZoIzYTkdNAIfq5MGeKqBXDtqjOX-qfYwmZFbrGco,3952 +httpcore/_utils.py,sha256=_RLgXYOAYC350ikALV59GZ68IJrdocRZxPs9PjmzdFY,1537 +httpcore/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/.venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/WHEEL b/.venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..12228d414b6cfed7c39d3781c85c63256a1d7fb5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.27.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/licenses/LICENSE.md b/.venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/licenses/LICENSE.md new file mode 100644 index 0000000000000000000000000000000000000000..311b2b56c53f678ab95fc0def708c675d521a807 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/licenses/LICENSE.md @@ -0,0 +1,27 @@ +Copyright © 2020, [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/python3.13/site-packages/httpcore/__init__.py b/.venv/lib/python3.13/site-packages/httpcore/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9a92dc4a440bdf6f259ec1083c89c817eb7b631b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/__init__.py @@ -0,0 +1,141 @@ +from ._api import request, stream +from ._async import ( + AsyncConnectionInterface, + AsyncConnectionPool, + AsyncHTTP2Connection, + AsyncHTTP11Connection, + AsyncHTTPConnection, + AsyncHTTPProxy, + AsyncSOCKSProxy, +) +from ._backends.base import ( + SOCKET_OPTION, + AsyncNetworkBackend, + AsyncNetworkStream, + NetworkBackend, + NetworkStream, +) +from ._backends.mock import AsyncMockBackend, AsyncMockStream, MockBackend, MockStream +from ._backends.sync import SyncBackend +from ._exceptions import ( + ConnectError, + ConnectionNotAvailable, + ConnectTimeout, + LocalProtocolError, + NetworkError, + PoolTimeout, + ProtocolError, + ProxyError, + ReadError, + ReadTimeout, + RemoteProtocolError, + TimeoutException, + UnsupportedProtocol, + WriteError, + WriteTimeout, +) +from ._models import URL, Origin, Proxy, Request, Response +from ._ssl import default_ssl_context +from ._sync import ( + ConnectionInterface, + ConnectionPool, + HTTP2Connection, + HTTP11Connection, + HTTPConnection, + HTTPProxy, + SOCKSProxy, +) + +# The 'httpcore.AnyIOBackend' class is conditional on 'anyio' being installed. +try: + from ._backends.anyio import AnyIOBackend +except ImportError: # pragma: nocover + + class AnyIOBackend: # type: ignore + def __init__(self, *args, **kwargs): # type: ignore + msg = ( + "Attempted to use 'httpcore.AnyIOBackend' but 'anyio' is not installed." + ) + raise RuntimeError(msg) + + +# The 'httpcore.TrioBackend' class is conditional on 'trio' being installed. +try: + from ._backends.trio import TrioBackend +except ImportError: # pragma: nocover + + class TrioBackend: # type: ignore + def __init__(self, *args, **kwargs): # type: ignore + msg = "Attempted to use 'httpcore.TrioBackend' but 'trio' is not installed." + raise RuntimeError(msg) + + +__all__ = [ + # top-level requests + "request", + "stream", + # models + "Origin", + "URL", + "Request", + "Response", + "Proxy", + # async + "AsyncHTTPConnection", + "AsyncConnectionPool", + "AsyncHTTPProxy", + "AsyncHTTP11Connection", + "AsyncHTTP2Connection", + "AsyncConnectionInterface", + "AsyncSOCKSProxy", + # sync + "HTTPConnection", + "ConnectionPool", + "HTTPProxy", + "HTTP11Connection", + "HTTP2Connection", + "ConnectionInterface", + "SOCKSProxy", + # network backends, implementations + "SyncBackend", + "AnyIOBackend", + "TrioBackend", + # network backends, mock implementations + "AsyncMockBackend", + "AsyncMockStream", + "MockBackend", + "MockStream", + # network backends, interface + "AsyncNetworkStream", + "AsyncNetworkBackend", + "NetworkStream", + "NetworkBackend", + # util + "default_ssl_context", + "SOCKET_OPTION", + # exceptions + "ConnectionNotAvailable", + "ProxyError", + "ProtocolError", + "LocalProtocolError", + "RemoteProtocolError", + "UnsupportedProtocol", + "TimeoutException", + "PoolTimeout", + "ConnectTimeout", + "ReadTimeout", + "WriteTimeout", + "NetworkError", + "ConnectError", + "ReadError", + "WriteError", +] + +__version__ = "1.0.9" + + +__locals = locals() +for __name in __all__: + # Exclude SOCKET_OPTION, it causes AttributeError on Python 3.14 + if not __name.startswith(("__", "SOCKET_OPTION")): + setattr(__locals[__name], "__module__", "httpcore") # noqa diff --git a/.venv/lib/python3.13/site-packages/httpcore/_api.py b/.venv/lib/python3.13/site-packages/httpcore/_api.py new file mode 100644 index 0000000000000000000000000000000000000000..38b961d10de88bebc98c758d0d1f14af1e7c0370 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_api.py @@ -0,0 +1,94 @@ +from __future__ import annotations + +import contextlib +import typing + +from ._models import URL, Extensions, HeaderTypes, Response +from ._sync.connection_pool import ConnectionPool + + +def request( + method: bytes | str, + url: URL | bytes | str, + *, + headers: HeaderTypes = None, + content: bytes | typing.Iterator[bytes] | None = None, + extensions: Extensions | None = None, +) -> Response: + """ + Sends an HTTP request, returning the response. + + ``` + response = httpcore.request("GET", "https://www.example.com/") + ``` + + Arguments: + method: The HTTP method for the request. Typically one of `"GET"`, + `"OPTIONS"`, `"HEAD"`, `"POST"`, `"PUT"`, `"PATCH"`, or `"DELETE"`. + url: The URL of the HTTP request. Either as an instance of `httpcore.URL`, + or as str/bytes. + headers: The HTTP request headers. Either as a dictionary of str/bytes, + or as a list of two-tuples of str/bytes. + content: The content of the request body. Either as bytes, + or as a bytes iterator. + extensions: A dictionary of optional extra information included on the request. + Possible keys include `"timeout"`. + + Returns: + An instance of `httpcore.Response`. + """ + with ConnectionPool() as pool: + return pool.request( + method=method, + url=url, + headers=headers, + content=content, + extensions=extensions, + ) + + +@contextlib.contextmanager +def stream( + method: bytes | str, + url: URL | bytes | str, + *, + headers: HeaderTypes = None, + content: bytes | typing.Iterator[bytes] | None = None, + extensions: Extensions | None = None, +) -> typing.Iterator[Response]: + """ + Sends an HTTP request, returning the response within a content manager. + + ``` + with httpcore.stream("GET", "https://www.example.com/") as response: + ... + ``` + + When using the `stream()` function, the body of the response will not be + automatically read. If you want to access the response body you should + either use `content = response.read()`, or `for chunk in response.iter_content()`. + + Arguments: + method: The HTTP method for the request. Typically one of `"GET"`, + `"OPTIONS"`, `"HEAD"`, `"POST"`, `"PUT"`, `"PATCH"`, or `"DELETE"`. + url: The URL of the HTTP request. Either as an instance of `httpcore.URL`, + or as str/bytes. + headers: The HTTP request headers. Either as a dictionary of str/bytes, + or as a list of two-tuples of str/bytes. + content: The content of the request body. Either as bytes, + or as a bytes iterator. + extensions: A dictionary of optional extra information included on the request. + Possible keys include `"timeout"`. + + Returns: + An instance of `httpcore.Response`. + """ + with ConnectionPool() as pool: + with pool.stream( + method=method, + url=url, + headers=headers, + content=content, + extensions=extensions, + ) as response: + yield response diff --git a/.venv/lib/python3.13/site-packages/httpcore/_async/__init__.py b/.venv/lib/python3.13/site-packages/httpcore/_async/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..88dc7f01e132933728cbcf45c88ce82e85ddf65f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_async/__init__.py @@ -0,0 +1,39 @@ +from .connection import AsyncHTTPConnection +from .connection_pool import AsyncConnectionPool +from .http11 import AsyncHTTP11Connection +from .http_proxy import AsyncHTTPProxy +from .interfaces import AsyncConnectionInterface + +try: + from .http2 import AsyncHTTP2Connection +except ImportError: # pragma: nocover + + class AsyncHTTP2Connection: # type: ignore + def __init__(self, *args, **kwargs) -> None: # type: ignore + raise RuntimeError( + "Attempted to use http2 support, but the `h2` package is not " + "installed. Use 'pip install httpcore[http2]'." + ) + + +try: + from .socks_proxy import AsyncSOCKSProxy +except ImportError: # pragma: nocover + + class AsyncSOCKSProxy: # type: ignore + def __init__(self, *args, **kwargs) -> None: # type: ignore + raise RuntimeError( + "Attempted to use SOCKS support, but the `socksio` package is not " + "installed. Use 'pip install httpcore[socks]'." + ) + + +__all__ = [ + "AsyncHTTPConnection", + "AsyncConnectionPool", + "AsyncHTTPProxy", + "AsyncHTTP11Connection", + "AsyncHTTP2Connection", + "AsyncConnectionInterface", + "AsyncSOCKSProxy", +] diff --git a/.venv/lib/python3.13/site-packages/httpcore/_async/connection.py b/.venv/lib/python3.13/site-packages/httpcore/_async/connection.py new file mode 100644 index 0000000000000000000000000000000000000000..b42581dff8aabf4c2ef80ffda26296e1b368d693 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_async/connection.py @@ -0,0 +1,222 @@ +from __future__ import annotations + +import itertools +import logging +import ssl +import types +import typing + +from .._backends.auto import AutoBackend +from .._backends.base import SOCKET_OPTION, AsyncNetworkBackend, AsyncNetworkStream +from .._exceptions import ConnectError, ConnectTimeout +from .._models import Origin, Request, Response +from .._ssl import default_ssl_context +from .._synchronization import AsyncLock +from .._trace import Trace +from .http11 import AsyncHTTP11Connection +from .interfaces import AsyncConnectionInterface + +RETRIES_BACKOFF_FACTOR = 0.5 # 0s, 0.5s, 1s, 2s, 4s, etc. + + +logger = logging.getLogger("httpcore.connection") + + +def exponential_backoff(factor: float) -> typing.Iterator[float]: + """ + Generate a geometric sequence that has a ratio of 2 and starts with 0. + + For example: + - `factor = 2`: `0, 2, 4, 8, 16, 32, 64, ...` + - `factor = 3`: `0, 3, 6, 12, 24, 48, 96, ...` + """ + yield 0 + for n in itertools.count(): + yield factor * 2**n + + +class AsyncHTTPConnection(AsyncConnectionInterface): + def __init__( + self, + origin: Origin, + ssl_context: ssl.SSLContext | None = None, + keepalive_expiry: float | None = None, + http1: bool = True, + http2: bool = False, + retries: int = 0, + local_address: str | None = None, + uds: str | None = None, + network_backend: AsyncNetworkBackend | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> None: + self._origin = origin + self._ssl_context = ssl_context + self._keepalive_expiry = keepalive_expiry + self._http1 = http1 + self._http2 = http2 + self._retries = retries + self._local_address = local_address + self._uds = uds + + self._network_backend: AsyncNetworkBackend = ( + AutoBackend() if network_backend is None else network_backend + ) + self._connection: AsyncConnectionInterface | None = None + self._connect_failed: bool = False + self._request_lock = AsyncLock() + self._socket_options = socket_options + + async def handle_async_request(self, request: Request) -> Response: + if not self.can_handle_request(request.url.origin): + raise RuntimeError( + f"Attempted to send request to {request.url.origin} on connection to {self._origin}" + ) + + try: + async with self._request_lock: + if self._connection is None: + stream = await self._connect(request) + + ssl_object = stream.get_extra_info("ssl_object") + http2_negotiated = ( + ssl_object is not None + and ssl_object.selected_alpn_protocol() == "h2" + ) + if http2_negotiated or (self._http2 and not self._http1): + from .http2 import AsyncHTTP2Connection + + self._connection = AsyncHTTP2Connection( + origin=self._origin, + stream=stream, + keepalive_expiry=self._keepalive_expiry, + ) + else: + self._connection = AsyncHTTP11Connection( + origin=self._origin, + stream=stream, + keepalive_expiry=self._keepalive_expiry, + ) + except BaseException as exc: + self._connect_failed = True + raise exc + + return await self._connection.handle_async_request(request) + + async def _connect(self, request: Request) -> AsyncNetworkStream: + timeouts = request.extensions.get("timeout", {}) + sni_hostname = request.extensions.get("sni_hostname", None) + timeout = timeouts.get("connect", None) + + retries_left = self._retries + delays = exponential_backoff(factor=RETRIES_BACKOFF_FACTOR) + + while True: + try: + if self._uds is None: + kwargs = { + "host": self._origin.host.decode("ascii"), + "port": self._origin.port, + "local_address": self._local_address, + "timeout": timeout, + "socket_options": self._socket_options, + } + async with Trace("connect_tcp", logger, request, kwargs) as trace: + stream = await self._network_backend.connect_tcp(**kwargs) + trace.return_value = stream + else: + kwargs = { + "path": self._uds, + "timeout": timeout, + "socket_options": self._socket_options, + } + async with Trace( + "connect_unix_socket", logger, request, kwargs + ) as trace: + stream = await self._network_backend.connect_unix_socket( + **kwargs + ) + trace.return_value = stream + + if self._origin.scheme in (b"https", b"wss"): + ssl_context = ( + default_ssl_context() + if self._ssl_context is None + else self._ssl_context + ) + alpn_protocols = ["http/1.1", "h2"] if self._http2 else ["http/1.1"] + ssl_context.set_alpn_protocols(alpn_protocols) + + kwargs = { + "ssl_context": ssl_context, + "server_hostname": sni_hostname + or self._origin.host.decode("ascii"), + "timeout": timeout, + } + async with Trace("start_tls", logger, request, kwargs) as trace: + stream = await stream.start_tls(**kwargs) + trace.return_value = stream + return stream + except (ConnectError, ConnectTimeout): + if retries_left <= 0: + raise + retries_left -= 1 + delay = next(delays) + async with Trace("retry", logger, request, kwargs) as trace: + await self._network_backend.sleep(delay) + + def can_handle_request(self, origin: Origin) -> bool: + return origin == self._origin + + async def aclose(self) -> None: + if self._connection is not None: + async with Trace("close", logger, None, {}): + await self._connection.aclose() + + def is_available(self) -> bool: + if self._connection is None: + # If HTTP/2 support is enabled, and the resulting connection could + # end up as HTTP/2 then we should indicate the connection as being + # available to service multiple requests. + return ( + self._http2 + and (self._origin.scheme == b"https" or not self._http1) + and not self._connect_failed + ) + return self._connection.is_available() + + def has_expired(self) -> bool: + if self._connection is None: + return self._connect_failed + return self._connection.has_expired() + + def is_idle(self) -> bool: + if self._connection is None: + return self._connect_failed + return self._connection.is_idle() + + def is_closed(self) -> bool: + if self._connection is None: + return self._connect_failed + return self._connection.is_closed() + + def info(self) -> str: + if self._connection is None: + return "CONNECTION FAILED" if self._connect_failed else "CONNECTING" + return self._connection.info() + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} [{self.info()}]>" + + # These context managers are not used in the standard flow, but are + # useful for testing or working with connection instances directly. + + async def __aenter__(self) -> AsyncHTTPConnection: + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + await self.aclose() diff --git a/.venv/lib/python3.13/site-packages/httpcore/_async/connection_pool.py b/.venv/lib/python3.13/site-packages/httpcore/_async/connection_pool.py new file mode 100644 index 0000000000000000000000000000000000000000..96e973d0ce223f6bed9be9e6a6a2f3c01622c611 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_async/connection_pool.py @@ -0,0 +1,420 @@ +from __future__ import annotations + +import ssl +import sys +import types +import typing + +from .._backends.auto import AutoBackend +from .._backends.base import SOCKET_OPTION, AsyncNetworkBackend +from .._exceptions import ConnectionNotAvailable, UnsupportedProtocol +from .._models import Origin, Proxy, Request, Response +from .._synchronization import AsyncEvent, AsyncShieldCancellation, AsyncThreadLock +from .connection import AsyncHTTPConnection +from .interfaces import AsyncConnectionInterface, AsyncRequestInterface + + +class AsyncPoolRequest: + def __init__(self, request: Request) -> None: + self.request = request + self.connection: AsyncConnectionInterface | None = None + self._connection_acquired = AsyncEvent() + + def assign_to_connection(self, connection: AsyncConnectionInterface | None) -> None: + self.connection = connection + self._connection_acquired.set() + + def clear_connection(self) -> None: + self.connection = None + self._connection_acquired = AsyncEvent() + + async def wait_for_connection( + self, timeout: float | None = None + ) -> AsyncConnectionInterface: + if self.connection is None: + await self._connection_acquired.wait(timeout=timeout) + assert self.connection is not None + return self.connection + + def is_queued(self) -> bool: + return self.connection is None + + +class AsyncConnectionPool(AsyncRequestInterface): + """ + A connection pool for making HTTP requests. + """ + + def __init__( + self, + ssl_context: ssl.SSLContext | None = None, + proxy: Proxy | None = None, + max_connections: int | None = 10, + max_keepalive_connections: int | None = None, + keepalive_expiry: float | None = None, + http1: bool = True, + http2: bool = False, + retries: int = 0, + local_address: str | None = None, + uds: str | None = None, + network_backend: AsyncNetworkBackend | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> None: + """ + A connection pool for making HTTP requests. + + Parameters: + ssl_context: An SSL context to use for verifying connections. + If not specified, the default `httpcore.default_ssl_context()` + will be used. + max_connections: The maximum number of concurrent HTTP connections that + the pool should allow. Any attempt to send a request on a pool that + would exceed this amount will block until a connection is available. + max_keepalive_connections: The maximum number of idle HTTP connections + that will be maintained in the pool. + keepalive_expiry: The duration in seconds that an idle HTTP connection + may be maintained for before being expired from the pool. + http1: A boolean indicating if HTTP/1.1 requests should be supported + by the connection pool. Defaults to True. + http2: A boolean indicating if HTTP/2 requests should be supported by + the connection pool. Defaults to False. + retries: The maximum number of retries when trying to establish a + connection. + local_address: Local address to connect from. Can also be used to connect + using a particular address family. Using `local_address="0.0.0.0"` + will connect using an `AF_INET` address (IPv4), while using + `local_address="::"` will connect using an `AF_INET6` address (IPv6). + uds: Path to a Unix Domain Socket to use instead of TCP sockets. + network_backend: A backend instance to use for handling network I/O. + socket_options: Socket options that have to be included + in the TCP socket when the connection was established. + """ + self._ssl_context = ssl_context + self._proxy = proxy + self._max_connections = ( + sys.maxsize if max_connections is None else max_connections + ) + self._max_keepalive_connections = ( + sys.maxsize + if max_keepalive_connections is None + else max_keepalive_connections + ) + self._max_keepalive_connections = min( + self._max_connections, self._max_keepalive_connections + ) + + self._keepalive_expiry = keepalive_expiry + self._http1 = http1 + self._http2 = http2 + self._retries = retries + self._local_address = local_address + self._uds = uds + + self._network_backend = ( + AutoBackend() if network_backend is None else network_backend + ) + self._socket_options = socket_options + + # The mutable state on a connection pool is the queue of incoming requests, + # and the set of connections that are servicing those requests. + self._connections: list[AsyncConnectionInterface] = [] + self._requests: list[AsyncPoolRequest] = [] + + # We only mutate the state of the connection pool within an 'optional_thread_lock' + # context. This holds a threading lock unless we're running in async mode, + # in which case it is a no-op. + self._optional_thread_lock = AsyncThreadLock() + + def create_connection(self, origin: Origin) -> AsyncConnectionInterface: + if self._proxy is not None: + if self._proxy.url.scheme in (b"socks5", b"socks5h"): + from .socks_proxy import AsyncSocks5Connection + + return AsyncSocks5Connection( + proxy_origin=self._proxy.url.origin, + proxy_auth=self._proxy.auth, + remote_origin=origin, + ssl_context=self._ssl_context, + keepalive_expiry=self._keepalive_expiry, + http1=self._http1, + http2=self._http2, + network_backend=self._network_backend, + ) + elif origin.scheme == b"http": + from .http_proxy import AsyncForwardHTTPConnection + + return AsyncForwardHTTPConnection( + proxy_origin=self._proxy.url.origin, + proxy_headers=self._proxy.headers, + proxy_ssl_context=self._proxy.ssl_context, + remote_origin=origin, + keepalive_expiry=self._keepalive_expiry, + network_backend=self._network_backend, + ) + from .http_proxy import AsyncTunnelHTTPConnection + + return AsyncTunnelHTTPConnection( + proxy_origin=self._proxy.url.origin, + proxy_headers=self._proxy.headers, + proxy_ssl_context=self._proxy.ssl_context, + remote_origin=origin, + ssl_context=self._ssl_context, + keepalive_expiry=self._keepalive_expiry, + http1=self._http1, + http2=self._http2, + network_backend=self._network_backend, + ) + + return AsyncHTTPConnection( + origin=origin, + ssl_context=self._ssl_context, + keepalive_expiry=self._keepalive_expiry, + http1=self._http1, + http2=self._http2, + retries=self._retries, + local_address=self._local_address, + uds=self._uds, + network_backend=self._network_backend, + socket_options=self._socket_options, + ) + + @property + def connections(self) -> list[AsyncConnectionInterface]: + """ + Return a list of the connections currently in the pool. + + For example: + + ```python + >>> pool.connections + [ + , + , + , + ] + ``` + """ + return list(self._connections) + + async def handle_async_request(self, request: Request) -> Response: + """ + Send an HTTP request, and return an HTTP response. + + This is the core implementation that is called into by `.request()` or `.stream()`. + """ + scheme = request.url.scheme.decode() + if scheme == "": + raise UnsupportedProtocol( + "Request URL is missing an 'http://' or 'https://' protocol." + ) + if scheme not in ("http", "https", "ws", "wss"): + raise UnsupportedProtocol( + f"Request URL has an unsupported protocol '{scheme}://'." + ) + + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("pool", None) + + with self._optional_thread_lock: + # Add the incoming request to our request queue. + pool_request = AsyncPoolRequest(request) + self._requests.append(pool_request) + + try: + while True: + with self._optional_thread_lock: + # Assign incoming requests to available connections, + # closing or creating new connections as required. + closing = self._assign_requests_to_connections() + await self._close_connections(closing) + + # Wait until this request has an assigned connection. + connection = await pool_request.wait_for_connection(timeout=timeout) + + try: + # Send the request on the assigned connection. + response = await connection.handle_async_request( + pool_request.request + ) + except ConnectionNotAvailable: + # In some cases a connection may initially be available to + # handle a request, but then become unavailable. + # + # In this case we clear the connection and try again. + pool_request.clear_connection() + else: + break # pragma: nocover + + except BaseException as exc: + with self._optional_thread_lock: + # For any exception or cancellation we remove the request from + # the queue, and then re-assign requests to connections. + self._requests.remove(pool_request) + closing = self._assign_requests_to_connections() + + await self._close_connections(closing) + raise exc from None + + # Return the response. Note that in this case we still have to manage + # the point at which the response is closed. + assert isinstance(response.stream, typing.AsyncIterable) + return Response( + status=response.status, + headers=response.headers, + content=PoolByteStream( + stream=response.stream, pool_request=pool_request, pool=self + ), + extensions=response.extensions, + ) + + def _assign_requests_to_connections(self) -> list[AsyncConnectionInterface]: + """ + Manage the state of the connection pool, assigning incoming + requests to connections as available. + + Called whenever a new request is added or removed from the pool. + + Any closing connections are returned, allowing the I/O for closing + those connections to be handled seperately. + """ + closing_connections = [] + + # First we handle cleaning up any connections that are closed, + # have expired their keep-alive, or surplus idle connections. + for connection in list(self._connections): + if connection.is_closed(): + # log: "removing closed connection" + self._connections.remove(connection) + elif connection.has_expired(): + # log: "closing expired connection" + self._connections.remove(connection) + closing_connections.append(connection) + elif ( + connection.is_idle() + and len([connection.is_idle() for connection in self._connections]) + > self._max_keepalive_connections + ): + # log: "closing idle connection" + self._connections.remove(connection) + closing_connections.append(connection) + + # Assign queued requests to connections. + queued_requests = [request for request in self._requests if request.is_queued()] + for pool_request in queued_requests: + origin = pool_request.request.url.origin + available_connections = [ + connection + for connection in self._connections + if connection.can_handle_request(origin) and connection.is_available() + ] + idle_connections = [ + connection for connection in self._connections if connection.is_idle() + ] + + # There are three cases for how we may be able to handle the request: + # + # 1. There is an existing connection that can handle the request. + # 2. We can create a new connection to handle the request. + # 3. We can close an idle connection and then create a new connection + # to handle the request. + if available_connections: + # log: "reusing existing connection" + connection = available_connections[0] + pool_request.assign_to_connection(connection) + elif len(self._connections) < self._max_connections: + # log: "creating new connection" + connection = self.create_connection(origin) + self._connections.append(connection) + pool_request.assign_to_connection(connection) + elif idle_connections: + # log: "closing idle connection" + connection = idle_connections[0] + self._connections.remove(connection) + closing_connections.append(connection) + # log: "creating new connection" + connection = self.create_connection(origin) + self._connections.append(connection) + pool_request.assign_to_connection(connection) + + return closing_connections + + async def _close_connections(self, closing: list[AsyncConnectionInterface]) -> None: + # Close connections which have been removed from the pool. + with AsyncShieldCancellation(): + for connection in closing: + await connection.aclose() + + async def aclose(self) -> None: + # Explicitly close the connection pool. + # Clears all existing requests and connections. + with self._optional_thread_lock: + closing_connections = list(self._connections) + self._connections = [] + await self._close_connections(closing_connections) + + async def __aenter__(self) -> AsyncConnectionPool: + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + await self.aclose() + + def __repr__(self) -> str: + class_name = self.__class__.__name__ + with self._optional_thread_lock: + request_is_queued = [request.is_queued() for request in self._requests] + connection_is_idle = [ + connection.is_idle() for connection in self._connections + ] + + num_active_requests = request_is_queued.count(False) + num_queued_requests = request_is_queued.count(True) + num_active_connections = connection_is_idle.count(False) + num_idle_connections = connection_is_idle.count(True) + + requests_info = ( + f"Requests: {num_active_requests} active, {num_queued_requests} queued" + ) + connection_info = ( + f"Connections: {num_active_connections} active, {num_idle_connections} idle" + ) + + return f"<{class_name} [{requests_info} | {connection_info}]>" + + +class PoolByteStream: + def __init__( + self, + stream: typing.AsyncIterable[bytes], + pool_request: AsyncPoolRequest, + pool: AsyncConnectionPool, + ) -> None: + self._stream = stream + self._pool_request = pool_request + self._pool = pool + self._closed = False + + async def __aiter__(self) -> typing.AsyncIterator[bytes]: + try: + async for part in self._stream: + yield part + except BaseException as exc: + await self.aclose() + raise exc from None + + async def aclose(self) -> None: + if not self._closed: + self._closed = True + with AsyncShieldCancellation(): + if hasattr(self._stream, "aclose"): + await self._stream.aclose() + + with self._pool._optional_thread_lock: + self._pool._requests.remove(self._pool_request) + closing = self._pool._assign_requests_to_connections() + + await self._pool._close_connections(closing) diff --git a/.venv/lib/python3.13/site-packages/httpcore/_async/http11.py b/.venv/lib/python3.13/site-packages/httpcore/_async/http11.py new file mode 100644 index 0000000000000000000000000000000000000000..e6d6d709852b137a862cfe2b3af42dc790fa705d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_async/http11.py @@ -0,0 +1,379 @@ +from __future__ import annotations + +import enum +import logging +import ssl +import time +import types +import typing + +import h11 + +from .._backends.base import AsyncNetworkStream +from .._exceptions import ( + ConnectionNotAvailable, + LocalProtocolError, + RemoteProtocolError, + WriteError, + map_exceptions, +) +from .._models import Origin, Request, Response +from .._synchronization import AsyncLock, AsyncShieldCancellation +from .._trace import Trace +from .interfaces import AsyncConnectionInterface + +logger = logging.getLogger("httpcore.http11") + + +# A subset of `h11.Event` types supported by `_send_event` +H11SendEvent = typing.Union[ + h11.Request, + h11.Data, + h11.EndOfMessage, +] + + +class HTTPConnectionState(enum.IntEnum): + NEW = 0 + ACTIVE = 1 + IDLE = 2 + CLOSED = 3 + + +class AsyncHTTP11Connection(AsyncConnectionInterface): + READ_NUM_BYTES = 64 * 1024 + MAX_INCOMPLETE_EVENT_SIZE = 100 * 1024 + + def __init__( + self, + origin: Origin, + stream: AsyncNetworkStream, + keepalive_expiry: float | None = None, + ) -> None: + self._origin = origin + self._network_stream = stream + self._keepalive_expiry: float | None = keepalive_expiry + self._expire_at: float | None = None + self._state = HTTPConnectionState.NEW + self._state_lock = AsyncLock() + self._request_count = 0 + self._h11_state = h11.Connection( + our_role=h11.CLIENT, + max_incomplete_event_size=self.MAX_INCOMPLETE_EVENT_SIZE, + ) + + async def handle_async_request(self, request: Request) -> Response: + if not self.can_handle_request(request.url.origin): + raise RuntimeError( + f"Attempted to send request to {request.url.origin} on connection " + f"to {self._origin}" + ) + + async with self._state_lock: + if self._state in (HTTPConnectionState.NEW, HTTPConnectionState.IDLE): + self._request_count += 1 + self._state = HTTPConnectionState.ACTIVE + self._expire_at = None + else: + raise ConnectionNotAvailable() + + try: + kwargs = {"request": request} + try: + async with Trace( + "send_request_headers", logger, request, kwargs + ) as trace: + await self._send_request_headers(**kwargs) + async with Trace("send_request_body", logger, request, kwargs) as trace: + await self._send_request_body(**kwargs) + except WriteError: + # If we get a write error while we're writing the request, + # then we supress this error and move on to attempting to + # read the response. Servers can sometimes close the request + # pre-emptively and then respond with a well formed HTTP + # error response. + pass + + async with Trace( + "receive_response_headers", logger, request, kwargs + ) as trace: + ( + http_version, + status, + reason_phrase, + headers, + trailing_data, + ) = await self._receive_response_headers(**kwargs) + trace.return_value = ( + http_version, + status, + reason_phrase, + headers, + ) + + network_stream = self._network_stream + + # CONNECT or Upgrade request + if (status == 101) or ( + (request.method == b"CONNECT") and (200 <= status < 300) + ): + network_stream = AsyncHTTP11UpgradeStream(network_stream, trailing_data) + + return Response( + status=status, + headers=headers, + content=HTTP11ConnectionByteStream(self, request), + extensions={ + "http_version": http_version, + "reason_phrase": reason_phrase, + "network_stream": network_stream, + }, + ) + except BaseException as exc: + with AsyncShieldCancellation(): + async with Trace("response_closed", logger, request) as trace: + await self._response_closed() + raise exc + + # Sending the request... + + async def _send_request_headers(self, request: Request) -> None: + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("write", None) + + with map_exceptions({h11.LocalProtocolError: LocalProtocolError}): + event = h11.Request( + method=request.method, + target=request.url.target, + headers=request.headers, + ) + await self._send_event(event, timeout=timeout) + + async def _send_request_body(self, request: Request) -> None: + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("write", None) + + assert isinstance(request.stream, typing.AsyncIterable) + async for chunk in request.stream: + event = h11.Data(data=chunk) + await self._send_event(event, timeout=timeout) + + await self._send_event(h11.EndOfMessage(), timeout=timeout) + + async def _send_event(self, event: h11.Event, timeout: float | None = None) -> None: + bytes_to_send = self._h11_state.send(event) + if bytes_to_send is not None: + await self._network_stream.write(bytes_to_send, timeout=timeout) + + # Receiving the response... + + async def _receive_response_headers( + self, request: Request + ) -> tuple[bytes, int, bytes, list[tuple[bytes, bytes]], bytes]: + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("read", None) + + while True: + event = await self._receive_event(timeout=timeout) + if isinstance(event, h11.Response): + break + if ( + isinstance(event, h11.InformationalResponse) + and event.status_code == 101 + ): + break + + http_version = b"HTTP/" + event.http_version + + # h11 version 0.11+ supports a `raw_items` interface to get the + # raw header casing, rather than the enforced lowercase headers. + headers = event.headers.raw_items() + + trailing_data, _ = self._h11_state.trailing_data + + return http_version, event.status_code, event.reason, headers, trailing_data + + async def _receive_response_body( + self, request: Request + ) -> typing.AsyncIterator[bytes]: + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("read", None) + + while True: + event = await self._receive_event(timeout=timeout) + if isinstance(event, h11.Data): + yield bytes(event.data) + elif isinstance(event, (h11.EndOfMessage, h11.PAUSED)): + break + + async def _receive_event( + self, timeout: float | None = None + ) -> h11.Event | type[h11.PAUSED]: + while True: + with map_exceptions({h11.RemoteProtocolError: RemoteProtocolError}): + event = self._h11_state.next_event() + + if event is h11.NEED_DATA: + data = await self._network_stream.read( + self.READ_NUM_BYTES, timeout=timeout + ) + + # If we feed this case through h11 we'll raise an exception like: + # + # httpcore.RemoteProtocolError: can't handle event type + # ConnectionClosed when role=SERVER and state=SEND_RESPONSE + # + # Which is accurate, but not very informative from an end-user + # perspective. Instead we handle this case distinctly and treat + # it as a ConnectError. + if data == b"" and self._h11_state.their_state == h11.SEND_RESPONSE: + msg = "Server disconnected without sending a response." + raise RemoteProtocolError(msg) + + self._h11_state.receive_data(data) + else: + # mypy fails to narrow the type in the above if statement above + return event # type: ignore[return-value] + + async def _response_closed(self) -> None: + async with self._state_lock: + if ( + self._h11_state.our_state is h11.DONE + and self._h11_state.their_state is h11.DONE + ): + self._state = HTTPConnectionState.IDLE + self._h11_state.start_next_cycle() + if self._keepalive_expiry is not None: + now = time.monotonic() + self._expire_at = now + self._keepalive_expiry + else: + await self.aclose() + + # Once the connection is no longer required... + + async def aclose(self) -> None: + # Note that this method unilaterally closes the connection, and does + # not have any kind of locking in place around it. + self._state = HTTPConnectionState.CLOSED + await self._network_stream.aclose() + + # The AsyncConnectionInterface methods provide information about the state of + # the connection, allowing for a connection pooling implementation to + # determine when to reuse and when to close the connection... + + def can_handle_request(self, origin: Origin) -> bool: + return origin == self._origin + + def is_available(self) -> bool: + # Note that HTTP/1.1 connections in the "NEW" state are not treated as + # being "available". The control flow which created the connection will + # be able to send an outgoing request, but the connection will not be + # acquired from the connection pool for any other request. + return self._state == HTTPConnectionState.IDLE + + def has_expired(self) -> bool: + now = time.monotonic() + keepalive_expired = self._expire_at is not None and now > self._expire_at + + # If the HTTP connection is idle but the socket is readable, then the + # only valid state is that the socket is about to return b"", indicating + # a server-initiated disconnect. + server_disconnected = ( + self._state == HTTPConnectionState.IDLE + and self._network_stream.get_extra_info("is_readable") + ) + + return keepalive_expired or server_disconnected + + def is_idle(self) -> bool: + return self._state == HTTPConnectionState.IDLE + + def is_closed(self) -> bool: + return self._state == HTTPConnectionState.CLOSED + + def info(self) -> str: + origin = str(self._origin) + return ( + f"{origin!r}, HTTP/1.1, {self._state.name}, " + f"Request Count: {self._request_count}" + ) + + def __repr__(self) -> str: + class_name = self.__class__.__name__ + origin = str(self._origin) + return ( + f"<{class_name} [{origin!r}, {self._state.name}, " + f"Request Count: {self._request_count}]>" + ) + + # These context managers are not used in the standard flow, but are + # useful for testing or working with connection instances directly. + + async def __aenter__(self) -> AsyncHTTP11Connection: + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + await self.aclose() + + +class HTTP11ConnectionByteStream: + def __init__(self, connection: AsyncHTTP11Connection, request: Request) -> None: + self._connection = connection + self._request = request + self._closed = False + + async def __aiter__(self) -> typing.AsyncIterator[bytes]: + kwargs = {"request": self._request} + try: + async with Trace("receive_response_body", logger, self._request, kwargs): + async for chunk in self._connection._receive_response_body(**kwargs): + yield chunk + except BaseException as exc: + # If we get an exception while streaming the response, + # we want to close the response (and possibly the connection) + # before raising that exception. + with AsyncShieldCancellation(): + await self.aclose() + raise exc + + async def aclose(self) -> None: + if not self._closed: + self._closed = True + async with Trace("response_closed", logger, self._request): + await self._connection._response_closed() + + +class AsyncHTTP11UpgradeStream(AsyncNetworkStream): + def __init__(self, stream: AsyncNetworkStream, leading_data: bytes) -> None: + self._stream = stream + self._leading_data = leading_data + + async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: + if self._leading_data: + buffer = self._leading_data[:max_bytes] + self._leading_data = self._leading_data[max_bytes:] + return buffer + else: + return await self._stream.read(max_bytes, timeout) + + async def write(self, buffer: bytes, timeout: float | None = None) -> None: + await self._stream.write(buffer, timeout) + + async def aclose(self) -> None: + await self._stream.aclose() + + async def start_tls( + self, + ssl_context: ssl.SSLContext, + server_hostname: str | None = None, + timeout: float | None = None, + ) -> AsyncNetworkStream: + return await self._stream.start_tls(ssl_context, server_hostname, timeout) + + def get_extra_info(self, info: str) -> typing.Any: + return self._stream.get_extra_info(info) diff --git a/.venv/lib/python3.13/site-packages/httpcore/_async/http2.py b/.venv/lib/python3.13/site-packages/httpcore/_async/http2.py new file mode 100644 index 0000000000000000000000000000000000000000..dbd0beeb4da32d8c0175d412fa442eae8f837723 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_async/http2.py @@ -0,0 +1,592 @@ +from __future__ import annotations + +import enum +import logging +import time +import types +import typing + +import h2.config +import h2.connection +import h2.events +import h2.exceptions +import h2.settings + +from .._backends.base import AsyncNetworkStream +from .._exceptions import ( + ConnectionNotAvailable, + LocalProtocolError, + RemoteProtocolError, +) +from .._models import Origin, Request, Response +from .._synchronization import AsyncLock, AsyncSemaphore, AsyncShieldCancellation +from .._trace import Trace +from .interfaces import AsyncConnectionInterface + +logger = logging.getLogger("httpcore.http2") + + +def has_body_headers(request: Request) -> bool: + return any( + k.lower() == b"content-length" or k.lower() == b"transfer-encoding" + for k, v in request.headers + ) + + +class HTTPConnectionState(enum.IntEnum): + ACTIVE = 1 + IDLE = 2 + CLOSED = 3 + + +class AsyncHTTP2Connection(AsyncConnectionInterface): + READ_NUM_BYTES = 64 * 1024 + CONFIG = h2.config.H2Configuration(validate_inbound_headers=False) + + def __init__( + self, + origin: Origin, + stream: AsyncNetworkStream, + keepalive_expiry: float | None = None, + ): + self._origin = origin + self._network_stream = stream + self._keepalive_expiry: float | None = keepalive_expiry + self._h2_state = h2.connection.H2Connection(config=self.CONFIG) + self._state = HTTPConnectionState.IDLE + self._expire_at: float | None = None + self._request_count = 0 + self._init_lock = AsyncLock() + self._state_lock = AsyncLock() + self._read_lock = AsyncLock() + self._write_lock = AsyncLock() + self._sent_connection_init = False + self._used_all_stream_ids = False + self._connection_error = False + + # Mapping from stream ID to response stream events. + self._events: dict[ + int, + list[ + h2.events.ResponseReceived + | h2.events.DataReceived + | h2.events.StreamEnded + | h2.events.StreamReset, + ], + ] = {} + + # Connection terminated events are stored as state since + # we need to handle them for all streams. + self._connection_terminated: h2.events.ConnectionTerminated | None = None + + self._read_exception: Exception | None = None + self._write_exception: Exception | None = None + + async def handle_async_request(self, request: Request) -> Response: + if not self.can_handle_request(request.url.origin): + # This cannot occur in normal operation, since the connection pool + # will only send requests on connections that handle them. + # It's in place simply for resilience as a guard against incorrect + # usage, for anyone working directly with httpcore connections. + raise RuntimeError( + f"Attempted to send request to {request.url.origin} on connection " + f"to {self._origin}" + ) + + async with self._state_lock: + if self._state in (HTTPConnectionState.ACTIVE, HTTPConnectionState.IDLE): + self._request_count += 1 + self._expire_at = None + self._state = HTTPConnectionState.ACTIVE + else: + raise ConnectionNotAvailable() + + async with self._init_lock: + if not self._sent_connection_init: + try: + sci_kwargs = {"request": request} + async with Trace( + "send_connection_init", logger, request, sci_kwargs + ): + await self._send_connection_init(**sci_kwargs) + except BaseException as exc: + with AsyncShieldCancellation(): + await self.aclose() + raise exc + + self._sent_connection_init = True + + # Initially start with just 1 until the remote server provides + # its max_concurrent_streams value + self._max_streams = 1 + + local_settings_max_streams = ( + self._h2_state.local_settings.max_concurrent_streams + ) + self._max_streams_semaphore = AsyncSemaphore(local_settings_max_streams) + + for _ in range(local_settings_max_streams - self._max_streams): + await self._max_streams_semaphore.acquire() + + await self._max_streams_semaphore.acquire() + + try: + stream_id = self._h2_state.get_next_available_stream_id() + self._events[stream_id] = [] + except h2.exceptions.NoAvailableStreamIDError: # pragma: nocover + self._used_all_stream_ids = True + self._request_count -= 1 + raise ConnectionNotAvailable() + + try: + kwargs = {"request": request, "stream_id": stream_id} + async with Trace("send_request_headers", logger, request, kwargs): + await self._send_request_headers(request=request, stream_id=stream_id) + async with Trace("send_request_body", logger, request, kwargs): + await self._send_request_body(request=request, stream_id=stream_id) + async with Trace( + "receive_response_headers", logger, request, kwargs + ) as trace: + status, headers = await self._receive_response( + request=request, stream_id=stream_id + ) + trace.return_value = (status, headers) + + return Response( + status=status, + headers=headers, + content=HTTP2ConnectionByteStream(self, request, stream_id=stream_id), + extensions={ + "http_version": b"HTTP/2", + "network_stream": self._network_stream, + "stream_id": stream_id, + }, + ) + except BaseException as exc: # noqa: PIE786 + with AsyncShieldCancellation(): + kwargs = {"stream_id": stream_id} + async with Trace("response_closed", logger, request, kwargs): + await self._response_closed(stream_id=stream_id) + + if isinstance(exc, h2.exceptions.ProtocolError): + # One case where h2 can raise a protocol error is when a + # closed frame has been seen by the state machine. + # + # This happens when one stream is reading, and encounters + # a GOAWAY event. Other flows of control may then raise + # a protocol error at any point they interact with the 'h2_state'. + # + # In this case we'll have stored the event, and should raise + # it as a RemoteProtocolError. + if self._connection_terminated: # pragma: nocover + raise RemoteProtocolError(self._connection_terminated) + # If h2 raises a protocol error in some other state then we + # must somehow have made a protocol violation. + raise LocalProtocolError(exc) # pragma: nocover + + raise exc + + async def _send_connection_init(self, request: Request) -> None: + """ + The HTTP/2 connection requires some initial setup before we can start + using individual request/response streams on it. + """ + # Need to set these manually here instead of manipulating via + # __setitem__() otherwise the H2Connection will emit SettingsUpdate + # frames in addition to sending the undesired defaults. + self._h2_state.local_settings = h2.settings.Settings( + client=True, + initial_values={ + # Disable PUSH_PROMISE frames from the server since we don't do anything + # with them for now. Maybe when we support caching? + h2.settings.SettingCodes.ENABLE_PUSH: 0, + # These two are taken from h2 for safe defaults + h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS: 100, + h2.settings.SettingCodes.MAX_HEADER_LIST_SIZE: 65536, + }, + ) + + # Some websites (*cough* Yahoo *cough*) balk at this setting being + # present in the initial handshake since it's not defined in the original + # RFC despite the RFC mandating ignoring settings you don't know about. + del self._h2_state.local_settings[ + h2.settings.SettingCodes.ENABLE_CONNECT_PROTOCOL + ] + + self._h2_state.initiate_connection() + self._h2_state.increment_flow_control_window(2**24) + await self._write_outgoing_data(request) + + # Sending the request... + + async def _send_request_headers(self, request: Request, stream_id: int) -> None: + """ + Send the request headers to a given stream ID. + """ + end_stream = not has_body_headers(request) + + # In HTTP/2 the ':authority' pseudo-header is used instead of 'Host'. + # In order to gracefully handle HTTP/1.1 and HTTP/2 we always require + # HTTP/1.1 style headers, and map them appropriately if we end up on + # an HTTP/2 connection. + authority = [v for k, v in request.headers if k.lower() == b"host"][0] + + headers = [ + (b":method", request.method), + (b":authority", authority), + (b":scheme", request.url.scheme), + (b":path", request.url.target), + ] + [ + (k.lower(), v) + for k, v in request.headers + if k.lower() + not in ( + b"host", + b"transfer-encoding", + ) + ] + + self._h2_state.send_headers(stream_id, headers, end_stream=end_stream) + self._h2_state.increment_flow_control_window(2**24, stream_id=stream_id) + await self._write_outgoing_data(request) + + async def _send_request_body(self, request: Request, stream_id: int) -> None: + """ + Iterate over the request body sending it to a given stream ID. + """ + if not has_body_headers(request): + return + + assert isinstance(request.stream, typing.AsyncIterable) + async for data in request.stream: + await self._send_stream_data(request, stream_id, data) + await self._send_end_stream(request, stream_id) + + async def _send_stream_data( + self, request: Request, stream_id: int, data: bytes + ) -> None: + """ + Send a single chunk of data in one or more data frames. + """ + while data: + max_flow = await self._wait_for_outgoing_flow(request, stream_id) + chunk_size = min(len(data), max_flow) + chunk, data = data[:chunk_size], data[chunk_size:] + self._h2_state.send_data(stream_id, chunk) + await self._write_outgoing_data(request) + + async def _send_end_stream(self, request: Request, stream_id: int) -> None: + """ + Send an empty data frame on on a given stream ID with the END_STREAM flag set. + """ + self._h2_state.end_stream(stream_id) + await self._write_outgoing_data(request) + + # Receiving the response... + + async def _receive_response( + self, request: Request, stream_id: int + ) -> tuple[int, list[tuple[bytes, bytes]]]: + """ + Return the response status code and headers for a given stream ID. + """ + while True: + event = await self._receive_stream_event(request, stream_id) + if isinstance(event, h2.events.ResponseReceived): + break + + status_code = 200 + headers = [] + assert event.headers is not None + for k, v in event.headers: + if k == b":status": + status_code = int(v.decode("ascii", errors="ignore")) + elif not k.startswith(b":"): + headers.append((k, v)) + + return (status_code, headers) + + async def _receive_response_body( + self, request: Request, stream_id: int + ) -> typing.AsyncIterator[bytes]: + """ + Iterator that returns the bytes of the response body for a given stream ID. + """ + while True: + event = await self._receive_stream_event(request, stream_id) + if isinstance(event, h2.events.DataReceived): + assert event.flow_controlled_length is not None + assert event.data is not None + amount = event.flow_controlled_length + self._h2_state.acknowledge_received_data(amount, stream_id) + await self._write_outgoing_data(request) + yield event.data + elif isinstance(event, h2.events.StreamEnded): + break + + async def _receive_stream_event( + self, request: Request, stream_id: int + ) -> h2.events.ResponseReceived | h2.events.DataReceived | h2.events.StreamEnded: + """ + Return the next available event for a given stream ID. + + Will read more data from the network if required. + """ + while not self._events.get(stream_id): + await self._receive_events(request, stream_id) + event = self._events[stream_id].pop(0) + if isinstance(event, h2.events.StreamReset): + raise RemoteProtocolError(event) + return event + + async def _receive_events( + self, request: Request, stream_id: int | None = None + ) -> None: + """ + Read some data from the network until we see one or more events + for a given stream ID. + """ + async with self._read_lock: + if self._connection_terminated is not None: + last_stream_id = self._connection_terminated.last_stream_id + if stream_id and last_stream_id and stream_id > last_stream_id: + self._request_count -= 1 + raise ConnectionNotAvailable() + raise RemoteProtocolError(self._connection_terminated) + + # This conditional is a bit icky. We don't want to block reading if we've + # actually got an event to return for a given stream. We need to do that + # check *within* the atomic read lock. Though it also need to be optional, + # because when we call it from `_wait_for_outgoing_flow` we *do* want to + # block until we've available flow control, event when we have events + # pending for the stream ID we're attempting to send on. + if stream_id is None or not self._events.get(stream_id): + events = await self._read_incoming_data(request) + for event in events: + if isinstance(event, h2.events.RemoteSettingsChanged): + async with Trace( + "receive_remote_settings", logger, request + ) as trace: + await self._receive_remote_settings_change(event) + trace.return_value = event + + elif isinstance( + event, + ( + h2.events.ResponseReceived, + h2.events.DataReceived, + h2.events.StreamEnded, + h2.events.StreamReset, + ), + ): + if event.stream_id in self._events: + self._events[event.stream_id].append(event) + + elif isinstance(event, h2.events.ConnectionTerminated): + self._connection_terminated = event + + await self._write_outgoing_data(request) + + async def _receive_remote_settings_change( + self, event: h2.events.RemoteSettingsChanged + ) -> None: + max_concurrent_streams = event.changed_settings.get( + h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS + ) + if max_concurrent_streams: + new_max_streams = min( + max_concurrent_streams.new_value, + self._h2_state.local_settings.max_concurrent_streams, + ) + if new_max_streams and new_max_streams != self._max_streams: + while new_max_streams > self._max_streams: + await self._max_streams_semaphore.release() + self._max_streams += 1 + while new_max_streams < self._max_streams: + await self._max_streams_semaphore.acquire() + self._max_streams -= 1 + + async def _response_closed(self, stream_id: int) -> None: + await self._max_streams_semaphore.release() + del self._events[stream_id] + async with self._state_lock: + if self._connection_terminated and not self._events: + await self.aclose() + + elif self._state == HTTPConnectionState.ACTIVE and not self._events: + self._state = HTTPConnectionState.IDLE + if self._keepalive_expiry is not None: + now = time.monotonic() + self._expire_at = now + self._keepalive_expiry + if self._used_all_stream_ids: # pragma: nocover + await self.aclose() + + async def aclose(self) -> None: + # Note that this method unilaterally closes the connection, and does + # not have any kind of locking in place around it. + self._h2_state.close_connection() + self._state = HTTPConnectionState.CLOSED + await self._network_stream.aclose() + + # Wrappers around network read/write operations... + + async def _read_incoming_data(self, request: Request) -> list[h2.events.Event]: + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("read", None) + + if self._read_exception is not None: + raise self._read_exception # pragma: nocover + + try: + data = await self._network_stream.read(self.READ_NUM_BYTES, timeout) + if data == b"": + raise RemoteProtocolError("Server disconnected") + except Exception as exc: + # If we get a network error we should: + # + # 1. Save the exception and just raise it immediately on any future reads. + # (For example, this means that a single read timeout or disconnect will + # immediately close all pending streams. Without requiring multiple + # sequential timeouts.) + # 2. Mark the connection as errored, so that we don't accept any other + # incoming requests. + self._read_exception = exc + self._connection_error = True + raise exc + + events: list[h2.events.Event] = self._h2_state.receive_data(data) + + return events + + async def _write_outgoing_data(self, request: Request) -> None: + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("write", None) + + async with self._write_lock: + data_to_send = self._h2_state.data_to_send() + + if self._write_exception is not None: + raise self._write_exception # pragma: nocover + + try: + await self._network_stream.write(data_to_send, timeout) + except Exception as exc: # pragma: nocover + # If we get a network error we should: + # + # 1. Save the exception and just raise it immediately on any future write. + # (For example, this means that a single write timeout or disconnect will + # immediately close all pending streams. Without requiring multiple + # sequential timeouts.) + # 2. Mark the connection as errored, so that we don't accept any other + # incoming requests. + self._write_exception = exc + self._connection_error = True + raise exc + + # Flow control... + + async def _wait_for_outgoing_flow(self, request: Request, stream_id: int) -> int: + """ + Returns the maximum allowable outgoing flow for a given stream. + + If the allowable flow is zero, then waits on the network until + WindowUpdated frames have increased the flow rate. + https://tools.ietf.org/html/rfc7540#section-6.9 + """ + local_flow: int = self._h2_state.local_flow_control_window(stream_id) + max_frame_size: int = self._h2_state.max_outbound_frame_size + flow = min(local_flow, max_frame_size) + while flow == 0: + await self._receive_events(request) + local_flow = self._h2_state.local_flow_control_window(stream_id) + max_frame_size = self._h2_state.max_outbound_frame_size + flow = min(local_flow, max_frame_size) + return flow + + # Interface for connection pooling... + + def can_handle_request(self, origin: Origin) -> bool: + return origin == self._origin + + def is_available(self) -> bool: + return ( + self._state != HTTPConnectionState.CLOSED + and not self._connection_error + and not self._used_all_stream_ids + and not ( + self._h2_state.state_machine.state + == h2.connection.ConnectionState.CLOSED + ) + ) + + def has_expired(self) -> bool: + now = time.monotonic() + return self._expire_at is not None and now > self._expire_at + + def is_idle(self) -> bool: + return self._state == HTTPConnectionState.IDLE + + def is_closed(self) -> bool: + return self._state == HTTPConnectionState.CLOSED + + def info(self) -> str: + origin = str(self._origin) + return ( + f"{origin!r}, HTTP/2, {self._state.name}, " + f"Request Count: {self._request_count}" + ) + + def __repr__(self) -> str: + class_name = self.__class__.__name__ + origin = str(self._origin) + return ( + f"<{class_name} [{origin!r}, {self._state.name}, " + f"Request Count: {self._request_count}]>" + ) + + # These context managers are not used in the standard flow, but are + # useful for testing or working with connection instances directly. + + async def __aenter__(self) -> AsyncHTTP2Connection: + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + await self.aclose() + + +class HTTP2ConnectionByteStream: + def __init__( + self, connection: AsyncHTTP2Connection, request: Request, stream_id: int + ) -> None: + self._connection = connection + self._request = request + self._stream_id = stream_id + self._closed = False + + async def __aiter__(self) -> typing.AsyncIterator[bytes]: + kwargs = {"request": self._request, "stream_id": self._stream_id} + try: + async with Trace("receive_response_body", logger, self._request, kwargs): + async for chunk in self._connection._receive_response_body( + request=self._request, stream_id=self._stream_id + ): + yield chunk + except BaseException as exc: + # If we get an exception while streaming the response, + # we want to close the response (and possibly the connection) + # before raising that exception. + with AsyncShieldCancellation(): + await self.aclose() + raise exc + + async def aclose(self) -> None: + if not self._closed: + self._closed = True + kwargs = {"stream_id": self._stream_id} + async with Trace("response_closed", logger, self._request, kwargs): + await self._connection._response_closed(stream_id=self._stream_id) diff --git a/.venv/lib/python3.13/site-packages/httpcore/_async/http_proxy.py b/.venv/lib/python3.13/site-packages/httpcore/_async/http_proxy.py new file mode 100644 index 0000000000000000000000000000000000000000..cc9d92066e1680576846e46ccdf645a2b1dd5718 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_async/http_proxy.py @@ -0,0 +1,367 @@ +from __future__ import annotations + +import base64 +import logging +import ssl +import typing + +from .._backends.base import SOCKET_OPTION, AsyncNetworkBackend +from .._exceptions import ProxyError +from .._models import ( + URL, + Origin, + Request, + Response, + enforce_bytes, + enforce_headers, + enforce_url, +) +from .._ssl import default_ssl_context +from .._synchronization import AsyncLock +from .._trace import Trace +from .connection import AsyncHTTPConnection +from .connection_pool import AsyncConnectionPool +from .http11 import AsyncHTTP11Connection +from .interfaces import AsyncConnectionInterface + +ByteOrStr = typing.Union[bytes, str] +HeadersAsSequence = typing.Sequence[typing.Tuple[ByteOrStr, ByteOrStr]] +HeadersAsMapping = typing.Mapping[ByteOrStr, ByteOrStr] + + +logger = logging.getLogger("httpcore.proxy") + + +def merge_headers( + default_headers: typing.Sequence[tuple[bytes, bytes]] | None = None, + override_headers: typing.Sequence[tuple[bytes, bytes]] | None = None, +) -> list[tuple[bytes, bytes]]: + """ + Append default_headers and override_headers, de-duplicating if a key exists + in both cases. + """ + default_headers = [] if default_headers is None else list(default_headers) + override_headers = [] if override_headers is None else list(override_headers) + has_override = set(key.lower() for key, value in override_headers) + default_headers = [ + (key, value) + for key, value in default_headers + if key.lower() not in has_override + ] + return default_headers + override_headers + + +class AsyncHTTPProxy(AsyncConnectionPool): # pragma: nocover + """ + A connection pool that sends requests via an HTTP proxy. + """ + + def __init__( + self, + proxy_url: URL | bytes | str, + proxy_auth: tuple[bytes | str, bytes | str] | None = None, + proxy_headers: HeadersAsMapping | HeadersAsSequence | None = None, + ssl_context: ssl.SSLContext | None = None, + proxy_ssl_context: ssl.SSLContext | None = None, + max_connections: int | None = 10, + max_keepalive_connections: int | None = None, + keepalive_expiry: float | None = None, + http1: bool = True, + http2: bool = False, + retries: int = 0, + local_address: str | None = None, + uds: str | None = None, + network_backend: AsyncNetworkBackend | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> None: + """ + A connection pool for making HTTP requests. + + Parameters: + proxy_url: The URL to use when connecting to the proxy server. + For example `"http://127.0.0.1:8080/"`. + proxy_auth: Any proxy authentication as a two-tuple of + (username, password). May be either bytes or ascii-only str. + proxy_headers: Any HTTP headers to use for the proxy requests. + For example `{"Proxy-Authorization": "Basic :"}`. + ssl_context: An SSL context to use for verifying connections. + If not specified, the default `httpcore.default_ssl_context()` + will be used. + proxy_ssl_context: The same as `ssl_context`, but for a proxy server rather than a remote origin. + max_connections: The maximum number of concurrent HTTP connections that + the pool should allow. Any attempt to send a request on a pool that + would exceed this amount will block until a connection is available. + max_keepalive_connections: The maximum number of idle HTTP connections + that will be maintained in the pool. + keepalive_expiry: The duration in seconds that an idle HTTP connection + may be maintained for before being expired from the pool. + http1: A boolean indicating if HTTP/1.1 requests should be supported + by the connection pool. Defaults to True. + http2: A boolean indicating if HTTP/2 requests should be supported by + the connection pool. Defaults to False. + retries: The maximum number of retries when trying to establish + a connection. + local_address: Local address to connect from. Can also be used to + connect using a particular address family. Using + `local_address="0.0.0.0"` will connect using an `AF_INET` address + (IPv4), while using `local_address="::"` will connect using an + `AF_INET6` address (IPv6). + uds: Path to a Unix Domain Socket to use instead of TCP sockets. + network_backend: A backend instance to use for handling network I/O. + """ + super().__init__( + ssl_context=ssl_context, + max_connections=max_connections, + max_keepalive_connections=max_keepalive_connections, + keepalive_expiry=keepalive_expiry, + http1=http1, + http2=http2, + network_backend=network_backend, + retries=retries, + local_address=local_address, + uds=uds, + socket_options=socket_options, + ) + + self._proxy_url = enforce_url(proxy_url, name="proxy_url") + if ( + self._proxy_url.scheme == b"http" and proxy_ssl_context is not None + ): # pragma: no cover + raise RuntimeError( + "The `proxy_ssl_context` argument is not allowed for the http scheme" + ) + + self._ssl_context = ssl_context + self._proxy_ssl_context = proxy_ssl_context + self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") + if proxy_auth is not None: + username = enforce_bytes(proxy_auth[0], name="proxy_auth") + password = enforce_bytes(proxy_auth[1], name="proxy_auth") + userpass = username + b":" + password + authorization = b"Basic " + base64.b64encode(userpass) + self._proxy_headers = [ + (b"Proxy-Authorization", authorization) + ] + self._proxy_headers + + def create_connection(self, origin: Origin) -> AsyncConnectionInterface: + if origin.scheme == b"http": + return AsyncForwardHTTPConnection( + proxy_origin=self._proxy_url.origin, + proxy_headers=self._proxy_headers, + remote_origin=origin, + keepalive_expiry=self._keepalive_expiry, + network_backend=self._network_backend, + proxy_ssl_context=self._proxy_ssl_context, + ) + return AsyncTunnelHTTPConnection( + proxy_origin=self._proxy_url.origin, + proxy_headers=self._proxy_headers, + remote_origin=origin, + ssl_context=self._ssl_context, + proxy_ssl_context=self._proxy_ssl_context, + keepalive_expiry=self._keepalive_expiry, + http1=self._http1, + http2=self._http2, + network_backend=self._network_backend, + ) + + +class AsyncForwardHTTPConnection(AsyncConnectionInterface): + def __init__( + self, + proxy_origin: Origin, + remote_origin: Origin, + proxy_headers: HeadersAsMapping | HeadersAsSequence | None = None, + keepalive_expiry: float | None = None, + network_backend: AsyncNetworkBackend | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + proxy_ssl_context: ssl.SSLContext | None = None, + ) -> None: + self._connection = AsyncHTTPConnection( + origin=proxy_origin, + keepalive_expiry=keepalive_expiry, + network_backend=network_backend, + socket_options=socket_options, + ssl_context=proxy_ssl_context, + ) + self._proxy_origin = proxy_origin + self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") + self._remote_origin = remote_origin + + async def handle_async_request(self, request: Request) -> Response: + headers = merge_headers(self._proxy_headers, request.headers) + url = URL( + scheme=self._proxy_origin.scheme, + host=self._proxy_origin.host, + port=self._proxy_origin.port, + target=bytes(request.url), + ) + proxy_request = Request( + method=request.method, + url=url, + headers=headers, + content=request.stream, + extensions=request.extensions, + ) + return await self._connection.handle_async_request(proxy_request) + + def can_handle_request(self, origin: Origin) -> bool: + return origin == self._remote_origin + + async def aclose(self) -> None: + await self._connection.aclose() + + def info(self) -> str: + return self._connection.info() + + def is_available(self) -> bool: + return self._connection.is_available() + + def has_expired(self) -> bool: + return self._connection.has_expired() + + def is_idle(self) -> bool: + return self._connection.is_idle() + + def is_closed(self) -> bool: + return self._connection.is_closed() + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} [{self.info()}]>" + + +class AsyncTunnelHTTPConnection(AsyncConnectionInterface): + def __init__( + self, + proxy_origin: Origin, + remote_origin: Origin, + ssl_context: ssl.SSLContext | None = None, + proxy_ssl_context: ssl.SSLContext | None = None, + proxy_headers: typing.Sequence[tuple[bytes, bytes]] | None = None, + keepalive_expiry: float | None = None, + http1: bool = True, + http2: bool = False, + network_backend: AsyncNetworkBackend | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> None: + self._connection: AsyncConnectionInterface = AsyncHTTPConnection( + origin=proxy_origin, + keepalive_expiry=keepalive_expiry, + network_backend=network_backend, + socket_options=socket_options, + ssl_context=proxy_ssl_context, + ) + self._proxy_origin = proxy_origin + self._remote_origin = remote_origin + self._ssl_context = ssl_context + self._proxy_ssl_context = proxy_ssl_context + self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") + self._keepalive_expiry = keepalive_expiry + self._http1 = http1 + self._http2 = http2 + self._connect_lock = AsyncLock() + self._connected = False + + async def handle_async_request(self, request: Request) -> Response: + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("connect", None) + + async with self._connect_lock: + if not self._connected: + target = b"%b:%d" % (self._remote_origin.host, self._remote_origin.port) + + connect_url = URL( + scheme=self._proxy_origin.scheme, + host=self._proxy_origin.host, + port=self._proxy_origin.port, + target=target, + ) + connect_headers = merge_headers( + [(b"Host", target), (b"Accept", b"*/*")], self._proxy_headers + ) + connect_request = Request( + method=b"CONNECT", + url=connect_url, + headers=connect_headers, + extensions=request.extensions, + ) + connect_response = await self._connection.handle_async_request( + connect_request + ) + + if connect_response.status < 200 or connect_response.status > 299: + reason_bytes = connect_response.extensions.get("reason_phrase", b"") + reason_str = reason_bytes.decode("ascii", errors="ignore") + msg = "%d %s" % (connect_response.status, reason_str) + await self._connection.aclose() + raise ProxyError(msg) + + stream = connect_response.extensions["network_stream"] + + # Upgrade the stream to SSL + ssl_context = ( + default_ssl_context() + if self._ssl_context is None + else self._ssl_context + ) + alpn_protocols = ["http/1.1", "h2"] if self._http2 else ["http/1.1"] + ssl_context.set_alpn_protocols(alpn_protocols) + + kwargs = { + "ssl_context": ssl_context, + "server_hostname": self._remote_origin.host.decode("ascii"), + "timeout": timeout, + } + async with Trace("start_tls", logger, request, kwargs) as trace: + stream = await stream.start_tls(**kwargs) + trace.return_value = stream + + # Determine if we should be using HTTP/1.1 or HTTP/2 + ssl_object = stream.get_extra_info("ssl_object") + http2_negotiated = ( + ssl_object is not None + and ssl_object.selected_alpn_protocol() == "h2" + ) + + # Create the HTTP/1.1 or HTTP/2 connection + if http2_negotiated or (self._http2 and not self._http1): + from .http2 import AsyncHTTP2Connection + + self._connection = AsyncHTTP2Connection( + origin=self._remote_origin, + stream=stream, + keepalive_expiry=self._keepalive_expiry, + ) + else: + self._connection = AsyncHTTP11Connection( + origin=self._remote_origin, + stream=stream, + keepalive_expiry=self._keepalive_expiry, + ) + + self._connected = True + return await self._connection.handle_async_request(request) + + def can_handle_request(self, origin: Origin) -> bool: + return origin == self._remote_origin + + async def aclose(self) -> None: + await self._connection.aclose() + + def info(self) -> str: + return self._connection.info() + + def is_available(self) -> bool: + return self._connection.is_available() + + def has_expired(self) -> bool: + return self._connection.has_expired() + + def is_idle(self) -> bool: + return self._connection.is_idle() + + def is_closed(self) -> bool: + return self._connection.is_closed() + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} [{self.info()}]>" diff --git a/.venv/lib/python3.13/site-packages/httpcore/_async/interfaces.py b/.venv/lib/python3.13/site-packages/httpcore/_async/interfaces.py new file mode 100644 index 0000000000000000000000000000000000000000..361583bede6b2b84088b38054d5d8116ef9f1597 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_async/interfaces.py @@ -0,0 +1,137 @@ +from __future__ import annotations + +import contextlib +import typing + +from .._models import ( + URL, + Extensions, + HeaderTypes, + Origin, + Request, + Response, + enforce_bytes, + enforce_headers, + enforce_url, + include_request_headers, +) + + +class AsyncRequestInterface: + async def request( + self, + method: bytes | str, + url: URL | bytes | str, + *, + headers: HeaderTypes = None, + content: bytes | typing.AsyncIterator[bytes] | None = None, + extensions: Extensions | None = None, + ) -> Response: + # Strict type checking on our parameters. + method = enforce_bytes(method, name="method") + url = enforce_url(url, name="url") + headers = enforce_headers(headers, name="headers") + + # Include Host header, and optionally Content-Length or Transfer-Encoding. + headers = include_request_headers(headers, url=url, content=content) + + request = Request( + method=method, + url=url, + headers=headers, + content=content, + extensions=extensions, + ) + response = await self.handle_async_request(request) + try: + await response.aread() + finally: + await response.aclose() + return response + + @contextlib.asynccontextmanager + async def stream( + self, + method: bytes | str, + url: URL | bytes | str, + *, + headers: HeaderTypes = None, + content: bytes | typing.AsyncIterator[bytes] | None = None, + extensions: Extensions | None = None, + ) -> typing.AsyncIterator[Response]: + # Strict type checking on our parameters. + method = enforce_bytes(method, name="method") + url = enforce_url(url, name="url") + headers = enforce_headers(headers, name="headers") + + # Include Host header, and optionally Content-Length or Transfer-Encoding. + headers = include_request_headers(headers, url=url, content=content) + + request = Request( + method=method, + url=url, + headers=headers, + content=content, + extensions=extensions, + ) + response = await self.handle_async_request(request) + try: + yield response + finally: + await response.aclose() + + async def handle_async_request(self, request: Request) -> Response: + raise NotImplementedError() # pragma: nocover + + +class AsyncConnectionInterface(AsyncRequestInterface): + async def aclose(self) -> None: + raise NotImplementedError() # pragma: nocover + + def info(self) -> str: + raise NotImplementedError() # pragma: nocover + + def can_handle_request(self, origin: Origin) -> bool: + raise NotImplementedError() # pragma: nocover + + def is_available(self) -> bool: + """ + Return `True` if the connection is currently able to accept an + outgoing request. + + An HTTP/1.1 connection will only be available if it is currently idle. + + An HTTP/2 connection will be available so long as the stream ID space is + not yet exhausted, and the connection is not in an error state. + + While the connection is being established we may not yet know if it is going + to result in an HTTP/1.1 or HTTP/2 connection. The connection should be + treated as being available, but might ultimately raise `NewConnectionRequired` + required exceptions if multiple requests are attempted over a connection + that ends up being established as HTTP/1.1. + """ + raise NotImplementedError() # pragma: nocover + + def has_expired(self) -> bool: + """ + Return `True` if the connection is in a state where it should be closed. + + This either means that the connection is idle and it has passed the + expiry time on its keep-alive, or that server has sent an EOF. + """ + raise NotImplementedError() # pragma: nocover + + def is_idle(self) -> bool: + """ + Return `True` if the connection is currently idle. + """ + raise NotImplementedError() # pragma: nocover + + def is_closed(self) -> bool: + """ + Return `True` if the connection has been closed. + + Used when a response is closed to determine if the connection may be + returned to the connection pool or not. + """ + raise NotImplementedError() # pragma: nocover diff --git a/.venv/lib/python3.13/site-packages/httpcore/_async/socks_proxy.py b/.venv/lib/python3.13/site-packages/httpcore/_async/socks_proxy.py new file mode 100644 index 0000000000000000000000000000000000000000..b363f55a0b071de6c5f377726be82dc2110e373c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_async/socks_proxy.py @@ -0,0 +1,341 @@ +from __future__ import annotations + +import logging +import ssl + +import socksio + +from .._backends.auto import AutoBackend +from .._backends.base import AsyncNetworkBackend, AsyncNetworkStream +from .._exceptions import ConnectionNotAvailable, ProxyError +from .._models import URL, Origin, Request, Response, enforce_bytes, enforce_url +from .._ssl import default_ssl_context +from .._synchronization import AsyncLock +from .._trace import Trace +from .connection_pool import AsyncConnectionPool +from .http11 import AsyncHTTP11Connection +from .interfaces import AsyncConnectionInterface + +logger = logging.getLogger("httpcore.socks") + + +AUTH_METHODS = { + b"\x00": "NO AUTHENTICATION REQUIRED", + b"\x01": "GSSAPI", + b"\x02": "USERNAME/PASSWORD", + b"\xff": "NO ACCEPTABLE METHODS", +} + +REPLY_CODES = { + b"\x00": "Succeeded", + b"\x01": "General SOCKS server failure", + b"\x02": "Connection not allowed by ruleset", + b"\x03": "Network unreachable", + b"\x04": "Host unreachable", + b"\x05": "Connection refused", + b"\x06": "TTL expired", + b"\x07": "Command not supported", + b"\x08": "Address type not supported", +} + + +async def _init_socks5_connection( + stream: AsyncNetworkStream, + *, + host: bytes, + port: int, + auth: tuple[bytes, bytes] | None = None, +) -> None: + conn = socksio.socks5.SOCKS5Connection() + + # Auth method request + auth_method = ( + socksio.socks5.SOCKS5AuthMethod.NO_AUTH_REQUIRED + if auth is None + else socksio.socks5.SOCKS5AuthMethod.USERNAME_PASSWORD + ) + conn.send(socksio.socks5.SOCKS5AuthMethodsRequest([auth_method])) + outgoing_bytes = conn.data_to_send() + await stream.write(outgoing_bytes) + + # Auth method response + incoming_bytes = await stream.read(max_bytes=4096) + response = conn.receive_data(incoming_bytes) + assert isinstance(response, socksio.socks5.SOCKS5AuthReply) + if response.method != auth_method: + requested = AUTH_METHODS.get(auth_method, "UNKNOWN") + responded = AUTH_METHODS.get(response.method, "UNKNOWN") + raise ProxyError( + f"Requested {requested} from proxy server, but got {responded}." + ) + + if response.method == socksio.socks5.SOCKS5AuthMethod.USERNAME_PASSWORD: + # Username/password request + assert auth is not None + username, password = auth + conn.send(socksio.socks5.SOCKS5UsernamePasswordRequest(username, password)) + outgoing_bytes = conn.data_to_send() + await stream.write(outgoing_bytes) + + # Username/password response + incoming_bytes = await stream.read(max_bytes=4096) + response = conn.receive_data(incoming_bytes) + assert isinstance(response, socksio.socks5.SOCKS5UsernamePasswordReply) + if not response.success: + raise ProxyError("Invalid username/password") + + # Connect request + conn.send( + socksio.socks5.SOCKS5CommandRequest.from_address( + socksio.socks5.SOCKS5Command.CONNECT, (host, port) + ) + ) + outgoing_bytes = conn.data_to_send() + await stream.write(outgoing_bytes) + + # Connect response + incoming_bytes = await stream.read(max_bytes=4096) + response = conn.receive_data(incoming_bytes) + assert isinstance(response, socksio.socks5.SOCKS5Reply) + if response.reply_code != socksio.socks5.SOCKS5ReplyCode.SUCCEEDED: + reply_code = REPLY_CODES.get(response.reply_code, "UNKOWN") + raise ProxyError(f"Proxy Server could not connect: {reply_code}.") + + +class AsyncSOCKSProxy(AsyncConnectionPool): # pragma: nocover + """ + A connection pool that sends requests via an HTTP proxy. + """ + + def __init__( + self, + proxy_url: URL | bytes | str, + proxy_auth: tuple[bytes | str, bytes | str] | None = None, + ssl_context: ssl.SSLContext | None = None, + max_connections: int | None = 10, + max_keepalive_connections: int | None = None, + keepalive_expiry: float | None = None, + http1: bool = True, + http2: bool = False, + retries: int = 0, + network_backend: AsyncNetworkBackend | None = None, + ) -> None: + """ + A connection pool for making HTTP requests. + + Parameters: + proxy_url: The URL to use when connecting to the proxy server. + For example `"http://127.0.0.1:8080/"`. + ssl_context: An SSL context to use for verifying connections. + If not specified, the default `httpcore.default_ssl_context()` + will be used. + max_connections: The maximum number of concurrent HTTP connections that + the pool should allow. Any attempt to send a request on a pool that + would exceed this amount will block until a connection is available. + max_keepalive_connections: The maximum number of idle HTTP connections + that will be maintained in the pool. + keepalive_expiry: The duration in seconds that an idle HTTP connection + may be maintained for before being expired from the pool. + http1: A boolean indicating if HTTP/1.1 requests should be supported + by the connection pool. Defaults to True. + http2: A boolean indicating if HTTP/2 requests should be supported by + the connection pool. Defaults to False. + retries: The maximum number of retries when trying to establish + a connection. + local_address: Local address to connect from. Can also be used to + connect using a particular address family. Using + `local_address="0.0.0.0"` will connect using an `AF_INET` address + (IPv4), while using `local_address="::"` will connect using an + `AF_INET6` address (IPv6). + uds: Path to a Unix Domain Socket to use instead of TCP sockets. + network_backend: A backend instance to use for handling network I/O. + """ + super().__init__( + ssl_context=ssl_context, + max_connections=max_connections, + max_keepalive_connections=max_keepalive_connections, + keepalive_expiry=keepalive_expiry, + http1=http1, + http2=http2, + network_backend=network_backend, + retries=retries, + ) + self._ssl_context = ssl_context + self._proxy_url = enforce_url(proxy_url, name="proxy_url") + if proxy_auth is not None: + username, password = proxy_auth + username_bytes = enforce_bytes(username, name="proxy_auth") + password_bytes = enforce_bytes(password, name="proxy_auth") + self._proxy_auth: tuple[bytes, bytes] | None = ( + username_bytes, + password_bytes, + ) + else: + self._proxy_auth = None + + def create_connection(self, origin: Origin) -> AsyncConnectionInterface: + return AsyncSocks5Connection( + proxy_origin=self._proxy_url.origin, + remote_origin=origin, + proxy_auth=self._proxy_auth, + ssl_context=self._ssl_context, + keepalive_expiry=self._keepalive_expiry, + http1=self._http1, + http2=self._http2, + network_backend=self._network_backend, + ) + + +class AsyncSocks5Connection(AsyncConnectionInterface): + def __init__( + self, + proxy_origin: Origin, + remote_origin: Origin, + proxy_auth: tuple[bytes, bytes] | None = None, + ssl_context: ssl.SSLContext | None = None, + keepalive_expiry: float | None = None, + http1: bool = True, + http2: bool = False, + network_backend: AsyncNetworkBackend | None = None, + ) -> None: + self._proxy_origin = proxy_origin + self._remote_origin = remote_origin + self._proxy_auth = proxy_auth + self._ssl_context = ssl_context + self._keepalive_expiry = keepalive_expiry + self._http1 = http1 + self._http2 = http2 + + self._network_backend: AsyncNetworkBackend = ( + AutoBackend() if network_backend is None else network_backend + ) + self._connect_lock = AsyncLock() + self._connection: AsyncConnectionInterface | None = None + self._connect_failed = False + + async def handle_async_request(self, request: Request) -> Response: + timeouts = request.extensions.get("timeout", {}) + sni_hostname = request.extensions.get("sni_hostname", None) + timeout = timeouts.get("connect", None) + + async with self._connect_lock: + if self._connection is None: + try: + # Connect to the proxy + kwargs = { + "host": self._proxy_origin.host.decode("ascii"), + "port": self._proxy_origin.port, + "timeout": timeout, + } + async with Trace("connect_tcp", logger, request, kwargs) as trace: + stream = await self._network_backend.connect_tcp(**kwargs) + trace.return_value = stream + + # Connect to the remote host using socks5 + kwargs = { + "stream": stream, + "host": self._remote_origin.host.decode("ascii"), + "port": self._remote_origin.port, + "auth": self._proxy_auth, + } + async with Trace( + "setup_socks5_connection", logger, request, kwargs + ) as trace: + await _init_socks5_connection(**kwargs) + trace.return_value = stream + + # Upgrade the stream to SSL + if self._remote_origin.scheme == b"https": + ssl_context = ( + default_ssl_context() + if self._ssl_context is None + else self._ssl_context + ) + alpn_protocols = ( + ["http/1.1", "h2"] if self._http2 else ["http/1.1"] + ) + ssl_context.set_alpn_protocols(alpn_protocols) + + kwargs = { + "ssl_context": ssl_context, + "server_hostname": sni_hostname + or self._remote_origin.host.decode("ascii"), + "timeout": timeout, + } + async with Trace("start_tls", logger, request, kwargs) as trace: + stream = await stream.start_tls(**kwargs) + trace.return_value = stream + + # Determine if we should be using HTTP/1.1 or HTTP/2 + ssl_object = stream.get_extra_info("ssl_object") + http2_negotiated = ( + ssl_object is not None + and ssl_object.selected_alpn_protocol() == "h2" + ) + + # Create the HTTP/1.1 or HTTP/2 connection + if http2_negotiated or ( + self._http2 and not self._http1 + ): # pragma: nocover + from .http2 import AsyncHTTP2Connection + + self._connection = AsyncHTTP2Connection( + origin=self._remote_origin, + stream=stream, + keepalive_expiry=self._keepalive_expiry, + ) + else: + self._connection = AsyncHTTP11Connection( + origin=self._remote_origin, + stream=stream, + keepalive_expiry=self._keepalive_expiry, + ) + except Exception as exc: + self._connect_failed = True + raise exc + elif not self._connection.is_available(): # pragma: nocover + raise ConnectionNotAvailable() + + return await self._connection.handle_async_request(request) + + def can_handle_request(self, origin: Origin) -> bool: + return origin == self._remote_origin + + async def aclose(self) -> None: + if self._connection is not None: + await self._connection.aclose() + + def is_available(self) -> bool: + if self._connection is None: # pragma: nocover + # If HTTP/2 support is enabled, and the resulting connection could + # end up as HTTP/2 then we should indicate the connection as being + # available to service multiple requests. + return ( + self._http2 + and (self._remote_origin.scheme == b"https" or not self._http1) + and not self._connect_failed + ) + return self._connection.is_available() + + def has_expired(self) -> bool: + if self._connection is None: # pragma: nocover + return self._connect_failed + return self._connection.has_expired() + + def is_idle(self) -> bool: + if self._connection is None: # pragma: nocover + return self._connect_failed + return self._connection.is_idle() + + def is_closed(self) -> bool: + if self._connection is None: # pragma: nocover + return self._connect_failed + return self._connection.is_closed() + + def info(self) -> str: + if self._connection is None: # pragma: nocover + return "CONNECTION FAILED" if self._connect_failed else "CONNECTING" + return self._connection.info() + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} [{self.info()}]>" diff --git a/.venv/lib/python3.13/site-packages/httpcore/_backends/__init__.py b/.venv/lib/python3.13/site-packages/httpcore/_backends/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/lib/python3.13/site-packages/httpcore/_backends/anyio.py b/.venv/lib/python3.13/site-packages/httpcore/_backends/anyio.py new file mode 100644 index 0000000000000000000000000000000000000000..a140095e1b8de022f321a41c0125e0e5febc0749 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_backends/anyio.py @@ -0,0 +1,146 @@ +from __future__ import annotations + +import ssl +import typing + +import anyio + +from .._exceptions import ( + ConnectError, + ConnectTimeout, + ReadError, + ReadTimeout, + WriteError, + WriteTimeout, + map_exceptions, +) +from .._utils import is_socket_readable +from .base import SOCKET_OPTION, AsyncNetworkBackend, AsyncNetworkStream + + +class AnyIOStream(AsyncNetworkStream): + def __init__(self, stream: anyio.abc.ByteStream) -> None: + self._stream = stream + + async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: + exc_map = { + TimeoutError: ReadTimeout, + anyio.BrokenResourceError: ReadError, + anyio.ClosedResourceError: ReadError, + anyio.EndOfStream: ReadError, + } + with map_exceptions(exc_map): + with anyio.fail_after(timeout): + try: + return await self._stream.receive(max_bytes=max_bytes) + except anyio.EndOfStream: # pragma: nocover + return b"" + + async def write(self, buffer: bytes, timeout: float | None = None) -> None: + if not buffer: + return + + exc_map = { + TimeoutError: WriteTimeout, + anyio.BrokenResourceError: WriteError, + anyio.ClosedResourceError: WriteError, + } + with map_exceptions(exc_map): + with anyio.fail_after(timeout): + await self._stream.send(item=buffer) + + async def aclose(self) -> None: + await self._stream.aclose() + + async def start_tls( + self, + ssl_context: ssl.SSLContext, + server_hostname: str | None = None, + timeout: float | None = None, + ) -> AsyncNetworkStream: + exc_map = { + TimeoutError: ConnectTimeout, + anyio.BrokenResourceError: ConnectError, + anyio.EndOfStream: ConnectError, + ssl.SSLError: ConnectError, + } + with map_exceptions(exc_map): + try: + with anyio.fail_after(timeout): + ssl_stream = await anyio.streams.tls.TLSStream.wrap( + self._stream, + ssl_context=ssl_context, + hostname=server_hostname, + standard_compatible=False, + server_side=False, + ) + except Exception as exc: # pragma: nocover + await self.aclose() + raise exc + return AnyIOStream(ssl_stream) + + def get_extra_info(self, info: str) -> typing.Any: + if info == "ssl_object": + return self._stream.extra(anyio.streams.tls.TLSAttribute.ssl_object, None) + if info == "client_addr": + return self._stream.extra(anyio.abc.SocketAttribute.local_address, None) + if info == "server_addr": + return self._stream.extra(anyio.abc.SocketAttribute.remote_address, None) + if info == "socket": + return self._stream.extra(anyio.abc.SocketAttribute.raw_socket, None) + if info == "is_readable": + sock = self._stream.extra(anyio.abc.SocketAttribute.raw_socket, None) + return is_socket_readable(sock) + return None + + +class AnyIOBackend(AsyncNetworkBackend): + async def connect_tcp( + self, + host: str, + port: int, + timeout: float | None = None, + local_address: str | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> AsyncNetworkStream: # pragma: nocover + if socket_options is None: + socket_options = [] + exc_map = { + TimeoutError: ConnectTimeout, + OSError: ConnectError, + anyio.BrokenResourceError: ConnectError, + } + with map_exceptions(exc_map): + with anyio.fail_after(timeout): + stream: anyio.abc.ByteStream = await anyio.connect_tcp( + remote_host=host, + remote_port=port, + local_host=local_address, + ) + # By default TCP sockets opened in `asyncio` include TCP_NODELAY. + for option in socket_options: + stream._raw_socket.setsockopt(*option) # type: ignore[attr-defined] # pragma: no cover + return AnyIOStream(stream) + + async def connect_unix_socket( + self, + path: str, + timeout: float | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> AsyncNetworkStream: # pragma: nocover + if socket_options is None: + socket_options = [] + exc_map = { + TimeoutError: ConnectTimeout, + OSError: ConnectError, + anyio.BrokenResourceError: ConnectError, + } + with map_exceptions(exc_map): + with anyio.fail_after(timeout): + stream: anyio.abc.ByteStream = await anyio.connect_unix(path) + for option in socket_options: + stream._raw_socket.setsockopt(*option) # type: ignore[attr-defined] # pragma: no cover + return AnyIOStream(stream) + + async def sleep(self, seconds: float) -> None: + await anyio.sleep(seconds) # pragma: nocover diff --git a/.venv/lib/python3.13/site-packages/httpcore/_backends/auto.py b/.venv/lib/python3.13/site-packages/httpcore/_backends/auto.py new file mode 100644 index 0000000000000000000000000000000000000000..49f0e698c97ad5623f376d8182675352e21c2c3c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_backends/auto.py @@ -0,0 +1,52 @@ +from __future__ import annotations + +import typing + +from .._synchronization import current_async_library +from .base import SOCKET_OPTION, AsyncNetworkBackend, AsyncNetworkStream + + +class AutoBackend(AsyncNetworkBackend): + async def _init_backend(self) -> None: + if not (hasattr(self, "_backend")): + backend = current_async_library() + if backend == "trio": + from .trio import TrioBackend + + self._backend: AsyncNetworkBackend = TrioBackend() + else: + from .anyio import AnyIOBackend + + self._backend = AnyIOBackend() + + async def connect_tcp( + self, + host: str, + port: int, + timeout: float | None = None, + local_address: str | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> AsyncNetworkStream: + await self._init_backend() + return await self._backend.connect_tcp( + host, + port, + timeout=timeout, + local_address=local_address, + socket_options=socket_options, + ) + + async def connect_unix_socket( + self, + path: str, + timeout: float | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> AsyncNetworkStream: # pragma: nocover + await self._init_backend() + return await self._backend.connect_unix_socket( + path, timeout=timeout, socket_options=socket_options + ) + + async def sleep(self, seconds: float) -> None: # pragma: nocover + await self._init_backend() + return await self._backend.sleep(seconds) diff --git a/.venv/lib/python3.13/site-packages/httpcore/_backends/base.py b/.venv/lib/python3.13/site-packages/httpcore/_backends/base.py new file mode 100644 index 0000000000000000000000000000000000000000..cf55c8b10eb543872550be863206fe2f760d0d8d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_backends/base.py @@ -0,0 +1,101 @@ +from __future__ import annotations + +import ssl +import time +import typing + +SOCKET_OPTION = typing.Union[ + typing.Tuple[int, int, int], + typing.Tuple[int, int, typing.Union[bytes, bytearray]], + typing.Tuple[int, int, None, int], +] + + +class NetworkStream: + def read(self, max_bytes: int, timeout: float | None = None) -> bytes: + raise NotImplementedError() # pragma: nocover + + def write(self, buffer: bytes, timeout: float | None = None) -> None: + raise NotImplementedError() # pragma: nocover + + def close(self) -> None: + raise NotImplementedError() # pragma: nocover + + def start_tls( + self, + ssl_context: ssl.SSLContext, + server_hostname: str | None = None, + timeout: float | None = None, + ) -> NetworkStream: + raise NotImplementedError() # pragma: nocover + + def get_extra_info(self, info: str) -> typing.Any: + return None # pragma: nocover + + +class NetworkBackend: + def connect_tcp( + self, + host: str, + port: int, + timeout: float | None = None, + local_address: str | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> NetworkStream: + raise NotImplementedError() # pragma: nocover + + def connect_unix_socket( + self, + path: str, + timeout: float | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> NetworkStream: + raise NotImplementedError() # pragma: nocover + + def sleep(self, seconds: float) -> None: + time.sleep(seconds) # pragma: nocover + + +class AsyncNetworkStream: + async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: + raise NotImplementedError() # pragma: nocover + + async def write(self, buffer: bytes, timeout: float | None = None) -> None: + raise NotImplementedError() # pragma: nocover + + async def aclose(self) -> None: + raise NotImplementedError() # pragma: nocover + + async def start_tls( + self, + ssl_context: ssl.SSLContext, + server_hostname: str | None = None, + timeout: float | None = None, + ) -> AsyncNetworkStream: + raise NotImplementedError() # pragma: nocover + + def get_extra_info(self, info: str) -> typing.Any: + return None # pragma: nocover + + +class AsyncNetworkBackend: + async def connect_tcp( + self, + host: str, + port: int, + timeout: float | None = None, + local_address: str | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> AsyncNetworkStream: + raise NotImplementedError() # pragma: nocover + + async def connect_unix_socket( + self, + path: str, + timeout: float | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> AsyncNetworkStream: + raise NotImplementedError() # pragma: nocover + + async def sleep(self, seconds: float) -> None: + raise NotImplementedError() # pragma: nocover diff --git a/.venv/lib/python3.13/site-packages/httpcore/_backends/mock.py b/.venv/lib/python3.13/site-packages/httpcore/_backends/mock.py new file mode 100644 index 0000000000000000000000000000000000000000..9b6edca03d4d4b34f355fd53e49d4b4c699c972c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_backends/mock.py @@ -0,0 +1,143 @@ +from __future__ import annotations + +import ssl +import typing + +from .._exceptions import ReadError +from .base import ( + SOCKET_OPTION, + AsyncNetworkBackend, + AsyncNetworkStream, + NetworkBackend, + NetworkStream, +) + + +class MockSSLObject: + def __init__(self, http2: bool): + self._http2 = http2 + + def selected_alpn_protocol(self) -> str: + return "h2" if self._http2 else "http/1.1" + + +class MockStream(NetworkStream): + def __init__(self, buffer: list[bytes], http2: bool = False) -> None: + self._buffer = buffer + self._http2 = http2 + self._closed = False + + def read(self, max_bytes: int, timeout: float | None = None) -> bytes: + if self._closed: + raise ReadError("Connection closed") + if not self._buffer: + return b"" + return self._buffer.pop(0) + + def write(self, buffer: bytes, timeout: float | None = None) -> None: + pass + + def close(self) -> None: + self._closed = True + + def start_tls( + self, + ssl_context: ssl.SSLContext, + server_hostname: str | None = None, + timeout: float | None = None, + ) -> NetworkStream: + return self + + def get_extra_info(self, info: str) -> typing.Any: + return MockSSLObject(http2=self._http2) if info == "ssl_object" else None + + def __repr__(self) -> str: + return "" + + +class MockBackend(NetworkBackend): + def __init__(self, buffer: list[bytes], http2: bool = False) -> None: + self._buffer = buffer + self._http2 = http2 + + def connect_tcp( + self, + host: str, + port: int, + timeout: float | None = None, + local_address: str | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> NetworkStream: + return MockStream(list(self._buffer), http2=self._http2) + + def connect_unix_socket( + self, + path: str, + timeout: float | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> NetworkStream: + return MockStream(list(self._buffer), http2=self._http2) + + def sleep(self, seconds: float) -> None: + pass + + +class AsyncMockStream(AsyncNetworkStream): + def __init__(self, buffer: list[bytes], http2: bool = False) -> None: + self._buffer = buffer + self._http2 = http2 + self._closed = False + + async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: + if self._closed: + raise ReadError("Connection closed") + if not self._buffer: + return b"" + return self._buffer.pop(0) + + async def write(self, buffer: bytes, timeout: float | None = None) -> None: + pass + + async def aclose(self) -> None: + self._closed = True + + async def start_tls( + self, + ssl_context: ssl.SSLContext, + server_hostname: str | None = None, + timeout: float | None = None, + ) -> AsyncNetworkStream: + return self + + def get_extra_info(self, info: str) -> typing.Any: + return MockSSLObject(http2=self._http2) if info == "ssl_object" else None + + def __repr__(self) -> str: + return "" + + +class AsyncMockBackend(AsyncNetworkBackend): + def __init__(self, buffer: list[bytes], http2: bool = False) -> None: + self._buffer = buffer + self._http2 = http2 + + async def connect_tcp( + self, + host: str, + port: int, + timeout: float | None = None, + local_address: str | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> AsyncNetworkStream: + return AsyncMockStream(list(self._buffer), http2=self._http2) + + async def connect_unix_socket( + self, + path: str, + timeout: float | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> AsyncNetworkStream: + return AsyncMockStream(list(self._buffer), http2=self._http2) + + async def sleep(self, seconds: float) -> None: + pass diff --git a/.venv/lib/python3.13/site-packages/httpcore/_backends/sync.py b/.venv/lib/python3.13/site-packages/httpcore/_backends/sync.py new file mode 100644 index 0000000000000000000000000000000000000000..4018a09c6fb1e0ef1b03ab8d84b13ebef4031f7c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_backends/sync.py @@ -0,0 +1,241 @@ +from __future__ import annotations + +import functools +import socket +import ssl +import sys +import typing + +from .._exceptions import ( + ConnectError, + ConnectTimeout, + ExceptionMapping, + ReadError, + ReadTimeout, + WriteError, + WriteTimeout, + map_exceptions, +) +from .._utils import is_socket_readable +from .base import SOCKET_OPTION, NetworkBackend, NetworkStream + + +class TLSinTLSStream(NetworkStream): # pragma: no cover + """ + Because the standard `SSLContext.wrap_socket` method does + not work for `SSLSocket` objects, we need this class + to implement TLS stream using an underlying `SSLObject` + instance in order to support TLS on top of TLS. + """ + + # Defined in RFC 8449 + TLS_RECORD_SIZE = 16384 + + def __init__( + self, + sock: socket.socket, + ssl_context: ssl.SSLContext, + server_hostname: str | None = None, + timeout: float | None = None, + ): + self._sock = sock + self._incoming = ssl.MemoryBIO() + self._outgoing = ssl.MemoryBIO() + + self.ssl_obj = ssl_context.wrap_bio( + incoming=self._incoming, + outgoing=self._outgoing, + server_hostname=server_hostname, + ) + + self._sock.settimeout(timeout) + self._perform_io(self.ssl_obj.do_handshake) + + def _perform_io( + self, + func: typing.Callable[..., typing.Any], + ) -> typing.Any: + ret = None + + while True: + errno = None + try: + ret = func() + except (ssl.SSLWantReadError, ssl.SSLWantWriteError) as e: + errno = e.errno + + self._sock.sendall(self._outgoing.read()) + + if errno == ssl.SSL_ERROR_WANT_READ: + buf = self._sock.recv(self.TLS_RECORD_SIZE) + + if buf: + self._incoming.write(buf) + else: + self._incoming.write_eof() + if errno is None: + return ret + + def read(self, max_bytes: int, timeout: float | None = None) -> bytes: + exc_map: ExceptionMapping = {socket.timeout: ReadTimeout, OSError: ReadError} + with map_exceptions(exc_map): + self._sock.settimeout(timeout) + return typing.cast( + bytes, self._perform_io(functools.partial(self.ssl_obj.read, max_bytes)) + ) + + def write(self, buffer: bytes, timeout: float | None = None) -> None: + exc_map: ExceptionMapping = {socket.timeout: WriteTimeout, OSError: WriteError} + with map_exceptions(exc_map): + self._sock.settimeout(timeout) + while buffer: + nsent = self._perform_io(functools.partial(self.ssl_obj.write, buffer)) + buffer = buffer[nsent:] + + def close(self) -> None: + self._sock.close() + + def start_tls( + self, + ssl_context: ssl.SSLContext, + server_hostname: str | None = None, + timeout: float | None = None, + ) -> NetworkStream: + raise NotImplementedError() + + def get_extra_info(self, info: str) -> typing.Any: + if info == "ssl_object": + return self.ssl_obj + if info == "client_addr": + return self._sock.getsockname() + if info == "server_addr": + return self._sock.getpeername() + if info == "socket": + return self._sock + if info == "is_readable": + return is_socket_readable(self._sock) + return None + + +class SyncStream(NetworkStream): + def __init__(self, sock: socket.socket) -> None: + self._sock = sock + + def read(self, max_bytes: int, timeout: float | None = None) -> bytes: + exc_map: ExceptionMapping = {socket.timeout: ReadTimeout, OSError: ReadError} + with map_exceptions(exc_map): + self._sock.settimeout(timeout) + return self._sock.recv(max_bytes) + + def write(self, buffer: bytes, timeout: float | None = None) -> None: + if not buffer: + return + + exc_map: ExceptionMapping = {socket.timeout: WriteTimeout, OSError: WriteError} + with map_exceptions(exc_map): + while buffer: + self._sock.settimeout(timeout) + n = self._sock.send(buffer) + buffer = buffer[n:] + + def close(self) -> None: + self._sock.close() + + def start_tls( + self, + ssl_context: ssl.SSLContext, + server_hostname: str | None = None, + timeout: float | None = None, + ) -> NetworkStream: + exc_map: ExceptionMapping = { + socket.timeout: ConnectTimeout, + OSError: ConnectError, + } + with map_exceptions(exc_map): + try: + if isinstance(self._sock, ssl.SSLSocket): # pragma: no cover + # If the underlying socket has already been upgraded + # to the TLS layer (i.e. is an instance of SSLSocket), + # we need some additional smarts to support TLS-in-TLS. + return TLSinTLSStream( + self._sock, ssl_context, server_hostname, timeout + ) + else: + self._sock.settimeout(timeout) + sock = ssl_context.wrap_socket( + self._sock, server_hostname=server_hostname + ) + except Exception as exc: # pragma: nocover + self.close() + raise exc + return SyncStream(sock) + + def get_extra_info(self, info: str) -> typing.Any: + if info == "ssl_object" and isinstance(self._sock, ssl.SSLSocket): + return self._sock._sslobj # type: ignore + if info == "client_addr": + return self._sock.getsockname() + if info == "server_addr": + return self._sock.getpeername() + if info == "socket": + return self._sock + if info == "is_readable": + return is_socket_readable(self._sock) + return None + + +class SyncBackend(NetworkBackend): + def connect_tcp( + self, + host: str, + port: int, + timeout: float | None = None, + local_address: str | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> NetworkStream: + # Note that we automatically include `TCP_NODELAY` + # in addition to any other custom socket options. + if socket_options is None: + socket_options = [] # pragma: no cover + address = (host, port) + source_address = None if local_address is None else (local_address, 0) + exc_map: ExceptionMapping = { + socket.timeout: ConnectTimeout, + OSError: ConnectError, + } + + with map_exceptions(exc_map): + sock = socket.create_connection( + address, + timeout, + source_address=source_address, + ) + for option in socket_options: + sock.setsockopt(*option) # pragma: no cover + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + return SyncStream(sock) + + def connect_unix_socket( + self, + path: str, + timeout: float | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> NetworkStream: # pragma: nocover + if sys.platform == "win32": + raise RuntimeError( + "Attempted to connect to a UNIX socket on a Windows system." + ) + if socket_options is None: + socket_options = [] + + exc_map: ExceptionMapping = { + socket.timeout: ConnectTimeout, + OSError: ConnectError, + } + with map_exceptions(exc_map): + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + for option in socket_options: + sock.setsockopt(*option) + sock.settimeout(timeout) + sock.connect(path) + return SyncStream(sock) diff --git a/.venv/lib/python3.13/site-packages/httpcore/_backends/trio.py b/.venv/lib/python3.13/site-packages/httpcore/_backends/trio.py new file mode 100644 index 0000000000000000000000000000000000000000..6f53f5f2a025e01e9949e2530bd9ca6928859251 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_backends/trio.py @@ -0,0 +1,159 @@ +from __future__ import annotations + +import ssl +import typing + +import trio + +from .._exceptions import ( + ConnectError, + ConnectTimeout, + ExceptionMapping, + ReadError, + ReadTimeout, + WriteError, + WriteTimeout, + map_exceptions, +) +from .base import SOCKET_OPTION, AsyncNetworkBackend, AsyncNetworkStream + + +class TrioStream(AsyncNetworkStream): + def __init__(self, stream: trio.abc.Stream) -> None: + self._stream = stream + + async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: + timeout_or_inf = float("inf") if timeout is None else timeout + exc_map: ExceptionMapping = { + trio.TooSlowError: ReadTimeout, + trio.BrokenResourceError: ReadError, + trio.ClosedResourceError: ReadError, + } + with map_exceptions(exc_map): + with trio.fail_after(timeout_or_inf): + data: bytes = await self._stream.receive_some(max_bytes=max_bytes) + return data + + async def write(self, buffer: bytes, timeout: float | None = None) -> None: + if not buffer: + return + + timeout_or_inf = float("inf") if timeout is None else timeout + exc_map: ExceptionMapping = { + trio.TooSlowError: WriteTimeout, + trio.BrokenResourceError: WriteError, + trio.ClosedResourceError: WriteError, + } + with map_exceptions(exc_map): + with trio.fail_after(timeout_or_inf): + await self._stream.send_all(data=buffer) + + async def aclose(self) -> None: + await self._stream.aclose() + + async def start_tls( + self, + ssl_context: ssl.SSLContext, + server_hostname: str | None = None, + timeout: float | None = None, + ) -> AsyncNetworkStream: + timeout_or_inf = float("inf") if timeout is None else timeout + exc_map: ExceptionMapping = { + trio.TooSlowError: ConnectTimeout, + trio.BrokenResourceError: ConnectError, + } + ssl_stream = trio.SSLStream( + self._stream, + ssl_context=ssl_context, + server_hostname=server_hostname, + https_compatible=True, + server_side=False, + ) + with map_exceptions(exc_map): + try: + with trio.fail_after(timeout_or_inf): + await ssl_stream.do_handshake() + except Exception as exc: # pragma: nocover + await self.aclose() + raise exc + return TrioStream(ssl_stream) + + def get_extra_info(self, info: str) -> typing.Any: + if info == "ssl_object" and isinstance(self._stream, trio.SSLStream): + # Type checkers cannot see `_ssl_object` attribute because trio._ssl.SSLStream uses __getattr__/__setattr__. + # Tracked at https://github.com/python-trio/trio/issues/542 + return self._stream._ssl_object # type: ignore[attr-defined] + if info == "client_addr": + return self._get_socket_stream().socket.getsockname() + if info == "server_addr": + return self._get_socket_stream().socket.getpeername() + if info == "socket": + stream = self._stream + while isinstance(stream, trio.SSLStream): + stream = stream.transport_stream + assert isinstance(stream, trio.SocketStream) + return stream.socket + if info == "is_readable": + socket = self.get_extra_info("socket") + return socket.is_readable() + return None + + def _get_socket_stream(self) -> trio.SocketStream: + stream = self._stream + while isinstance(stream, trio.SSLStream): + stream = stream.transport_stream + assert isinstance(stream, trio.SocketStream) + return stream + + +class TrioBackend(AsyncNetworkBackend): + async def connect_tcp( + self, + host: str, + port: int, + timeout: float | None = None, + local_address: str | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> AsyncNetworkStream: + # By default for TCP sockets, trio enables TCP_NODELAY. + # https://trio.readthedocs.io/en/stable/reference-io.html#trio.SocketStream + if socket_options is None: + socket_options = [] # pragma: no cover + timeout_or_inf = float("inf") if timeout is None else timeout + exc_map: ExceptionMapping = { + trio.TooSlowError: ConnectTimeout, + trio.BrokenResourceError: ConnectError, + OSError: ConnectError, + } + with map_exceptions(exc_map): + with trio.fail_after(timeout_or_inf): + stream: trio.abc.Stream = await trio.open_tcp_stream( + host=host, port=port, local_address=local_address + ) + for option in socket_options: + stream.setsockopt(*option) # type: ignore[attr-defined] # pragma: no cover + return TrioStream(stream) + + async def connect_unix_socket( + self, + path: str, + timeout: float | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> AsyncNetworkStream: # pragma: nocover + if socket_options is None: + socket_options = [] + timeout_or_inf = float("inf") if timeout is None else timeout + exc_map: ExceptionMapping = { + trio.TooSlowError: ConnectTimeout, + trio.BrokenResourceError: ConnectError, + OSError: ConnectError, + } + with map_exceptions(exc_map): + with trio.fail_after(timeout_or_inf): + stream: trio.abc.Stream = await trio.open_unix_socket(path) + for option in socket_options: + stream.setsockopt(*option) # type: ignore[attr-defined] # pragma: no cover + return TrioStream(stream) + + async def sleep(self, seconds: float) -> None: + await trio.sleep(seconds) # pragma: nocover diff --git a/.venv/lib/python3.13/site-packages/httpcore/_exceptions.py b/.venv/lib/python3.13/site-packages/httpcore/_exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..bc28d44f55bdc4b872951a74780469a3999d9ab4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_exceptions.py @@ -0,0 +1,81 @@ +import contextlib +import typing + +ExceptionMapping = typing.Mapping[typing.Type[Exception], typing.Type[Exception]] + + +@contextlib.contextmanager +def map_exceptions(map: ExceptionMapping) -> typing.Iterator[None]: + try: + yield + except Exception as exc: # noqa: PIE786 + for from_exc, to_exc in map.items(): + if isinstance(exc, from_exc): + raise to_exc(exc) from exc + raise # pragma: nocover + + +class ConnectionNotAvailable(Exception): + pass + + +class ProxyError(Exception): + pass + + +class UnsupportedProtocol(Exception): + pass + + +class ProtocolError(Exception): + pass + + +class RemoteProtocolError(ProtocolError): + pass + + +class LocalProtocolError(ProtocolError): + pass + + +# Timeout errors + + +class TimeoutException(Exception): + pass + + +class PoolTimeout(TimeoutException): + pass + + +class ConnectTimeout(TimeoutException): + pass + + +class ReadTimeout(TimeoutException): + pass + + +class WriteTimeout(TimeoutException): + pass + + +# Network errors + + +class NetworkError(Exception): + pass + + +class ConnectError(NetworkError): + pass + + +class ReadError(NetworkError): + pass + + +class WriteError(NetworkError): + pass diff --git a/.venv/lib/python3.13/site-packages/httpcore/_models.py b/.venv/lib/python3.13/site-packages/httpcore/_models.py new file mode 100644 index 0000000000000000000000000000000000000000..8a65f13347d6621289a166d08123cbc8e1ad0157 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_models.py @@ -0,0 +1,516 @@ +from __future__ import annotations + +import base64 +import ssl +import typing +import urllib.parse + +# Functions for typechecking... + + +ByteOrStr = typing.Union[bytes, str] +HeadersAsSequence = typing.Sequence[typing.Tuple[ByteOrStr, ByteOrStr]] +HeadersAsMapping = typing.Mapping[ByteOrStr, ByteOrStr] +HeaderTypes = typing.Union[HeadersAsSequence, HeadersAsMapping, None] + +Extensions = typing.MutableMapping[str, typing.Any] + + +def enforce_bytes(value: bytes | str, *, name: str) -> bytes: + """ + Any arguments that are ultimately represented as bytes can be specified + either as bytes or as strings. + + However we enforce that any string arguments must only contain characters in + the plain ASCII range. chr(0)...chr(127). If you need to use characters + outside that range then be precise, and use a byte-wise argument. + """ + if isinstance(value, str): + try: + return value.encode("ascii") + except UnicodeEncodeError: + raise TypeError(f"{name} strings may not include unicode characters.") + elif isinstance(value, bytes): + return value + + seen_type = type(value).__name__ + raise TypeError(f"{name} must be bytes or str, but got {seen_type}.") + + +def enforce_url(value: URL | bytes | str, *, name: str) -> URL: + """ + Type check for URL parameters. + """ + if isinstance(value, (bytes, str)): + return URL(value) + elif isinstance(value, URL): + return value + + seen_type = type(value).__name__ + raise TypeError(f"{name} must be a URL, bytes, or str, but got {seen_type}.") + + +def enforce_headers( + value: HeadersAsMapping | HeadersAsSequence | None = None, *, name: str +) -> list[tuple[bytes, bytes]]: + """ + Convienence function that ensure all items in request or response headers + are either bytes or strings in the plain ASCII range. + """ + if value is None: + return [] + elif isinstance(value, typing.Mapping): + return [ + ( + enforce_bytes(k, name="header name"), + enforce_bytes(v, name="header value"), + ) + for k, v in value.items() + ] + elif isinstance(value, typing.Sequence): + return [ + ( + enforce_bytes(k, name="header name"), + enforce_bytes(v, name="header value"), + ) + for k, v in value + ] + + seen_type = type(value).__name__ + raise TypeError( + f"{name} must be a mapping or sequence of two-tuples, but got {seen_type}." + ) + + +def enforce_stream( + value: bytes | typing.Iterable[bytes] | typing.AsyncIterable[bytes] | None, + *, + name: str, +) -> typing.Iterable[bytes] | typing.AsyncIterable[bytes]: + if value is None: + return ByteStream(b"") + elif isinstance(value, bytes): + return ByteStream(value) + return value + + +# * https://tools.ietf.org/html/rfc3986#section-3.2.3 +# * https://url.spec.whatwg.org/#url-miscellaneous +# * https://url.spec.whatwg.org/#scheme-state +DEFAULT_PORTS = { + b"ftp": 21, + b"http": 80, + b"https": 443, + b"ws": 80, + b"wss": 443, +} + + +def include_request_headers( + headers: list[tuple[bytes, bytes]], + *, + url: "URL", + content: None | bytes | typing.Iterable[bytes] | typing.AsyncIterable[bytes], +) -> list[tuple[bytes, bytes]]: + headers_set = set(k.lower() for k, v in headers) + + if b"host" not in headers_set: + default_port = DEFAULT_PORTS.get(url.scheme) + if url.port is None or url.port == default_port: + header_value = url.host + else: + header_value = b"%b:%d" % (url.host, url.port) + headers = [(b"Host", header_value)] + headers + + if ( + content is not None + and b"content-length" not in headers_set + and b"transfer-encoding" not in headers_set + ): + if isinstance(content, bytes): + content_length = str(len(content)).encode("ascii") + headers += [(b"Content-Length", content_length)] + else: + headers += [(b"Transfer-Encoding", b"chunked")] # pragma: nocover + + return headers + + +# Interfaces for byte streams... + + +class ByteStream: + """ + A container for non-streaming content, and that supports both sync and async + stream iteration. + """ + + def __init__(self, content: bytes) -> None: + self._content = content + + def __iter__(self) -> typing.Iterator[bytes]: + yield self._content + + async def __aiter__(self) -> typing.AsyncIterator[bytes]: + yield self._content + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} [{len(self._content)} bytes]>" + + +class Origin: + def __init__(self, scheme: bytes, host: bytes, port: int) -> None: + self.scheme = scheme + self.host = host + self.port = port + + def __eq__(self, other: typing.Any) -> bool: + return ( + isinstance(other, Origin) + and self.scheme == other.scheme + and self.host == other.host + and self.port == other.port + ) + + def __str__(self) -> str: + scheme = self.scheme.decode("ascii") + host = self.host.decode("ascii") + port = str(self.port) + return f"{scheme}://{host}:{port}" + + +class URL: + """ + Represents the URL against which an HTTP request may be made. + + The URL may either be specified as a plain string, for convienence: + + ```python + url = httpcore.URL("https://www.example.com/") + ``` + + Or be constructed with explicitily pre-parsed components: + + ```python + url = httpcore.URL(scheme=b'https', host=b'www.example.com', port=None, target=b'/') + ``` + + Using this second more explicit style allows integrations that are using + `httpcore` to pass through URLs that have already been parsed in order to use + libraries such as `rfc-3986` rather than relying on the stdlib. It also ensures + that URL parsing is treated identically at both the networking level and at any + higher layers of abstraction. + + The four components are important here, as they allow the URL to be precisely + specified in a pre-parsed format. They also allow certain types of request to + be created that could not otherwise be expressed. + + For example, an HTTP request to `http://www.example.com/` forwarded via a proxy + at `http://localhost:8080`... + + ```python + # Constructs an HTTP request with a complete URL as the target: + # GET https://www.example.com/ HTTP/1.1 + url = httpcore.URL( + scheme=b'http', + host=b'localhost', + port=8080, + target=b'https://www.example.com/' + ) + request = httpcore.Request( + method="GET", + url=url + ) + ``` + + Another example is constructing an `OPTIONS *` request... + + ```python + # Constructs an 'OPTIONS *' HTTP request: + # OPTIONS * HTTP/1.1 + url = httpcore.URL(scheme=b'https', host=b'www.example.com', target=b'*') + request = httpcore.Request(method="OPTIONS", url=url) + ``` + + This kind of request is not possible to formulate with a URL string, + because the `/` delimiter is always used to demark the target from the + host/port portion of the URL. + + For convenience, string-like arguments may be specified either as strings or + as bytes. However, once a request is being issue over-the-wire, the URL + components are always ultimately required to be a bytewise representation. + + In order to avoid any ambiguity over character encodings, when strings are used + as arguments, they must be strictly limited to the ASCII range `chr(0)`-`chr(127)`. + If you require a bytewise representation that is outside this range you must + handle the character encoding directly, and pass a bytes instance. + """ + + def __init__( + self, + url: bytes | str = "", + *, + scheme: bytes | str = b"", + host: bytes | str = b"", + port: int | None = None, + target: bytes | str = b"", + ) -> None: + """ + Parameters: + url: The complete URL as a string or bytes. + scheme: The URL scheme as a string or bytes. + Typically either `"http"` or `"https"`. + host: The URL host as a string or bytes. Such as `"www.example.com"`. + port: The port to connect to. Either an integer or `None`. + target: The target of the HTTP request. Such as `"/items?search=red"`. + """ + if url: + parsed = urllib.parse.urlparse(enforce_bytes(url, name="url")) + self.scheme = parsed.scheme + self.host = parsed.hostname or b"" + self.port = parsed.port + self.target = (parsed.path or b"/") + ( + b"?" + parsed.query if parsed.query else b"" + ) + else: + self.scheme = enforce_bytes(scheme, name="scheme") + self.host = enforce_bytes(host, name="host") + self.port = port + self.target = enforce_bytes(target, name="target") + + @property + def origin(self) -> Origin: + default_port = { + b"http": 80, + b"https": 443, + b"ws": 80, + b"wss": 443, + b"socks5": 1080, + b"socks5h": 1080, + }[self.scheme] + return Origin( + scheme=self.scheme, host=self.host, port=self.port or default_port + ) + + def __eq__(self, other: typing.Any) -> bool: + return ( + isinstance(other, URL) + and other.scheme == self.scheme + and other.host == self.host + and other.port == self.port + and other.target == self.target + ) + + def __bytes__(self) -> bytes: + if self.port is None: + return b"%b://%b%b" % (self.scheme, self.host, self.target) + return b"%b://%b:%d%b" % (self.scheme, self.host, self.port, self.target) + + def __repr__(self) -> str: + return ( + f"{self.__class__.__name__}(scheme={self.scheme!r}, " + f"host={self.host!r}, port={self.port!r}, target={self.target!r})" + ) + + +class Request: + """ + An HTTP request. + """ + + def __init__( + self, + method: bytes | str, + url: URL | bytes | str, + *, + headers: HeaderTypes = None, + content: bytes + | typing.Iterable[bytes] + | typing.AsyncIterable[bytes] + | None = None, + extensions: Extensions | None = None, + ) -> None: + """ + Parameters: + method: The HTTP request method, either as a string or bytes. + For example: `GET`. + url: The request URL, either as a `URL` instance, or as a string or bytes. + For example: `"https://www.example.com".` + headers: The HTTP request headers. + content: The content of the request body. + extensions: A dictionary of optional extra information included on + the request. Possible keys include `"timeout"`, and `"trace"`. + """ + self.method: bytes = enforce_bytes(method, name="method") + self.url: URL = enforce_url(url, name="url") + self.headers: list[tuple[bytes, bytes]] = enforce_headers( + headers, name="headers" + ) + self.stream: typing.Iterable[bytes] | typing.AsyncIterable[bytes] = ( + enforce_stream(content, name="content") + ) + self.extensions = {} if extensions is None else extensions + + if "target" in self.extensions: + self.url = URL( + scheme=self.url.scheme, + host=self.url.host, + port=self.url.port, + target=self.extensions["target"], + ) + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} [{self.method!r}]>" + + +class Response: + """ + An HTTP response. + """ + + def __init__( + self, + status: int, + *, + headers: HeaderTypes = None, + content: bytes + | typing.Iterable[bytes] + | typing.AsyncIterable[bytes] + | None = None, + extensions: Extensions | None = None, + ) -> None: + """ + Parameters: + status: The HTTP status code of the response. For example `200`. + headers: The HTTP response headers. + content: The content of the response body. + extensions: A dictionary of optional extra information included on + the responseself.Possible keys include `"http_version"`, + `"reason_phrase"`, and `"network_stream"`. + """ + self.status: int = status + self.headers: list[tuple[bytes, bytes]] = enforce_headers( + headers, name="headers" + ) + self.stream: typing.Iterable[bytes] | typing.AsyncIterable[bytes] = ( + enforce_stream(content, name="content") + ) + self.extensions = {} if extensions is None else extensions + + self._stream_consumed = False + + @property + def content(self) -> bytes: + if not hasattr(self, "_content"): + if isinstance(self.stream, typing.Iterable): + raise RuntimeError( + "Attempted to access 'response.content' on a streaming response. " + "Call 'response.read()' first." + ) + else: + raise RuntimeError( + "Attempted to access 'response.content' on a streaming response. " + "Call 'await response.aread()' first." + ) + return self._content + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} [{self.status}]>" + + # Sync interface... + + def read(self) -> bytes: + if not isinstance(self.stream, typing.Iterable): # pragma: nocover + raise RuntimeError( + "Attempted to read an asynchronous response using 'response.read()'. " + "You should use 'await response.aread()' instead." + ) + if not hasattr(self, "_content"): + self._content = b"".join([part for part in self.iter_stream()]) + return self._content + + def iter_stream(self) -> typing.Iterator[bytes]: + if not isinstance(self.stream, typing.Iterable): # pragma: nocover + raise RuntimeError( + "Attempted to stream an asynchronous response using 'for ... in " + "response.iter_stream()'. " + "You should use 'async for ... in response.aiter_stream()' instead." + ) + if self._stream_consumed: + raise RuntimeError( + "Attempted to call 'for ... in response.iter_stream()' more than once." + ) + self._stream_consumed = True + for chunk in self.stream: + yield chunk + + def close(self) -> None: + if not isinstance(self.stream, typing.Iterable): # pragma: nocover + raise RuntimeError( + "Attempted to close an asynchronous response using 'response.close()'. " + "You should use 'await response.aclose()' instead." + ) + if hasattr(self.stream, "close"): + self.stream.close() + + # Async interface... + + async def aread(self) -> bytes: + if not isinstance(self.stream, typing.AsyncIterable): # pragma: nocover + raise RuntimeError( + "Attempted to read an synchronous response using " + "'await response.aread()'. " + "You should use 'response.read()' instead." + ) + if not hasattr(self, "_content"): + self._content = b"".join([part async for part in self.aiter_stream()]) + return self._content + + async def aiter_stream(self) -> typing.AsyncIterator[bytes]: + if not isinstance(self.stream, typing.AsyncIterable): # pragma: nocover + raise RuntimeError( + "Attempted to stream an synchronous response using 'async for ... in " + "response.aiter_stream()'. " + "You should use 'for ... in response.iter_stream()' instead." + ) + if self._stream_consumed: + raise RuntimeError( + "Attempted to call 'async for ... in response.aiter_stream()' " + "more than once." + ) + self._stream_consumed = True + async for chunk in self.stream: + yield chunk + + async def aclose(self) -> None: + if not isinstance(self.stream, typing.AsyncIterable): # pragma: nocover + raise RuntimeError( + "Attempted to close a synchronous response using " + "'await response.aclose()'. " + "You should use 'response.close()' instead." + ) + if hasattr(self.stream, "aclose"): + await self.stream.aclose() + + +class Proxy: + def __init__( + self, + url: URL | bytes | str, + auth: tuple[bytes | str, bytes | str] | None = None, + headers: HeadersAsMapping | HeadersAsSequence | None = None, + ssl_context: ssl.SSLContext | None = None, + ): + self.url = enforce_url(url, name="url") + self.headers = enforce_headers(headers, name="headers") + self.ssl_context = ssl_context + + if auth is not None: + username = enforce_bytes(auth[0], name="auth") + password = enforce_bytes(auth[1], name="auth") + userpass = username + b":" + password + authorization = b"Basic " + base64.b64encode(userpass) + self.auth: tuple[bytes, bytes] | None = (username, password) + self.headers = [(b"Proxy-Authorization", authorization)] + self.headers + else: + self.auth = None diff --git a/.venv/lib/python3.13/site-packages/httpcore/_ssl.py b/.venv/lib/python3.13/site-packages/httpcore/_ssl.py new file mode 100644 index 0000000000000000000000000000000000000000..c99c5a67945b8a3a3544d481e979c791ab45fe23 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_ssl.py @@ -0,0 +1,9 @@ +import ssl + +import certifi + + +def default_ssl_context() -> ssl.SSLContext: + context = ssl.create_default_context() + context.load_verify_locations(certifi.where()) + return context diff --git a/.venv/lib/python3.13/site-packages/httpcore/_sync/__init__.py b/.venv/lib/python3.13/site-packages/httpcore/_sync/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b476d76d9a7ff45de8d18ec22d33d6af2982f92e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_sync/__init__.py @@ -0,0 +1,39 @@ +from .connection import HTTPConnection +from .connection_pool import ConnectionPool +from .http11 import HTTP11Connection +from .http_proxy import HTTPProxy +from .interfaces import ConnectionInterface + +try: + from .http2 import HTTP2Connection +except ImportError: # pragma: nocover + + class HTTP2Connection: # type: ignore + def __init__(self, *args, **kwargs) -> None: # type: ignore + raise RuntimeError( + "Attempted to use http2 support, but the `h2` package is not " + "installed. Use 'pip install httpcore[http2]'." + ) + + +try: + from .socks_proxy import SOCKSProxy +except ImportError: # pragma: nocover + + class SOCKSProxy: # type: ignore + def __init__(self, *args, **kwargs) -> None: # type: ignore + raise RuntimeError( + "Attempted to use SOCKS support, but the `socksio` package is not " + "installed. Use 'pip install httpcore[socks]'." + ) + + +__all__ = [ + "HTTPConnection", + "ConnectionPool", + "HTTPProxy", + "HTTP11Connection", + "HTTP2Connection", + "ConnectionInterface", + "SOCKSProxy", +] diff --git a/.venv/lib/python3.13/site-packages/httpcore/_sync/connection.py b/.venv/lib/python3.13/site-packages/httpcore/_sync/connection.py new file mode 100644 index 0000000000000000000000000000000000000000..363f8be819d2576ea65365e625dd1596ea40429a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_sync/connection.py @@ -0,0 +1,222 @@ +from __future__ import annotations + +import itertools +import logging +import ssl +import types +import typing + +from .._backends.sync import SyncBackend +from .._backends.base import SOCKET_OPTION, NetworkBackend, NetworkStream +from .._exceptions import ConnectError, ConnectTimeout +from .._models import Origin, Request, Response +from .._ssl import default_ssl_context +from .._synchronization import Lock +from .._trace import Trace +from .http11 import HTTP11Connection +from .interfaces import ConnectionInterface + +RETRIES_BACKOFF_FACTOR = 0.5 # 0s, 0.5s, 1s, 2s, 4s, etc. + + +logger = logging.getLogger("httpcore.connection") + + +def exponential_backoff(factor: float) -> typing.Iterator[float]: + """ + Generate a geometric sequence that has a ratio of 2 and starts with 0. + + For example: + - `factor = 2`: `0, 2, 4, 8, 16, 32, 64, ...` + - `factor = 3`: `0, 3, 6, 12, 24, 48, 96, ...` + """ + yield 0 + for n in itertools.count(): + yield factor * 2**n + + +class HTTPConnection(ConnectionInterface): + def __init__( + self, + origin: Origin, + ssl_context: ssl.SSLContext | None = None, + keepalive_expiry: float | None = None, + http1: bool = True, + http2: bool = False, + retries: int = 0, + local_address: str | None = None, + uds: str | None = None, + network_backend: NetworkBackend | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> None: + self._origin = origin + self._ssl_context = ssl_context + self._keepalive_expiry = keepalive_expiry + self._http1 = http1 + self._http2 = http2 + self._retries = retries + self._local_address = local_address + self._uds = uds + + self._network_backend: NetworkBackend = ( + SyncBackend() if network_backend is None else network_backend + ) + self._connection: ConnectionInterface | None = None + self._connect_failed: bool = False + self._request_lock = Lock() + self._socket_options = socket_options + + def handle_request(self, request: Request) -> Response: + if not self.can_handle_request(request.url.origin): + raise RuntimeError( + f"Attempted to send request to {request.url.origin} on connection to {self._origin}" + ) + + try: + with self._request_lock: + if self._connection is None: + stream = self._connect(request) + + ssl_object = stream.get_extra_info("ssl_object") + http2_negotiated = ( + ssl_object is not None + and ssl_object.selected_alpn_protocol() == "h2" + ) + if http2_negotiated or (self._http2 and not self._http1): + from .http2 import HTTP2Connection + + self._connection = HTTP2Connection( + origin=self._origin, + stream=stream, + keepalive_expiry=self._keepalive_expiry, + ) + else: + self._connection = HTTP11Connection( + origin=self._origin, + stream=stream, + keepalive_expiry=self._keepalive_expiry, + ) + except BaseException as exc: + self._connect_failed = True + raise exc + + return self._connection.handle_request(request) + + def _connect(self, request: Request) -> NetworkStream: + timeouts = request.extensions.get("timeout", {}) + sni_hostname = request.extensions.get("sni_hostname", None) + timeout = timeouts.get("connect", None) + + retries_left = self._retries + delays = exponential_backoff(factor=RETRIES_BACKOFF_FACTOR) + + while True: + try: + if self._uds is None: + kwargs = { + "host": self._origin.host.decode("ascii"), + "port": self._origin.port, + "local_address": self._local_address, + "timeout": timeout, + "socket_options": self._socket_options, + } + with Trace("connect_tcp", logger, request, kwargs) as trace: + stream = self._network_backend.connect_tcp(**kwargs) + trace.return_value = stream + else: + kwargs = { + "path": self._uds, + "timeout": timeout, + "socket_options": self._socket_options, + } + with Trace( + "connect_unix_socket", logger, request, kwargs + ) as trace: + stream = self._network_backend.connect_unix_socket( + **kwargs + ) + trace.return_value = stream + + if self._origin.scheme in (b"https", b"wss"): + ssl_context = ( + default_ssl_context() + if self._ssl_context is None + else self._ssl_context + ) + alpn_protocols = ["http/1.1", "h2"] if self._http2 else ["http/1.1"] + ssl_context.set_alpn_protocols(alpn_protocols) + + kwargs = { + "ssl_context": ssl_context, + "server_hostname": sni_hostname + or self._origin.host.decode("ascii"), + "timeout": timeout, + } + with Trace("start_tls", logger, request, kwargs) as trace: + stream = stream.start_tls(**kwargs) + trace.return_value = stream + return stream + except (ConnectError, ConnectTimeout): + if retries_left <= 0: + raise + retries_left -= 1 + delay = next(delays) + with Trace("retry", logger, request, kwargs) as trace: + self._network_backend.sleep(delay) + + def can_handle_request(self, origin: Origin) -> bool: + return origin == self._origin + + def close(self) -> None: + if self._connection is not None: + with Trace("close", logger, None, {}): + self._connection.close() + + def is_available(self) -> bool: + if self._connection is None: + # If HTTP/2 support is enabled, and the resulting connection could + # end up as HTTP/2 then we should indicate the connection as being + # available to service multiple requests. + return ( + self._http2 + and (self._origin.scheme == b"https" or not self._http1) + and not self._connect_failed + ) + return self._connection.is_available() + + def has_expired(self) -> bool: + if self._connection is None: + return self._connect_failed + return self._connection.has_expired() + + def is_idle(self) -> bool: + if self._connection is None: + return self._connect_failed + return self._connection.is_idle() + + def is_closed(self) -> bool: + if self._connection is None: + return self._connect_failed + return self._connection.is_closed() + + def info(self) -> str: + if self._connection is None: + return "CONNECTION FAILED" if self._connect_failed else "CONNECTING" + return self._connection.info() + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} [{self.info()}]>" + + # These context managers are not used in the standard flow, but are + # useful for testing or working with connection instances directly. + + def __enter__(self) -> HTTPConnection: + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + self.close() diff --git a/.venv/lib/python3.13/site-packages/httpcore/_sync/connection_pool.py b/.venv/lib/python3.13/site-packages/httpcore/_sync/connection_pool.py new file mode 100644 index 0000000000000000000000000000000000000000..9ccfa53e597a29ee387f9d16f3af4f695ac0d33a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_sync/connection_pool.py @@ -0,0 +1,420 @@ +from __future__ import annotations + +import ssl +import sys +import types +import typing + +from .._backends.sync import SyncBackend +from .._backends.base import SOCKET_OPTION, NetworkBackend +from .._exceptions import ConnectionNotAvailable, UnsupportedProtocol +from .._models import Origin, Proxy, Request, Response +from .._synchronization import Event, ShieldCancellation, ThreadLock +from .connection import HTTPConnection +from .interfaces import ConnectionInterface, RequestInterface + + +class PoolRequest: + def __init__(self, request: Request) -> None: + self.request = request + self.connection: ConnectionInterface | None = None + self._connection_acquired = Event() + + def assign_to_connection(self, connection: ConnectionInterface | None) -> None: + self.connection = connection + self._connection_acquired.set() + + def clear_connection(self) -> None: + self.connection = None + self._connection_acquired = Event() + + def wait_for_connection( + self, timeout: float | None = None + ) -> ConnectionInterface: + if self.connection is None: + self._connection_acquired.wait(timeout=timeout) + assert self.connection is not None + return self.connection + + def is_queued(self) -> bool: + return self.connection is None + + +class ConnectionPool(RequestInterface): + """ + A connection pool for making HTTP requests. + """ + + def __init__( + self, + ssl_context: ssl.SSLContext | None = None, + proxy: Proxy | None = None, + max_connections: int | None = 10, + max_keepalive_connections: int | None = None, + keepalive_expiry: float | None = None, + http1: bool = True, + http2: bool = False, + retries: int = 0, + local_address: str | None = None, + uds: str | None = None, + network_backend: NetworkBackend | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> None: + """ + A connection pool for making HTTP requests. + + Parameters: + ssl_context: An SSL context to use for verifying connections. + If not specified, the default `httpcore.default_ssl_context()` + will be used. + max_connections: The maximum number of concurrent HTTP connections that + the pool should allow. Any attempt to send a request on a pool that + would exceed this amount will block until a connection is available. + max_keepalive_connections: The maximum number of idle HTTP connections + that will be maintained in the pool. + keepalive_expiry: The duration in seconds that an idle HTTP connection + may be maintained for before being expired from the pool. + http1: A boolean indicating if HTTP/1.1 requests should be supported + by the connection pool. Defaults to True. + http2: A boolean indicating if HTTP/2 requests should be supported by + the connection pool. Defaults to False. + retries: The maximum number of retries when trying to establish a + connection. + local_address: Local address to connect from. Can also be used to connect + using a particular address family. Using `local_address="0.0.0.0"` + will connect using an `AF_INET` address (IPv4), while using + `local_address="::"` will connect using an `AF_INET6` address (IPv6). + uds: Path to a Unix Domain Socket to use instead of TCP sockets. + network_backend: A backend instance to use for handling network I/O. + socket_options: Socket options that have to be included + in the TCP socket when the connection was established. + """ + self._ssl_context = ssl_context + self._proxy = proxy + self._max_connections = ( + sys.maxsize if max_connections is None else max_connections + ) + self._max_keepalive_connections = ( + sys.maxsize + if max_keepalive_connections is None + else max_keepalive_connections + ) + self._max_keepalive_connections = min( + self._max_connections, self._max_keepalive_connections + ) + + self._keepalive_expiry = keepalive_expiry + self._http1 = http1 + self._http2 = http2 + self._retries = retries + self._local_address = local_address + self._uds = uds + + self._network_backend = ( + SyncBackend() if network_backend is None else network_backend + ) + self._socket_options = socket_options + + # The mutable state on a connection pool is the queue of incoming requests, + # and the set of connections that are servicing those requests. + self._connections: list[ConnectionInterface] = [] + self._requests: list[PoolRequest] = [] + + # We only mutate the state of the connection pool within an 'optional_thread_lock' + # context. This holds a threading lock unless we're running in async mode, + # in which case it is a no-op. + self._optional_thread_lock = ThreadLock() + + def create_connection(self, origin: Origin) -> ConnectionInterface: + if self._proxy is not None: + if self._proxy.url.scheme in (b"socks5", b"socks5h"): + from .socks_proxy import Socks5Connection + + return Socks5Connection( + proxy_origin=self._proxy.url.origin, + proxy_auth=self._proxy.auth, + remote_origin=origin, + ssl_context=self._ssl_context, + keepalive_expiry=self._keepalive_expiry, + http1=self._http1, + http2=self._http2, + network_backend=self._network_backend, + ) + elif origin.scheme == b"http": + from .http_proxy import ForwardHTTPConnection + + return ForwardHTTPConnection( + proxy_origin=self._proxy.url.origin, + proxy_headers=self._proxy.headers, + proxy_ssl_context=self._proxy.ssl_context, + remote_origin=origin, + keepalive_expiry=self._keepalive_expiry, + network_backend=self._network_backend, + ) + from .http_proxy import TunnelHTTPConnection + + return TunnelHTTPConnection( + proxy_origin=self._proxy.url.origin, + proxy_headers=self._proxy.headers, + proxy_ssl_context=self._proxy.ssl_context, + remote_origin=origin, + ssl_context=self._ssl_context, + keepalive_expiry=self._keepalive_expiry, + http1=self._http1, + http2=self._http2, + network_backend=self._network_backend, + ) + + return HTTPConnection( + origin=origin, + ssl_context=self._ssl_context, + keepalive_expiry=self._keepalive_expiry, + http1=self._http1, + http2=self._http2, + retries=self._retries, + local_address=self._local_address, + uds=self._uds, + network_backend=self._network_backend, + socket_options=self._socket_options, + ) + + @property + def connections(self) -> list[ConnectionInterface]: + """ + Return a list of the connections currently in the pool. + + For example: + + ```python + >>> pool.connections + [ + , + , + , + ] + ``` + """ + return list(self._connections) + + def handle_request(self, request: Request) -> Response: + """ + Send an HTTP request, and return an HTTP response. + + This is the core implementation that is called into by `.request()` or `.stream()`. + """ + scheme = request.url.scheme.decode() + if scheme == "": + raise UnsupportedProtocol( + "Request URL is missing an 'http://' or 'https://' protocol." + ) + if scheme not in ("http", "https", "ws", "wss"): + raise UnsupportedProtocol( + f"Request URL has an unsupported protocol '{scheme}://'." + ) + + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("pool", None) + + with self._optional_thread_lock: + # Add the incoming request to our request queue. + pool_request = PoolRequest(request) + self._requests.append(pool_request) + + try: + while True: + with self._optional_thread_lock: + # Assign incoming requests to available connections, + # closing or creating new connections as required. + closing = self._assign_requests_to_connections() + self._close_connections(closing) + + # Wait until this request has an assigned connection. + connection = pool_request.wait_for_connection(timeout=timeout) + + try: + # Send the request on the assigned connection. + response = connection.handle_request( + pool_request.request + ) + except ConnectionNotAvailable: + # In some cases a connection may initially be available to + # handle a request, but then become unavailable. + # + # In this case we clear the connection and try again. + pool_request.clear_connection() + else: + break # pragma: nocover + + except BaseException as exc: + with self._optional_thread_lock: + # For any exception or cancellation we remove the request from + # the queue, and then re-assign requests to connections. + self._requests.remove(pool_request) + closing = self._assign_requests_to_connections() + + self._close_connections(closing) + raise exc from None + + # Return the response. Note that in this case we still have to manage + # the point at which the response is closed. + assert isinstance(response.stream, typing.Iterable) + return Response( + status=response.status, + headers=response.headers, + content=PoolByteStream( + stream=response.stream, pool_request=pool_request, pool=self + ), + extensions=response.extensions, + ) + + def _assign_requests_to_connections(self) -> list[ConnectionInterface]: + """ + Manage the state of the connection pool, assigning incoming + requests to connections as available. + + Called whenever a new request is added or removed from the pool. + + Any closing connections are returned, allowing the I/O for closing + those connections to be handled seperately. + """ + closing_connections = [] + + # First we handle cleaning up any connections that are closed, + # have expired their keep-alive, or surplus idle connections. + for connection in list(self._connections): + if connection.is_closed(): + # log: "removing closed connection" + self._connections.remove(connection) + elif connection.has_expired(): + # log: "closing expired connection" + self._connections.remove(connection) + closing_connections.append(connection) + elif ( + connection.is_idle() + and len([connection.is_idle() for connection in self._connections]) + > self._max_keepalive_connections + ): + # log: "closing idle connection" + self._connections.remove(connection) + closing_connections.append(connection) + + # Assign queued requests to connections. + queued_requests = [request for request in self._requests if request.is_queued()] + for pool_request in queued_requests: + origin = pool_request.request.url.origin + available_connections = [ + connection + for connection in self._connections + if connection.can_handle_request(origin) and connection.is_available() + ] + idle_connections = [ + connection for connection in self._connections if connection.is_idle() + ] + + # There are three cases for how we may be able to handle the request: + # + # 1. There is an existing connection that can handle the request. + # 2. We can create a new connection to handle the request. + # 3. We can close an idle connection and then create a new connection + # to handle the request. + if available_connections: + # log: "reusing existing connection" + connection = available_connections[0] + pool_request.assign_to_connection(connection) + elif len(self._connections) < self._max_connections: + # log: "creating new connection" + connection = self.create_connection(origin) + self._connections.append(connection) + pool_request.assign_to_connection(connection) + elif idle_connections: + # log: "closing idle connection" + connection = idle_connections[0] + self._connections.remove(connection) + closing_connections.append(connection) + # log: "creating new connection" + connection = self.create_connection(origin) + self._connections.append(connection) + pool_request.assign_to_connection(connection) + + return closing_connections + + def _close_connections(self, closing: list[ConnectionInterface]) -> None: + # Close connections which have been removed from the pool. + with ShieldCancellation(): + for connection in closing: + connection.close() + + def close(self) -> None: + # Explicitly close the connection pool. + # Clears all existing requests and connections. + with self._optional_thread_lock: + closing_connections = list(self._connections) + self._connections = [] + self._close_connections(closing_connections) + + def __enter__(self) -> ConnectionPool: + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + self.close() + + def __repr__(self) -> str: + class_name = self.__class__.__name__ + with self._optional_thread_lock: + request_is_queued = [request.is_queued() for request in self._requests] + connection_is_idle = [ + connection.is_idle() for connection in self._connections + ] + + num_active_requests = request_is_queued.count(False) + num_queued_requests = request_is_queued.count(True) + num_active_connections = connection_is_idle.count(False) + num_idle_connections = connection_is_idle.count(True) + + requests_info = ( + f"Requests: {num_active_requests} active, {num_queued_requests} queued" + ) + connection_info = ( + f"Connections: {num_active_connections} active, {num_idle_connections} idle" + ) + + return f"<{class_name} [{requests_info} | {connection_info}]>" + + +class PoolByteStream: + def __init__( + self, + stream: typing.Iterable[bytes], + pool_request: PoolRequest, + pool: ConnectionPool, + ) -> None: + self._stream = stream + self._pool_request = pool_request + self._pool = pool + self._closed = False + + def __iter__(self) -> typing.Iterator[bytes]: + try: + for part in self._stream: + yield part + except BaseException as exc: + self.close() + raise exc from None + + def close(self) -> None: + if not self._closed: + self._closed = True + with ShieldCancellation(): + if hasattr(self._stream, "close"): + self._stream.close() + + with self._pool._optional_thread_lock: + self._pool._requests.remove(self._pool_request) + closing = self._pool._assign_requests_to_connections() + + self._pool._close_connections(closing) diff --git a/.venv/lib/python3.13/site-packages/httpcore/_sync/http11.py b/.venv/lib/python3.13/site-packages/httpcore/_sync/http11.py new file mode 100644 index 0000000000000000000000000000000000000000..ebd3a97480c720d418acb1285a7b75da19b62c8c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_sync/http11.py @@ -0,0 +1,379 @@ +from __future__ import annotations + +import enum +import logging +import ssl +import time +import types +import typing + +import h11 + +from .._backends.base import NetworkStream +from .._exceptions import ( + ConnectionNotAvailable, + LocalProtocolError, + RemoteProtocolError, + WriteError, + map_exceptions, +) +from .._models import Origin, Request, Response +from .._synchronization import Lock, ShieldCancellation +from .._trace import Trace +from .interfaces import ConnectionInterface + +logger = logging.getLogger("httpcore.http11") + + +# A subset of `h11.Event` types supported by `_send_event` +H11SendEvent = typing.Union[ + h11.Request, + h11.Data, + h11.EndOfMessage, +] + + +class HTTPConnectionState(enum.IntEnum): + NEW = 0 + ACTIVE = 1 + IDLE = 2 + CLOSED = 3 + + +class HTTP11Connection(ConnectionInterface): + READ_NUM_BYTES = 64 * 1024 + MAX_INCOMPLETE_EVENT_SIZE = 100 * 1024 + + def __init__( + self, + origin: Origin, + stream: NetworkStream, + keepalive_expiry: float | None = None, + ) -> None: + self._origin = origin + self._network_stream = stream + self._keepalive_expiry: float | None = keepalive_expiry + self._expire_at: float | None = None + self._state = HTTPConnectionState.NEW + self._state_lock = Lock() + self._request_count = 0 + self._h11_state = h11.Connection( + our_role=h11.CLIENT, + max_incomplete_event_size=self.MAX_INCOMPLETE_EVENT_SIZE, + ) + + def handle_request(self, request: Request) -> Response: + if not self.can_handle_request(request.url.origin): + raise RuntimeError( + f"Attempted to send request to {request.url.origin} on connection " + f"to {self._origin}" + ) + + with self._state_lock: + if self._state in (HTTPConnectionState.NEW, HTTPConnectionState.IDLE): + self._request_count += 1 + self._state = HTTPConnectionState.ACTIVE + self._expire_at = None + else: + raise ConnectionNotAvailable() + + try: + kwargs = {"request": request} + try: + with Trace( + "send_request_headers", logger, request, kwargs + ) as trace: + self._send_request_headers(**kwargs) + with Trace("send_request_body", logger, request, kwargs) as trace: + self._send_request_body(**kwargs) + except WriteError: + # If we get a write error while we're writing the request, + # then we supress this error and move on to attempting to + # read the response. Servers can sometimes close the request + # pre-emptively and then respond with a well formed HTTP + # error response. + pass + + with Trace( + "receive_response_headers", logger, request, kwargs + ) as trace: + ( + http_version, + status, + reason_phrase, + headers, + trailing_data, + ) = self._receive_response_headers(**kwargs) + trace.return_value = ( + http_version, + status, + reason_phrase, + headers, + ) + + network_stream = self._network_stream + + # CONNECT or Upgrade request + if (status == 101) or ( + (request.method == b"CONNECT") and (200 <= status < 300) + ): + network_stream = HTTP11UpgradeStream(network_stream, trailing_data) + + return Response( + status=status, + headers=headers, + content=HTTP11ConnectionByteStream(self, request), + extensions={ + "http_version": http_version, + "reason_phrase": reason_phrase, + "network_stream": network_stream, + }, + ) + except BaseException as exc: + with ShieldCancellation(): + with Trace("response_closed", logger, request) as trace: + self._response_closed() + raise exc + + # Sending the request... + + def _send_request_headers(self, request: Request) -> None: + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("write", None) + + with map_exceptions({h11.LocalProtocolError: LocalProtocolError}): + event = h11.Request( + method=request.method, + target=request.url.target, + headers=request.headers, + ) + self._send_event(event, timeout=timeout) + + def _send_request_body(self, request: Request) -> None: + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("write", None) + + assert isinstance(request.stream, typing.Iterable) + for chunk in request.stream: + event = h11.Data(data=chunk) + self._send_event(event, timeout=timeout) + + self._send_event(h11.EndOfMessage(), timeout=timeout) + + def _send_event(self, event: h11.Event, timeout: float | None = None) -> None: + bytes_to_send = self._h11_state.send(event) + if bytes_to_send is not None: + self._network_stream.write(bytes_to_send, timeout=timeout) + + # Receiving the response... + + def _receive_response_headers( + self, request: Request + ) -> tuple[bytes, int, bytes, list[tuple[bytes, bytes]], bytes]: + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("read", None) + + while True: + event = self._receive_event(timeout=timeout) + if isinstance(event, h11.Response): + break + if ( + isinstance(event, h11.InformationalResponse) + and event.status_code == 101 + ): + break + + http_version = b"HTTP/" + event.http_version + + # h11 version 0.11+ supports a `raw_items` interface to get the + # raw header casing, rather than the enforced lowercase headers. + headers = event.headers.raw_items() + + trailing_data, _ = self._h11_state.trailing_data + + return http_version, event.status_code, event.reason, headers, trailing_data + + def _receive_response_body( + self, request: Request + ) -> typing.Iterator[bytes]: + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("read", None) + + while True: + event = self._receive_event(timeout=timeout) + if isinstance(event, h11.Data): + yield bytes(event.data) + elif isinstance(event, (h11.EndOfMessage, h11.PAUSED)): + break + + def _receive_event( + self, timeout: float | None = None + ) -> h11.Event | type[h11.PAUSED]: + while True: + with map_exceptions({h11.RemoteProtocolError: RemoteProtocolError}): + event = self._h11_state.next_event() + + if event is h11.NEED_DATA: + data = self._network_stream.read( + self.READ_NUM_BYTES, timeout=timeout + ) + + # If we feed this case through h11 we'll raise an exception like: + # + # httpcore.RemoteProtocolError: can't handle event type + # ConnectionClosed when role=SERVER and state=SEND_RESPONSE + # + # Which is accurate, but not very informative from an end-user + # perspective. Instead we handle this case distinctly and treat + # it as a ConnectError. + if data == b"" and self._h11_state.their_state == h11.SEND_RESPONSE: + msg = "Server disconnected without sending a response." + raise RemoteProtocolError(msg) + + self._h11_state.receive_data(data) + else: + # mypy fails to narrow the type in the above if statement above + return event # type: ignore[return-value] + + def _response_closed(self) -> None: + with self._state_lock: + if ( + self._h11_state.our_state is h11.DONE + and self._h11_state.their_state is h11.DONE + ): + self._state = HTTPConnectionState.IDLE + self._h11_state.start_next_cycle() + if self._keepalive_expiry is not None: + now = time.monotonic() + self._expire_at = now + self._keepalive_expiry + else: + self.close() + + # Once the connection is no longer required... + + def close(self) -> None: + # Note that this method unilaterally closes the connection, and does + # not have any kind of locking in place around it. + self._state = HTTPConnectionState.CLOSED + self._network_stream.close() + + # The ConnectionInterface methods provide information about the state of + # the connection, allowing for a connection pooling implementation to + # determine when to reuse and when to close the connection... + + def can_handle_request(self, origin: Origin) -> bool: + return origin == self._origin + + def is_available(self) -> bool: + # Note that HTTP/1.1 connections in the "NEW" state are not treated as + # being "available". The control flow which created the connection will + # be able to send an outgoing request, but the connection will not be + # acquired from the connection pool for any other request. + return self._state == HTTPConnectionState.IDLE + + def has_expired(self) -> bool: + now = time.monotonic() + keepalive_expired = self._expire_at is not None and now > self._expire_at + + # If the HTTP connection is idle but the socket is readable, then the + # only valid state is that the socket is about to return b"", indicating + # a server-initiated disconnect. + server_disconnected = ( + self._state == HTTPConnectionState.IDLE + and self._network_stream.get_extra_info("is_readable") + ) + + return keepalive_expired or server_disconnected + + def is_idle(self) -> bool: + return self._state == HTTPConnectionState.IDLE + + def is_closed(self) -> bool: + return self._state == HTTPConnectionState.CLOSED + + def info(self) -> str: + origin = str(self._origin) + return ( + f"{origin!r}, HTTP/1.1, {self._state.name}, " + f"Request Count: {self._request_count}" + ) + + def __repr__(self) -> str: + class_name = self.__class__.__name__ + origin = str(self._origin) + return ( + f"<{class_name} [{origin!r}, {self._state.name}, " + f"Request Count: {self._request_count}]>" + ) + + # These context managers are not used in the standard flow, but are + # useful for testing or working with connection instances directly. + + def __enter__(self) -> HTTP11Connection: + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + self.close() + + +class HTTP11ConnectionByteStream: + def __init__(self, connection: HTTP11Connection, request: Request) -> None: + self._connection = connection + self._request = request + self._closed = False + + def __iter__(self) -> typing.Iterator[bytes]: + kwargs = {"request": self._request} + try: + with Trace("receive_response_body", logger, self._request, kwargs): + for chunk in self._connection._receive_response_body(**kwargs): + yield chunk + except BaseException as exc: + # If we get an exception while streaming the response, + # we want to close the response (and possibly the connection) + # before raising that exception. + with ShieldCancellation(): + self.close() + raise exc + + def close(self) -> None: + if not self._closed: + self._closed = True + with Trace("response_closed", logger, self._request): + self._connection._response_closed() + + +class HTTP11UpgradeStream(NetworkStream): + def __init__(self, stream: NetworkStream, leading_data: bytes) -> None: + self._stream = stream + self._leading_data = leading_data + + def read(self, max_bytes: int, timeout: float | None = None) -> bytes: + if self._leading_data: + buffer = self._leading_data[:max_bytes] + self._leading_data = self._leading_data[max_bytes:] + return buffer + else: + return self._stream.read(max_bytes, timeout) + + def write(self, buffer: bytes, timeout: float | None = None) -> None: + self._stream.write(buffer, timeout) + + def close(self) -> None: + self._stream.close() + + def start_tls( + self, + ssl_context: ssl.SSLContext, + server_hostname: str | None = None, + timeout: float | None = None, + ) -> NetworkStream: + return self._stream.start_tls(ssl_context, server_hostname, timeout) + + def get_extra_info(self, info: str) -> typing.Any: + return self._stream.get_extra_info(info) diff --git a/.venv/lib/python3.13/site-packages/httpcore/_sync/http2.py b/.venv/lib/python3.13/site-packages/httpcore/_sync/http2.py new file mode 100644 index 0000000000000000000000000000000000000000..ddcc189001c50c37c6a03810dc21d955df919f10 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_sync/http2.py @@ -0,0 +1,592 @@ +from __future__ import annotations + +import enum +import logging +import time +import types +import typing + +import h2.config +import h2.connection +import h2.events +import h2.exceptions +import h2.settings + +from .._backends.base import NetworkStream +from .._exceptions import ( + ConnectionNotAvailable, + LocalProtocolError, + RemoteProtocolError, +) +from .._models import Origin, Request, Response +from .._synchronization import Lock, Semaphore, ShieldCancellation +from .._trace import Trace +from .interfaces import ConnectionInterface + +logger = logging.getLogger("httpcore.http2") + + +def has_body_headers(request: Request) -> bool: + return any( + k.lower() == b"content-length" or k.lower() == b"transfer-encoding" + for k, v in request.headers + ) + + +class HTTPConnectionState(enum.IntEnum): + ACTIVE = 1 + IDLE = 2 + CLOSED = 3 + + +class HTTP2Connection(ConnectionInterface): + READ_NUM_BYTES = 64 * 1024 + CONFIG = h2.config.H2Configuration(validate_inbound_headers=False) + + def __init__( + self, + origin: Origin, + stream: NetworkStream, + keepalive_expiry: float | None = None, + ): + self._origin = origin + self._network_stream = stream + self._keepalive_expiry: float | None = keepalive_expiry + self._h2_state = h2.connection.H2Connection(config=self.CONFIG) + self._state = HTTPConnectionState.IDLE + self._expire_at: float | None = None + self._request_count = 0 + self._init_lock = Lock() + self._state_lock = Lock() + self._read_lock = Lock() + self._write_lock = Lock() + self._sent_connection_init = False + self._used_all_stream_ids = False + self._connection_error = False + + # Mapping from stream ID to response stream events. + self._events: dict[ + int, + list[ + h2.events.ResponseReceived + | h2.events.DataReceived + | h2.events.StreamEnded + | h2.events.StreamReset, + ], + ] = {} + + # Connection terminated events are stored as state since + # we need to handle them for all streams. + self._connection_terminated: h2.events.ConnectionTerminated | None = None + + self._read_exception: Exception | None = None + self._write_exception: Exception | None = None + + def handle_request(self, request: Request) -> Response: + if not self.can_handle_request(request.url.origin): + # This cannot occur in normal operation, since the connection pool + # will only send requests on connections that handle them. + # It's in place simply for resilience as a guard against incorrect + # usage, for anyone working directly with httpcore connections. + raise RuntimeError( + f"Attempted to send request to {request.url.origin} on connection " + f"to {self._origin}" + ) + + with self._state_lock: + if self._state in (HTTPConnectionState.ACTIVE, HTTPConnectionState.IDLE): + self._request_count += 1 + self._expire_at = None + self._state = HTTPConnectionState.ACTIVE + else: + raise ConnectionNotAvailable() + + with self._init_lock: + if not self._sent_connection_init: + try: + sci_kwargs = {"request": request} + with Trace( + "send_connection_init", logger, request, sci_kwargs + ): + self._send_connection_init(**sci_kwargs) + except BaseException as exc: + with ShieldCancellation(): + self.close() + raise exc + + self._sent_connection_init = True + + # Initially start with just 1 until the remote server provides + # its max_concurrent_streams value + self._max_streams = 1 + + local_settings_max_streams = ( + self._h2_state.local_settings.max_concurrent_streams + ) + self._max_streams_semaphore = Semaphore(local_settings_max_streams) + + for _ in range(local_settings_max_streams - self._max_streams): + self._max_streams_semaphore.acquire() + + self._max_streams_semaphore.acquire() + + try: + stream_id = self._h2_state.get_next_available_stream_id() + self._events[stream_id] = [] + except h2.exceptions.NoAvailableStreamIDError: # pragma: nocover + self._used_all_stream_ids = True + self._request_count -= 1 + raise ConnectionNotAvailable() + + try: + kwargs = {"request": request, "stream_id": stream_id} + with Trace("send_request_headers", logger, request, kwargs): + self._send_request_headers(request=request, stream_id=stream_id) + with Trace("send_request_body", logger, request, kwargs): + self._send_request_body(request=request, stream_id=stream_id) + with Trace( + "receive_response_headers", logger, request, kwargs + ) as trace: + status, headers = self._receive_response( + request=request, stream_id=stream_id + ) + trace.return_value = (status, headers) + + return Response( + status=status, + headers=headers, + content=HTTP2ConnectionByteStream(self, request, stream_id=stream_id), + extensions={ + "http_version": b"HTTP/2", + "network_stream": self._network_stream, + "stream_id": stream_id, + }, + ) + except BaseException as exc: # noqa: PIE786 + with ShieldCancellation(): + kwargs = {"stream_id": stream_id} + with Trace("response_closed", logger, request, kwargs): + self._response_closed(stream_id=stream_id) + + if isinstance(exc, h2.exceptions.ProtocolError): + # One case where h2 can raise a protocol error is when a + # closed frame has been seen by the state machine. + # + # This happens when one stream is reading, and encounters + # a GOAWAY event. Other flows of control may then raise + # a protocol error at any point they interact with the 'h2_state'. + # + # In this case we'll have stored the event, and should raise + # it as a RemoteProtocolError. + if self._connection_terminated: # pragma: nocover + raise RemoteProtocolError(self._connection_terminated) + # If h2 raises a protocol error in some other state then we + # must somehow have made a protocol violation. + raise LocalProtocolError(exc) # pragma: nocover + + raise exc + + def _send_connection_init(self, request: Request) -> None: + """ + The HTTP/2 connection requires some initial setup before we can start + using individual request/response streams on it. + """ + # Need to set these manually here instead of manipulating via + # __setitem__() otherwise the H2Connection will emit SettingsUpdate + # frames in addition to sending the undesired defaults. + self._h2_state.local_settings = h2.settings.Settings( + client=True, + initial_values={ + # Disable PUSH_PROMISE frames from the server since we don't do anything + # with them for now. Maybe when we support caching? + h2.settings.SettingCodes.ENABLE_PUSH: 0, + # These two are taken from h2 for safe defaults + h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS: 100, + h2.settings.SettingCodes.MAX_HEADER_LIST_SIZE: 65536, + }, + ) + + # Some websites (*cough* Yahoo *cough*) balk at this setting being + # present in the initial handshake since it's not defined in the original + # RFC despite the RFC mandating ignoring settings you don't know about. + del self._h2_state.local_settings[ + h2.settings.SettingCodes.ENABLE_CONNECT_PROTOCOL + ] + + self._h2_state.initiate_connection() + self._h2_state.increment_flow_control_window(2**24) + self._write_outgoing_data(request) + + # Sending the request... + + def _send_request_headers(self, request: Request, stream_id: int) -> None: + """ + Send the request headers to a given stream ID. + """ + end_stream = not has_body_headers(request) + + # In HTTP/2 the ':authority' pseudo-header is used instead of 'Host'. + # In order to gracefully handle HTTP/1.1 and HTTP/2 we always require + # HTTP/1.1 style headers, and map them appropriately if we end up on + # an HTTP/2 connection. + authority = [v for k, v in request.headers if k.lower() == b"host"][0] + + headers = [ + (b":method", request.method), + (b":authority", authority), + (b":scheme", request.url.scheme), + (b":path", request.url.target), + ] + [ + (k.lower(), v) + for k, v in request.headers + if k.lower() + not in ( + b"host", + b"transfer-encoding", + ) + ] + + self._h2_state.send_headers(stream_id, headers, end_stream=end_stream) + self._h2_state.increment_flow_control_window(2**24, stream_id=stream_id) + self._write_outgoing_data(request) + + def _send_request_body(self, request: Request, stream_id: int) -> None: + """ + Iterate over the request body sending it to a given stream ID. + """ + if not has_body_headers(request): + return + + assert isinstance(request.stream, typing.Iterable) + for data in request.stream: + self._send_stream_data(request, stream_id, data) + self._send_end_stream(request, stream_id) + + def _send_stream_data( + self, request: Request, stream_id: int, data: bytes + ) -> None: + """ + Send a single chunk of data in one or more data frames. + """ + while data: + max_flow = self._wait_for_outgoing_flow(request, stream_id) + chunk_size = min(len(data), max_flow) + chunk, data = data[:chunk_size], data[chunk_size:] + self._h2_state.send_data(stream_id, chunk) + self._write_outgoing_data(request) + + def _send_end_stream(self, request: Request, stream_id: int) -> None: + """ + Send an empty data frame on on a given stream ID with the END_STREAM flag set. + """ + self._h2_state.end_stream(stream_id) + self._write_outgoing_data(request) + + # Receiving the response... + + def _receive_response( + self, request: Request, stream_id: int + ) -> tuple[int, list[tuple[bytes, bytes]]]: + """ + Return the response status code and headers for a given stream ID. + """ + while True: + event = self._receive_stream_event(request, stream_id) + if isinstance(event, h2.events.ResponseReceived): + break + + status_code = 200 + headers = [] + assert event.headers is not None + for k, v in event.headers: + if k == b":status": + status_code = int(v.decode("ascii", errors="ignore")) + elif not k.startswith(b":"): + headers.append((k, v)) + + return (status_code, headers) + + def _receive_response_body( + self, request: Request, stream_id: int + ) -> typing.Iterator[bytes]: + """ + Iterator that returns the bytes of the response body for a given stream ID. + """ + while True: + event = self._receive_stream_event(request, stream_id) + if isinstance(event, h2.events.DataReceived): + assert event.flow_controlled_length is not None + assert event.data is not None + amount = event.flow_controlled_length + self._h2_state.acknowledge_received_data(amount, stream_id) + self._write_outgoing_data(request) + yield event.data + elif isinstance(event, h2.events.StreamEnded): + break + + def _receive_stream_event( + self, request: Request, stream_id: int + ) -> h2.events.ResponseReceived | h2.events.DataReceived | h2.events.StreamEnded: + """ + Return the next available event for a given stream ID. + + Will read more data from the network if required. + """ + while not self._events.get(stream_id): + self._receive_events(request, stream_id) + event = self._events[stream_id].pop(0) + if isinstance(event, h2.events.StreamReset): + raise RemoteProtocolError(event) + return event + + def _receive_events( + self, request: Request, stream_id: int | None = None + ) -> None: + """ + Read some data from the network until we see one or more events + for a given stream ID. + """ + with self._read_lock: + if self._connection_terminated is not None: + last_stream_id = self._connection_terminated.last_stream_id + if stream_id and last_stream_id and stream_id > last_stream_id: + self._request_count -= 1 + raise ConnectionNotAvailable() + raise RemoteProtocolError(self._connection_terminated) + + # This conditional is a bit icky. We don't want to block reading if we've + # actually got an event to return for a given stream. We need to do that + # check *within* the atomic read lock. Though it also need to be optional, + # because when we call it from `_wait_for_outgoing_flow` we *do* want to + # block until we've available flow control, event when we have events + # pending for the stream ID we're attempting to send on. + if stream_id is None or not self._events.get(stream_id): + events = self._read_incoming_data(request) + for event in events: + if isinstance(event, h2.events.RemoteSettingsChanged): + with Trace( + "receive_remote_settings", logger, request + ) as trace: + self._receive_remote_settings_change(event) + trace.return_value = event + + elif isinstance( + event, + ( + h2.events.ResponseReceived, + h2.events.DataReceived, + h2.events.StreamEnded, + h2.events.StreamReset, + ), + ): + if event.stream_id in self._events: + self._events[event.stream_id].append(event) + + elif isinstance(event, h2.events.ConnectionTerminated): + self._connection_terminated = event + + self._write_outgoing_data(request) + + def _receive_remote_settings_change( + self, event: h2.events.RemoteSettingsChanged + ) -> None: + max_concurrent_streams = event.changed_settings.get( + h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS + ) + if max_concurrent_streams: + new_max_streams = min( + max_concurrent_streams.new_value, + self._h2_state.local_settings.max_concurrent_streams, + ) + if new_max_streams and new_max_streams != self._max_streams: + while new_max_streams > self._max_streams: + self._max_streams_semaphore.release() + self._max_streams += 1 + while new_max_streams < self._max_streams: + self._max_streams_semaphore.acquire() + self._max_streams -= 1 + + def _response_closed(self, stream_id: int) -> None: + self._max_streams_semaphore.release() + del self._events[stream_id] + with self._state_lock: + if self._connection_terminated and not self._events: + self.close() + + elif self._state == HTTPConnectionState.ACTIVE and not self._events: + self._state = HTTPConnectionState.IDLE + if self._keepalive_expiry is not None: + now = time.monotonic() + self._expire_at = now + self._keepalive_expiry + if self._used_all_stream_ids: # pragma: nocover + self.close() + + def close(self) -> None: + # Note that this method unilaterally closes the connection, and does + # not have any kind of locking in place around it. + self._h2_state.close_connection() + self._state = HTTPConnectionState.CLOSED + self._network_stream.close() + + # Wrappers around network read/write operations... + + def _read_incoming_data(self, request: Request) -> list[h2.events.Event]: + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("read", None) + + if self._read_exception is not None: + raise self._read_exception # pragma: nocover + + try: + data = self._network_stream.read(self.READ_NUM_BYTES, timeout) + if data == b"": + raise RemoteProtocolError("Server disconnected") + except Exception as exc: + # If we get a network error we should: + # + # 1. Save the exception and just raise it immediately on any future reads. + # (For example, this means that a single read timeout or disconnect will + # immediately close all pending streams. Without requiring multiple + # sequential timeouts.) + # 2. Mark the connection as errored, so that we don't accept any other + # incoming requests. + self._read_exception = exc + self._connection_error = True + raise exc + + events: list[h2.events.Event] = self._h2_state.receive_data(data) + + return events + + def _write_outgoing_data(self, request: Request) -> None: + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("write", None) + + with self._write_lock: + data_to_send = self._h2_state.data_to_send() + + if self._write_exception is not None: + raise self._write_exception # pragma: nocover + + try: + self._network_stream.write(data_to_send, timeout) + except Exception as exc: # pragma: nocover + # If we get a network error we should: + # + # 1. Save the exception and just raise it immediately on any future write. + # (For example, this means that a single write timeout or disconnect will + # immediately close all pending streams. Without requiring multiple + # sequential timeouts.) + # 2. Mark the connection as errored, so that we don't accept any other + # incoming requests. + self._write_exception = exc + self._connection_error = True + raise exc + + # Flow control... + + def _wait_for_outgoing_flow(self, request: Request, stream_id: int) -> int: + """ + Returns the maximum allowable outgoing flow for a given stream. + + If the allowable flow is zero, then waits on the network until + WindowUpdated frames have increased the flow rate. + https://tools.ietf.org/html/rfc7540#section-6.9 + """ + local_flow: int = self._h2_state.local_flow_control_window(stream_id) + max_frame_size: int = self._h2_state.max_outbound_frame_size + flow = min(local_flow, max_frame_size) + while flow == 0: + self._receive_events(request) + local_flow = self._h2_state.local_flow_control_window(stream_id) + max_frame_size = self._h2_state.max_outbound_frame_size + flow = min(local_flow, max_frame_size) + return flow + + # Interface for connection pooling... + + def can_handle_request(self, origin: Origin) -> bool: + return origin == self._origin + + def is_available(self) -> bool: + return ( + self._state != HTTPConnectionState.CLOSED + and not self._connection_error + and not self._used_all_stream_ids + and not ( + self._h2_state.state_machine.state + == h2.connection.ConnectionState.CLOSED + ) + ) + + def has_expired(self) -> bool: + now = time.monotonic() + return self._expire_at is not None and now > self._expire_at + + def is_idle(self) -> bool: + return self._state == HTTPConnectionState.IDLE + + def is_closed(self) -> bool: + return self._state == HTTPConnectionState.CLOSED + + def info(self) -> str: + origin = str(self._origin) + return ( + f"{origin!r}, HTTP/2, {self._state.name}, " + f"Request Count: {self._request_count}" + ) + + def __repr__(self) -> str: + class_name = self.__class__.__name__ + origin = str(self._origin) + return ( + f"<{class_name} [{origin!r}, {self._state.name}, " + f"Request Count: {self._request_count}]>" + ) + + # These context managers are not used in the standard flow, but are + # useful for testing or working with connection instances directly. + + def __enter__(self) -> HTTP2Connection: + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + self.close() + + +class HTTP2ConnectionByteStream: + def __init__( + self, connection: HTTP2Connection, request: Request, stream_id: int + ) -> None: + self._connection = connection + self._request = request + self._stream_id = stream_id + self._closed = False + + def __iter__(self) -> typing.Iterator[bytes]: + kwargs = {"request": self._request, "stream_id": self._stream_id} + try: + with Trace("receive_response_body", logger, self._request, kwargs): + for chunk in self._connection._receive_response_body( + request=self._request, stream_id=self._stream_id + ): + yield chunk + except BaseException as exc: + # If we get an exception while streaming the response, + # we want to close the response (and possibly the connection) + # before raising that exception. + with ShieldCancellation(): + self.close() + raise exc + + def close(self) -> None: + if not self._closed: + self._closed = True + kwargs = {"stream_id": self._stream_id} + with Trace("response_closed", logger, self._request, kwargs): + self._connection._response_closed(stream_id=self._stream_id) diff --git a/.venv/lib/python3.13/site-packages/httpcore/_sync/http_proxy.py b/.venv/lib/python3.13/site-packages/httpcore/_sync/http_proxy.py new file mode 100644 index 0000000000000000000000000000000000000000..ecca88f7dc93b78f2aa26f16cf29d17a8a83ae27 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_sync/http_proxy.py @@ -0,0 +1,367 @@ +from __future__ import annotations + +import base64 +import logging +import ssl +import typing + +from .._backends.base import SOCKET_OPTION, NetworkBackend +from .._exceptions import ProxyError +from .._models import ( + URL, + Origin, + Request, + Response, + enforce_bytes, + enforce_headers, + enforce_url, +) +from .._ssl import default_ssl_context +from .._synchronization import Lock +from .._trace import Trace +from .connection import HTTPConnection +from .connection_pool import ConnectionPool +from .http11 import HTTP11Connection +from .interfaces import ConnectionInterface + +ByteOrStr = typing.Union[bytes, str] +HeadersAsSequence = typing.Sequence[typing.Tuple[ByteOrStr, ByteOrStr]] +HeadersAsMapping = typing.Mapping[ByteOrStr, ByteOrStr] + + +logger = logging.getLogger("httpcore.proxy") + + +def merge_headers( + default_headers: typing.Sequence[tuple[bytes, bytes]] | None = None, + override_headers: typing.Sequence[tuple[bytes, bytes]] | None = None, +) -> list[tuple[bytes, bytes]]: + """ + Append default_headers and override_headers, de-duplicating if a key exists + in both cases. + """ + default_headers = [] if default_headers is None else list(default_headers) + override_headers = [] if override_headers is None else list(override_headers) + has_override = set(key.lower() for key, value in override_headers) + default_headers = [ + (key, value) + for key, value in default_headers + if key.lower() not in has_override + ] + return default_headers + override_headers + + +class HTTPProxy(ConnectionPool): # pragma: nocover + """ + A connection pool that sends requests via an HTTP proxy. + """ + + def __init__( + self, + proxy_url: URL | bytes | str, + proxy_auth: tuple[bytes | str, bytes | str] | None = None, + proxy_headers: HeadersAsMapping | HeadersAsSequence | None = None, + ssl_context: ssl.SSLContext | None = None, + proxy_ssl_context: ssl.SSLContext | None = None, + max_connections: int | None = 10, + max_keepalive_connections: int | None = None, + keepalive_expiry: float | None = None, + http1: bool = True, + http2: bool = False, + retries: int = 0, + local_address: str | None = None, + uds: str | None = None, + network_backend: NetworkBackend | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> None: + """ + A connection pool for making HTTP requests. + + Parameters: + proxy_url: The URL to use when connecting to the proxy server. + For example `"http://127.0.0.1:8080/"`. + proxy_auth: Any proxy authentication as a two-tuple of + (username, password). May be either bytes or ascii-only str. + proxy_headers: Any HTTP headers to use for the proxy requests. + For example `{"Proxy-Authorization": "Basic :"}`. + ssl_context: An SSL context to use for verifying connections. + If not specified, the default `httpcore.default_ssl_context()` + will be used. + proxy_ssl_context: The same as `ssl_context`, but for a proxy server rather than a remote origin. + max_connections: The maximum number of concurrent HTTP connections that + the pool should allow. Any attempt to send a request on a pool that + would exceed this amount will block until a connection is available. + max_keepalive_connections: The maximum number of idle HTTP connections + that will be maintained in the pool. + keepalive_expiry: The duration in seconds that an idle HTTP connection + may be maintained for before being expired from the pool. + http1: A boolean indicating if HTTP/1.1 requests should be supported + by the connection pool. Defaults to True. + http2: A boolean indicating if HTTP/2 requests should be supported by + the connection pool. Defaults to False. + retries: The maximum number of retries when trying to establish + a connection. + local_address: Local address to connect from. Can also be used to + connect using a particular address family. Using + `local_address="0.0.0.0"` will connect using an `AF_INET` address + (IPv4), while using `local_address="::"` will connect using an + `AF_INET6` address (IPv6). + uds: Path to a Unix Domain Socket to use instead of TCP sockets. + network_backend: A backend instance to use for handling network I/O. + """ + super().__init__( + ssl_context=ssl_context, + max_connections=max_connections, + max_keepalive_connections=max_keepalive_connections, + keepalive_expiry=keepalive_expiry, + http1=http1, + http2=http2, + network_backend=network_backend, + retries=retries, + local_address=local_address, + uds=uds, + socket_options=socket_options, + ) + + self._proxy_url = enforce_url(proxy_url, name="proxy_url") + if ( + self._proxy_url.scheme == b"http" and proxy_ssl_context is not None + ): # pragma: no cover + raise RuntimeError( + "The `proxy_ssl_context` argument is not allowed for the http scheme" + ) + + self._ssl_context = ssl_context + self._proxy_ssl_context = proxy_ssl_context + self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") + if proxy_auth is not None: + username = enforce_bytes(proxy_auth[0], name="proxy_auth") + password = enforce_bytes(proxy_auth[1], name="proxy_auth") + userpass = username + b":" + password + authorization = b"Basic " + base64.b64encode(userpass) + self._proxy_headers = [ + (b"Proxy-Authorization", authorization) + ] + self._proxy_headers + + def create_connection(self, origin: Origin) -> ConnectionInterface: + if origin.scheme == b"http": + return ForwardHTTPConnection( + proxy_origin=self._proxy_url.origin, + proxy_headers=self._proxy_headers, + remote_origin=origin, + keepalive_expiry=self._keepalive_expiry, + network_backend=self._network_backend, + proxy_ssl_context=self._proxy_ssl_context, + ) + return TunnelHTTPConnection( + proxy_origin=self._proxy_url.origin, + proxy_headers=self._proxy_headers, + remote_origin=origin, + ssl_context=self._ssl_context, + proxy_ssl_context=self._proxy_ssl_context, + keepalive_expiry=self._keepalive_expiry, + http1=self._http1, + http2=self._http2, + network_backend=self._network_backend, + ) + + +class ForwardHTTPConnection(ConnectionInterface): + def __init__( + self, + proxy_origin: Origin, + remote_origin: Origin, + proxy_headers: HeadersAsMapping | HeadersAsSequence | None = None, + keepalive_expiry: float | None = None, + network_backend: NetworkBackend | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + proxy_ssl_context: ssl.SSLContext | None = None, + ) -> None: + self._connection = HTTPConnection( + origin=proxy_origin, + keepalive_expiry=keepalive_expiry, + network_backend=network_backend, + socket_options=socket_options, + ssl_context=proxy_ssl_context, + ) + self._proxy_origin = proxy_origin + self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") + self._remote_origin = remote_origin + + def handle_request(self, request: Request) -> Response: + headers = merge_headers(self._proxy_headers, request.headers) + url = URL( + scheme=self._proxy_origin.scheme, + host=self._proxy_origin.host, + port=self._proxy_origin.port, + target=bytes(request.url), + ) + proxy_request = Request( + method=request.method, + url=url, + headers=headers, + content=request.stream, + extensions=request.extensions, + ) + return self._connection.handle_request(proxy_request) + + def can_handle_request(self, origin: Origin) -> bool: + return origin == self._remote_origin + + def close(self) -> None: + self._connection.close() + + def info(self) -> str: + return self._connection.info() + + def is_available(self) -> bool: + return self._connection.is_available() + + def has_expired(self) -> bool: + return self._connection.has_expired() + + def is_idle(self) -> bool: + return self._connection.is_idle() + + def is_closed(self) -> bool: + return self._connection.is_closed() + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} [{self.info()}]>" + + +class TunnelHTTPConnection(ConnectionInterface): + def __init__( + self, + proxy_origin: Origin, + remote_origin: Origin, + ssl_context: ssl.SSLContext | None = None, + proxy_ssl_context: ssl.SSLContext | None = None, + proxy_headers: typing.Sequence[tuple[bytes, bytes]] | None = None, + keepalive_expiry: float | None = None, + http1: bool = True, + http2: bool = False, + network_backend: NetworkBackend | None = None, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> None: + self._connection: ConnectionInterface = HTTPConnection( + origin=proxy_origin, + keepalive_expiry=keepalive_expiry, + network_backend=network_backend, + socket_options=socket_options, + ssl_context=proxy_ssl_context, + ) + self._proxy_origin = proxy_origin + self._remote_origin = remote_origin + self._ssl_context = ssl_context + self._proxy_ssl_context = proxy_ssl_context + self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") + self._keepalive_expiry = keepalive_expiry + self._http1 = http1 + self._http2 = http2 + self._connect_lock = Lock() + self._connected = False + + def handle_request(self, request: Request) -> Response: + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("connect", None) + + with self._connect_lock: + if not self._connected: + target = b"%b:%d" % (self._remote_origin.host, self._remote_origin.port) + + connect_url = URL( + scheme=self._proxy_origin.scheme, + host=self._proxy_origin.host, + port=self._proxy_origin.port, + target=target, + ) + connect_headers = merge_headers( + [(b"Host", target), (b"Accept", b"*/*")], self._proxy_headers + ) + connect_request = Request( + method=b"CONNECT", + url=connect_url, + headers=connect_headers, + extensions=request.extensions, + ) + connect_response = self._connection.handle_request( + connect_request + ) + + if connect_response.status < 200 or connect_response.status > 299: + reason_bytes = connect_response.extensions.get("reason_phrase", b"") + reason_str = reason_bytes.decode("ascii", errors="ignore") + msg = "%d %s" % (connect_response.status, reason_str) + self._connection.close() + raise ProxyError(msg) + + stream = connect_response.extensions["network_stream"] + + # Upgrade the stream to SSL + ssl_context = ( + default_ssl_context() + if self._ssl_context is None + else self._ssl_context + ) + alpn_protocols = ["http/1.1", "h2"] if self._http2 else ["http/1.1"] + ssl_context.set_alpn_protocols(alpn_protocols) + + kwargs = { + "ssl_context": ssl_context, + "server_hostname": self._remote_origin.host.decode("ascii"), + "timeout": timeout, + } + with Trace("start_tls", logger, request, kwargs) as trace: + stream = stream.start_tls(**kwargs) + trace.return_value = stream + + # Determine if we should be using HTTP/1.1 or HTTP/2 + ssl_object = stream.get_extra_info("ssl_object") + http2_negotiated = ( + ssl_object is not None + and ssl_object.selected_alpn_protocol() == "h2" + ) + + # Create the HTTP/1.1 or HTTP/2 connection + if http2_negotiated or (self._http2 and not self._http1): + from .http2 import HTTP2Connection + + self._connection = HTTP2Connection( + origin=self._remote_origin, + stream=stream, + keepalive_expiry=self._keepalive_expiry, + ) + else: + self._connection = HTTP11Connection( + origin=self._remote_origin, + stream=stream, + keepalive_expiry=self._keepalive_expiry, + ) + + self._connected = True + return self._connection.handle_request(request) + + def can_handle_request(self, origin: Origin) -> bool: + return origin == self._remote_origin + + def close(self) -> None: + self._connection.close() + + def info(self) -> str: + return self._connection.info() + + def is_available(self) -> bool: + return self._connection.is_available() + + def has_expired(self) -> bool: + return self._connection.has_expired() + + def is_idle(self) -> bool: + return self._connection.is_idle() + + def is_closed(self) -> bool: + return self._connection.is_closed() + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} [{self.info()}]>" diff --git a/.venv/lib/python3.13/site-packages/httpcore/_sync/interfaces.py b/.venv/lib/python3.13/site-packages/httpcore/_sync/interfaces.py new file mode 100644 index 0000000000000000000000000000000000000000..e673d4cc1b1dd7e7ecdbde91fd6ada386c3de03f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_sync/interfaces.py @@ -0,0 +1,137 @@ +from __future__ import annotations + +import contextlib +import typing + +from .._models import ( + URL, + Extensions, + HeaderTypes, + Origin, + Request, + Response, + enforce_bytes, + enforce_headers, + enforce_url, + include_request_headers, +) + + +class RequestInterface: + def request( + self, + method: bytes | str, + url: URL | bytes | str, + *, + headers: HeaderTypes = None, + content: bytes | typing.Iterator[bytes] | None = None, + extensions: Extensions | None = None, + ) -> Response: + # Strict type checking on our parameters. + method = enforce_bytes(method, name="method") + url = enforce_url(url, name="url") + headers = enforce_headers(headers, name="headers") + + # Include Host header, and optionally Content-Length or Transfer-Encoding. + headers = include_request_headers(headers, url=url, content=content) + + request = Request( + method=method, + url=url, + headers=headers, + content=content, + extensions=extensions, + ) + response = self.handle_request(request) + try: + response.read() + finally: + response.close() + return response + + @contextlib.contextmanager + def stream( + self, + method: bytes | str, + url: URL | bytes | str, + *, + headers: HeaderTypes = None, + content: bytes | typing.Iterator[bytes] | None = None, + extensions: Extensions | None = None, + ) -> typing.Iterator[Response]: + # Strict type checking on our parameters. + method = enforce_bytes(method, name="method") + url = enforce_url(url, name="url") + headers = enforce_headers(headers, name="headers") + + # Include Host header, and optionally Content-Length or Transfer-Encoding. + headers = include_request_headers(headers, url=url, content=content) + + request = Request( + method=method, + url=url, + headers=headers, + content=content, + extensions=extensions, + ) + response = self.handle_request(request) + try: + yield response + finally: + response.close() + + def handle_request(self, request: Request) -> Response: + raise NotImplementedError() # pragma: nocover + + +class ConnectionInterface(RequestInterface): + def close(self) -> None: + raise NotImplementedError() # pragma: nocover + + def info(self) -> str: + raise NotImplementedError() # pragma: nocover + + def can_handle_request(self, origin: Origin) -> bool: + raise NotImplementedError() # pragma: nocover + + def is_available(self) -> bool: + """ + Return `True` if the connection is currently able to accept an + outgoing request. + + An HTTP/1.1 connection will only be available if it is currently idle. + + An HTTP/2 connection will be available so long as the stream ID space is + not yet exhausted, and the connection is not in an error state. + + While the connection is being established we may not yet know if it is going + to result in an HTTP/1.1 or HTTP/2 connection. The connection should be + treated as being available, but might ultimately raise `NewConnectionRequired` + required exceptions if multiple requests are attempted over a connection + that ends up being established as HTTP/1.1. + """ + raise NotImplementedError() # pragma: nocover + + def has_expired(self) -> bool: + """ + Return `True` if the connection is in a state where it should be closed. + + This either means that the connection is idle and it has passed the + expiry time on its keep-alive, or that server has sent an EOF. + """ + raise NotImplementedError() # pragma: nocover + + def is_idle(self) -> bool: + """ + Return `True` if the connection is currently idle. + """ + raise NotImplementedError() # pragma: nocover + + def is_closed(self) -> bool: + """ + Return `True` if the connection has been closed. + + Used when a response is closed to determine if the connection may be + returned to the connection pool or not. + """ + raise NotImplementedError() # pragma: nocover diff --git a/.venv/lib/python3.13/site-packages/httpcore/_sync/socks_proxy.py b/.venv/lib/python3.13/site-packages/httpcore/_sync/socks_proxy.py new file mode 100644 index 0000000000000000000000000000000000000000..0ca96ddfb580b19413797f41e79f7abcecdd9d79 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_sync/socks_proxy.py @@ -0,0 +1,341 @@ +from __future__ import annotations + +import logging +import ssl + +import socksio + +from .._backends.sync import SyncBackend +from .._backends.base import NetworkBackend, NetworkStream +from .._exceptions import ConnectionNotAvailable, ProxyError +from .._models import URL, Origin, Request, Response, enforce_bytes, enforce_url +from .._ssl import default_ssl_context +from .._synchronization import Lock +from .._trace import Trace +from .connection_pool import ConnectionPool +from .http11 import HTTP11Connection +from .interfaces import ConnectionInterface + +logger = logging.getLogger("httpcore.socks") + + +AUTH_METHODS = { + b"\x00": "NO AUTHENTICATION REQUIRED", + b"\x01": "GSSAPI", + b"\x02": "USERNAME/PASSWORD", + b"\xff": "NO ACCEPTABLE METHODS", +} + +REPLY_CODES = { + b"\x00": "Succeeded", + b"\x01": "General SOCKS server failure", + b"\x02": "Connection not allowed by ruleset", + b"\x03": "Network unreachable", + b"\x04": "Host unreachable", + b"\x05": "Connection refused", + b"\x06": "TTL expired", + b"\x07": "Command not supported", + b"\x08": "Address type not supported", +} + + +def _init_socks5_connection( + stream: NetworkStream, + *, + host: bytes, + port: int, + auth: tuple[bytes, bytes] | None = None, +) -> None: + conn = socksio.socks5.SOCKS5Connection() + + # Auth method request + auth_method = ( + socksio.socks5.SOCKS5AuthMethod.NO_AUTH_REQUIRED + if auth is None + else socksio.socks5.SOCKS5AuthMethod.USERNAME_PASSWORD + ) + conn.send(socksio.socks5.SOCKS5AuthMethodsRequest([auth_method])) + outgoing_bytes = conn.data_to_send() + stream.write(outgoing_bytes) + + # Auth method response + incoming_bytes = stream.read(max_bytes=4096) + response = conn.receive_data(incoming_bytes) + assert isinstance(response, socksio.socks5.SOCKS5AuthReply) + if response.method != auth_method: + requested = AUTH_METHODS.get(auth_method, "UNKNOWN") + responded = AUTH_METHODS.get(response.method, "UNKNOWN") + raise ProxyError( + f"Requested {requested} from proxy server, but got {responded}." + ) + + if response.method == socksio.socks5.SOCKS5AuthMethod.USERNAME_PASSWORD: + # Username/password request + assert auth is not None + username, password = auth + conn.send(socksio.socks5.SOCKS5UsernamePasswordRequest(username, password)) + outgoing_bytes = conn.data_to_send() + stream.write(outgoing_bytes) + + # Username/password response + incoming_bytes = stream.read(max_bytes=4096) + response = conn.receive_data(incoming_bytes) + assert isinstance(response, socksio.socks5.SOCKS5UsernamePasswordReply) + if not response.success: + raise ProxyError("Invalid username/password") + + # Connect request + conn.send( + socksio.socks5.SOCKS5CommandRequest.from_address( + socksio.socks5.SOCKS5Command.CONNECT, (host, port) + ) + ) + outgoing_bytes = conn.data_to_send() + stream.write(outgoing_bytes) + + # Connect response + incoming_bytes = stream.read(max_bytes=4096) + response = conn.receive_data(incoming_bytes) + assert isinstance(response, socksio.socks5.SOCKS5Reply) + if response.reply_code != socksio.socks5.SOCKS5ReplyCode.SUCCEEDED: + reply_code = REPLY_CODES.get(response.reply_code, "UNKOWN") + raise ProxyError(f"Proxy Server could not connect: {reply_code}.") + + +class SOCKSProxy(ConnectionPool): # pragma: nocover + """ + A connection pool that sends requests via an HTTP proxy. + """ + + def __init__( + self, + proxy_url: URL | bytes | str, + proxy_auth: tuple[bytes | str, bytes | str] | None = None, + ssl_context: ssl.SSLContext | None = None, + max_connections: int | None = 10, + max_keepalive_connections: int | None = None, + keepalive_expiry: float | None = None, + http1: bool = True, + http2: bool = False, + retries: int = 0, + network_backend: NetworkBackend | None = None, + ) -> None: + """ + A connection pool for making HTTP requests. + + Parameters: + proxy_url: The URL to use when connecting to the proxy server. + For example `"http://127.0.0.1:8080/"`. + ssl_context: An SSL context to use for verifying connections. + If not specified, the default `httpcore.default_ssl_context()` + will be used. + max_connections: The maximum number of concurrent HTTP connections that + the pool should allow. Any attempt to send a request on a pool that + would exceed this amount will block until a connection is available. + max_keepalive_connections: The maximum number of idle HTTP connections + that will be maintained in the pool. + keepalive_expiry: The duration in seconds that an idle HTTP connection + may be maintained for before being expired from the pool. + http1: A boolean indicating if HTTP/1.1 requests should be supported + by the connection pool. Defaults to True. + http2: A boolean indicating if HTTP/2 requests should be supported by + the connection pool. Defaults to False. + retries: The maximum number of retries when trying to establish + a connection. + local_address: Local address to connect from. Can also be used to + connect using a particular address family. Using + `local_address="0.0.0.0"` will connect using an `AF_INET` address + (IPv4), while using `local_address="::"` will connect using an + `AF_INET6` address (IPv6). + uds: Path to a Unix Domain Socket to use instead of TCP sockets. + network_backend: A backend instance to use for handling network I/O. + """ + super().__init__( + ssl_context=ssl_context, + max_connections=max_connections, + max_keepalive_connections=max_keepalive_connections, + keepalive_expiry=keepalive_expiry, + http1=http1, + http2=http2, + network_backend=network_backend, + retries=retries, + ) + self._ssl_context = ssl_context + self._proxy_url = enforce_url(proxy_url, name="proxy_url") + if proxy_auth is not None: + username, password = proxy_auth + username_bytes = enforce_bytes(username, name="proxy_auth") + password_bytes = enforce_bytes(password, name="proxy_auth") + self._proxy_auth: tuple[bytes, bytes] | None = ( + username_bytes, + password_bytes, + ) + else: + self._proxy_auth = None + + def create_connection(self, origin: Origin) -> ConnectionInterface: + return Socks5Connection( + proxy_origin=self._proxy_url.origin, + remote_origin=origin, + proxy_auth=self._proxy_auth, + ssl_context=self._ssl_context, + keepalive_expiry=self._keepalive_expiry, + http1=self._http1, + http2=self._http2, + network_backend=self._network_backend, + ) + + +class Socks5Connection(ConnectionInterface): + def __init__( + self, + proxy_origin: Origin, + remote_origin: Origin, + proxy_auth: tuple[bytes, bytes] | None = None, + ssl_context: ssl.SSLContext | None = None, + keepalive_expiry: float | None = None, + http1: bool = True, + http2: bool = False, + network_backend: NetworkBackend | None = None, + ) -> None: + self._proxy_origin = proxy_origin + self._remote_origin = remote_origin + self._proxy_auth = proxy_auth + self._ssl_context = ssl_context + self._keepalive_expiry = keepalive_expiry + self._http1 = http1 + self._http2 = http2 + + self._network_backend: NetworkBackend = ( + SyncBackend() if network_backend is None else network_backend + ) + self._connect_lock = Lock() + self._connection: ConnectionInterface | None = None + self._connect_failed = False + + def handle_request(self, request: Request) -> Response: + timeouts = request.extensions.get("timeout", {}) + sni_hostname = request.extensions.get("sni_hostname", None) + timeout = timeouts.get("connect", None) + + with self._connect_lock: + if self._connection is None: + try: + # Connect to the proxy + kwargs = { + "host": self._proxy_origin.host.decode("ascii"), + "port": self._proxy_origin.port, + "timeout": timeout, + } + with Trace("connect_tcp", logger, request, kwargs) as trace: + stream = self._network_backend.connect_tcp(**kwargs) + trace.return_value = stream + + # Connect to the remote host using socks5 + kwargs = { + "stream": stream, + "host": self._remote_origin.host.decode("ascii"), + "port": self._remote_origin.port, + "auth": self._proxy_auth, + } + with Trace( + "setup_socks5_connection", logger, request, kwargs + ) as trace: + _init_socks5_connection(**kwargs) + trace.return_value = stream + + # Upgrade the stream to SSL + if self._remote_origin.scheme == b"https": + ssl_context = ( + default_ssl_context() + if self._ssl_context is None + else self._ssl_context + ) + alpn_protocols = ( + ["http/1.1", "h2"] if self._http2 else ["http/1.1"] + ) + ssl_context.set_alpn_protocols(alpn_protocols) + + kwargs = { + "ssl_context": ssl_context, + "server_hostname": sni_hostname + or self._remote_origin.host.decode("ascii"), + "timeout": timeout, + } + with Trace("start_tls", logger, request, kwargs) as trace: + stream = stream.start_tls(**kwargs) + trace.return_value = stream + + # Determine if we should be using HTTP/1.1 or HTTP/2 + ssl_object = stream.get_extra_info("ssl_object") + http2_negotiated = ( + ssl_object is not None + and ssl_object.selected_alpn_protocol() == "h2" + ) + + # Create the HTTP/1.1 or HTTP/2 connection + if http2_negotiated or ( + self._http2 and not self._http1 + ): # pragma: nocover + from .http2 import HTTP2Connection + + self._connection = HTTP2Connection( + origin=self._remote_origin, + stream=stream, + keepalive_expiry=self._keepalive_expiry, + ) + else: + self._connection = HTTP11Connection( + origin=self._remote_origin, + stream=stream, + keepalive_expiry=self._keepalive_expiry, + ) + except Exception as exc: + self._connect_failed = True + raise exc + elif not self._connection.is_available(): # pragma: nocover + raise ConnectionNotAvailable() + + return self._connection.handle_request(request) + + def can_handle_request(self, origin: Origin) -> bool: + return origin == self._remote_origin + + def close(self) -> None: + if self._connection is not None: + self._connection.close() + + def is_available(self) -> bool: + if self._connection is None: # pragma: nocover + # If HTTP/2 support is enabled, and the resulting connection could + # end up as HTTP/2 then we should indicate the connection as being + # available to service multiple requests. + return ( + self._http2 + and (self._remote_origin.scheme == b"https" or not self._http1) + and not self._connect_failed + ) + return self._connection.is_available() + + def has_expired(self) -> bool: + if self._connection is None: # pragma: nocover + return self._connect_failed + return self._connection.has_expired() + + def is_idle(self) -> bool: + if self._connection is None: # pragma: nocover + return self._connect_failed + return self._connection.is_idle() + + def is_closed(self) -> bool: + if self._connection is None: # pragma: nocover + return self._connect_failed + return self._connection.is_closed() + + def info(self) -> str: + if self._connection is None: # pragma: nocover + return "CONNECTION FAILED" if self._connect_failed else "CONNECTING" + return self._connection.info() + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} [{self.info()}]>" diff --git a/.venv/lib/python3.13/site-packages/httpcore/_synchronization.py b/.venv/lib/python3.13/site-packages/httpcore/_synchronization.py new file mode 100644 index 0000000000000000000000000000000000000000..2ecc9e9c363e2f16c4f934cf41cf871826d6a495 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_synchronization.py @@ -0,0 +1,318 @@ +from __future__ import annotations + +import threading +import types + +from ._exceptions import ExceptionMapping, PoolTimeout, map_exceptions + +# Our async synchronization primatives use either 'anyio' or 'trio' depending +# on if they're running under asyncio or trio. + +try: + import trio +except (ImportError, NotImplementedError): # pragma: nocover + trio = None # type: ignore + +try: + import anyio +except ImportError: # pragma: nocover + anyio = None # type: ignore + + +def current_async_library() -> str: + # Determine if we're running under trio or asyncio. + # See https://sniffio.readthedocs.io/en/latest/ + try: + import sniffio + except ImportError: # pragma: nocover + environment = "asyncio" + else: + environment = sniffio.current_async_library() + + if environment not in ("asyncio", "trio"): # pragma: nocover + raise RuntimeError("Running under an unsupported async environment.") + + if environment == "asyncio" and anyio is None: # pragma: nocover + raise RuntimeError( + "Running with asyncio requires installation of 'httpcore[asyncio]'." + ) + + if environment == "trio" and trio is None: # pragma: nocover + raise RuntimeError( + "Running with trio requires installation of 'httpcore[trio]'." + ) + + return environment + + +class AsyncLock: + """ + This is a standard lock. + + In the sync case `Lock` provides thread locking. + In the async case `AsyncLock` provides async locking. + """ + + def __init__(self) -> None: + self._backend = "" + + def setup(self) -> None: + """ + Detect if we're running under 'asyncio' or 'trio' and create + a lock with the correct implementation. + """ + self._backend = current_async_library() + if self._backend == "trio": + self._trio_lock = trio.Lock() + elif self._backend == "asyncio": + self._anyio_lock = anyio.Lock() + + async def __aenter__(self) -> AsyncLock: + if not self._backend: + self.setup() + + if self._backend == "trio": + await self._trio_lock.acquire() + elif self._backend == "asyncio": + await self._anyio_lock.acquire() + + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + if self._backend == "trio": + self._trio_lock.release() + elif self._backend == "asyncio": + self._anyio_lock.release() + + +class AsyncThreadLock: + """ + This is a threading-only lock for no-I/O contexts. + + In the sync case `ThreadLock` provides thread locking. + In the async case `AsyncThreadLock` is a no-op. + """ + + def __enter__(self) -> AsyncThreadLock: + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + pass + + +class AsyncEvent: + def __init__(self) -> None: + self._backend = "" + + def setup(self) -> None: + """ + Detect if we're running under 'asyncio' or 'trio' and create + a lock with the correct implementation. + """ + self._backend = current_async_library() + if self._backend == "trio": + self._trio_event = trio.Event() + elif self._backend == "asyncio": + self._anyio_event = anyio.Event() + + def set(self) -> None: + if not self._backend: + self.setup() + + if self._backend == "trio": + self._trio_event.set() + elif self._backend == "asyncio": + self._anyio_event.set() + + async def wait(self, timeout: float | None = None) -> None: + if not self._backend: + self.setup() + + if self._backend == "trio": + trio_exc_map: ExceptionMapping = {trio.TooSlowError: PoolTimeout} + timeout_or_inf = float("inf") if timeout is None else timeout + with map_exceptions(trio_exc_map): + with trio.fail_after(timeout_or_inf): + await self._trio_event.wait() + elif self._backend == "asyncio": + anyio_exc_map: ExceptionMapping = {TimeoutError: PoolTimeout} + with map_exceptions(anyio_exc_map): + with anyio.fail_after(timeout): + await self._anyio_event.wait() + + +class AsyncSemaphore: + def __init__(self, bound: int) -> None: + self._bound = bound + self._backend = "" + + def setup(self) -> None: + """ + Detect if we're running under 'asyncio' or 'trio' and create + a semaphore with the correct implementation. + """ + self._backend = current_async_library() + if self._backend == "trio": + self._trio_semaphore = trio.Semaphore( + initial_value=self._bound, max_value=self._bound + ) + elif self._backend == "asyncio": + self._anyio_semaphore = anyio.Semaphore( + initial_value=self._bound, max_value=self._bound + ) + + async def acquire(self) -> None: + if not self._backend: + self.setup() + + if self._backend == "trio": + await self._trio_semaphore.acquire() + elif self._backend == "asyncio": + await self._anyio_semaphore.acquire() + + async def release(self) -> None: + if self._backend == "trio": + self._trio_semaphore.release() + elif self._backend == "asyncio": + self._anyio_semaphore.release() + + +class AsyncShieldCancellation: + # For certain portions of our codebase where we're dealing with + # closing connections during exception handling we want to shield + # the operation from being cancelled. + # + # with AsyncShieldCancellation(): + # ... # clean-up operations, shielded from cancellation. + + def __init__(self) -> None: + """ + Detect if we're running under 'asyncio' or 'trio' and create + a shielded scope with the correct implementation. + """ + self._backend = current_async_library() + + if self._backend == "trio": + self._trio_shield = trio.CancelScope(shield=True) + elif self._backend == "asyncio": + self._anyio_shield = anyio.CancelScope(shield=True) + + def __enter__(self) -> AsyncShieldCancellation: + if self._backend == "trio": + self._trio_shield.__enter__() + elif self._backend == "asyncio": + self._anyio_shield.__enter__() + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + if self._backend == "trio": + self._trio_shield.__exit__(exc_type, exc_value, traceback) + elif self._backend == "asyncio": + self._anyio_shield.__exit__(exc_type, exc_value, traceback) + + +# Our thread-based synchronization primitives... + + +class Lock: + """ + This is a standard lock. + + In the sync case `Lock` provides thread locking. + In the async case `AsyncLock` provides async locking. + """ + + def __init__(self) -> None: + self._lock = threading.Lock() + + def __enter__(self) -> Lock: + self._lock.acquire() + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + self._lock.release() + + +class ThreadLock: + """ + This is a threading-only lock for no-I/O contexts. + + In the sync case `ThreadLock` provides thread locking. + In the async case `AsyncThreadLock` is a no-op. + """ + + def __init__(self) -> None: + self._lock = threading.Lock() + + def __enter__(self) -> ThreadLock: + self._lock.acquire() + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + self._lock.release() + + +class Event: + def __init__(self) -> None: + self._event = threading.Event() + + def set(self) -> None: + self._event.set() + + def wait(self, timeout: float | None = None) -> None: + if timeout == float("inf"): # pragma: no cover + timeout = None + if not self._event.wait(timeout=timeout): + raise PoolTimeout() # pragma: nocover + + +class Semaphore: + def __init__(self, bound: int) -> None: + self._semaphore = threading.Semaphore(value=bound) + + def acquire(self) -> None: + self._semaphore.acquire() + + def release(self) -> None: + self._semaphore.release() + + +class ShieldCancellation: + # Thread-synchronous codebases don't support cancellation semantics. + # We have this class because we need to mirror the async and sync + # cases within our package, but it's just a no-op. + def __enter__(self) -> ShieldCancellation: + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + pass diff --git a/.venv/lib/python3.13/site-packages/httpcore/_trace.py b/.venv/lib/python3.13/site-packages/httpcore/_trace.py new file mode 100644 index 0000000000000000000000000000000000000000..5f1cd7c47829ce17dbcf651ab56b4ffdce04a485 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_trace.py @@ -0,0 +1,107 @@ +from __future__ import annotations + +import inspect +import logging +import types +import typing + +from ._models import Request + + +class Trace: + def __init__( + self, + name: str, + logger: logging.Logger, + request: Request | None = None, + kwargs: dict[str, typing.Any] | None = None, + ) -> None: + self.name = name + self.logger = logger + self.trace_extension = ( + None if request is None else request.extensions.get("trace") + ) + self.debug = self.logger.isEnabledFor(logging.DEBUG) + self.kwargs = kwargs or {} + self.return_value: typing.Any = None + self.should_trace = self.debug or self.trace_extension is not None + self.prefix = self.logger.name.split(".")[-1] + + def trace(self, name: str, info: dict[str, typing.Any]) -> None: + if self.trace_extension is not None: + prefix_and_name = f"{self.prefix}.{name}" + ret = self.trace_extension(prefix_and_name, info) + if inspect.iscoroutine(ret): # pragma: no cover + raise TypeError( + "If you are using a synchronous interface, " + "the callback of the `trace` extension should " + "be a normal function instead of an asynchronous function." + ) + + if self.debug: + if not info or "return_value" in info and info["return_value"] is None: + message = name + else: + args = " ".join([f"{key}={value!r}" for key, value in info.items()]) + message = f"{name} {args}" + self.logger.debug(message) + + def __enter__(self) -> Trace: + if self.should_trace: + info = self.kwargs + self.trace(f"{self.name}.started", info) + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + if self.should_trace: + if exc_value is None: + info = {"return_value": self.return_value} + self.trace(f"{self.name}.complete", info) + else: + info = {"exception": exc_value} + self.trace(f"{self.name}.failed", info) + + async def atrace(self, name: str, info: dict[str, typing.Any]) -> None: + if self.trace_extension is not None: + prefix_and_name = f"{self.prefix}.{name}" + coro = self.trace_extension(prefix_and_name, info) + if not inspect.iscoroutine(coro): # pragma: no cover + raise TypeError( + "If you're using an asynchronous interface, " + "the callback of the `trace` extension should " + "be an asynchronous function rather than a normal function." + ) + await coro + + if self.debug: + if not info or "return_value" in info and info["return_value"] is None: + message = name + else: + args = " ".join([f"{key}={value!r}" for key, value in info.items()]) + message = f"{name} {args}" + self.logger.debug(message) + + async def __aenter__(self) -> Trace: + if self.should_trace: + info = self.kwargs + await self.atrace(f"{self.name}.started", info) + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + if self.should_trace: + if exc_value is None: + info = {"return_value": self.return_value} + await self.atrace(f"{self.name}.complete", info) + else: + info = {"exception": exc_value} + await self.atrace(f"{self.name}.failed", info) diff --git a/.venv/lib/python3.13/site-packages/httpcore/_utils.py b/.venv/lib/python3.13/site-packages/httpcore/_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..c44ff93cb2f572afc6e679308024b744b65c3b0a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpcore/_utils.py @@ -0,0 +1,37 @@ +from __future__ import annotations + +import select +import socket +import sys + + +def is_socket_readable(sock: socket.socket | None) -> bool: + """ + Return whether a socket, as identifed by its file descriptor, is readable. + "A socket is readable" means that the read buffer isn't empty, i.e. that calling + .recv() on it would immediately return some data. + """ + # NOTE: we want check for readability without actually attempting to read, because + # we don't want to block forever if it's not readable. + + # In the case that the socket no longer exists, or cannot return a file + # descriptor, we treat it as being readable, as if it the next read operation + # on it is ready to return the terminating `b""`. + sock_fd = None if sock is None else sock.fileno() + if sock_fd is None or sock_fd < 0: # pragma: nocover + return True + + # The implementation below was stolen from: + # https://github.com/python-trio/trio/blob/20ee2b1b7376db637435d80e266212a35837ddcc/trio/_socket.py#L471-L478 + # See also: https://github.com/encode/httpcore/pull/193#issuecomment-703129316 + + # Use select.select on Windows, and when poll is unavailable and select.poll + # everywhere else. (E.g. When eventlet is in use. See #327) + if ( + sys.platform == "win32" or getattr(select, "poll", None) is None + ): # pragma: nocover + rready, _, _ = select.select([sock_fd], [], [], 0) + return bool(rready) + p = select.poll() + p.register(sock_fd, select.POLLIN) + return bool(p.poll(0)) diff --git a/.venv/lib/python3.13/site-packages/httpcore/py.typed b/.venv/lib/python3.13/site-packages/httpcore/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/INSTALLER b/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/METADATA b/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..b0d2b196385e98259971519793447c1fd7a9a643 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/METADATA @@ -0,0 +1,203 @@ +Metadata-Version: 2.3 +Name: httpx +Version: 0.28.1 +Summary: The next generation HTTP client. +Project-URL: Changelog, https://github.com/encode/httpx/blob/master/CHANGELOG.md +Project-URL: Documentation, https://www.python-httpx.org +Project-URL: Homepage, https://github.com/encode/httpx +Project-URL: Source, https://github.com/encode/httpx +Author-email: Tom Christie +License: BSD-3-Clause +Classifier: Development Status :: 4 - Beta +Classifier: Environment :: Web Environment +Classifier: Framework :: AsyncIO +Classifier: Framework :: Trio +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.8 +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: Topic :: Internet :: WWW/HTTP +Requires-Python: >=3.8 +Requires-Dist: anyio +Requires-Dist: certifi +Requires-Dist: httpcore==1.* +Requires-Dist: idna +Provides-Extra: brotli +Requires-Dist: brotli; (platform_python_implementation == 'CPython') and extra == 'brotli' +Requires-Dist: brotlicffi; (platform_python_implementation != 'CPython') and extra == 'brotli' +Provides-Extra: cli +Requires-Dist: click==8.*; extra == 'cli' +Requires-Dist: pygments==2.*; extra == 'cli' +Requires-Dist: rich<14,>=10; extra == 'cli' +Provides-Extra: http2 +Requires-Dist: h2<5,>=3; extra == 'http2' +Provides-Extra: socks +Requires-Dist: socksio==1.*; extra == 'socks' +Provides-Extra: zstd +Requires-Dist: zstandard>=0.18.0; extra == 'zstd' +Description-Content-Type: text/markdown + +

+ HTTPX +

+ +

HTTPX - A next-generation HTTP client for Python.

+ +

+ + Test Suite + + + Package version + +

+ +HTTPX is a fully featured HTTP client library for Python 3. It includes **an integrated command line client**, has support for both **HTTP/1.1 and HTTP/2**, and provides both **sync and async APIs**. + +--- + +Install HTTPX using pip: + +```shell +$ pip install httpx +``` + +Now, let's get started: + +```pycon +>>> import httpx +>>> r = httpx.get('https://www.example.org/') +>>> r + +>>> r.status_code +200 +>>> r.headers['content-type'] +'text/html; charset=UTF-8' +>>> r.text +'\n\n\nExample Domain...' +``` + +Or, using the command-line client. + +```shell +$ pip install 'httpx[cli]' # The command line client is an optional dependency. +``` + +Which now allows us to use HTTPX directly from the command-line... + +

+ httpx --help +

+ +Sending a request... + +

+ httpx http://httpbin.org/json +

+ +## Features + +HTTPX builds on the well-established usability of `requests`, and gives you: + +* A broadly [requests-compatible API](https://www.python-httpx.org/compatibility/). +* An integrated command-line client. +* HTTP/1.1 [and HTTP/2 support](https://www.python-httpx.org/http2/). +* Standard synchronous interface, but with [async support if you need it](https://www.python-httpx.org/async/). +* Ability to make requests directly to [WSGI applications](https://www.python-httpx.org/advanced/transports/#wsgi-transport) or [ASGI applications](https://www.python-httpx.org/advanced/transports/#asgi-transport). +* Strict timeouts everywhere. +* Fully type annotated. +* 100% test coverage. + +Plus all the standard features of `requests`... + +* International Domains and URLs +* Keep-Alive & Connection Pooling +* Sessions with Cookie Persistence +* Browser-style SSL Verification +* Basic/Digest Authentication +* Elegant Key/Value Cookies +* Automatic Decompression +* Automatic Content Decoding +* Unicode Response Bodies +* Multipart File Uploads +* HTTP(S) Proxy Support +* Connection Timeouts +* Streaming Downloads +* .netrc Support +* Chunked Requests + +## Installation + +Install with pip: + +```shell +$ pip install httpx +``` + +Or, to include the optional HTTP/2 support, use: + +```shell +$ pip install httpx[http2] +``` + +HTTPX requires Python 3.8+. + +## Documentation + +Project documentation is available at [https://www.python-httpx.org/](https://www.python-httpx.org/). + +For a run-through of all the basics, head over to the [QuickStart](https://www.python-httpx.org/quickstart/). + +For more advanced topics, see the [Advanced Usage](https://www.python-httpx.org/advanced/) section, the [async support](https://www.python-httpx.org/async/) section, or the [HTTP/2](https://www.python-httpx.org/http2/) section. + +The [Developer Interface](https://www.python-httpx.org/api/) provides a comprehensive API reference. + +To find out about tools that integrate with HTTPX, see [Third Party Packages](https://www.python-httpx.org/third_party_packages/). + +## Contribute + +If you want to contribute with HTTPX check out the [Contributing Guide](https://www.python-httpx.org/contributing/) to learn how to start. + +## Dependencies + +The HTTPX project relies on these excellent libraries: + +* `httpcore` - The underlying transport implementation for `httpx`. + * `h11` - HTTP/1.1 support. +* `certifi` - SSL certificates. +* `idna` - Internationalized domain name support. +* `sniffio` - Async library autodetection. + +As well as these optional installs: + +* `h2` - HTTP/2 support. *(Optional, with `httpx[http2]`)* +* `socksio` - SOCKS proxy support. *(Optional, with `httpx[socks]`)* +* `rich` - Rich terminal support. *(Optional, with `httpx[cli]`)* +* `click` - Command line client support. *(Optional, with `httpx[cli]`)* +* `brotli` or `brotlicffi` - Decoding for "brotli" compressed responses. *(Optional, with `httpx[brotli]`)* +* `zstandard` - Decoding for "zstd" compressed responses. *(Optional, with `httpx[zstd]`)* + +A huge amount of credit is due to `requests` for the API layout that +much of this work follows, as well as to `urllib3` for plenty of design +inspiration around the lower-level networking details. + +--- + +

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

— 🦋 —

+ +## Release Information + +### Fixed + +* Reintroduced supposedly-private `URLTypes` shortcut. (#2673) + + +--- + +[Full changelog](https://github.com/encode/httpx/blob/master/CHANGELOG.md) diff --git a/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/RECORD b/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..e06bdb2ebcf0319594dc35bca62a14241b7222f4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/RECORD @@ -0,0 +1,54 @@ +../../../bin/httpx,sha256=xVgaQx2lu9oggGGMOZuZf5AqBh_f0nDR3FjV83IyoAg,183 +httpx-0.28.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +httpx-0.28.1.dist-info/METADATA,sha256=_rubD48-gNV8gZnDBPNcQzboWB0dGNeYPJJ2a4J5OyU,7052 +httpx-0.28.1.dist-info/RECORD,, +httpx-0.28.1.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87 +httpx-0.28.1.dist-info/entry_points.txt,sha256=2lVkdQmxLA1pNMgSN2eV89o90HCZezhmNwsy6ryKDSA,37 +httpx-0.28.1.dist-info/licenses/LICENSE.md,sha256=TsWdVE8StfU5o6cW_TIaxYzNgDC0ZSIfLIgCAM3yjY0,1508 +httpx/__init__.py,sha256=CsaZe6yZj0rHg6322AWKWHGTMVr9txgEfD5P3_Rrz60,2171 +httpx/__pycache__/__init__.cpython-313.pyc,, +httpx/__pycache__/__version__.cpython-313.pyc,, +httpx/__pycache__/_api.cpython-313.pyc,, +httpx/__pycache__/_auth.cpython-313.pyc,, +httpx/__pycache__/_client.cpython-313.pyc,, +httpx/__pycache__/_config.cpython-313.pyc,, +httpx/__pycache__/_content.cpython-313.pyc,, +httpx/__pycache__/_decoders.cpython-313.pyc,, +httpx/__pycache__/_exceptions.cpython-313.pyc,, +httpx/__pycache__/_main.cpython-313.pyc,, +httpx/__pycache__/_models.cpython-313.pyc,, +httpx/__pycache__/_multipart.cpython-313.pyc,, +httpx/__pycache__/_status_codes.cpython-313.pyc,, +httpx/__pycache__/_types.cpython-313.pyc,, +httpx/__pycache__/_urlparse.cpython-313.pyc,, +httpx/__pycache__/_urls.cpython-313.pyc,, +httpx/__pycache__/_utils.cpython-313.pyc,, +httpx/__version__.py,sha256=LoUyYeOXTieGzuP_64UL0wxdtxjuu_QbOvE7NOg-IqU,108 +httpx/_api.py,sha256=r_Zgs4jIpcPJLqK5dbbSayqo_iVMKFaxZCd-oOHxLEs,11743 +httpx/_auth.py,sha256=Yr3QwaUSK17rGYx-7j-FdicFIzz4Y9FFV-1F4-7RXX4,11891 +httpx/_client.py,sha256=xD-UG67-WMkeltAAOeGGj-cZ2RRTAm19sWRxlFY7_40,65714 +httpx/_config.py,sha256=pPp2U-wicfcKsF-KYRE1LYdt3e6ERGeIoXZ8Gjo3LWc,8547 +httpx/_content.py,sha256=LGGzrJTR3OvN4Mb1GVVNLXkXJH-6oKlwAttO9p5w_yg,8161 +httpx/_decoders.py,sha256=p0dX8I0NEHexs3UGp4SsZutiMhsXrrWl6-GnqVb0iKM,12041 +httpx/_exceptions.py,sha256=bxW7fxzgVMAdNTbwT0Vnq04gJDW1_gI_GFiQPuMyjL0,8527 +httpx/_main.py,sha256=Cg9GMabiTT_swaDfUgIRitSwxLRMSwUDOm7LdSGqlA4,15626 +httpx/_models.py,sha256=4__Guyv1gLxuZChwim8kfQNiIOcJ9acreFOSurvZfms,44700 +httpx/_multipart.py,sha256=KOHEZZl6oohg9mPaKyyu345qq1rJLg35TUG3YAzXB3Y,9843 +httpx/_status_codes.py,sha256=DYn-2ufBgMeXy5s8x3_TB7wjAuAAMewTakPrm5rXEsc,5639 +httpx/_transports/__init__.py,sha256=GbUoBSAOp7z-l-9j5YhMhR3DMIcn6FVLhj072O3Nnno,275 +httpx/_transports/__pycache__/__init__.cpython-313.pyc,, +httpx/_transports/__pycache__/asgi.cpython-313.pyc,, +httpx/_transports/__pycache__/base.cpython-313.pyc,, +httpx/_transports/__pycache__/default.cpython-313.pyc,, +httpx/_transports/__pycache__/mock.cpython-313.pyc,, +httpx/_transports/__pycache__/wsgi.cpython-313.pyc,, +httpx/_transports/asgi.py,sha256=HRfiDYMPt4wQH2gFgHZg4c-i3sblo6bL5GTqcET-xz8,5501 +httpx/_transports/base.py,sha256=kZS_VMbViYfF570pogUCJ1bulz-ybfL51Pqs9yktebU,2523 +httpx/_transports/default.py,sha256=AzeaRUyVwCccTyyNJexDf0n1dFfzzydpdIQgvw7PLnk,13983 +httpx/_transports/mock.py,sha256=PTo0d567RITXxGrki6kN7_67wwAxfwiMDcuXJiZCjEo,1232 +httpx/_transports/wsgi.py,sha256=NcPX3Xap_EwCFZWO_OaSyQNuInCYx1QMNbO8GAei6jY,4825 +httpx/_types.py,sha256=Jyh41GQq7AOev8IOWKDAg7zCbvHAfufmW5g_PiTtErY,2965 +httpx/_urlparse.py,sha256=ZAmH47ONfkxrrj-PPYhGeiHjb6AjKCS-ANWIN4OL_KY,18546 +httpx/_urls.py,sha256=dX99VR1DSOHpgo9Aq7PzYO4FKdxqKjwyNp8grf8dHN0,21550 +httpx/_utils.py,sha256=_TVeqAKvxJkKHdz7dFeb4s0LZqQXgeFkXSgfiHBK_1o,8285 +httpx/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/WHEEL b/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..21aaa72961a8af71c17d2cb3b76d5f7f567100e4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.26.3 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/entry_points.txt b/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/entry_points.txt new file mode 100644 index 0000000000000000000000000000000000000000..8ae96007f7d725813fd02dc1d06d3834ee1939e4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +httpx = httpx:main diff --git a/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/licenses/LICENSE.md b/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/licenses/LICENSE.md new file mode 100644 index 0000000000000000000000000000000000000000..ab79d16a3f4c6c894c028d1f7431811e8711b42b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/licenses/LICENSE.md @@ -0,0 +1,12 @@ +Copyright © 2019, [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/python3.13/site-packages/httpx/__init__.py b/.venv/lib/python3.13/site-packages/httpx/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e9addde071f81758baf350c4ab6bde2556340131 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/__init__.py @@ -0,0 +1,105 @@ +from .__version__ import __description__, __title__, __version__ +from ._api import * +from ._auth import * +from ._client import * +from ._config import * +from ._content import * +from ._exceptions import * +from ._models import * +from ._status_codes import * +from ._transports import * +from ._types import * +from ._urls import * + +try: + from ._main import main +except ImportError: # pragma: no cover + + def main() -> None: # type: ignore + import sys + + print( + "The httpx command line client could not run because the required " + "dependencies were not installed.\nMake sure you've installed " + "everything with: pip install 'httpx[cli]'" + ) + sys.exit(1) + + +__all__ = [ + "__description__", + "__title__", + "__version__", + "ASGITransport", + "AsyncBaseTransport", + "AsyncByteStream", + "AsyncClient", + "AsyncHTTPTransport", + "Auth", + "BaseTransport", + "BasicAuth", + "ByteStream", + "Client", + "CloseError", + "codes", + "ConnectError", + "ConnectTimeout", + "CookieConflict", + "Cookies", + "create_ssl_context", + "DecodingError", + "delete", + "DigestAuth", + "get", + "head", + "Headers", + "HTTPError", + "HTTPStatusError", + "HTTPTransport", + "InvalidURL", + "Limits", + "LocalProtocolError", + "main", + "MockTransport", + "NetRCAuth", + "NetworkError", + "options", + "patch", + "PoolTimeout", + "post", + "ProtocolError", + "Proxy", + "ProxyError", + "put", + "QueryParams", + "ReadError", + "ReadTimeout", + "RemoteProtocolError", + "request", + "Request", + "RequestError", + "RequestNotRead", + "Response", + "ResponseNotRead", + "stream", + "StreamClosed", + "StreamConsumed", + "StreamError", + "SyncByteStream", + "Timeout", + "TimeoutException", + "TooManyRedirects", + "TransportError", + "UnsupportedProtocol", + "URL", + "USE_CLIENT_DEFAULT", + "WriteError", + "WriteTimeout", + "WSGITransport", +] + + +__locals = locals() +for __name in __all__: + if not __name.startswith("__"): + setattr(__locals[__name], "__module__", "httpx") # noqa diff --git a/.venv/lib/python3.13/site-packages/httpx/__version__.py b/.venv/lib/python3.13/site-packages/httpx/__version__.py new file mode 100644 index 0000000000000000000000000000000000000000..801bfacf671017cfbebf1ac26ec385daa02ed260 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/__version__.py @@ -0,0 +1,3 @@ +__title__ = "httpx" +__description__ = "A next generation HTTP client, for Python 3." +__version__ = "0.28.1" diff --git a/.venv/lib/python3.13/site-packages/httpx/_api.py b/.venv/lib/python3.13/site-packages/httpx/_api.py new file mode 100644 index 0000000000000000000000000000000000000000..c3cda1ecda8629edbdca2e3bc04bc51dba5e1430 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_api.py @@ -0,0 +1,438 @@ +from __future__ import annotations + +import typing +from contextlib import contextmanager + +from ._client import Client +from ._config import DEFAULT_TIMEOUT_CONFIG +from ._models import Response +from ._types import ( + AuthTypes, + CookieTypes, + HeaderTypes, + ProxyTypes, + QueryParamTypes, + RequestContent, + RequestData, + RequestFiles, + TimeoutTypes, +) +from ._urls import URL + +if typing.TYPE_CHECKING: + import ssl # pragma: no cover + + +__all__ = [ + "delete", + "get", + "head", + "options", + "patch", + "post", + "put", + "request", + "stream", +] + + +def request( + method: str, + url: URL | str, + *, + params: QueryParamTypes | None = None, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | None = None, + proxy: ProxyTypes | None = None, + timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, + follow_redirects: bool = False, + verify: ssl.SSLContext | str | bool = True, + trust_env: bool = True, +) -> Response: + """ + Sends an HTTP request. + + **Parameters:** + + * **method** - HTTP method for the new `Request` object: `GET`, `OPTIONS`, + `HEAD`, `POST`, `PUT`, `PATCH`, or `DELETE`. + * **url** - URL for the new `Request` object. + * **params** - *(optional)* Query parameters to include in the URL, as a + string, dictionary, or sequence of two-tuples. + * **content** - *(optional)* Binary content to include in the body of the + request, as bytes or a byte iterator. + * **data** - *(optional)* Form data to include in the body of the request, + as a dictionary. + * **files** - *(optional)* A dictionary of upload files to include in the + body of the request. + * **json** - *(optional)* A JSON serializable object to include in the body + of the request. + * **headers** - *(optional)* Dictionary of HTTP headers to include in the + request. + * **cookies** - *(optional)* Dictionary of Cookie items to include in the + request. + * **auth** - *(optional)* An authentication class to use when sending the + request. + * **proxy** - *(optional)* A proxy URL where all the traffic should be routed. + * **timeout** - *(optional)* The timeout configuration to use when sending + the request. + * **follow_redirects** - *(optional)* Enables or disables HTTP redirects. + * **verify** - *(optional)* Either `True` to use an SSL context with the + default CA bundle, `False` to disable verification, or an instance of + `ssl.SSLContext` to use a custom context. + * **trust_env** - *(optional)* Enables or disables usage of environment + variables for configuration. + + **Returns:** `Response` + + Usage: + + ``` + >>> import httpx + >>> response = httpx.request('GET', 'https://httpbin.org/get') + >>> response + + ``` + """ + with Client( + cookies=cookies, + proxy=proxy, + verify=verify, + timeout=timeout, + trust_env=trust_env, + ) as client: + return client.request( + method=method, + url=url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + auth=auth, + follow_redirects=follow_redirects, + ) + + +@contextmanager +def stream( + method: str, + url: URL | str, + *, + params: QueryParamTypes | None = None, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | None = None, + proxy: ProxyTypes | None = None, + timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, + follow_redirects: bool = False, + verify: ssl.SSLContext | str | bool = True, + trust_env: bool = True, +) -> typing.Iterator[Response]: + """ + Alternative to `httpx.request()` that streams the response body + instead of loading it into memory at once. + + **Parameters**: See `httpx.request`. + + See also: [Streaming Responses][0] + + [0]: /quickstart#streaming-responses + """ + with Client( + cookies=cookies, + proxy=proxy, + verify=verify, + timeout=timeout, + trust_env=trust_env, + ) as client: + with client.stream( + method=method, + url=url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + auth=auth, + follow_redirects=follow_redirects, + ) as response: + yield response + + +def get( + url: URL | str, + *, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | None = None, + proxy: ProxyTypes | None = None, + follow_redirects: bool = False, + verify: ssl.SSLContext | str | bool = True, + timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, + trust_env: bool = True, +) -> Response: + """ + Sends a `GET` request. + + **Parameters**: See `httpx.request`. + + Note that the `data`, `files`, `json` and `content` parameters are not available + on this function, as `GET` requests should not include a request body. + """ + return request( + "GET", + url, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + proxy=proxy, + follow_redirects=follow_redirects, + verify=verify, + timeout=timeout, + trust_env=trust_env, + ) + + +def options( + url: URL | str, + *, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | None = None, + proxy: ProxyTypes | None = None, + follow_redirects: bool = False, + verify: ssl.SSLContext | str | bool = True, + timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, + trust_env: bool = True, +) -> Response: + """ + Sends an `OPTIONS` request. + + **Parameters**: See `httpx.request`. + + Note that the `data`, `files`, `json` and `content` parameters are not available + on this function, as `OPTIONS` requests should not include a request body. + """ + return request( + "OPTIONS", + url, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + proxy=proxy, + follow_redirects=follow_redirects, + verify=verify, + timeout=timeout, + trust_env=trust_env, + ) + + +def head( + url: URL | str, + *, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | None = None, + proxy: ProxyTypes | None = None, + follow_redirects: bool = False, + verify: ssl.SSLContext | str | bool = True, + timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, + trust_env: bool = True, +) -> Response: + """ + Sends a `HEAD` request. + + **Parameters**: See `httpx.request`. + + Note that the `data`, `files`, `json` and `content` parameters are not available + on this function, as `HEAD` requests should not include a request body. + """ + return request( + "HEAD", + url, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + proxy=proxy, + follow_redirects=follow_redirects, + verify=verify, + timeout=timeout, + trust_env=trust_env, + ) + + +def post( + url: URL | str, + *, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | None = None, + proxy: ProxyTypes | None = None, + follow_redirects: bool = False, + verify: ssl.SSLContext | str | bool = True, + timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, + trust_env: bool = True, +) -> Response: + """ + Sends a `POST` request. + + **Parameters**: See `httpx.request`. + """ + return request( + "POST", + url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + proxy=proxy, + follow_redirects=follow_redirects, + verify=verify, + timeout=timeout, + trust_env=trust_env, + ) + + +def put( + url: URL | str, + *, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | None = None, + proxy: ProxyTypes | None = None, + follow_redirects: bool = False, + verify: ssl.SSLContext | str | bool = True, + timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, + trust_env: bool = True, +) -> Response: + """ + Sends a `PUT` request. + + **Parameters**: See `httpx.request`. + """ + return request( + "PUT", + url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + proxy=proxy, + follow_redirects=follow_redirects, + verify=verify, + timeout=timeout, + trust_env=trust_env, + ) + + +def patch( + url: URL | str, + *, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | None = None, + proxy: ProxyTypes | None = None, + follow_redirects: bool = False, + verify: ssl.SSLContext | str | bool = True, + timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, + trust_env: bool = True, +) -> Response: + """ + Sends a `PATCH` request. + + **Parameters**: See `httpx.request`. + """ + return request( + "PATCH", + url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + proxy=proxy, + follow_redirects=follow_redirects, + verify=verify, + timeout=timeout, + trust_env=trust_env, + ) + + +def delete( + url: URL | str, + *, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | None = None, + proxy: ProxyTypes | None = None, + follow_redirects: bool = False, + timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, + verify: ssl.SSLContext | str | bool = True, + trust_env: bool = True, +) -> Response: + """ + Sends a `DELETE` request. + + **Parameters**: See `httpx.request`. + + Note that the `data`, `files`, `json` and `content` parameters are not available + on this function, as `DELETE` requests should not include a request body. + """ + return request( + "DELETE", + url, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + proxy=proxy, + follow_redirects=follow_redirects, + verify=verify, + timeout=timeout, + trust_env=trust_env, + ) diff --git a/.venv/lib/python3.13/site-packages/httpx/_auth.py b/.venv/lib/python3.13/site-packages/httpx/_auth.py new file mode 100644 index 0000000000000000000000000000000000000000..b03971ab4b311d60790dc22ca24d9966426ec0a4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_auth.py @@ -0,0 +1,348 @@ +from __future__ import annotations + +import hashlib +import os +import re +import time +import typing +from base64 import b64encode +from urllib.request import parse_http_list + +from ._exceptions import ProtocolError +from ._models import Cookies, Request, Response +from ._utils import to_bytes, to_str, unquote + +if typing.TYPE_CHECKING: # pragma: no cover + from hashlib import _Hash + + +__all__ = ["Auth", "BasicAuth", "DigestAuth", "NetRCAuth"] + + +class Auth: + """ + Base class for all authentication schemes. + + To implement a custom authentication scheme, subclass `Auth` and override + the `.auth_flow()` method. + + If the authentication scheme does I/O such as disk access or network calls, or uses + synchronization primitives such as locks, you should override `.sync_auth_flow()` + and/or `.async_auth_flow()` instead of `.auth_flow()` to provide specialized + implementations that will be used by `Client` and `AsyncClient` respectively. + """ + + requires_request_body = False + requires_response_body = False + + def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: + """ + Execute the authentication flow. + + To dispatch a request, `yield` it: + + ``` + yield request + ``` + + The client will `.send()` the response back into the flow generator. You can + access it like so: + + ``` + response = yield request + ``` + + A `return` (or reaching the end of the generator) will result in the + client returning the last response obtained from the server. + + You can dispatch as many requests as is necessary. + """ + yield request + + def sync_auth_flow( + self, request: Request + ) -> typing.Generator[Request, Response, None]: + """ + Execute the authentication flow synchronously. + + By default, this defers to `.auth_flow()`. You should override this method + when the authentication scheme does I/O and/or uses concurrency primitives. + """ + if self.requires_request_body: + request.read() + + flow = self.auth_flow(request) + request = next(flow) + + while True: + response = yield request + if self.requires_response_body: + response.read() + + try: + request = flow.send(response) + except StopIteration: + break + + async def async_auth_flow( + self, request: Request + ) -> typing.AsyncGenerator[Request, Response]: + """ + Execute the authentication flow asynchronously. + + By default, this defers to `.auth_flow()`. You should override this method + when the authentication scheme does I/O and/or uses concurrency primitives. + """ + if self.requires_request_body: + await request.aread() + + flow = self.auth_flow(request) + request = next(flow) + + while True: + response = yield request + if self.requires_response_body: + await response.aread() + + try: + request = flow.send(response) + except StopIteration: + break + + +class FunctionAuth(Auth): + """ + Allows the 'auth' argument to be passed as a simple callable function, + that takes the request, and returns a new, modified request. + """ + + def __init__(self, func: typing.Callable[[Request], Request]) -> None: + self._func = func + + def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: + yield self._func(request) + + +class BasicAuth(Auth): + """ + Allows the 'auth' argument to be passed as a (username, password) pair, + and uses HTTP Basic authentication. + """ + + def __init__(self, username: str | bytes, password: str | bytes) -> None: + self._auth_header = self._build_auth_header(username, password) + + def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: + request.headers["Authorization"] = self._auth_header + yield request + + def _build_auth_header(self, username: str | bytes, password: str | bytes) -> str: + userpass = b":".join((to_bytes(username), to_bytes(password))) + token = b64encode(userpass).decode() + return f"Basic {token}" + + +class NetRCAuth(Auth): + """ + Use a 'netrc' file to lookup basic auth credentials based on the url host. + """ + + def __init__(self, file: str | None = None) -> None: + # Lazily import 'netrc'. + # There's no need for us to load this module unless 'NetRCAuth' is being used. + import netrc + + self._netrc_info = netrc.netrc(file) + + def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: + auth_info = self._netrc_info.authenticators(request.url.host) + if auth_info is None or not auth_info[2]: + # The netrc file did not have authentication credentials for this host. + yield request + else: + # Build a basic auth header with credentials from the netrc file. + request.headers["Authorization"] = self._build_auth_header( + username=auth_info[0], password=auth_info[2] + ) + yield request + + def _build_auth_header(self, username: str | bytes, password: str | bytes) -> str: + userpass = b":".join((to_bytes(username), to_bytes(password))) + token = b64encode(userpass).decode() + return f"Basic {token}" + + +class DigestAuth(Auth): + _ALGORITHM_TO_HASH_FUNCTION: dict[str, typing.Callable[[bytes], _Hash]] = { + "MD5": hashlib.md5, + "MD5-SESS": hashlib.md5, + "SHA": hashlib.sha1, + "SHA-SESS": hashlib.sha1, + "SHA-256": hashlib.sha256, + "SHA-256-SESS": hashlib.sha256, + "SHA-512": hashlib.sha512, + "SHA-512-SESS": hashlib.sha512, + } + + def __init__(self, username: str | bytes, password: str | bytes) -> None: + self._username = to_bytes(username) + self._password = to_bytes(password) + self._last_challenge: _DigestAuthChallenge | None = None + self._nonce_count = 1 + + def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: + if self._last_challenge: + request.headers["Authorization"] = self._build_auth_header( + request, self._last_challenge + ) + + response = yield request + + if response.status_code != 401 or "www-authenticate" not in response.headers: + # If the response is not a 401 then we don't + # need to build an authenticated request. + return + + for auth_header in response.headers.get_list("www-authenticate"): + if auth_header.lower().startswith("digest "): + break + else: + # If the response does not include a 'WWW-Authenticate: Digest ...' + # header, then we don't need to build an authenticated request. + return + + self._last_challenge = self._parse_challenge(request, response, auth_header) + self._nonce_count = 1 + + request.headers["Authorization"] = self._build_auth_header( + request, self._last_challenge + ) + if response.cookies: + Cookies(response.cookies).set_cookie_header(request=request) + yield request + + def _parse_challenge( + self, request: Request, response: Response, auth_header: str + ) -> _DigestAuthChallenge: + """ + Returns a challenge from a Digest WWW-Authenticate header. + These take the form of: + `Digest realm="realm@host.com",qop="auth,auth-int",nonce="abc",opaque="xyz"` + """ + scheme, _, fields = auth_header.partition(" ") + + # This method should only ever have been called with a Digest auth header. + assert scheme.lower() == "digest" + + header_dict: dict[str, str] = {} + for field in parse_http_list(fields): + key, value = field.strip().split("=", 1) + header_dict[key] = unquote(value) + + try: + realm = header_dict["realm"].encode() + nonce = header_dict["nonce"].encode() + algorithm = header_dict.get("algorithm", "MD5") + opaque = header_dict["opaque"].encode() if "opaque" in header_dict else None + qop = header_dict["qop"].encode() if "qop" in header_dict else None + return _DigestAuthChallenge( + realm=realm, nonce=nonce, algorithm=algorithm, opaque=opaque, qop=qop + ) + except KeyError as exc: + message = "Malformed Digest WWW-Authenticate header" + raise ProtocolError(message, request=request) from exc + + def _build_auth_header( + self, request: Request, challenge: _DigestAuthChallenge + ) -> str: + hash_func = self._ALGORITHM_TO_HASH_FUNCTION[challenge.algorithm.upper()] + + def digest(data: bytes) -> bytes: + return hash_func(data).hexdigest().encode() + + A1 = b":".join((self._username, challenge.realm, self._password)) + + path = request.url.raw_path + A2 = b":".join((request.method.encode(), path)) + # TODO: implement auth-int + HA2 = digest(A2) + + nc_value = b"%08x" % self._nonce_count + cnonce = self._get_client_nonce(self._nonce_count, challenge.nonce) + self._nonce_count += 1 + + HA1 = digest(A1) + if challenge.algorithm.lower().endswith("-sess"): + HA1 = digest(b":".join((HA1, challenge.nonce, cnonce))) + + qop = self._resolve_qop(challenge.qop, request=request) + if qop is None: + # Following RFC 2069 + digest_data = [HA1, challenge.nonce, HA2] + else: + # Following RFC 2617/7616 + digest_data = [HA1, challenge.nonce, nc_value, cnonce, qop, HA2] + + format_args = { + "username": self._username, + "realm": challenge.realm, + "nonce": challenge.nonce, + "uri": path, + "response": digest(b":".join(digest_data)), + "algorithm": challenge.algorithm.encode(), + } + if challenge.opaque: + format_args["opaque"] = challenge.opaque + if qop: + format_args["qop"] = b"auth" + format_args["nc"] = nc_value + format_args["cnonce"] = cnonce + + return "Digest " + self._get_header_value(format_args) + + def _get_client_nonce(self, nonce_count: int, nonce: bytes) -> bytes: + s = str(nonce_count).encode() + s += nonce + s += time.ctime().encode() + s += os.urandom(8) + + return hashlib.sha1(s).hexdigest()[:16].encode() + + def _get_header_value(self, header_fields: dict[str, bytes]) -> str: + NON_QUOTED_FIELDS = ("algorithm", "qop", "nc") + QUOTED_TEMPLATE = '{}="{}"' + NON_QUOTED_TEMPLATE = "{}={}" + + header_value = "" + for i, (field, value) in enumerate(header_fields.items()): + if i > 0: + header_value += ", " + template = ( + QUOTED_TEMPLATE + if field not in NON_QUOTED_FIELDS + else NON_QUOTED_TEMPLATE + ) + header_value += template.format(field, to_str(value)) + + return header_value + + def _resolve_qop(self, qop: bytes | None, request: Request) -> bytes | None: + if qop is None: + return None + qops = re.split(b", ?", qop) + if b"auth" in qops: + return b"auth" + + if qops == [b"auth-int"]: + raise NotImplementedError("Digest auth-int support is not yet implemented") + + message = f'Unexpected qop value "{qop!r}" in digest auth' + raise ProtocolError(message, request=request) + + +class _DigestAuthChallenge(typing.NamedTuple): + realm: bytes + nonce: bytes + algorithm: str + opaque: bytes | None + qop: bytes | None diff --git a/.venv/lib/python3.13/site-packages/httpx/_client.py b/.venv/lib/python3.13/site-packages/httpx/_client.py new file mode 100644 index 0000000000000000000000000000000000000000..2249231f8c3b912c731ff160344d3672e2f11738 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_client.py @@ -0,0 +1,2019 @@ +from __future__ import annotations + +import datetime +import enum +import logging +import time +import typing +import warnings +from contextlib import asynccontextmanager, contextmanager +from types import TracebackType + +from .__version__ import __version__ +from ._auth import Auth, BasicAuth, FunctionAuth +from ._config import ( + DEFAULT_LIMITS, + DEFAULT_MAX_REDIRECTS, + DEFAULT_TIMEOUT_CONFIG, + Limits, + Proxy, + Timeout, +) +from ._decoders import SUPPORTED_DECODERS +from ._exceptions import ( + InvalidURL, + RemoteProtocolError, + TooManyRedirects, + request_context, +) +from ._models import Cookies, Headers, Request, Response +from ._status_codes import codes +from ._transports.base import AsyncBaseTransport, BaseTransport +from ._transports.default import AsyncHTTPTransport, HTTPTransport +from ._types import ( + AsyncByteStream, + AuthTypes, + CertTypes, + CookieTypes, + HeaderTypes, + ProxyTypes, + QueryParamTypes, + RequestContent, + RequestData, + RequestExtensions, + RequestFiles, + SyncByteStream, + TimeoutTypes, +) +from ._urls import URL, QueryParams +from ._utils import URLPattern, get_environment_proxies + +if typing.TYPE_CHECKING: + import ssl # pragma: no cover + +__all__ = ["USE_CLIENT_DEFAULT", "AsyncClient", "Client"] + +# The type annotation for @classmethod and context managers here follows PEP 484 +# https://www.python.org/dev/peps/pep-0484/#annotating-instance-and-class-methods +T = typing.TypeVar("T", bound="Client") +U = typing.TypeVar("U", bound="AsyncClient") + + +def _is_https_redirect(url: URL, location: URL) -> bool: + """ + Return 'True' if 'location' is a HTTPS upgrade of 'url' + """ + if url.host != location.host: + return False + + return ( + url.scheme == "http" + and _port_or_default(url) == 80 + and location.scheme == "https" + and _port_or_default(location) == 443 + ) + + +def _port_or_default(url: URL) -> int | None: + if url.port is not None: + return url.port + return {"http": 80, "https": 443}.get(url.scheme) + + +def _same_origin(url: URL, other: URL) -> bool: + """ + Return 'True' if the given URLs share the same origin. + """ + return ( + url.scheme == other.scheme + and url.host == other.host + and _port_or_default(url) == _port_or_default(other) + ) + + +class UseClientDefault: + """ + For some parameters such as `auth=...` and `timeout=...` we need to be able + to indicate the default "unset" state, in a way that is distinctly different + to using `None`. + + The default "unset" state indicates that whatever default is set on the + client should be used. This is different to setting `None`, which + explicitly disables the parameter, possibly overriding a client default. + + For example we use `timeout=USE_CLIENT_DEFAULT` in the `request()` signature. + Omitting the `timeout` parameter will send a request using whatever default + timeout has been configured on the client. Including `timeout=None` will + ensure no timeout is used. + + Note that user code shouldn't need to use the `USE_CLIENT_DEFAULT` constant, + but it is used internally when a parameter is not included. + """ + + +USE_CLIENT_DEFAULT = UseClientDefault() + + +logger = logging.getLogger("httpx") + +USER_AGENT = f"python-httpx/{__version__}" +ACCEPT_ENCODING = ", ".join( + [key for key in SUPPORTED_DECODERS.keys() if key != "identity"] +) + + +class ClientState(enum.Enum): + # UNOPENED: + # The client has been instantiated, but has not been used to send a request, + # or been opened by entering the context of a `with` block. + UNOPENED = 1 + # OPENED: + # The client has either sent a request, or is within a `with` block. + OPENED = 2 + # CLOSED: + # The client has either exited the `with` block, or `close()` has + # been called explicitly. + CLOSED = 3 + + +class BoundSyncStream(SyncByteStream): + """ + A byte stream that is bound to a given response instance, and that + ensures the `response.elapsed` is set once the response is closed. + """ + + def __init__( + self, stream: SyncByteStream, response: Response, start: float + ) -> None: + self._stream = stream + self._response = response + self._start = start + + def __iter__(self) -> typing.Iterator[bytes]: + for chunk in self._stream: + yield chunk + + def close(self) -> None: + elapsed = time.perf_counter() - self._start + self._response.elapsed = datetime.timedelta(seconds=elapsed) + self._stream.close() + + +class BoundAsyncStream(AsyncByteStream): + """ + An async byte stream that is bound to a given response instance, and that + ensures the `response.elapsed` is set once the response is closed. + """ + + def __init__( + self, stream: AsyncByteStream, response: Response, start: float + ) -> None: + self._stream = stream + self._response = response + self._start = start + + async def __aiter__(self) -> typing.AsyncIterator[bytes]: + async for chunk in self._stream: + yield chunk + + async def aclose(self) -> None: + elapsed = time.perf_counter() - self._start + self._response.elapsed = datetime.timedelta(seconds=elapsed) + await self._stream.aclose() + + +EventHook = typing.Callable[..., typing.Any] + + +class BaseClient: + def __init__( + self, + *, + auth: AuthTypes | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, + follow_redirects: bool = False, + max_redirects: int = DEFAULT_MAX_REDIRECTS, + event_hooks: None | (typing.Mapping[str, list[EventHook]]) = None, + base_url: URL | str = "", + trust_env: bool = True, + default_encoding: str | typing.Callable[[bytes], str] = "utf-8", + ) -> None: + event_hooks = {} if event_hooks is None else event_hooks + + self._base_url = self._enforce_trailing_slash(URL(base_url)) + + self._auth = self._build_auth(auth) + self._params = QueryParams(params) + self.headers = Headers(headers) + self._cookies = Cookies(cookies) + self._timeout = Timeout(timeout) + self.follow_redirects = follow_redirects + self.max_redirects = max_redirects + self._event_hooks = { + "request": list(event_hooks.get("request", [])), + "response": list(event_hooks.get("response", [])), + } + self._trust_env = trust_env + self._default_encoding = default_encoding + self._state = ClientState.UNOPENED + + @property + def is_closed(self) -> bool: + """ + Check if the client being closed + """ + return self._state == ClientState.CLOSED + + @property + def trust_env(self) -> bool: + return self._trust_env + + def _enforce_trailing_slash(self, url: URL) -> URL: + if url.raw_path.endswith(b"/"): + return url + return url.copy_with(raw_path=url.raw_path + b"/") + + def _get_proxy_map( + self, proxy: ProxyTypes | None, allow_env_proxies: bool + ) -> dict[str, Proxy | None]: + if proxy is None: + if allow_env_proxies: + return { + key: None if url is None else Proxy(url=url) + for key, url in get_environment_proxies().items() + } + return {} + else: + proxy = Proxy(url=proxy) if isinstance(proxy, (str, URL)) else proxy + return {"all://": proxy} + + @property + def timeout(self) -> Timeout: + return self._timeout + + @timeout.setter + def timeout(self, timeout: TimeoutTypes) -> None: + self._timeout = Timeout(timeout) + + @property + def event_hooks(self) -> dict[str, list[EventHook]]: + return self._event_hooks + + @event_hooks.setter + def event_hooks(self, event_hooks: dict[str, list[EventHook]]) -> None: + self._event_hooks = { + "request": list(event_hooks.get("request", [])), + "response": list(event_hooks.get("response", [])), + } + + @property + def auth(self) -> Auth | None: + """ + Authentication class used when none is passed at the request-level. + + See also [Authentication][0]. + + [0]: /quickstart/#authentication + """ + return self._auth + + @auth.setter + def auth(self, auth: AuthTypes) -> None: + self._auth = self._build_auth(auth) + + @property + def base_url(self) -> URL: + """ + Base URL to use when sending requests with relative URLs. + """ + return self._base_url + + @base_url.setter + def base_url(self, url: URL | str) -> None: + self._base_url = self._enforce_trailing_slash(URL(url)) + + @property + def headers(self) -> Headers: + """ + HTTP headers to include when sending requests. + """ + return self._headers + + @headers.setter + def headers(self, headers: HeaderTypes) -> None: + client_headers = Headers( + { + b"Accept": b"*/*", + b"Accept-Encoding": ACCEPT_ENCODING.encode("ascii"), + b"Connection": b"keep-alive", + b"User-Agent": USER_AGENT.encode("ascii"), + } + ) + client_headers.update(headers) + self._headers = client_headers + + @property + def cookies(self) -> Cookies: + """ + Cookie values to include when sending requests. + """ + return self._cookies + + @cookies.setter + def cookies(self, cookies: CookieTypes) -> None: + self._cookies = Cookies(cookies) + + @property + def params(self) -> QueryParams: + """ + Query parameters to include in the URL when sending requests. + """ + return self._params + + @params.setter + def params(self, params: QueryParamTypes) -> None: + self._params = QueryParams(params) + + def build_request( + self, + method: str, + url: URL | str, + *, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Request: + """ + Build and return a request instance. + + * The `params`, `headers` and `cookies` arguments + are merged with any values set on the client. + * The `url` argument is merged with any `base_url` set on the client. + + See also: [Request instances][0] + + [0]: /advanced/clients/#request-instances + """ + url = self._merge_url(url) + headers = self._merge_headers(headers) + cookies = self._merge_cookies(cookies) + params = self._merge_queryparams(params) + extensions = {} if extensions is None else extensions + if "timeout" not in extensions: + timeout = ( + self.timeout + if isinstance(timeout, UseClientDefault) + else Timeout(timeout) + ) + extensions = dict(**extensions, timeout=timeout.as_dict()) + return Request( + method, + url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + cookies=cookies, + extensions=extensions, + ) + + def _merge_url(self, url: URL | str) -> URL: + """ + Merge a URL argument together with any 'base_url' on the client, + to create the URL used for the outgoing request. + """ + merge_url = URL(url) + if merge_url.is_relative_url: + # To merge URLs we always append to the base URL. To get this + # behaviour correct we always ensure the base URL ends in a '/' + # separator, and strip any leading '/' from the merge URL. + # + # So, eg... + # + # >>> client = Client(base_url="https://www.example.com/subpath") + # >>> client.base_url + # URL('https://www.example.com/subpath/') + # >>> client.build_request("GET", "/path").url + # URL('https://www.example.com/subpath/path') + merge_raw_path = self.base_url.raw_path + merge_url.raw_path.lstrip(b"/") + return self.base_url.copy_with(raw_path=merge_raw_path) + return merge_url + + def _merge_cookies(self, cookies: CookieTypes | None = None) -> CookieTypes | None: + """ + Merge a cookies argument together with any cookies on the client, + to create the cookies used for the outgoing request. + """ + if cookies or self.cookies: + merged_cookies = Cookies(self.cookies) + merged_cookies.update(cookies) + return merged_cookies + return cookies + + def _merge_headers(self, headers: HeaderTypes | None = None) -> HeaderTypes | None: + """ + Merge a headers argument together with any headers on the client, + to create the headers used for the outgoing request. + """ + merged_headers = Headers(self.headers) + merged_headers.update(headers) + return merged_headers + + def _merge_queryparams( + self, params: QueryParamTypes | None = None + ) -> QueryParamTypes | None: + """ + Merge a queryparams argument together with any queryparams on the client, + to create the queryparams used for the outgoing request. + """ + if params or self.params: + merged_queryparams = QueryParams(self.params) + return merged_queryparams.merge(params) + return params + + def _build_auth(self, auth: AuthTypes | None) -> Auth | None: + if auth is None: + return None + elif isinstance(auth, tuple): + return BasicAuth(username=auth[0], password=auth[1]) + elif isinstance(auth, Auth): + return auth + elif callable(auth): + return FunctionAuth(func=auth) + else: + raise TypeError(f'Invalid "auth" argument: {auth!r}') + + def _build_request_auth( + self, + request: Request, + auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, + ) -> Auth: + auth = ( + self._auth if isinstance(auth, UseClientDefault) else self._build_auth(auth) + ) + + if auth is not None: + return auth + + username, password = request.url.username, request.url.password + if username or password: + return BasicAuth(username=username, password=password) + + return Auth() + + def _build_redirect_request(self, request: Request, response: Response) -> Request: + """ + Given a request and a redirect response, return a new request that + should be used to effect the redirect. + """ + method = self._redirect_method(request, response) + url = self._redirect_url(request, response) + headers = self._redirect_headers(request, url, method) + stream = self._redirect_stream(request, method) + cookies = Cookies(self.cookies) + return Request( + method=method, + url=url, + headers=headers, + cookies=cookies, + stream=stream, + extensions=request.extensions, + ) + + def _redirect_method(self, request: Request, response: Response) -> str: + """ + When being redirected we may want to change the method of the request + based on certain specs or browser behavior. + """ + method = request.method + + # https://tools.ietf.org/html/rfc7231#section-6.4.4 + if response.status_code == codes.SEE_OTHER and method != "HEAD": + method = "GET" + + # Do what the browsers do, despite standards... + # Turn 302s into GETs. + if response.status_code == codes.FOUND and method != "HEAD": + method = "GET" + + # If a POST is responded to with a 301, turn it into a GET. + # This bizarre behaviour is explained in 'requests' issue 1704. + if response.status_code == codes.MOVED_PERMANENTLY and method == "POST": + method = "GET" + + return method + + def _redirect_url(self, request: Request, response: Response) -> URL: + """ + Return the URL for the redirect to follow. + """ + location = response.headers["Location"] + + try: + url = URL(location) + except InvalidURL as exc: + raise RemoteProtocolError( + f"Invalid URL in location header: {exc}.", request=request + ) from None + + # Handle malformed 'Location' headers that are "absolute" form, have no host. + # See: https://github.com/encode/httpx/issues/771 + if url.scheme and not url.host: + url = url.copy_with(host=request.url.host) + + # Facilitate relative 'Location' headers, as allowed by RFC 7231. + # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource') + if url.is_relative_url: + url = request.url.join(url) + + # Attach previous fragment if needed (RFC 7231 7.1.2) + if request.url.fragment and not url.fragment: + url = url.copy_with(fragment=request.url.fragment) + + return url + + def _redirect_headers(self, request: Request, url: URL, method: str) -> Headers: + """ + Return the headers that should be used for the redirect request. + """ + headers = Headers(request.headers) + + if not _same_origin(url, request.url): + if not _is_https_redirect(request.url, url): + # Strip Authorization headers when responses are redirected + # away from the origin. (Except for direct HTTP to HTTPS redirects.) + headers.pop("Authorization", None) + + # Update the Host header. + headers["Host"] = url.netloc.decode("ascii") + + if method != request.method and method == "GET": + # If we've switch to a 'GET' request, then strip any headers which + # are only relevant to the request body. + headers.pop("Content-Length", None) + headers.pop("Transfer-Encoding", None) + + # We should use the client cookie store to determine any cookie header, + # rather than whatever was on the original outgoing request. + headers.pop("Cookie", None) + + return headers + + def _redirect_stream( + self, request: Request, method: str + ) -> SyncByteStream | AsyncByteStream | None: + """ + Return the body that should be used for the redirect request. + """ + if method != request.method and method == "GET": + return None + + return request.stream + + def _set_timeout(self, request: Request) -> None: + if "timeout" not in request.extensions: + timeout = ( + self.timeout + if isinstance(self.timeout, UseClientDefault) + else Timeout(self.timeout) + ) + request.extensions = dict(**request.extensions, timeout=timeout.as_dict()) + + +class Client(BaseClient): + """ + An HTTP client, with connection pooling, HTTP/2, redirects, cookie persistence, etc. + + It can be shared between threads. + + Usage: + + ```python + >>> client = httpx.Client() + >>> response = client.get('https://example.org') + ``` + + **Parameters:** + + * **auth** - *(optional)* An authentication class to use when sending + requests. + * **params** - *(optional)* Query parameters to include in request URLs, as + a string, dictionary, or sequence of two-tuples. + * **headers** - *(optional)* Dictionary of HTTP headers to include when + sending requests. + * **cookies** - *(optional)* Dictionary of Cookie items to include when + sending requests. + * **verify** - *(optional)* Either `True` to use an SSL context with the + default CA bundle, `False` to disable verification, or an instance of + `ssl.SSLContext` to use a custom context. + * **http2** - *(optional)* A boolean indicating if HTTP/2 support should be + enabled. Defaults to `False`. + * **proxy** - *(optional)* A proxy URL where all the traffic should be routed. + * **timeout** - *(optional)* The timeout configuration to use when sending + requests. + * **limits** - *(optional)* The limits configuration to use. + * **max_redirects** - *(optional)* The maximum number of redirect responses + that should be followed. + * **base_url** - *(optional)* A URL to use as the base when building + request URLs. + * **transport** - *(optional)* A transport class to use for sending requests + over the network. + * **trust_env** - *(optional)* Enables or disables usage of environment + variables for configuration. + * **default_encoding** - *(optional)* The default encoding to use for decoding + response text, if no charset information is included in a response Content-Type + header. Set to a callable for automatic character set detection. Default: "utf-8". + """ + + def __init__( + self, + *, + auth: AuthTypes | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + verify: ssl.SSLContext | str | bool = True, + cert: CertTypes | None = None, + trust_env: bool = True, + http1: bool = True, + http2: bool = False, + proxy: ProxyTypes | None = None, + mounts: None | (typing.Mapping[str, BaseTransport | None]) = None, + timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, + follow_redirects: bool = False, + limits: Limits = DEFAULT_LIMITS, + max_redirects: int = DEFAULT_MAX_REDIRECTS, + event_hooks: None | (typing.Mapping[str, list[EventHook]]) = None, + base_url: URL | str = "", + transport: BaseTransport | None = None, + default_encoding: str | typing.Callable[[bytes], str] = "utf-8", + ) -> None: + super().__init__( + auth=auth, + params=params, + headers=headers, + cookies=cookies, + timeout=timeout, + follow_redirects=follow_redirects, + max_redirects=max_redirects, + event_hooks=event_hooks, + base_url=base_url, + trust_env=trust_env, + default_encoding=default_encoding, + ) + + if http2: + try: + import h2 # noqa + except ImportError: # pragma: no cover + raise ImportError( + "Using http2=True, but the 'h2' package is not installed. " + "Make sure to install httpx using `pip install httpx[http2]`." + ) from None + + allow_env_proxies = trust_env and transport is None + proxy_map = self._get_proxy_map(proxy, allow_env_proxies) + + self._transport = self._init_transport( + verify=verify, + cert=cert, + trust_env=trust_env, + http1=http1, + http2=http2, + limits=limits, + transport=transport, + ) + self._mounts: dict[URLPattern, BaseTransport | None] = { + URLPattern(key): None + if proxy is None + else self._init_proxy_transport( + proxy, + verify=verify, + cert=cert, + trust_env=trust_env, + http1=http1, + http2=http2, + limits=limits, + ) + for key, proxy in proxy_map.items() + } + if mounts is not None: + self._mounts.update( + {URLPattern(key): transport for key, transport in mounts.items()} + ) + + self._mounts = dict(sorted(self._mounts.items())) + + def _init_transport( + self, + verify: ssl.SSLContext | str | bool = True, + cert: CertTypes | None = None, + trust_env: bool = True, + http1: bool = True, + http2: bool = False, + limits: Limits = DEFAULT_LIMITS, + transport: BaseTransport | None = None, + ) -> BaseTransport: + if transport is not None: + return transport + + return HTTPTransport( + verify=verify, + cert=cert, + trust_env=trust_env, + http1=http1, + http2=http2, + limits=limits, + ) + + def _init_proxy_transport( + self, + proxy: Proxy, + verify: ssl.SSLContext | str | bool = True, + cert: CertTypes | None = None, + trust_env: bool = True, + http1: bool = True, + http2: bool = False, + limits: Limits = DEFAULT_LIMITS, + ) -> BaseTransport: + return HTTPTransport( + verify=verify, + cert=cert, + trust_env=trust_env, + http1=http1, + http2=http2, + limits=limits, + proxy=proxy, + ) + + def _transport_for_url(self, url: URL) -> BaseTransport: + """ + Returns the transport instance that should be used for a given URL. + This will either be the standard connection pool, or a proxy. + """ + for pattern, transport in self._mounts.items(): + if pattern.matches(url): + return self._transport if transport is None else transport + + return self._transport + + def request( + self, + method: str, + url: URL | str, + *, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Build and send a request. + + Equivalent to: + + ```python + request = client.build_request(...) + response = client.send(request, ...) + ``` + + See `Client.build_request()`, `Client.send()` and + [Merging of configuration][0] for how the various parameters + are merged with client-level configuration. + + [0]: /advanced/clients/#merging-of-configuration + """ + if cookies is not None: + message = ( + "Setting per-request cookies=<...> is being deprecated, because " + "the expected behaviour on cookie persistence is ambiguous. Set " + "cookies directly on the client instance instead." + ) + warnings.warn(message, DeprecationWarning, stacklevel=2) + + request = self.build_request( + method=method, + url=url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + cookies=cookies, + timeout=timeout, + extensions=extensions, + ) + return self.send(request, auth=auth, follow_redirects=follow_redirects) + + @contextmanager + def stream( + self, + method: str, + url: URL | str, + *, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> typing.Iterator[Response]: + """ + Alternative to `httpx.request()` that streams the response body + instead of loading it into memory at once. + + **Parameters**: See `httpx.request`. + + See also: [Streaming Responses][0] + + [0]: /quickstart#streaming-responses + """ + request = self.build_request( + method=method, + url=url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + cookies=cookies, + timeout=timeout, + extensions=extensions, + ) + response = self.send( + request=request, + auth=auth, + follow_redirects=follow_redirects, + stream=True, + ) + try: + yield response + finally: + response.close() + + def send( + self, + request: Request, + *, + stream: bool = False, + auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + ) -> Response: + """ + Send a request. + + The request is sent as-is, unmodified. + + Typically you'll want to build one with `Client.build_request()` + so that any client-level configuration is merged into the request, + but passing an explicit `httpx.Request()` is supported as well. + + See also: [Request instances][0] + + [0]: /advanced/clients/#request-instances + """ + if self._state == ClientState.CLOSED: + raise RuntimeError("Cannot send a request, as the client has been closed.") + + self._state = ClientState.OPENED + follow_redirects = ( + self.follow_redirects + if isinstance(follow_redirects, UseClientDefault) + else follow_redirects + ) + + self._set_timeout(request) + + auth = self._build_request_auth(request, auth) + + response = self._send_handling_auth( + request, + auth=auth, + follow_redirects=follow_redirects, + history=[], + ) + try: + if not stream: + response.read() + + return response + + except BaseException as exc: + response.close() + raise exc + + def _send_handling_auth( + self, + request: Request, + auth: Auth, + follow_redirects: bool, + history: list[Response], + ) -> Response: + auth_flow = auth.sync_auth_flow(request) + try: + request = next(auth_flow) + + while True: + response = self._send_handling_redirects( + request, + follow_redirects=follow_redirects, + history=history, + ) + try: + try: + next_request = auth_flow.send(response) + except StopIteration: + return response + + response.history = list(history) + response.read() + request = next_request + history.append(response) + + except BaseException as exc: + response.close() + raise exc + finally: + auth_flow.close() + + def _send_handling_redirects( + self, + request: Request, + follow_redirects: bool, + history: list[Response], + ) -> Response: + while True: + if len(history) > self.max_redirects: + raise TooManyRedirects( + "Exceeded maximum allowed redirects.", request=request + ) + + for hook in self._event_hooks["request"]: + hook(request) + + response = self._send_single_request(request) + try: + for hook in self._event_hooks["response"]: + hook(response) + response.history = list(history) + + if not response.has_redirect_location: + return response + + request = self._build_redirect_request(request, response) + history = history + [response] + + if follow_redirects: + response.read() + else: + response.next_request = request + return response + + except BaseException as exc: + response.close() + raise exc + + def _send_single_request(self, request: Request) -> Response: + """ + Sends a single request, without handling any redirections. + """ + transport = self._transport_for_url(request.url) + start = time.perf_counter() + + if not isinstance(request.stream, SyncByteStream): + raise RuntimeError( + "Attempted to send an async request with a sync Client instance." + ) + + with request_context(request=request): + response = transport.handle_request(request) + + assert isinstance(response.stream, SyncByteStream) + + response.request = request + response.stream = BoundSyncStream( + response.stream, response=response, start=start + ) + self.cookies.extract_cookies(response) + response.default_encoding = self._default_encoding + + logger.info( + 'HTTP Request: %s %s "%s %d %s"', + request.method, + request.url, + response.http_version, + response.status_code, + response.reason_phrase, + ) + + return response + + def get( + self, + url: URL | str, + *, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Send a `GET` request. + + **Parameters**: See `httpx.request`. + """ + return self.request( + "GET", + url, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + follow_redirects=follow_redirects, + timeout=timeout, + extensions=extensions, + ) + + def options( + self, + url: URL | str, + *, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Send an `OPTIONS` request. + + **Parameters**: See `httpx.request`. + """ + return self.request( + "OPTIONS", + url, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + follow_redirects=follow_redirects, + timeout=timeout, + extensions=extensions, + ) + + def head( + self, + url: URL | str, + *, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Send a `HEAD` request. + + **Parameters**: See `httpx.request`. + """ + return self.request( + "HEAD", + url, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + follow_redirects=follow_redirects, + timeout=timeout, + extensions=extensions, + ) + + def post( + self, + url: URL | str, + *, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Send a `POST` request. + + **Parameters**: See `httpx.request`. + """ + return self.request( + "POST", + url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + follow_redirects=follow_redirects, + timeout=timeout, + extensions=extensions, + ) + + def put( + self, + url: URL | str, + *, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Send a `PUT` request. + + **Parameters**: See `httpx.request`. + """ + return self.request( + "PUT", + url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + follow_redirects=follow_redirects, + timeout=timeout, + extensions=extensions, + ) + + def patch( + self, + url: URL | str, + *, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Send a `PATCH` request. + + **Parameters**: See `httpx.request`. + """ + return self.request( + "PATCH", + url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + follow_redirects=follow_redirects, + timeout=timeout, + extensions=extensions, + ) + + def delete( + self, + url: URL | str, + *, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Send a `DELETE` request. + + **Parameters**: See `httpx.request`. + """ + return self.request( + "DELETE", + url, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + follow_redirects=follow_redirects, + timeout=timeout, + extensions=extensions, + ) + + def close(self) -> None: + """ + Close transport and proxies. + """ + if self._state != ClientState.CLOSED: + self._state = ClientState.CLOSED + + self._transport.close() + for transport in self._mounts.values(): + if transport is not None: + transport.close() + + def __enter__(self: T) -> T: + if self._state != ClientState.UNOPENED: + msg = { + ClientState.OPENED: "Cannot open a client instance more than once.", + ClientState.CLOSED: ( + "Cannot reopen a client instance, once it has been closed." + ), + }[self._state] + raise RuntimeError(msg) + + self._state = ClientState.OPENED + + self._transport.__enter__() + for transport in self._mounts.values(): + if transport is not None: + transport.__enter__() + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: TracebackType | None = None, + ) -> None: + self._state = ClientState.CLOSED + + self._transport.__exit__(exc_type, exc_value, traceback) + for transport in self._mounts.values(): + if transport is not None: + transport.__exit__(exc_type, exc_value, traceback) + + +class AsyncClient(BaseClient): + """ + An asynchronous HTTP client, with connection pooling, HTTP/2, redirects, + cookie persistence, etc. + + It can be shared between tasks. + + Usage: + + ```python + >>> async with httpx.AsyncClient() as client: + >>> response = await client.get('https://example.org') + ``` + + **Parameters:** + + * **auth** - *(optional)* An authentication class to use when sending + requests. + * **params** - *(optional)* Query parameters to include in request URLs, as + a string, dictionary, or sequence of two-tuples. + * **headers** - *(optional)* Dictionary of HTTP headers to include when + sending requests. + * **cookies** - *(optional)* Dictionary of Cookie items to include when + sending requests. + * **verify** - *(optional)* Either `True` to use an SSL context with the + default CA bundle, `False` to disable verification, or an instance of + `ssl.SSLContext` to use a custom context. + * **http2** - *(optional)* A boolean indicating if HTTP/2 support should be + enabled. Defaults to `False`. + * **proxy** - *(optional)* A proxy URL where all the traffic should be routed. + * **timeout** - *(optional)* The timeout configuration to use when sending + requests. + * **limits** - *(optional)* The limits configuration to use. + * **max_redirects** - *(optional)* The maximum number of redirect responses + that should be followed. + * **base_url** - *(optional)* A URL to use as the base when building + request URLs. + * **transport** - *(optional)* A transport class to use for sending requests + over the network. + * **trust_env** - *(optional)* Enables or disables usage of environment + variables for configuration. + * **default_encoding** - *(optional)* The default encoding to use for decoding + response text, if no charset information is included in a response Content-Type + header. Set to a callable for automatic character set detection. Default: "utf-8". + """ + + def __init__( + self, + *, + auth: AuthTypes | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + verify: ssl.SSLContext | str | bool = True, + cert: CertTypes | None = None, + http1: bool = True, + http2: bool = False, + proxy: ProxyTypes | None = None, + mounts: None | (typing.Mapping[str, AsyncBaseTransport | None]) = None, + timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, + follow_redirects: bool = False, + limits: Limits = DEFAULT_LIMITS, + max_redirects: int = DEFAULT_MAX_REDIRECTS, + event_hooks: None | (typing.Mapping[str, list[EventHook]]) = None, + base_url: URL | str = "", + transport: AsyncBaseTransport | None = None, + trust_env: bool = True, + default_encoding: str | typing.Callable[[bytes], str] = "utf-8", + ) -> None: + super().__init__( + auth=auth, + params=params, + headers=headers, + cookies=cookies, + timeout=timeout, + follow_redirects=follow_redirects, + max_redirects=max_redirects, + event_hooks=event_hooks, + base_url=base_url, + trust_env=trust_env, + default_encoding=default_encoding, + ) + + if http2: + try: + import h2 # noqa + except ImportError: # pragma: no cover + raise ImportError( + "Using http2=True, but the 'h2' package is not installed. " + "Make sure to install httpx using `pip install httpx[http2]`." + ) from None + + allow_env_proxies = trust_env and transport is None + proxy_map = self._get_proxy_map(proxy, allow_env_proxies) + + self._transport = self._init_transport( + verify=verify, + cert=cert, + trust_env=trust_env, + http1=http1, + http2=http2, + limits=limits, + transport=transport, + ) + + self._mounts: dict[URLPattern, AsyncBaseTransport | None] = { + URLPattern(key): None + if proxy is None + else self._init_proxy_transport( + proxy, + verify=verify, + cert=cert, + trust_env=trust_env, + http1=http1, + http2=http2, + limits=limits, + ) + for key, proxy in proxy_map.items() + } + if mounts is not None: + self._mounts.update( + {URLPattern(key): transport for key, transport in mounts.items()} + ) + self._mounts = dict(sorted(self._mounts.items())) + + def _init_transport( + self, + verify: ssl.SSLContext | str | bool = True, + cert: CertTypes | None = None, + trust_env: bool = True, + http1: bool = True, + http2: bool = False, + limits: Limits = DEFAULT_LIMITS, + transport: AsyncBaseTransport | None = None, + ) -> AsyncBaseTransport: + if transport is not None: + return transport + + return AsyncHTTPTransport( + verify=verify, + cert=cert, + trust_env=trust_env, + http1=http1, + http2=http2, + limits=limits, + ) + + def _init_proxy_transport( + self, + proxy: Proxy, + verify: ssl.SSLContext | str | bool = True, + cert: CertTypes | None = None, + trust_env: bool = True, + http1: bool = True, + http2: bool = False, + limits: Limits = DEFAULT_LIMITS, + ) -> AsyncBaseTransport: + return AsyncHTTPTransport( + verify=verify, + cert=cert, + trust_env=trust_env, + http1=http1, + http2=http2, + limits=limits, + proxy=proxy, + ) + + def _transport_for_url(self, url: URL) -> AsyncBaseTransport: + """ + Returns the transport instance that should be used for a given URL. + This will either be the standard connection pool, or a proxy. + """ + for pattern, transport in self._mounts.items(): + if pattern.matches(url): + return self._transport if transport is None else transport + + return self._transport + + async def request( + self, + method: str, + url: URL | str, + *, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Build and send a request. + + Equivalent to: + + ```python + request = client.build_request(...) + response = await client.send(request, ...) + ``` + + See `AsyncClient.build_request()`, `AsyncClient.send()` + and [Merging of configuration][0] for how the various parameters + are merged with client-level configuration. + + [0]: /advanced/clients/#merging-of-configuration + """ + + if cookies is not None: # pragma: no cover + message = ( + "Setting per-request cookies=<...> is being deprecated, because " + "the expected behaviour on cookie persistence is ambiguous. Set " + "cookies directly on the client instance instead." + ) + warnings.warn(message, DeprecationWarning, stacklevel=2) + + request = self.build_request( + method=method, + url=url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + cookies=cookies, + timeout=timeout, + extensions=extensions, + ) + return await self.send(request, auth=auth, follow_redirects=follow_redirects) + + @asynccontextmanager + async def stream( + self, + method: str, + url: URL | str, + *, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> typing.AsyncIterator[Response]: + """ + Alternative to `httpx.request()` that streams the response body + instead of loading it into memory at once. + + **Parameters**: See `httpx.request`. + + See also: [Streaming Responses][0] + + [0]: /quickstart#streaming-responses + """ + request = self.build_request( + method=method, + url=url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + cookies=cookies, + timeout=timeout, + extensions=extensions, + ) + response = await self.send( + request=request, + auth=auth, + follow_redirects=follow_redirects, + stream=True, + ) + try: + yield response + finally: + await response.aclose() + + async def send( + self, + request: Request, + *, + stream: bool = False, + auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + ) -> Response: + """ + Send a request. + + The request is sent as-is, unmodified. + + Typically you'll want to build one with `AsyncClient.build_request()` + so that any client-level configuration is merged into the request, + but passing an explicit `httpx.Request()` is supported as well. + + See also: [Request instances][0] + + [0]: /advanced/clients/#request-instances + """ + if self._state == ClientState.CLOSED: + raise RuntimeError("Cannot send a request, as the client has been closed.") + + self._state = ClientState.OPENED + follow_redirects = ( + self.follow_redirects + if isinstance(follow_redirects, UseClientDefault) + else follow_redirects + ) + + self._set_timeout(request) + + auth = self._build_request_auth(request, auth) + + response = await self._send_handling_auth( + request, + auth=auth, + follow_redirects=follow_redirects, + history=[], + ) + try: + if not stream: + await response.aread() + + return response + + except BaseException as exc: + await response.aclose() + raise exc + + async def _send_handling_auth( + self, + request: Request, + auth: Auth, + follow_redirects: bool, + history: list[Response], + ) -> Response: + auth_flow = auth.async_auth_flow(request) + try: + request = await auth_flow.__anext__() + + while True: + response = await self._send_handling_redirects( + request, + follow_redirects=follow_redirects, + history=history, + ) + try: + try: + next_request = await auth_flow.asend(response) + except StopAsyncIteration: + return response + + response.history = list(history) + await response.aread() + request = next_request + history.append(response) + + except BaseException as exc: + await response.aclose() + raise exc + finally: + await auth_flow.aclose() + + async def _send_handling_redirects( + self, + request: Request, + follow_redirects: bool, + history: list[Response], + ) -> Response: + while True: + if len(history) > self.max_redirects: + raise TooManyRedirects( + "Exceeded maximum allowed redirects.", request=request + ) + + for hook in self._event_hooks["request"]: + await hook(request) + + response = await self._send_single_request(request) + try: + for hook in self._event_hooks["response"]: + await hook(response) + + response.history = list(history) + + if not response.has_redirect_location: + return response + + request = self._build_redirect_request(request, response) + history = history + [response] + + if follow_redirects: + await response.aread() + else: + response.next_request = request + return response + + except BaseException as exc: + await response.aclose() + raise exc + + async def _send_single_request(self, request: Request) -> Response: + """ + Sends a single request, without handling any redirections. + """ + transport = self._transport_for_url(request.url) + start = time.perf_counter() + + if not isinstance(request.stream, AsyncByteStream): + raise RuntimeError( + "Attempted to send an sync request with an AsyncClient instance." + ) + + with request_context(request=request): + response = await transport.handle_async_request(request) + + assert isinstance(response.stream, AsyncByteStream) + response.request = request + response.stream = BoundAsyncStream( + response.stream, response=response, start=start + ) + self.cookies.extract_cookies(response) + response.default_encoding = self._default_encoding + + logger.info( + 'HTTP Request: %s %s "%s %d %s"', + request.method, + request.url, + response.http_version, + response.status_code, + response.reason_phrase, + ) + + return response + + async def get( + self, + url: URL | str, + *, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Send a `GET` request. + + **Parameters**: See `httpx.request`. + """ + return await self.request( + "GET", + url, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + follow_redirects=follow_redirects, + timeout=timeout, + extensions=extensions, + ) + + async def options( + self, + url: URL | str, + *, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Send an `OPTIONS` request. + + **Parameters**: See `httpx.request`. + """ + return await self.request( + "OPTIONS", + url, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + follow_redirects=follow_redirects, + timeout=timeout, + extensions=extensions, + ) + + async def head( + self, + url: URL | str, + *, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Send a `HEAD` request. + + **Parameters**: See `httpx.request`. + """ + return await self.request( + "HEAD", + url, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + follow_redirects=follow_redirects, + timeout=timeout, + extensions=extensions, + ) + + async def post( + self, + url: URL | str, + *, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Send a `POST` request. + + **Parameters**: See `httpx.request`. + """ + return await self.request( + "POST", + url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + follow_redirects=follow_redirects, + timeout=timeout, + extensions=extensions, + ) + + async def put( + self, + url: URL | str, + *, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Send a `PUT` request. + + **Parameters**: See `httpx.request`. + """ + return await self.request( + "PUT", + url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + follow_redirects=follow_redirects, + timeout=timeout, + extensions=extensions, + ) + + async def patch( + self, + url: URL | str, + *, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Send a `PATCH` request. + + **Parameters**: See `httpx.request`. + """ + return await self.request( + "PATCH", + url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + follow_redirects=follow_redirects, + timeout=timeout, + extensions=extensions, + ) + + async def delete( + self, + url: URL | str, + *, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, + follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, + timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, + extensions: RequestExtensions | None = None, + ) -> Response: + """ + Send a `DELETE` request. + + **Parameters**: See `httpx.request`. + """ + return await self.request( + "DELETE", + url, + params=params, + headers=headers, + cookies=cookies, + auth=auth, + follow_redirects=follow_redirects, + timeout=timeout, + extensions=extensions, + ) + + async def aclose(self) -> None: + """ + Close transport and proxies. + """ + if self._state != ClientState.CLOSED: + self._state = ClientState.CLOSED + + await self._transport.aclose() + for proxy in self._mounts.values(): + if proxy is not None: + await proxy.aclose() + + async def __aenter__(self: U) -> U: + if self._state != ClientState.UNOPENED: + msg = { + ClientState.OPENED: "Cannot open a client instance more than once.", + ClientState.CLOSED: ( + "Cannot reopen a client instance, once it has been closed." + ), + }[self._state] + raise RuntimeError(msg) + + self._state = ClientState.OPENED + + await self._transport.__aenter__() + for proxy in self._mounts.values(): + if proxy is not None: + await proxy.__aenter__() + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: TracebackType | None = None, + ) -> None: + self._state = ClientState.CLOSED + + await self._transport.__aexit__(exc_type, exc_value, traceback) + for proxy in self._mounts.values(): + if proxy is not None: + await proxy.__aexit__(exc_type, exc_value, traceback) diff --git a/.venv/lib/python3.13/site-packages/httpx/_config.py b/.venv/lib/python3.13/site-packages/httpx/_config.py new file mode 100644 index 0000000000000000000000000000000000000000..467a6c90ae269babe3af7963d9d7c78b9f012268 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_config.py @@ -0,0 +1,248 @@ +from __future__ import annotations + +import os +import typing + +from ._models import Headers +from ._types import CertTypes, HeaderTypes, TimeoutTypes +from ._urls import URL + +if typing.TYPE_CHECKING: + import ssl # pragma: no cover + +__all__ = ["Limits", "Proxy", "Timeout", "create_ssl_context"] + + +class UnsetType: + pass # pragma: no cover + + +UNSET = UnsetType() + + +def create_ssl_context( + verify: ssl.SSLContext | str | bool = True, + cert: CertTypes | None = None, + trust_env: bool = True, +) -> ssl.SSLContext: + import ssl + import warnings + + import certifi + + if verify is True: + if trust_env and os.environ.get("SSL_CERT_FILE"): # pragma: nocover + ctx = ssl.create_default_context(cafile=os.environ["SSL_CERT_FILE"]) + elif trust_env and os.environ.get("SSL_CERT_DIR"): # pragma: nocover + ctx = ssl.create_default_context(capath=os.environ["SSL_CERT_DIR"]) + else: + # Default case... + ctx = ssl.create_default_context(cafile=certifi.where()) + elif verify is False: + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + ctx.check_hostname = False + ctx.verify_mode = ssl.CERT_NONE + elif isinstance(verify, str): # pragma: nocover + message = ( + "`verify=` is deprecated. " + "Use `verify=ssl.create_default_context(cafile=...)` " + "or `verify=ssl.create_default_context(capath=...)` instead." + ) + warnings.warn(message, DeprecationWarning) + if os.path.isdir(verify): + return ssl.create_default_context(capath=verify) + return ssl.create_default_context(cafile=verify) + else: + ctx = verify + + if cert: # pragma: nocover + message = ( + "`cert=...` is deprecated. Use `verify=` instead," + "with `.load_cert_chain()` to configure the certificate chain." + ) + warnings.warn(message, DeprecationWarning) + if isinstance(cert, str): + ctx.load_cert_chain(cert) + else: + ctx.load_cert_chain(*cert) + + return ctx + + +class Timeout: + """ + Timeout configuration. + + **Usage**: + + Timeout(None) # No timeouts. + Timeout(5.0) # 5s timeout on all operations. + Timeout(None, connect=5.0) # 5s timeout on connect, no other timeouts. + Timeout(5.0, connect=10.0) # 10s timeout on connect. 5s timeout elsewhere. + Timeout(5.0, pool=None) # No timeout on acquiring connection from pool. + # 5s timeout elsewhere. + """ + + def __init__( + self, + timeout: TimeoutTypes | UnsetType = UNSET, + *, + connect: None | float | UnsetType = UNSET, + read: None | float | UnsetType = UNSET, + write: None | float | UnsetType = UNSET, + pool: None | float | UnsetType = UNSET, + ) -> None: + if isinstance(timeout, Timeout): + # Passed as a single explicit Timeout. + assert connect is UNSET + assert read is UNSET + assert write is UNSET + assert pool is UNSET + self.connect = timeout.connect # type: typing.Optional[float] + self.read = timeout.read # type: typing.Optional[float] + self.write = timeout.write # type: typing.Optional[float] + self.pool = timeout.pool # type: typing.Optional[float] + elif isinstance(timeout, tuple): + # Passed as a tuple. + self.connect = timeout[0] + self.read = timeout[1] + self.write = None if len(timeout) < 3 else timeout[2] + self.pool = None if len(timeout) < 4 else timeout[3] + elif not ( + isinstance(connect, UnsetType) + or isinstance(read, UnsetType) + or isinstance(write, UnsetType) + or isinstance(pool, UnsetType) + ): + self.connect = connect + self.read = read + self.write = write + self.pool = pool + else: + if isinstance(timeout, UnsetType): + raise ValueError( + "httpx.Timeout must either include a default, or set all " + "four parameters explicitly." + ) + self.connect = timeout if isinstance(connect, UnsetType) else connect + self.read = timeout if isinstance(read, UnsetType) else read + self.write = timeout if isinstance(write, UnsetType) else write + self.pool = timeout if isinstance(pool, UnsetType) else pool + + def as_dict(self) -> dict[str, float | None]: + return { + "connect": self.connect, + "read": self.read, + "write": self.write, + "pool": self.pool, + } + + def __eq__(self, other: typing.Any) -> bool: + return ( + isinstance(other, self.__class__) + and self.connect == other.connect + and self.read == other.read + and self.write == other.write + and self.pool == other.pool + ) + + def __repr__(self) -> str: + class_name = self.__class__.__name__ + if len({self.connect, self.read, self.write, self.pool}) == 1: + return f"{class_name}(timeout={self.connect})" + return ( + f"{class_name}(connect={self.connect}, " + f"read={self.read}, write={self.write}, pool={self.pool})" + ) + + +class Limits: + """ + Configuration for limits to various client behaviors. + + **Parameters:** + + * **max_connections** - The maximum number of concurrent connections that may be + established. + * **max_keepalive_connections** - Allow the connection pool to maintain + keep-alive connections below this point. Should be less than or equal + to `max_connections`. + * **keepalive_expiry** - Time limit on idle keep-alive connections in seconds. + """ + + def __init__( + self, + *, + max_connections: int | None = None, + max_keepalive_connections: int | None = None, + keepalive_expiry: float | None = 5.0, + ) -> None: + self.max_connections = max_connections + self.max_keepalive_connections = max_keepalive_connections + self.keepalive_expiry = keepalive_expiry + + def __eq__(self, other: typing.Any) -> bool: + return ( + isinstance(other, self.__class__) + and self.max_connections == other.max_connections + and self.max_keepalive_connections == other.max_keepalive_connections + and self.keepalive_expiry == other.keepalive_expiry + ) + + def __repr__(self) -> str: + class_name = self.__class__.__name__ + return ( + f"{class_name}(max_connections={self.max_connections}, " + f"max_keepalive_connections={self.max_keepalive_connections}, " + f"keepalive_expiry={self.keepalive_expiry})" + ) + + +class Proxy: + def __init__( + self, + url: URL | str, + *, + ssl_context: ssl.SSLContext | None = None, + auth: tuple[str, str] | None = None, + headers: HeaderTypes | None = None, + ) -> None: + url = URL(url) + headers = Headers(headers) + + if url.scheme not in ("http", "https", "socks5", "socks5h"): + raise ValueError(f"Unknown scheme for proxy URL {url!r}") + + if url.username or url.password: + # Remove any auth credentials from the URL. + auth = (url.username, url.password) + url = url.copy_with(username=None, password=None) + + self.url = url + self.auth = auth + self.headers = headers + self.ssl_context = ssl_context + + @property + def raw_auth(self) -> tuple[bytes, bytes] | None: + # The proxy authentication as raw bytes. + return ( + None + if self.auth is None + else (self.auth[0].encode("utf-8"), self.auth[1].encode("utf-8")) + ) + + def __repr__(self) -> str: + # The authentication is represented with the password component masked. + auth = (self.auth[0], "********") if self.auth else None + + # Build a nice concise representation. + url_str = f"{str(self.url)!r}" + auth_str = f", auth={auth!r}" if auth else "" + headers_str = f", headers={dict(self.headers)!r}" if self.headers else "" + return f"Proxy({url_str}{auth_str}{headers_str})" + + +DEFAULT_TIMEOUT_CONFIG = Timeout(timeout=5.0) +DEFAULT_LIMITS = Limits(max_connections=100, max_keepalive_connections=20) +DEFAULT_MAX_REDIRECTS = 20 diff --git a/.venv/lib/python3.13/site-packages/httpx/_content.py b/.venv/lib/python3.13/site-packages/httpx/_content.py new file mode 100644 index 0000000000000000000000000000000000000000..6f479a0885f723b7395843d41164a87041820776 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_content.py @@ -0,0 +1,240 @@ +from __future__ import annotations + +import inspect +import warnings +from json import dumps as json_dumps +from typing import ( + Any, + AsyncIterable, + AsyncIterator, + Iterable, + Iterator, + Mapping, +) +from urllib.parse import urlencode + +from ._exceptions import StreamClosed, StreamConsumed +from ._multipart import MultipartStream +from ._types import ( + AsyncByteStream, + RequestContent, + RequestData, + RequestFiles, + ResponseContent, + SyncByteStream, +) +from ._utils import peek_filelike_length, primitive_value_to_str + +__all__ = ["ByteStream"] + + +class ByteStream(AsyncByteStream, SyncByteStream): + def __init__(self, stream: bytes) -> None: + self._stream = stream + + def __iter__(self) -> Iterator[bytes]: + yield self._stream + + async def __aiter__(self) -> AsyncIterator[bytes]: + yield self._stream + + +class IteratorByteStream(SyncByteStream): + CHUNK_SIZE = 65_536 + + def __init__(self, stream: Iterable[bytes]) -> None: + self._stream = stream + self._is_stream_consumed = False + self._is_generator = inspect.isgenerator(stream) + + def __iter__(self) -> Iterator[bytes]: + if self._is_stream_consumed and self._is_generator: + raise StreamConsumed() + + self._is_stream_consumed = True + if hasattr(self._stream, "read"): + # File-like interfaces should use 'read' directly. + chunk = self._stream.read(self.CHUNK_SIZE) + while chunk: + yield chunk + chunk = self._stream.read(self.CHUNK_SIZE) + else: + # Otherwise iterate. + for part in self._stream: + yield part + + +class AsyncIteratorByteStream(AsyncByteStream): + CHUNK_SIZE = 65_536 + + def __init__(self, stream: AsyncIterable[bytes]) -> None: + self._stream = stream + self._is_stream_consumed = False + self._is_generator = inspect.isasyncgen(stream) + + async def __aiter__(self) -> AsyncIterator[bytes]: + if self._is_stream_consumed and self._is_generator: + raise StreamConsumed() + + self._is_stream_consumed = True + if hasattr(self._stream, "aread"): + # File-like interfaces should use 'aread' directly. + chunk = await self._stream.aread(self.CHUNK_SIZE) + while chunk: + yield chunk + chunk = await self._stream.aread(self.CHUNK_SIZE) + else: + # Otherwise iterate. + async for part in self._stream: + yield part + + +class UnattachedStream(AsyncByteStream, SyncByteStream): + """ + If a request or response is serialized using pickle, then it is no longer + attached to a stream for I/O purposes. Any stream operations should result + in `httpx.StreamClosed`. + """ + + def __iter__(self) -> Iterator[bytes]: + raise StreamClosed() + + async def __aiter__(self) -> AsyncIterator[bytes]: + raise StreamClosed() + yield b"" # pragma: no cover + + +def encode_content( + content: str | bytes | Iterable[bytes] | AsyncIterable[bytes], +) -> tuple[dict[str, str], SyncByteStream | AsyncByteStream]: + if isinstance(content, (bytes, str)): + body = content.encode("utf-8") if isinstance(content, str) else content + content_length = len(body) + headers = {"Content-Length": str(content_length)} if body else {} + return headers, ByteStream(body) + + elif isinstance(content, Iterable) and not isinstance(content, dict): + # `not isinstance(content, dict)` is a bit oddly specific, but it + # catches a case that's easy for users to make in error, and would + # otherwise pass through here, like any other bytes-iterable, + # because `dict` happens to be iterable. See issue #2491. + content_length_or_none = peek_filelike_length(content) + + if content_length_or_none is None: + headers = {"Transfer-Encoding": "chunked"} + else: + headers = {"Content-Length": str(content_length_or_none)} + return headers, IteratorByteStream(content) # type: ignore + + elif isinstance(content, AsyncIterable): + headers = {"Transfer-Encoding": "chunked"} + return headers, AsyncIteratorByteStream(content) + + raise TypeError(f"Unexpected type for 'content', {type(content)!r}") + + +def encode_urlencoded_data( + data: RequestData, +) -> tuple[dict[str, str], ByteStream]: + plain_data = [] + for key, value in data.items(): + if isinstance(value, (list, tuple)): + plain_data.extend([(key, primitive_value_to_str(item)) for item in value]) + else: + plain_data.append((key, primitive_value_to_str(value))) + body = urlencode(plain_data, doseq=True).encode("utf-8") + content_length = str(len(body)) + content_type = "application/x-www-form-urlencoded" + headers = {"Content-Length": content_length, "Content-Type": content_type} + return headers, ByteStream(body) + + +def encode_multipart_data( + data: RequestData, files: RequestFiles, boundary: bytes | None +) -> tuple[dict[str, str], MultipartStream]: + multipart = MultipartStream(data=data, files=files, boundary=boundary) + headers = multipart.get_headers() + return headers, multipart + + +def encode_text(text: str) -> tuple[dict[str, str], ByteStream]: + body = text.encode("utf-8") + content_length = str(len(body)) + content_type = "text/plain; charset=utf-8" + headers = {"Content-Length": content_length, "Content-Type": content_type} + return headers, ByteStream(body) + + +def encode_html(html: str) -> tuple[dict[str, str], ByteStream]: + body = html.encode("utf-8") + content_length = str(len(body)) + content_type = "text/html; charset=utf-8" + headers = {"Content-Length": content_length, "Content-Type": content_type} + return headers, ByteStream(body) + + +def encode_json(json: Any) -> tuple[dict[str, str], ByteStream]: + body = json_dumps( + json, ensure_ascii=False, separators=(",", ":"), allow_nan=False + ).encode("utf-8") + content_length = str(len(body)) + content_type = "application/json" + headers = {"Content-Length": content_length, "Content-Type": content_type} + return headers, ByteStream(body) + + +def encode_request( + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: Any | None = None, + boundary: bytes | None = None, +) -> tuple[dict[str, str], SyncByteStream | AsyncByteStream]: + """ + Handles encoding the given `content`, `data`, `files`, and `json`, + returning a two-tuple of (, ). + """ + if data is not None and not isinstance(data, Mapping): + # We prefer to separate `content=` + # for raw request content, and `data=
` for url encoded or + # multipart form content. + # + # However for compat with requests, we *do* still support + # `data=` usages. We deal with that case here, treating it + # as if `content=<...>` had been supplied instead. + message = "Use 'content=<...>' to upload raw bytes/text content." + warnings.warn(message, DeprecationWarning, stacklevel=2) + return encode_content(data) + + if content is not None: + return encode_content(content) + elif files: + return encode_multipart_data(data or {}, files, boundary) + elif data: + return encode_urlencoded_data(data) + elif json is not None: + return encode_json(json) + + return {}, ByteStream(b"") + + +def encode_response( + content: ResponseContent | None = None, + text: str | None = None, + html: str | None = None, + json: Any | None = None, +) -> tuple[dict[str, str], SyncByteStream | AsyncByteStream]: + """ + Handles encoding the given `content`, returning a two-tuple of + (, ). + """ + if content is not None: + return encode_content(content) + elif text is not None: + return encode_text(text) + elif html is not None: + return encode_html(html) + elif json is not None: + return encode_json(json) + + return {}, ByteStream(b"") diff --git a/.venv/lib/python3.13/site-packages/httpx/_decoders.py b/.venv/lib/python3.13/site-packages/httpx/_decoders.py new file mode 100644 index 0000000000000000000000000000000000000000..899dfada878e1181fca6d3c75a79526a076abb9e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_decoders.py @@ -0,0 +1,393 @@ +""" +Handlers for Content-Encoding. + +See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding +""" + +from __future__ import annotations + +import codecs +import io +import typing +import zlib + +from ._exceptions import DecodingError + +# Brotli support is optional +try: + # The C bindings in `brotli` are recommended for CPython. + import brotli +except ImportError: # pragma: no cover + try: + # The CFFI bindings in `brotlicffi` are recommended for PyPy + # and other environments. + import brotlicffi as brotli + except ImportError: + brotli = None + + +# Zstandard support is optional +try: + import zstandard +except ImportError: # pragma: no cover + zstandard = None # type: ignore + + +class ContentDecoder: + def decode(self, data: bytes) -> bytes: + raise NotImplementedError() # pragma: no cover + + def flush(self) -> bytes: + raise NotImplementedError() # pragma: no cover + + +class IdentityDecoder(ContentDecoder): + """ + Handle unencoded data. + """ + + def decode(self, data: bytes) -> bytes: + return data + + def flush(self) -> bytes: + return b"" + + +class DeflateDecoder(ContentDecoder): + """ + Handle 'deflate' decoding. + + See: https://stackoverflow.com/questions/1838699 + """ + + def __init__(self) -> None: + self.first_attempt = True + self.decompressor = zlib.decompressobj() + + def decode(self, data: bytes) -> bytes: + was_first_attempt = self.first_attempt + self.first_attempt = False + try: + return self.decompressor.decompress(data) + except zlib.error as exc: + if was_first_attempt: + self.decompressor = zlib.decompressobj(-zlib.MAX_WBITS) + return self.decode(data) + raise DecodingError(str(exc)) from exc + + def flush(self) -> bytes: + try: + return self.decompressor.flush() + except zlib.error as exc: # pragma: no cover + raise DecodingError(str(exc)) from exc + + +class GZipDecoder(ContentDecoder): + """ + Handle 'gzip' decoding. + + See: https://stackoverflow.com/questions/1838699 + """ + + def __init__(self) -> None: + self.decompressor = zlib.decompressobj(zlib.MAX_WBITS | 16) + + def decode(self, data: bytes) -> bytes: + try: + return self.decompressor.decompress(data) + except zlib.error as exc: + raise DecodingError(str(exc)) from exc + + def flush(self) -> bytes: + try: + return self.decompressor.flush() + except zlib.error as exc: # pragma: no cover + raise DecodingError(str(exc)) from exc + + +class BrotliDecoder(ContentDecoder): + """ + Handle 'brotli' decoding. + + Requires `pip install brotlipy`. See: https://brotlipy.readthedocs.io/ + or `pip install brotli`. See https://github.com/google/brotli + Supports both 'brotlipy' and 'Brotli' packages since they share an import + name. The top branches are for 'brotlipy' and bottom branches for 'Brotli' + """ + + def __init__(self) -> None: + if brotli is None: # pragma: no cover + raise ImportError( + "Using 'BrotliDecoder', but neither of the 'brotlicffi' or 'brotli' " + "packages have been installed. " + "Make sure to install httpx using `pip install httpx[brotli]`." + ) from None + + self.decompressor = brotli.Decompressor() + self.seen_data = False + self._decompress: typing.Callable[[bytes], bytes] + if hasattr(self.decompressor, "decompress"): + # The 'brotlicffi' package. + self._decompress = self.decompressor.decompress # pragma: no cover + else: + # The 'brotli' package. + self._decompress = self.decompressor.process # pragma: no cover + + def decode(self, data: bytes) -> bytes: + if not data: + return b"" + self.seen_data = True + try: + return self._decompress(data) + except brotli.error as exc: + raise DecodingError(str(exc)) from exc + + def flush(self) -> bytes: + if not self.seen_data: + return b"" + try: + if hasattr(self.decompressor, "finish"): + # Only available in the 'brotlicffi' package. + + # As the decompressor decompresses eagerly, this + # will never actually emit any data. However, it will potentially throw + # errors if a truncated or damaged data stream has been used. + self.decompressor.finish() # pragma: no cover + return b"" + except brotli.error as exc: # pragma: no cover + raise DecodingError(str(exc)) from exc + + +class ZStandardDecoder(ContentDecoder): + """ + Handle 'zstd' RFC 8878 decoding. + + Requires `pip install zstandard`. + Can be installed as a dependency of httpx using `pip install httpx[zstd]`. + """ + + # inspired by the ZstdDecoder implementation in urllib3 + def __init__(self) -> None: + if zstandard is None: # pragma: no cover + raise ImportError( + "Using 'ZStandardDecoder', ..." + "Make sure to install httpx using `pip install httpx[zstd]`." + ) from None + + self.decompressor = zstandard.ZstdDecompressor().decompressobj() + self.seen_data = False + + def decode(self, data: bytes) -> bytes: + assert zstandard is not None + self.seen_data = True + output = io.BytesIO() + try: + output.write(self.decompressor.decompress(data)) + while self.decompressor.eof and self.decompressor.unused_data: + unused_data = self.decompressor.unused_data + self.decompressor = zstandard.ZstdDecompressor().decompressobj() + output.write(self.decompressor.decompress(unused_data)) + except zstandard.ZstdError as exc: + raise DecodingError(str(exc)) from exc + return output.getvalue() + + def flush(self) -> bytes: + if not self.seen_data: + return b"" + ret = self.decompressor.flush() # note: this is a no-op + if not self.decompressor.eof: + raise DecodingError("Zstandard data is incomplete") # pragma: no cover + return bytes(ret) + + +class MultiDecoder(ContentDecoder): + """ + Handle the case where multiple encodings have been applied. + """ + + def __init__(self, children: typing.Sequence[ContentDecoder]) -> None: + """ + 'children' should be a sequence of decoders in the order in which + each was applied. + """ + # Note that we reverse the order for decoding. + self.children = list(reversed(children)) + + def decode(self, data: bytes) -> bytes: + for child in self.children: + data = child.decode(data) + return data + + def flush(self) -> bytes: + data = b"" + for child in self.children: + data = child.decode(data) + child.flush() + return data + + +class ByteChunker: + """ + Handles returning byte content in fixed-size chunks. + """ + + def __init__(self, chunk_size: int | None = None) -> None: + self._buffer = io.BytesIO() + self._chunk_size = chunk_size + + def decode(self, content: bytes) -> list[bytes]: + if self._chunk_size is None: + return [content] if content else [] + + self._buffer.write(content) + if self._buffer.tell() >= self._chunk_size: + value = self._buffer.getvalue() + chunks = [ + value[i : i + self._chunk_size] + for i in range(0, len(value), self._chunk_size) + ] + if len(chunks[-1]) == self._chunk_size: + self._buffer.seek(0) + self._buffer.truncate() + return chunks + else: + self._buffer.seek(0) + self._buffer.write(chunks[-1]) + self._buffer.truncate() + return chunks[:-1] + else: + return [] + + def flush(self) -> list[bytes]: + value = self._buffer.getvalue() + self._buffer.seek(0) + self._buffer.truncate() + return [value] if value else [] + + +class TextChunker: + """ + Handles returning text content in fixed-size chunks. + """ + + def __init__(self, chunk_size: int | None = None) -> None: + self._buffer = io.StringIO() + self._chunk_size = chunk_size + + def decode(self, content: str) -> list[str]: + if self._chunk_size is None: + return [content] if content else [] + + self._buffer.write(content) + if self._buffer.tell() >= self._chunk_size: + value = self._buffer.getvalue() + chunks = [ + value[i : i + self._chunk_size] + for i in range(0, len(value), self._chunk_size) + ] + if len(chunks[-1]) == self._chunk_size: + self._buffer.seek(0) + self._buffer.truncate() + return chunks + else: + self._buffer.seek(0) + self._buffer.write(chunks[-1]) + self._buffer.truncate() + return chunks[:-1] + else: + return [] + + def flush(self) -> list[str]: + value = self._buffer.getvalue() + self._buffer.seek(0) + self._buffer.truncate() + return [value] if value else [] + + +class TextDecoder: + """ + Handles incrementally decoding bytes into text + """ + + def __init__(self, encoding: str = "utf-8") -> None: + self.decoder = codecs.getincrementaldecoder(encoding)(errors="replace") + + def decode(self, data: bytes) -> str: + return self.decoder.decode(data) + + def flush(self) -> str: + return self.decoder.decode(b"", True) + + +class LineDecoder: + """ + Handles incrementally reading lines from text. + + Has the same behaviour as the stdllib splitlines, + but handling the input iteratively. + """ + + def __init__(self) -> None: + self.buffer: list[str] = [] + self.trailing_cr: bool = False + + def decode(self, text: str) -> list[str]: + # See https://docs.python.org/3/library/stdtypes.html#str.splitlines + NEWLINE_CHARS = "\n\r\x0b\x0c\x1c\x1d\x1e\x85\u2028\u2029" + + # We always push a trailing `\r` into the next decode iteration. + if self.trailing_cr: + text = "\r" + text + self.trailing_cr = False + if text.endswith("\r"): + self.trailing_cr = True + text = text[:-1] + + if not text: + # NOTE: the edge case input of empty text doesn't occur in practice, + # because other httpx internals filter out this value + return [] # pragma: no cover + + trailing_newline = text[-1] in NEWLINE_CHARS + lines = text.splitlines() + + if len(lines) == 1 and not trailing_newline: + # No new lines, buffer the input and continue. + self.buffer.append(lines[0]) + return [] + + if self.buffer: + # Include any existing buffer in the first portion of the + # splitlines result. + lines = ["".join(self.buffer) + lines[0]] + lines[1:] + self.buffer = [] + + if not trailing_newline: + # If the last segment of splitlines is not newline terminated, + # then drop it from our output and start a new buffer. + self.buffer = [lines.pop()] + + return lines + + def flush(self) -> list[str]: + if not self.buffer and not self.trailing_cr: + return [] + + lines = ["".join(self.buffer)] + self.buffer = [] + self.trailing_cr = False + return lines + + +SUPPORTED_DECODERS = { + "identity": IdentityDecoder, + "gzip": GZipDecoder, + "deflate": DeflateDecoder, + "br": BrotliDecoder, + "zstd": ZStandardDecoder, +} + + +if brotli is None: + SUPPORTED_DECODERS.pop("br") # pragma: no cover +if zstandard is None: + SUPPORTED_DECODERS.pop("zstd") # pragma: no cover diff --git a/.venv/lib/python3.13/site-packages/httpx/_exceptions.py b/.venv/lib/python3.13/site-packages/httpx/_exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..77f45a6d3986d15626fc8a5fd459d6a3e0fbe466 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_exceptions.py @@ -0,0 +1,379 @@ +""" +Our exception hierarchy: + +* HTTPError + x RequestError + + TransportError + - TimeoutException + · ConnectTimeout + · ReadTimeout + · WriteTimeout + · PoolTimeout + - NetworkError + · ConnectError + · ReadError + · WriteError + · CloseError + - ProtocolError + · LocalProtocolError + · RemoteProtocolError + - ProxyError + - UnsupportedProtocol + + DecodingError + + TooManyRedirects + x HTTPStatusError +* InvalidURL +* CookieConflict +* StreamError + x StreamConsumed + x StreamClosed + x ResponseNotRead + x RequestNotRead +""" + +from __future__ import annotations + +import contextlib +import typing + +if typing.TYPE_CHECKING: + from ._models import Request, Response # pragma: no cover + +__all__ = [ + "CloseError", + "ConnectError", + "ConnectTimeout", + "CookieConflict", + "DecodingError", + "HTTPError", + "HTTPStatusError", + "InvalidURL", + "LocalProtocolError", + "NetworkError", + "PoolTimeout", + "ProtocolError", + "ProxyError", + "ReadError", + "ReadTimeout", + "RemoteProtocolError", + "RequestError", + "RequestNotRead", + "ResponseNotRead", + "StreamClosed", + "StreamConsumed", + "StreamError", + "TimeoutException", + "TooManyRedirects", + "TransportError", + "UnsupportedProtocol", + "WriteError", + "WriteTimeout", +] + + +class HTTPError(Exception): + """ + Base class for `RequestError` and `HTTPStatusError`. + + Useful for `try...except` blocks when issuing a request, + and then calling `.raise_for_status()`. + + For example: + + ``` + try: + response = httpx.get("https://www.example.com") + response.raise_for_status() + except httpx.HTTPError as exc: + print(f"HTTP Exception for {exc.request.url} - {exc}") + ``` + """ + + def __init__(self, message: str) -> None: + super().__init__(message) + self._request: Request | None = None + + @property + def request(self) -> Request: + if self._request is None: + raise RuntimeError("The .request property has not been set.") + return self._request + + @request.setter + def request(self, request: Request) -> None: + self._request = request + + +class RequestError(HTTPError): + """ + Base class for all exceptions that may occur when issuing a `.request()`. + """ + + def __init__(self, message: str, *, request: Request | None = None) -> None: + super().__init__(message) + # At the point an exception is raised we won't typically have a request + # instance to associate it with. + # + # The 'request_context' context manager is used within the Client and + # Response methods in order to ensure that any raised exceptions + # have a `.request` property set on them. + self._request = request + + +class TransportError(RequestError): + """ + Base class for all exceptions that occur at the level of the Transport API. + """ + + +# Timeout exceptions... + + +class TimeoutException(TransportError): + """ + The base class for timeout errors. + + An operation has timed out. + """ + + +class ConnectTimeout(TimeoutException): + """ + Timed out while connecting to the host. + """ + + +class ReadTimeout(TimeoutException): + """ + Timed out while receiving data from the host. + """ + + +class WriteTimeout(TimeoutException): + """ + Timed out while sending data to the host. + """ + + +class PoolTimeout(TimeoutException): + """ + Timed out waiting to acquire a connection from the pool. + """ + + +# Core networking exceptions... + + +class NetworkError(TransportError): + """ + The base class for network-related errors. + + An error occurred while interacting with the network. + """ + + +class ReadError(NetworkError): + """ + Failed to receive data from the network. + """ + + +class WriteError(NetworkError): + """ + Failed to send data through the network. + """ + + +class ConnectError(NetworkError): + """ + Failed to establish a connection. + """ + + +class CloseError(NetworkError): + """ + Failed to close a connection. + """ + + +# Other transport exceptions... + + +class ProxyError(TransportError): + """ + An error occurred while establishing a proxy connection. + """ + + +class UnsupportedProtocol(TransportError): + """ + Attempted to make a request to an unsupported protocol. + + For example issuing a request to `ftp://www.example.com`. + """ + + +class ProtocolError(TransportError): + """ + The protocol was violated. + """ + + +class LocalProtocolError(ProtocolError): + """ + A protocol was violated by the client. + + For example if the user instantiated a `Request` instance explicitly, + failed to include the mandatory `Host:` header, and then issued it directly + using `client.send()`. + """ + + +class RemoteProtocolError(ProtocolError): + """ + The protocol was violated by the server. + + For example, returning malformed HTTP. + """ + + +# Other request exceptions... + + +class DecodingError(RequestError): + """ + Decoding of the response failed, due to a malformed encoding. + """ + + +class TooManyRedirects(RequestError): + """ + Too many redirects. + """ + + +# Client errors + + +class HTTPStatusError(HTTPError): + """ + The response had an error HTTP status of 4xx or 5xx. + + May be raised when calling `response.raise_for_status()` + """ + + def __init__(self, message: str, *, request: Request, response: Response) -> None: + super().__init__(message) + self.request = request + self.response = response + + +class InvalidURL(Exception): + """ + URL is improperly formed or cannot be parsed. + """ + + def __init__(self, message: str) -> None: + super().__init__(message) + + +class CookieConflict(Exception): + """ + Attempted to lookup a cookie by name, but multiple cookies existed. + + Can occur when calling `response.cookies.get(...)`. + """ + + def __init__(self, message: str) -> None: + super().__init__(message) + + +# Stream exceptions... + +# These may occur as the result of a programming error, by accessing +# the request/response stream in an invalid manner. + + +class StreamError(RuntimeError): + """ + The base class for stream exceptions. + + The developer made an error in accessing the request stream in + an invalid way. + """ + + def __init__(self, message: str) -> None: + super().__init__(message) + + +class StreamConsumed(StreamError): + """ + Attempted to read or stream content, but the content has already + been streamed. + """ + + def __init__(self) -> None: + message = ( + "Attempted to read or stream some content, but the content has " + "already been streamed. For requests, this could be due to passing " + "a generator as request content, and then receiving a redirect " + "response or a secondary request as part of an authentication flow." + "For responses, this could be due to attempting to stream the response " + "content more than once." + ) + super().__init__(message) + + +class StreamClosed(StreamError): + """ + Attempted to read or stream response content, but the request has been + closed. + """ + + def __init__(self) -> None: + message = ( + "Attempted to read or stream content, but the stream has " "been closed." + ) + super().__init__(message) + + +class ResponseNotRead(StreamError): + """ + Attempted to access streaming response content, without having called `read()`. + """ + + def __init__(self) -> None: + message = ( + "Attempted to access streaming response content," + " without having called `read()`." + ) + super().__init__(message) + + +class RequestNotRead(StreamError): + """ + Attempted to access streaming request content, without having called `read()`. + """ + + def __init__(self) -> None: + message = ( + "Attempted to access streaming request content," + " without having called `read()`." + ) + super().__init__(message) + + +@contextlib.contextmanager +def request_context( + request: Request | None = None, +) -> typing.Iterator[None]: + """ + A context manager that can be used to attach the given request context + to any `RequestError` exceptions that are raised within the block. + """ + try: + yield + except RequestError as exc: + if request is not None: + exc.request = request + raise exc diff --git a/.venv/lib/python3.13/site-packages/httpx/_main.py b/.venv/lib/python3.13/site-packages/httpx/_main.py new file mode 100644 index 0000000000000000000000000000000000000000..cffa4bb7db0f930f4db56653a061c4d7400ba4e6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_main.py @@ -0,0 +1,506 @@ +from __future__ import annotations + +import functools +import json +import sys +import typing + +import click +import pygments.lexers +import pygments.util +import rich.console +import rich.markup +import rich.progress +import rich.syntax +import rich.table + +from ._client import Client +from ._exceptions import RequestError +from ._models import Response +from ._status_codes import codes + +if typing.TYPE_CHECKING: + import httpcore # pragma: no cover + + +def print_help() -> None: + console = rich.console.Console() + + console.print("[bold]HTTPX :butterfly:", justify="center") + console.print() + console.print("A next generation HTTP client.", justify="center") + console.print() + console.print( + "Usage: [bold]httpx[/bold] [cyan] [OPTIONS][/cyan] ", justify="left" + ) + console.print() + + table = rich.table.Table.grid(padding=1, pad_edge=True) + table.add_column("Parameter", no_wrap=True, justify="left", style="bold") + table.add_column("Description") + table.add_row( + "-m, --method [cyan]METHOD", + "Request method, such as GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD.\n" + "[Default: GET, or POST if a request body is included]", + ) + table.add_row( + "-p, --params [cyan] ...", + "Query parameters to include in the request URL.", + ) + table.add_row( + "-c, --content [cyan]TEXT", "Byte content to include in the request body." + ) + table.add_row( + "-d, --data [cyan] ...", "Form data to include in the request body." + ) + table.add_row( + "-f, --files [cyan] ...", + "Form files to include in the request body.", + ) + table.add_row("-j, --json [cyan]TEXT", "JSON data to include in the request body.") + table.add_row( + "-h, --headers [cyan] ...", + "Include additional HTTP headers in the request.", + ) + table.add_row( + "--cookies [cyan] ...", "Cookies to include in the request." + ) + table.add_row( + "--auth [cyan]", + "Username and password to include in the request. Specify '-' for the password" + " to use a password prompt. Note that using --verbose/-v will expose" + " the Authorization header, including the password encoding" + " in a trivially reversible format.", + ) + + table.add_row( + "--proxy [cyan]URL", + "Send the request via a proxy. Should be the URL giving the proxy address.", + ) + + table.add_row( + "--timeout [cyan]FLOAT", + "Timeout value to use for network operations, such as establishing the" + " connection, reading some data, etc... [Default: 5.0]", + ) + + table.add_row("--follow-redirects", "Automatically follow redirects.") + table.add_row("--no-verify", "Disable SSL verification.") + table.add_row( + "--http2", "Send the request using HTTP/2, if the remote server supports it." + ) + + table.add_row( + "--download [cyan]FILE", + "Save the response content as a file, rather than displaying it.", + ) + + table.add_row("-v, --verbose", "Verbose output. Show request as well as response.") + table.add_row("--help", "Show this message and exit.") + console.print(table) + + +def get_lexer_for_response(response: Response) -> str: + content_type = response.headers.get("Content-Type") + if content_type is not None: + mime_type, _, _ = content_type.partition(";") + try: + return typing.cast( + str, pygments.lexers.get_lexer_for_mimetype(mime_type.strip()).name + ) + except pygments.util.ClassNotFound: # pragma: no cover + pass + return "" # pragma: no cover + + +def format_request_headers(request: httpcore.Request, http2: bool = False) -> str: + version = "HTTP/2" if http2 else "HTTP/1.1" + headers = [ + (name.lower() if http2 else name, value) for name, value in request.headers + ] + method = request.method.decode("ascii") + target = request.url.target.decode("ascii") + lines = [f"{method} {target} {version}"] + [ + f"{name.decode('ascii')}: {value.decode('ascii')}" for name, value in headers + ] + return "\n".join(lines) + + +def format_response_headers( + http_version: bytes, + status: int, + reason_phrase: bytes | None, + headers: list[tuple[bytes, bytes]], +) -> str: + version = http_version.decode("ascii") + reason = ( + codes.get_reason_phrase(status) + if reason_phrase is None + else reason_phrase.decode("ascii") + ) + lines = [f"{version} {status} {reason}"] + [ + f"{name.decode('ascii')}: {value.decode('ascii')}" for name, value in headers + ] + return "\n".join(lines) + + +def print_request_headers(request: httpcore.Request, http2: bool = False) -> None: + console = rich.console.Console() + http_text = format_request_headers(request, http2=http2) + syntax = rich.syntax.Syntax(http_text, "http", theme="ansi_dark", word_wrap=True) + console.print(syntax) + syntax = rich.syntax.Syntax("", "http", theme="ansi_dark", word_wrap=True) + console.print(syntax) + + +def print_response_headers( + http_version: bytes, + status: int, + reason_phrase: bytes | None, + headers: list[tuple[bytes, bytes]], +) -> None: + console = rich.console.Console() + http_text = format_response_headers(http_version, status, reason_phrase, headers) + syntax = rich.syntax.Syntax(http_text, "http", theme="ansi_dark", word_wrap=True) + console.print(syntax) + syntax = rich.syntax.Syntax("", "http", theme="ansi_dark", word_wrap=True) + console.print(syntax) + + +def print_response(response: Response) -> None: + console = rich.console.Console() + lexer_name = get_lexer_for_response(response) + if lexer_name: + if lexer_name.lower() == "json": + try: + data = response.json() + text = json.dumps(data, indent=4) + except ValueError: # pragma: no cover + text = response.text + else: + text = response.text + + syntax = rich.syntax.Syntax(text, lexer_name, theme="ansi_dark", word_wrap=True) + console.print(syntax) + else: + console.print(f"<{len(response.content)} bytes of binary data>") + + +_PCTRTT = typing.Tuple[typing.Tuple[str, str], ...] +_PCTRTTT = typing.Tuple[_PCTRTT, ...] +_PeerCertRetDictType = typing.Dict[str, typing.Union[str, _PCTRTTT, _PCTRTT]] + + +def format_certificate(cert: _PeerCertRetDictType) -> str: # pragma: no cover + lines = [] + for key, value in cert.items(): + if isinstance(value, (list, tuple)): + lines.append(f"* {key}:") + for item in value: + if key in ("subject", "issuer"): + for sub_item in item: + lines.append(f"* {sub_item[0]}: {sub_item[1]!r}") + elif isinstance(item, tuple) and len(item) == 2: + lines.append(f"* {item[0]}: {item[1]!r}") + else: + lines.append(f"* {item!r}") + else: + lines.append(f"* {key}: {value!r}") + return "\n".join(lines) + + +def trace( + name: str, info: typing.Mapping[str, typing.Any], verbose: bool = False +) -> None: + console = rich.console.Console() + if name == "connection.connect_tcp.started" and verbose: + host = info["host"] + console.print(f"* Connecting to {host!r}") + elif name == "connection.connect_tcp.complete" and verbose: + stream = info["return_value"] + server_addr = stream.get_extra_info("server_addr") + console.print(f"* Connected to {server_addr[0]!r} on port {server_addr[1]}") + elif name == "connection.start_tls.complete" and verbose: # pragma: no cover + stream = info["return_value"] + ssl_object = stream.get_extra_info("ssl_object") + version = ssl_object.version() + cipher = ssl_object.cipher() + server_cert = ssl_object.getpeercert() + alpn = ssl_object.selected_alpn_protocol() + console.print(f"* SSL established using {version!r} / {cipher[0]!r}") + console.print(f"* Selected ALPN protocol: {alpn!r}") + if server_cert: + console.print("* Server certificate:") + console.print(format_certificate(server_cert)) + elif name == "http11.send_request_headers.started" and verbose: + request = info["request"] + print_request_headers(request, http2=False) + elif name == "http2.send_request_headers.started" and verbose: # pragma: no cover + request = info["request"] + print_request_headers(request, http2=True) + elif name == "http11.receive_response_headers.complete": + http_version, status, reason_phrase, headers = info["return_value"] + print_response_headers(http_version, status, reason_phrase, headers) + elif name == "http2.receive_response_headers.complete": # pragma: no cover + status, headers = info["return_value"] + http_version = b"HTTP/2" + reason_phrase = None + print_response_headers(http_version, status, reason_phrase, headers) + + +def download_response(response: Response, download: typing.BinaryIO) -> None: + console = rich.console.Console() + console.print() + content_length = response.headers.get("Content-Length") + with rich.progress.Progress( + "[progress.description]{task.description}", + "[progress.percentage]{task.percentage:>3.0f}%", + rich.progress.BarColumn(bar_width=None), + rich.progress.DownloadColumn(), + rich.progress.TransferSpeedColumn(), + ) as progress: + description = f"Downloading [bold]{rich.markup.escape(download.name)}" + download_task = progress.add_task( + description, + total=int(content_length or 0), + start=content_length is not None, + ) + for chunk in response.iter_bytes(): + download.write(chunk) + progress.update(download_task, completed=response.num_bytes_downloaded) + + +def validate_json( + ctx: click.Context, + param: click.Option | click.Parameter, + value: typing.Any, +) -> typing.Any: + if value is None: + return None + + try: + return json.loads(value) + except json.JSONDecodeError: # pragma: no cover + raise click.BadParameter("Not valid JSON") + + +def validate_auth( + ctx: click.Context, + param: click.Option | click.Parameter, + value: typing.Any, +) -> typing.Any: + if value == (None, None): + return None + + username, password = value + if password == "-": # pragma: no cover + password = click.prompt("Password", hide_input=True) + return (username, password) + + +def handle_help( + ctx: click.Context, + param: click.Option | click.Parameter, + value: typing.Any, +) -> None: + if not value or ctx.resilient_parsing: + return + + print_help() + ctx.exit() + + +@click.command(add_help_option=False) +@click.argument("url", type=str) +@click.option( + "--method", + "-m", + "method", + type=str, + help=( + "Request method, such as GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD. " + "[Default: GET, or POST if a request body is included]" + ), +) +@click.option( + "--params", + "-p", + "params", + type=(str, str), + multiple=True, + help="Query parameters to include in the request URL.", +) +@click.option( + "--content", + "-c", + "content", + type=str, + help="Byte content to include in the request body.", +) +@click.option( + "--data", + "-d", + "data", + type=(str, str), + multiple=True, + help="Form data to include in the request body.", +) +@click.option( + "--files", + "-f", + "files", + type=(str, click.File(mode="rb")), + multiple=True, + help="Form files to include in the request body.", +) +@click.option( + "--json", + "-j", + "json", + type=str, + callback=validate_json, + help="JSON data to include in the request body.", +) +@click.option( + "--headers", + "-h", + "headers", + type=(str, str), + multiple=True, + help="Include additional HTTP headers in the request.", +) +@click.option( + "--cookies", + "cookies", + type=(str, str), + multiple=True, + help="Cookies to include in the request.", +) +@click.option( + "--auth", + "auth", + type=(str, str), + default=(None, None), + callback=validate_auth, + help=( + "Username and password to include in the request. " + "Specify '-' for the password to use a password prompt. " + "Note that using --verbose/-v will expose the Authorization header, " + "including the password encoding in a trivially reversible format." + ), +) +@click.option( + "--proxy", + "proxy", + type=str, + default=None, + help="Send the request via a proxy. Should be the URL giving the proxy address.", +) +@click.option( + "--timeout", + "timeout", + type=float, + default=5.0, + help=( + "Timeout value to use for network operations, such as establishing the " + "connection, reading some data, etc... [Default: 5.0]" + ), +) +@click.option( + "--follow-redirects", + "follow_redirects", + is_flag=True, + default=False, + help="Automatically follow redirects.", +) +@click.option( + "--no-verify", + "verify", + is_flag=True, + default=True, + help="Disable SSL verification.", +) +@click.option( + "--http2", + "http2", + type=bool, + is_flag=True, + default=False, + help="Send the request using HTTP/2, if the remote server supports it.", +) +@click.option( + "--download", + type=click.File("wb"), + help="Save the response content as a file, rather than displaying it.", +) +@click.option( + "--verbose", + "-v", + type=bool, + is_flag=True, + default=False, + help="Verbose. Show request as well as response.", +) +@click.option( + "--help", + is_flag=True, + is_eager=True, + expose_value=False, + callback=handle_help, + help="Show this message and exit.", +) +def main( + url: str, + method: str, + params: list[tuple[str, str]], + content: str, + data: list[tuple[str, str]], + files: list[tuple[str, click.File]], + json: str, + headers: list[tuple[str, str]], + cookies: list[tuple[str, str]], + auth: tuple[str, str] | None, + proxy: str, + timeout: float, + follow_redirects: bool, + verify: bool, + http2: bool, + download: typing.BinaryIO | None, + verbose: bool, +) -> None: + """ + An HTTP command line client. + Sends a request and displays the response. + """ + if not method: + method = "POST" if content or data or files or json else "GET" + + try: + with Client(proxy=proxy, timeout=timeout, http2=http2, verify=verify) as client: + with client.stream( + method, + url, + params=list(params), + content=content, + data=dict(data), + files=files, # type: ignore + json=json, + headers=headers, + cookies=dict(cookies), + auth=auth, + follow_redirects=follow_redirects, + extensions={"trace": functools.partial(trace, verbose=verbose)}, + ) as response: + if download is not None: + download_response(response, download) + else: + response.read() + if response.content: + print_response(response) + + except RequestError as exc: + console = rich.console.Console() + console.print(f"[red]{type(exc).__name__}[/red]: {exc}") + sys.exit(1) + + sys.exit(0 if response.is_success else 1) diff --git a/.venv/lib/python3.13/site-packages/httpx/_models.py b/.venv/lib/python3.13/site-packages/httpx/_models.py new file mode 100644 index 0000000000000000000000000000000000000000..67d74bf86bfc80e22d9a4a3153572845accd9039 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_models.py @@ -0,0 +1,1277 @@ +from __future__ import annotations + +import codecs +import datetime +import email.message +import json as jsonlib +import re +import typing +import urllib.request +from collections.abc import Mapping +from http.cookiejar import Cookie, CookieJar + +from ._content import ByteStream, UnattachedStream, encode_request, encode_response +from ._decoders import ( + SUPPORTED_DECODERS, + ByteChunker, + ContentDecoder, + IdentityDecoder, + LineDecoder, + MultiDecoder, + TextChunker, + TextDecoder, +) +from ._exceptions import ( + CookieConflict, + HTTPStatusError, + RequestNotRead, + ResponseNotRead, + StreamClosed, + StreamConsumed, + request_context, +) +from ._multipart import get_multipart_boundary_from_content_type +from ._status_codes import codes +from ._types import ( + AsyncByteStream, + CookieTypes, + HeaderTypes, + QueryParamTypes, + RequestContent, + RequestData, + RequestExtensions, + RequestFiles, + ResponseContent, + ResponseExtensions, + SyncByteStream, +) +from ._urls import URL +from ._utils import to_bytes_or_str, to_str + +__all__ = ["Cookies", "Headers", "Request", "Response"] + +SENSITIVE_HEADERS = {"authorization", "proxy-authorization"} + + +def _is_known_encoding(encoding: str) -> bool: + """ + Return `True` if `encoding` is a known codec. + """ + try: + codecs.lookup(encoding) + except LookupError: + return False + return True + + +def _normalize_header_key(key: str | bytes, encoding: str | None = None) -> bytes: + """ + Coerce str/bytes into a strictly byte-wise HTTP header key. + """ + return key if isinstance(key, bytes) else key.encode(encoding or "ascii") + + +def _normalize_header_value(value: str | bytes, encoding: str | None = None) -> bytes: + """ + Coerce str/bytes into a strictly byte-wise HTTP header value. + """ + if isinstance(value, bytes): + return value + if not isinstance(value, str): + raise TypeError(f"Header value must be str or bytes, not {type(value)}") + return value.encode(encoding or "ascii") + + +def _parse_content_type_charset(content_type: str) -> str | None: + # We used to use `cgi.parse_header()` here, but `cgi` became a dead battery. + # See: https://peps.python.org/pep-0594/#cgi + msg = email.message.Message() + msg["content-type"] = content_type + return msg.get_content_charset(failobj=None) + + +def _parse_header_links(value: str) -> list[dict[str, str]]: + """ + Returns a list of parsed link headers, for more info see: + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link + The generic syntax of those is: + Link: < uri-reference >; param1=value1; param2="value2" + So for instance: + Link; '; type="image/jpeg",;' + would return + [ + {"url": "http:/.../front.jpeg", "type": "image/jpeg"}, + {"url": "http://.../back.jpeg"}, + ] + :param value: HTTP Link entity-header field + :return: list of parsed link headers + """ + links: list[dict[str, str]] = [] + replace_chars = " '\"" + value = value.strip(replace_chars) + if not value: + return links + for val in re.split(", *<", value): + try: + url, params = val.split(";", 1) + except ValueError: + url, params = val, "" + link = {"url": url.strip("<> '\"")} + for param in params.split(";"): + try: + key, value = param.split("=") + except ValueError: + break + link[key.strip(replace_chars)] = value.strip(replace_chars) + links.append(link) + return links + + +def _obfuscate_sensitive_headers( + items: typing.Iterable[tuple[typing.AnyStr, typing.AnyStr]], +) -> typing.Iterator[tuple[typing.AnyStr, typing.AnyStr]]: + for k, v in items: + if to_str(k.lower()) in SENSITIVE_HEADERS: + v = to_bytes_or_str("[secure]", match_type_of=v) + yield k, v + + +class Headers(typing.MutableMapping[str, str]): + """ + HTTP headers, as a case-insensitive multi-dict. + """ + + def __init__( + self, + headers: HeaderTypes | None = None, + encoding: str | None = None, + ) -> None: + self._list = [] # type: typing.List[typing.Tuple[bytes, bytes, bytes]] + + if isinstance(headers, Headers): + self._list = list(headers._list) + elif isinstance(headers, Mapping): + for k, v in headers.items(): + bytes_key = _normalize_header_key(k, encoding) + bytes_value = _normalize_header_value(v, encoding) + self._list.append((bytes_key, bytes_key.lower(), bytes_value)) + elif headers is not None: + for k, v in headers: + bytes_key = _normalize_header_key(k, encoding) + bytes_value = _normalize_header_value(v, encoding) + self._list.append((bytes_key, bytes_key.lower(), bytes_value)) + + self._encoding = encoding + + @property + def encoding(self) -> str: + """ + Header encoding is mandated as ascii, but we allow fallbacks to utf-8 + or iso-8859-1. + """ + if self._encoding is None: + for encoding in ["ascii", "utf-8"]: + for key, value in self.raw: + try: + key.decode(encoding) + value.decode(encoding) + except UnicodeDecodeError: + break + else: + # The else block runs if 'break' did not occur, meaning + # all values fitted the encoding. + self._encoding = encoding + break + else: + # The ISO-8859-1 encoding covers all 256 code points in a byte, + # so will never raise decode errors. + self._encoding = "iso-8859-1" + return self._encoding + + @encoding.setter + def encoding(self, value: str) -> None: + self._encoding = value + + @property + def raw(self) -> list[tuple[bytes, bytes]]: + """ + Returns a list of the raw header items, as byte pairs. + """ + return [(raw_key, value) for raw_key, _, value in self._list] + + def keys(self) -> typing.KeysView[str]: + return {key.decode(self.encoding): None for _, key, value in self._list}.keys() + + def values(self) -> typing.ValuesView[str]: + values_dict: dict[str, str] = {} + for _, key, value in self._list: + str_key = key.decode(self.encoding) + str_value = value.decode(self.encoding) + if str_key in values_dict: + values_dict[str_key] += f", {str_value}" + else: + values_dict[str_key] = str_value + return values_dict.values() + + def items(self) -> typing.ItemsView[str, str]: + """ + Return `(key, value)` items of headers. Concatenate headers + into a single comma separated value when a key occurs multiple times. + """ + values_dict: dict[str, str] = {} + for _, key, value in self._list: + str_key = key.decode(self.encoding) + str_value = value.decode(self.encoding) + if str_key in values_dict: + values_dict[str_key] += f", {str_value}" + else: + values_dict[str_key] = str_value + return values_dict.items() + + def multi_items(self) -> list[tuple[str, str]]: + """ + Return a list of `(key, value)` pairs of headers. Allow multiple + occurrences of the same key without concatenating into a single + comma separated value. + """ + return [ + (key.decode(self.encoding), value.decode(self.encoding)) + for _, key, value in self._list + ] + + def get(self, key: str, default: typing.Any = None) -> typing.Any: + """ + Return a header value. If multiple occurrences of the header occur + then concatenate them together with commas. + """ + try: + return self[key] + except KeyError: + return default + + def get_list(self, key: str, split_commas: bool = False) -> list[str]: + """ + Return a list of all header values for a given key. + If `split_commas=True` is passed, then any comma separated header + values are split into multiple return strings. + """ + get_header_key = key.lower().encode(self.encoding) + + values = [ + item_value.decode(self.encoding) + for _, item_key, item_value in self._list + if item_key.lower() == get_header_key + ] + + if not split_commas: + return values + + split_values = [] + for value in values: + split_values.extend([item.strip() for item in value.split(",")]) + return split_values + + def update(self, headers: HeaderTypes | None = None) -> None: # type: ignore + headers = Headers(headers) + for key in headers.keys(): + if key in self: + self.pop(key) + self._list.extend(headers._list) + + def copy(self) -> Headers: + return Headers(self, encoding=self.encoding) + + def __getitem__(self, key: str) -> str: + """ + Return a single header value. + + If there are multiple headers with the same key, then we concatenate + them with commas. See: https://tools.ietf.org/html/rfc7230#section-3.2.2 + """ + normalized_key = key.lower().encode(self.encoding) + + items = [ + header_value.decode(self.encoding) + for _, header_key, header_value in self._list + if header_key == normalized_key + ] + + if items: + return ", ".join(items) + + raise KeyError(key) + + def __setitem__(self, key: str, value: str) -> None: + """ + Set the header `key` to `value`, removing any duplicate entries. + Retains insertion order. + """ + set_key = key.encode(self._encoding or "utf-8") + set_value = value.encode(self._encoding or "utf-8") + lookup_key = set_key.lower() + + found_indexes = [ + idx + for idx, (_, item_key, _) in enumerate(self._list) + if item_key == lookup_key + ] + + for idx in reversed(found_indexes[1:]): + del self._list[idx] + + if found_indexes: + idx = found_indexes[0] + self._list[idx] = (set_key, lookup_key, set_value) + else: + self._list.append((set_key, lookup_key, set_value)) + + def __delitem__(self, key: str) -> None: + """ + Remove the header `key`. + """ + del_key = key.lower().encode(self.encoding) + + pop_indexes = [ + idx + for idx, (_, item_key, _) in enumerate(self._list) + if item_key.lower() == del_key + ] + + if not pop_indexes: + raise KeyError(key) + + for idx in reversed(pop_indexes): + del self._list[idx] + + def __contains__(self, key: typing.Any) -> bool: + header_key = key.lower().encode(self.encoding) + return header_key in [key for _, key, _ in self._list] + + def __iter__(self) -> typing.Iterator[typing.Any]: + return iter(self.keys()) + + def __len__(self) -> int: + return len(self._list) + + def __eq__(self, other: typing.Any) -> bool: + try: + other_headers = Headers(other) + except ValueError: + return False + + self_list = [(key, value) for _, key, value in self._list] + other_list = [(key, value) for _, key, value in other_headers._list] + return sorted(self_list) == sorted(other_list) + + def __repr__(self) -> str: + class_name = self.__class__.__name__ + + encoding_str = "" + if self.encoding != "ascii": + encoding_str = f", encoding={self.encoding!r}" + + as_list = list(_obfuscate_sensitive_headers(self.multi_items())) + as_dict = dict(as_list) + + no_duplicate_keys = len(as_dict) == len(as_list) + if no_duplicate_keys: + return f"{class_name}({as_dict!r}{encoding_str})" + return f"{class_name}({as_list!r}{encoding_str})" + + +class Request: + def __init__( + self, + method: str, + url: URL | str, + *, + params: QueryParamTypes | None = None, + headers: HeaderTypes | None = None, + cookies: CookieTypes | None = None, + content: RequestContent | None = None, + data: RequestData | None = None, + files: RequestFiles | None = None, + json: typing.Any | None = None, + stream: SyncByteStream | AsyncByteStream | None = None, + extensions: RequestExtensions | None = None, + ) -> None: + self.method = method.upper() + self.url = URL(url) if params is None else URL(url, params=params) + self.headers = Headers(headers) + self.extensions = {} if extensions is None else dict(extensions) + + if cookies: + Cookies(cookies).set_cookie_header(self) + + if stream is None: + content_type: str | None = self.headers.get("content-type") + headers, stream = encode_request( + content=content, + data=data, + files=files, + json=json, + boundary=get_multipart_boundary_from_content_type( + content_type=content_type.encode(self.headers.encoding) + if content_type + else None + ), + ) + self._prepare(headers) + self.stream = stream + # Load the request body, except for streaming content. + if isinstance(stream, ByteStream): + self.read() + else: + # There's an important distinction between `Request(content=...)`, + # and `Request(stream=...)`. + # + # Using `content=...` implies automatically populated `Host` and content + # headers, of either `Content-Length: ...` or `Transfer-Encoding: chunked`. + # + # Using `stream=...` will not automatically include *any* + # auto-populated headers. + # + # As an end-user you don't really need `stream=...`. It's only + # useful when: + # + # * Preserving the request stream when copying requests, eg for redirects. + # * Creating request instances on the *server-side* of the transport API. + self.stream = stream + + def _prepare(self, default_headers: dict[str, str]) -> None: + for key, value in default_headers.items(): + # Ignore Transfer-Encoding if the Content-Length has been set explicitly. + if key.lower() == "transfer-encoding" and "Content-Length" in self.headers: + continue + self.headers.setdefault(key, value) + + auto_headers: list[tuple[bytes, bytes]] = [] + + has_host = "Host" in self.headers + has_content_length = ( + "Content-Length" in self.headers or "Transfer-Encoding" in self.headers + ) + + if not has_host and self.url.host: + auto_headers.append((b"Host", self.url.netloc)) + if not has_content_length and self.method in ("POST", "PUT", "PATCH"): + auto_headers.append((b"Content-Length", b"0")) + + self.headers = Headers(auto_headers + self.headers.raw) + + @property + def content(self) -> bytes: + if not hasattr(self, "_content"): + raise RequestNotRead() + return self._content + + def read(self) -> bytes: + """ + Read and return the request content. + """ + if not hasattr(self, "_content"): + assert isinstance(self.stream, typing.Iterable) + self._content = b"".join(self.stream) + if not isinstance(self.stream, ByteStream): + # If a streaming request has been read entirely into memory, then + # we can replace the stream with a raw bytes implementation, + # to ensure that any non-replayable streams can still be used. + self.stream = ByteStream(self._content) + return self._content + + async def aread(self) -> bytes: + """ + Read and return the request content. + """ + if not hasattr(self, "_content"): + assert isinstance(self.stream, typing.AsyncIterable) + self._content = b"".join([part async for part in self.stream]) + if not isinstance(self.stream, ByteStream): + # If a streaming request has been read entirely into memory, then + # we can replace the stream with a raw bytes implementation, + # to ensure that any non-replayable streams can still be used. + self.stream = ByteStream(self._content) + return self._content + + def __repr__(self) -> str: + class_name = self.__class__.__name__ + url = str(self.url) + return f"<{class_name}({self.method!r}, {url!r})>" + + def __getstate__(self) -> dict[str, typing.Any]: + return { + name: value + for name, value in self.__dict__.items() + if name not in ["extensions", "stream"] + } + + def __setstate__(self, state: dict[str, typing.Any]) -> None: + for name, value in state.items(): + setattr(self, name, value) + self.extensions = {} + self.stream = UnattachedStream() + + +class Response: + def __init__( + self, + status_code: int, + *, + headers: HeaderTypes | None = None, + content: ResponseContent | None = None, + text: str | None = None, + html: str | None = None, + json: typing.Any = None, + stream: SyncByteStream | AsyncByteStream | None = None, + request: Request | None = None, + extensions: ResponseExtensions | None = None, + history: list[Response] | None = None, + default_encoding: str | typing.Callable[[bytes], str] = "utf-8", + ) -> None: + self.status_code = status_code + self.headers = Headers(headers) + + self._request: Request | None = request + + # When follow_redirects=False and a redirect is received, + # the client will set `response.next_request`. + self.next_request: Request | None = None + + self.extensions = {} if extensions is None else dict(extensions) + self.history = [] if history is None else list(history) + + self.is_closed = False + self.is_stream_consumed = False + + self.default_encoding = default_encoding + + if stream is None: + headers, stream = encode_response(content, text, html, json) + self._prepare(headers) + self.stream = stream + if isinstance(stream, ByteStream): + # Load the response body, except for streaming content. + self.read() + else: + # There's an important distinction between `Response(content=...)`, + # and `Response(stream=...)`. + # + # Using `content=...` implies automatically populated content headers, + # of either `Content-Length: ...` or `Transfer-Encoding: chunked`. + # + # Using `stream=...` will not automatically include any content headers. + # + # As an end-user you don't really need `stream=...`. It's only + # useful when creating response instances having received a stream + # from the transport API. + self.stream = stream + + self._num_bytes_downloaded = 0 + + def _prepare(self, default_headers: dict[str, str]) -> None: + for key, value in default_headers.items(): + # Ignore Transfer-Encoding if the Content-Length has been set explicitly. + if key.lower() == "transfer-encoding" and "content-length" in self.headers: + continue + self.headers.setdefault(key, value) + + @property + def elapsed(self) -> datetime.timedelta: + """ + Returns the time taken for the complete request/response + cycle to complete. + """ + if not hasattr(self, "_elapsed"): + raise RuntimeError( + "'.elapsed' may only be accessed after the response " + "has been read or closed." + ) + return self._elapsed + + @elapsed.setter + def elapsed(self, elapsed: datetime.timedelta) -> None: + self._elapsed = elapsed + + @property + def request(self) -> Request: + """ + Returns the request instance associated to the current response. + """ + if self._request is None: + raise RuntimeError( + "The request instance has not been set on this response." + ) + return self._request + + @request.setter + def request(self, value: Request) -> None: + self._request = value + + @property + def http_version(self) -> str: + try: + http_version: bytes = self.extensions["http_version"] + except KeyError: + return "HTTP/1.1" + else: + return http_version.decode("ascii", errors="ignore") + + @property + def reason_phrase(self) -> str: + try: + reason_phrase: bytes = self.extensions["reason_phrase"] + except KeyError: + return codes.get_reason_phrase(self.status_code) + else: + return reason_phrase.decode("ascii", errors="ignore") + + @property + def url(self) -> URL: + """ + Returns the URL for which the request was made. + """ + return self.request.url + + @property + def content(self) -> bytes: + if not hasattr(self, "_content"): + raise ResponseNotRead() + return self._content + + @property + def text(self) -> str: + if not hasattr(self, "_text"): + content = self.content + if not content: + self._text = "" + else: + decoder = TextDecoder(encoding=self.encoding or "utf-8") + self._text = "".join([decoder.decode(self.content), decoder.flush()]) + return self._text + + @property + def encoding(self) -> str | None: + """ + Return an encoding to use for decoding the byte content into text. + The priority for determining this is given by... + + * `.encoding = <>` has been set explicitly. + * The encoding as specified by the charset parameter in the Content-Type header. + * The encoding as determined by `default_encoding`, which may either be + a string like "utf-8" indicating the encoding to use, or may be a callable + which enables charset autodetection. + """ + if not hasattr(self, "_encoding"): + encoding = self.charset_encoding + if encoding is None or not _is_known_encoding(encoding): + if isinstance(self.default_encoding, str): + encoding = self.default_encoding + elif hasattr(self, "_content"): + encoding = self.default_encoding(self._content) + self._encoding = encoding or "utf-8" + return self._encoding + + @encoding.setter + def encoding(self, value: str) -> None: + """ + Set the encoding to use for decoding the byte content into text. + + If the `text` attribute has been accessed, attempting to set the + encoding will throw a ValueError. + """ + if hasattr(self, "_text"): + raise ValueError( + "Setting encoding after `text` has been accessed is not allowed." + ) + self._encoding = value + + @property + def charset_encoding(self) -> str | None: + """ + Return the encoding, as specified by the Content-Type header. + """ + content_type = self.headers.get("Content-Type") + if content_type is None: + return None + + return _parse_content_type_charset(content_type) + + def _get_content_decoder(self) -> ContentDecoder: + """ + Returns a decoder instance which can be used to decode the raw byte + content, depending on the Content-Encoding used in the response. + """ + if not hasattr(self, "_decoder"): + decoders: list[ContentDecoder] = [] + values = self.headers.get_list("content-encoding", split_commas=True) + for value in values: + value = value.strip().lower() + try: + decoder_cls = SUPPORTED_DECODERS[value] + decoders.append(decoder_cls()) + except KeyError: + continue + + if len(decoders) == 1: + self._decoder = decoders[0] + elif len(decoders) > 1: + self._decoder = MultiDecoder(children=decoders) + else: + self._decoder = IdentityDecoder() + + return self._decoder + + @property + def is_informational(self) -> bool: + """ + A property which is `True` for 1xx status codes, `False` otherwise. + """ + return codes.is_informational(self.status_code) + + @property + def is_success(self) -> bool: + """ + A property which is `True` for 2xx status codes, `False` otherwise. + """ + return codes.is_success(self.status_code) + + @property + def is_redirect(self) -> bool: + """ + A property which is `True` for 3xx status codes, `False` otherwise. + + Note that not all responses with a 3xx status code indicate a URL redirect. + + Use `response.has_redirect_location` to determine responses with a properly + formed URL redirection. + """ + return codes.is_redirect(self.status_code) + + @property + def is_client_error(self) -> bool: + """ + A property which is `True` for 4xx status codes, `False` otherwise. + """ + return codes.is_client_error(self.status_code) + + @property + def is_server_error(self) -> bool: + """ + A property which is `True` for 5xx status codes, `False` otherwise. + """ + return codes.is_server_error(self.status_code) + + @property + def is_error(self) -> bool: + """ + A property which is `True` for 4xx and 5xx status codes, `False` otherwise. + """ + return codes.is_error(self.status_code) + + @property + def has_redirect_location(self) -> bool: + """ + Returns True for 3xx responses with a properly formed URL redirection, + `False` otherwise. + """ + return ( + self.status_code + in ( + # 301 (Cacheable redirect. Method may change to GET.) + codes.MOVED_PERMANENTLY, + # 302 (Uncacheable redirect. Method may change to GET.) + codes.FOUND, + # 303 (Client should make a GET or HEAD request.) + codes.SEE_OTHER, + # 307 (Equiv. 302, but retain method) + codes.TEMPORARY_REDIRECT, + # 308 (Equiv. 301, but retain method) + codes.PERMANENT_REDIRECT, + ) + and "Location" in self.headers + ) + + def raise_for_status(self) -> Response: + """ + Raise the `HTTPStatusError` if one occurred. + """ + request = self._request + if request is None: + raise RuntimeError( + "Cannot call `raise_for_status` as the request " + "instance has not been set on this response." + ) + + if self.is_success: + return self + + if self.has_redirect_location: + message = ( + "{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n" + "Redirect location: '{0.headers[location]}'\n" + "For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}" + ) + else: + message = ( + "{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n" + "For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}" + ) + + status_class = self.status_code // 100 + error_types = { + 1: "Informational response", + 3: "Redirect response", + 4: "Client error", + 5: "Server error", + } + error_type = error_types.get(status_class, "Invalid status code") + message = message.format(self, error_type=error_type) + raise HTTPStatusError(message, request=request, response=self) + + def json(self, **kwargs: typing.Any) -> typing.Any: + return jsonlib.loads(self.content, **kwargs) + + @property + def cookies(self) -> Cookies: + if not hasattr(self, "_cookies"): + self._cookies = Cookies() + self._cookies.extract_cookies(self) + return self._cookies + + @property + def links(self) -> dict[str | None, dict[str, str]]: + """ + Returns the parsed header links of the response, if any + """ + header = self.headers.get("link") + if header is None: + return {} + + return { + (link.get("rel") or link.get("url")): link + for link in _parse_header_links(header) + } + + @property + def num_bytes_downloaded(self) -> int: + return self._num_bytes_downloaded + + def __repr__(self) -> str: + return f"" + + def __getstate__(self) -> dict[str, typing.Any]: + return { + name: value + for name, value in self.__dict__.items() + if name not in ["extensions", "stream", "is_closed", "_decoder"] + } + + def __setstate__(self, state: dict[str, typing.Any]) -> None: + for name, value in state.items(): + setattr(self, name, value) + self.is_closed = True + self.extensions = {} + self.stream = UnattachedStream() + + def read(self) -> bytes: + """ + Read and return the response content. + """ + if not hasattr(self, "_content"): + self._content = b"".join(self.iter_bytes()) + return self._content + + def iter_bytes(self, chunk_size: int | None = None) -> typing.Iterator[bytes]: + """ + A byte-iterator over the decoded response content. + This allows us to handle gzip, deflate, brotli, and zstd encoded responses. + """ + if hasattr(self, "_content"): + chunk_size = len(self._content) if chunk_size is None else chunk_size + for i in range(0, len(self._content), max(chunk_size, 1)): + yield self._content[i : i + chunk_size] + else: + decoder = self._get_content_decoder() + chunker = ByteChunker(chunk_size=chunk_size) + with request_context(request=self._request): + for raw_bytes in self.iter_raw(): + decoded = decoder.decode(raw_bytes) + for chunk in chunker.decode(decoded): + yield chunk + decoded = decoder.flush() + for chunk in chunker.decode(decoded): + yield chunk # pragma: no cover + for chunk in chunker.flush(): + yield chunk + + def iter_text(self, chunk_size: int | None = None) -> typing.Iterator[str]: + """ + A str-iterator over the decoded response content + that handles both gzip, deflate, etc but also detects the content's + string encoding. + """ + decoder = TextDecoder(encoding=self.encoding or "utf-8") + chunker = TextChunker(chunk_size=chunk_size) + with request_context(request=self._request): + for byte_content in self.iter_bytes(): + text_content = decoder.decode(byte_content) + for chunk in chunker.decode(text_content): + yield chunk + text_content = decoder.flush() + for chunk in chunker.decode(text_content): + yield chunk # pragma: no cover + for chunk in chunker.flush(): + yield chunk + + def iter_lines(self) -> typing.Iterator[str]: + decoder = LineDecoder() + with request_context(request=self._request): + for text in self.iter_text(): + for line in decoder.decode(text): + yield line + for line in decoder.flush(): + yield line + + def iter_raw(self, chunk_size: int | None = None) -> typing.Iterator[bytes]: + """ + A byte-iterator over the raw response content. + """ + if self.is_stream_consumed: + raise StreamConsumed() + if self.is_closed: + raise StreamClosed() + if not isinstance(self.stream, SyncByteStream): + raise RuntimeError("Attempted to call a sync iterator on an async stream.") + + self.is_stream_consumed = True + self._num_bytes_downloaded = 0 + chunker = ByteChunker(chunk_size=chunk_size) + + with request_context(request=self._request): + for raw_stream_bytes in self.stream: + self._num_bytes_downloaded += len(raw_stream_bytes) + for chunk in chunker.decode(raw_stream_bytes): + yield chunk + + for chunk in chunker.flush(): + yield chunk + + self.close() + + def close(self) -> None: + """ + Close the response and release the connection. + Automatically called if the response body is read to completion. + """ + if not isinstance(self.stream, SyncByteStream): + raise RuntimeError("Attempted to call an sync close on an async stream.") + + if not self.is_closed: + self.is_closed = True + with request_context(request=self._request): + self.stream.close() + + async def aread(self) -> bytes: + """ + Read and return the response content. + """ + if not hasattr(self, "_content"): + self._content = b"".join([part async for part in self.aiter_bytes()]) + return self._content + + async def aiter_bytes( + self, chunk_size: int | None = None + ) -> typing.AsyncIterator[bytes]: + """ + A byte-iterator over the decoded response content. + This allows us to handle gzip, deflate, brotli, and zstd encoded responses. + """ + if hasattr(self, "_content"): + chunk_size = len(self._content) if chunk_size is None else chunk_size + for i in range(0, len(self._content), max(chunk_size, 1)): + yield self._content[i : i + chunk_size] + else: + decoder = self._get_content_decoder() + chunker = ByteChunker(chunk_size=chunk_size) + with request_context(request=self._request): + async for raw_bytes in self.aiter_raw(): + decoded = decoder.decode(raw_bytes) + for chunk in chunker.decode(decoded): + yield chunk + decoded = decoder.flush() + for chunk in chunker.decode(decoded): + yield chunk # pragma: no cover + for chunk in chunker.flush(): + yield chunk + + async def aiter_text( + self, chunk_size: int | None = None + ) -> typing.AsyncIterator[str]: + """ + A str-iterator over the decoded response content + that handles both gzip, deflate, etc but also detects the content's + string encoding. + """ + decoder = TextDecoder(encoding=self.encoding or "utf-8") + chunker = TextChunker(chunk_size=chunk_size) + with request_context(request=self._request): + async for byte_content in self.aiter_bytes(): + text_content = decoder.decode(byte_content) + for chunk in chunker.decode(text_content): + yield chunk + text_content = decoder.flush() + for chunk in chunker.decode(text_content): + yield chunk # pragma: no cover + for chunk in chunker.flush(): + yield chunk + + async def aiter_lines(self) -> typing.AsyncIterator[str]: + decoder = LineDecoder() + with request_context(request=self._request): + async for text in self.aiter_text(): + for line in decoder.decode(text): + yield line + for line in decoder.flush(): + yield line + + async def aiter_raw( + self, chunk_size: int | None = None + ) -> typing.AsyncIterator[bytes]: + """ + A byte-iterator over the raw response content. + """ + if self.is_stream_consumed: + raise StreamConsumed() + if self.is_closed: + raise StreamClosed() + if not isinstance(self.stream, AsyncByteStream): + raise RuntimeError("Attempted to call an async iterator on an sync stream.") + + self.is_stream_consumed = True + self._num_bytes_downloaded = 0 + chunker = ByteChunker(chunk_size=chunk_size) + + with request_context(request=self._request): + async for raw_stream_bytes in self.stream: + self._num_bytes_downloaded += len(raw_stream_bytes) + for chunk in chunker.decode(raw_stream_bytes): + yield chunk + + for chunk in chunker.flush(): + yield chunk + + await self.aclose() + + async def aclose(self) -> None: + """ + Close the response and release the connection. + Automatically called if the response body is read to completion. + """ + if not isinstance(self.stream, AsyncByteStream): + raise RuntimeError("Attempted to call an async close on an sync stream.") + + if not self.is_closed: + self.is_closed = True + with request_context(request=self._request): + await self.stream.aclose() + + +class Cookies(typing.MutableMapping[str, str]): + """ + HTTP Cookies, as a mutable mapping. + """ + + def __init__(self, cookies: CookieTypes | None = None) -> None: + if cookies is None or isinstance(cookies, dict): + self.jar = CookieJar() + if isinstance(cookies, dict): + for key, value in cookies.items(): + self.set(key, value) + elif isinstance(cookies, list): + self.jar = CookieJar() + for key, value in cookies: + self.set(key, value) + elif isinstance(cookies, Cookies): + self.jar = CookieJar() + for cookie in cookies.jar: + self.jar.set_cookie(cookie) + else: + self.jar = cookies + + def extract_cookies(self, response: Response) -> None: + """ + Loads any cookies based on the response `Set-Cookie` headers. + """ + urllib_response = self._CookieCompatResponse(response) + urllib_request = self._CookieCompatRequest(response.request) + + self.jar.extract_cookies(urllib_response, urllib_request) # type: ignore + + def set_cookie_header(self, request: Request) -> None: + """ + Sets an appropriate 'Cookie:' HTTP header on the `Request`. + """ + urllib_request = self._CookieCompatRequest(request) + self.jar.add_cookie_header(urllib_request) + + def set(self, name: str, value: str, domain: str = "", path: str = "/") -> None: + """ + Set a cookie value by name. May optionally include domain and path. + """ + kwargs = { + "version": 0, + "name": name, + "value": value, + "port": None, + "port_specified": False, + "domain": domain, + "domain_specified": bool(domain), + "domain_initial_dot": domain.startswith("."), + "path": path, + "path_specified": bool(path), + "secure": False, + "expires": None, + "discard": True, + "comment": None, + "comment_url": None, + "rest": {"HttpOnly": None}, + "rfc2109": False, + } + cookie = Cookie(**kwargs) # type: ignore + self.jar.set_cookie(cookie) + + def get( # type: ignore + self, + name: str, + default: str | None = None, + domain: str | None = None, + path: str | None = None, + ) -> str | None: + """ + Get a cookie by name. May optionally include domain and path + in order to specify exactly which cookie to retrieve. + """ + value = None + for cookie in self.jar: + if cookie.name == name: + if domain is None or cookie.domain == domain: + if path is None or cookie.path == path: + if value is not None: + message = f"Multiple cookies exist with name={name}" + raise CookieConflict(message) + value = cookie.value + + if value is None: + return default + return value + + def delete( + self, + name: str, + domain: str | None = None, + path: str | None = None, + ) -> None: + """ + Delete a cookie by name. May optionally include domain and path + in order to specify exactly which cookie to delete. + """ + if domain is not None and path is not None: + return self.jar.clear(domain, path, name) + + remove = [ + cookie + for cookie in self.jar + if cookie.name == name + and (domain is None or cookie.domain == domain) + and (path is None or cookie.path == path) + ] + + for cookie in remove: + self.jar.clear(cookie.domain, cookie.path, cookie.name) + + def clear(self, domain: str | None = None, path: str | None = None) -> None: + """ + Delete all cookies. Optionally include a domain and path in + order to only delete a subset of all the cookies. + """ + args = [] + if domain is not None: + args.append(domain) + if path is not None: + assert domain is not None + args.append(path) + self.jar.clear(*args) + + def update(self, cookies: CookieTypes | None = None) -> None: # type: ignore + cookies = Cookies(cookies) + for cookie in cookies.jar: + self.jar.set_cookie(cookie) + + def __setitem__(self, name: str, value: str) -> None: + return self.set(name, value) + + def __getitem__(self, name: str) -> str: + value = self.get(name) + if value is None: + raise KeyError(name) + return value + + def __delitem__(self, name: str) -> None: + return self.delete(name) + + def __len__(self) -> int: + return len(self.jar) + + def __iter__(self) -> typing.Iterator[str]: + return (cookie.name for cookie in self.jar) + + def __bool__(self) -> bool: + for _ in self.jar: + return True + return False + + def __repr__(self) -> str: + cookies_repr = ", ".join( + [ + f"" + for cookie in self.jar + ] + ) + + return f"" + + class _CookieCompatRequest(urllib.request.Request): + """ + Wraps a `Request` instance up in a compatibility interface suitable + for use with `CookieJar` operations. + """ + + def __init__(self, request: Request) -> None: + super().__init__( + url=str(request.url), + headers=dict(request.headers), + method=request.method, + ) + self.request = request + + def add_unredirected_header(self, key: str, value: str) -> None: + super().add_unredirected_header(key, value) + self.request.headers[key] = value + + class _CookieCompatResponse: + """ + Wraps a `Request` instance up in a compatibility interface suitable + for use with `CookieJar` operations. + """ + + def __init__(self, response: Response) -> None: + self.response = response + + def info(self) -> email.message.Message: + info = email.message.Message() + for key, value in self.response.headers.multi_items(): + # Note that setting `info[key]` here is an "append" operation, + # not a "replace" operation. + # https://docs.python.org/3/library/email.compat32-message.html#email.message.Message.__setitem__ + info[key] = value + return info diff --git a/.venv/lib/python3.13/site-packages/httpx/_multipart.py b/.venv/lib/python3.13/site-packages/httpx/_multipart.py new file mode 100644 index 0000000000000000000000000000000000000000..b4761af9b2cf384de5189269927d781a700dbe46 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_multipart.py @@ -0,0 +1,300 @@ +from __future__ import annotations + +import io +import mimetypes +import os +import re +import typing +from pathlib import Path + +from ._types import ( + AsyncByteStream, + FileContent, + FileTypes, + RequestData, + RequestFiles, + SyncByteStream, +) +from ._utils import ( + peek_filelike_length, + primitive_value_to_str, + to_bytes, +) + +_HTML5_FORM_ENCODING_REPLACEMENTS = {'"': "%22", "\\": "\\\\"} +_HTML5_FORM_ENCODING_REPLACEMENTS.update( + {chr(c): "%{:02X}".format(c) for c in range(0x1F + 1) if c != 0x1B} +) +_HTML5_FORM_ENCODING_RE = re.compile( + r"|".join([re.escape(c) for c in _HTML5_FORM_ENCODING_REPLACEMENTS.keys()]) +) + + +def _format_form_param(name: str, value: str) -> bytes: + """ + Encode a name/value pair within a multipart form. + """ + + def replacer(match: typing.Match[str]) -> str: + return _HTML5_FORM_ENCODING_REPLACEMENTS[match.group(0)] + + value = _HTML5_FORM_ENCODING_RE.sub(replacer, value) + return f'{name}="{value}"'.encode() + + +def _guess_content_type(filename: str | None) -> str | None: + """ + Guesses the mimetype based on a filename. Defaults to `application/octet-stream`. + + Returns `None` if `filename` is `None` or empty. + """ + if filename: + return mimetypes.guess_type(filename)[0] or "application/octet-stream" + return None + + +def get_multipart_boundary_from_content_type( + content_type: bytes | None, +) -> bytes | None: + if not content_type or not content_type.startswith(b"multipart/form-data"): + return None + # parse boundary according to + # https://www.rfc-editor.org/rfc/rfc2046#section-5.1.1 + if b";" in content_type: + for section in content_type.split(b";"): + if section.strip().lower().startswith(b"boundary="): + return section.strip()[len(b"boundary=") :].strip(b'"') + return None + + +class DataField: + """ + A single form field item, within a multipart form field. + """ + + def __init__(self, name: str, value: str | bytes | int | float | None) -> None: + if not isinstance(name, str): + raise TypeError( + f"Invalid type for name. Expected str, got {type(name)}: {name!r}" + ) + if value is not None and not isinstance(value, (str, bytes, int, float)): + raise TypeError( + "Invalid type for value. Expected primitive type," + f" got {type(value)}: {value!r}" + ) + self.name = name + self.value: str | bytes = ( + value if isinstance(value, bytes) else primitive_value_to_str(value) + ) + + def render_headers(self) -> bytes: + if not hasattr(self, "_headers"): + name = _format_form_param("name", self.name) + self._headers = b"".join( + [b"Content-Disposition: form-data; ", name, b"\r\n\r\n"] + ) + + return self._headers + + def render_data(self) -> bytes: + if not hasattr(self, "_data"): + self._data = to_bytes(self.value) + + return self._data + + def get_length(self) -> int: + headers = self.render_headers() + data = self.render_data() + return len(headers) + len(data) + + def render(self) -> typing.Iterator[bytes]: + yield self.render_headers() + yield self.render_data() + + +class FileField: + """ + A single file field item, within a multipart form field. + """ + + CHUNK_SIZE = 64 * 1024 + + def __init__(self, name: str, value: FileTypes) -> None: + self.name = name + + fileobj: FileContent + + headers: dict[str, str] = {} + content_type: str | None = None + + # This large tuple based API largely mirror's requests' API + # It would be good to think of better APIs for this that we could + # include in httpx 2.0 since variable length tuples(especially of 4 elements) + # are quite unwieldly + if isinstance(value, tuple): + if len(value) == 2: + # neither the 3rd parameter (content_type) nor the 4th (headers) + # was included + filename, fileobj = value + elif len(value) == 3: + filename, fileobj, content_type = value + else: + # all 4 parameters included + filename, fileobj, content_type, headers = value # type: ignore + else: + filename = Path(str(getattr(value, "name", "upload"))).name + fileobj = value + + if content_type is None: + content_type = _guess_content_type(filename) + + has_content_type_header = any("content-type" in key.lower() for key in headers) + if content_type is not None and not has_content_type_header: + # note that unlike requests, we ignore the content_type provided in the 3rd + # tuple element if it is also included in the headers requests does + # the opposite (it overwrites the headerwith the 3rd tuple element) + headers["Content-Type"] = content_type + + if isinstance(fileobj, io.StringIO): + raise TypeError( + "Multipart file uploads require 'io.BytesIO', not 'io.StringIO'." + ) + if isinstance(fileobj, io.TextIOBase): + raise TypeError( + "Multipart file uploads must be opened in binary mode, not text mode." + ) + + self.filename = filename + self.file = fileobj + self.headers = headers + + def get_length(self) -> int | None: + headers = self.render_headers() + + if isinstance(self.file, (str, bytes)): + return len(headers) + len(to_bytes(self.file)) + + file_length = peek_filelike_length(self.file) + + # If we can't determine the filesize without reading it into memory, + # then return `None` here, to indicate an unknown file length. + if file_length is None: + return None + + return len(headers) + file_length + + def render_headers(self) -> bytes: + if not hasattr(self, "_headers"): + parts = [ + b"Content-Disposition: form-data; ", + _format_form_param("name", self.name), + ] + if self.filename: + filename = _format_form_param("filename", self.filename) + parts.extend([b"; ", filename]) + for header_name, header_value in self.headers.items(): + key, val = f"\r\n{header_name}: ".encode(), header_value.encode() + parts.extend([key, val]) + parts.append(b"\r\n\r\n") + self._headers = b"".join(parts) + + return self._headers + + def render_data(self) -> typing.Iterator[bytes]: + if isinstance(self.file, (str, bytes)): + yield to_bytes(self.file) + return + + if hasattr(self.file, "seek"): + try: + self.file.seek(0) + except io.UnsupportedOperation: + pass + + chunk = self.file.read(self.CHUNK_SIZE) + while chunk: + yield to_bytes(chunk) + chunk = self.file.read(self.CHUNK_SIZE) + + def render(self) -> typing.Iterator[bytes]: + yield self.render_headers() + yield from self.render_data() + + +class MultipartStream(SyncByteStream, AsyncByteStream): + """ + Request content as streaming multipart encoded form data. + """ + + def __init__( + self, + data: RequestData, + files: RequestFiles, + boundary: bytes | None = None, + ) -> None: + if boundary is None: + boundary = os.urandom(16).hex().encode("ascii") + + self.boundary = boundary + self.content_type = "multipart/form-data; boundary=%s" % boundary.decode( + "ascii" + ) + self.fields = list(self._iter_fields(data, files)) + + def _iter_fields( + self, data: RequestData, files: RequestFiles + ) -> typing.Iterator[FileField | DataField]: + for name, value in data.items(): + if isinstance(value, (tuple, list)): + for item in value: + yield DataField(name=name, value=item) + else: + yield DataField(name=name, value=value) + + file_items = files.items() if isinstance(files, typing.Mapping) else files + for name, value in file_items: + yield FileField(name=name, value=value) + + def iter_chunks(self) -> typing.Iterator[bytes]: + for field in self.fields: + yield b"--%s\r\n" % self.boundary + yield from field.render() + yield b"\r\n" + yield b"--%s--\r\n" % self.boundary + + def get_content_length(self) -> int | None: + """ + Return the length of the multipart encoded content, or `None` if + any of the files have a length that cannot be determined upfront. + """ + boundary_length = len(self.boundary) + length = 0 + + for field in self.fields: + field_length = field.get_length() + if field_length is None: + return None + + length += 2 + boundary_length + 2 # b"--{boundary}\r\n" + length += field_length + length += 2 # b"\r\n" + + length += 2 + boundary_length + 4 # b"--{boundary}--\r\n" + return length + + # Content stream interface. + + def get_headers(self) -> dict[str, str]: + content_length = self.get_content_length() + content_type = self.content_type + if content_length is None: + return {"Transfer-Encoding": "chunked", "Content-Type": content_type} + return {"Content-Length": str(content_length), "Content-Type": content_type} + + def __iter__(self) -> typing.Iterator[bytes]: + for chunk in self.iter_chunks(): + yield chunk + + async def __aiter__(self) -> typing.AsyncIterator[bytes]: + for chunk in self.iter_chunks(): + yield chunk diff --git a/.venv/lib/python3.13/site-packages/httpx/_status_codes.py b/.venv/lib/python3.13/site-packages/httpx/_status_codes.py new file mode 100644 index 0000000000000000000000000000000000000000..133a6231a5b53fd2f073799ca1bd07c50abe40ae --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_status_codes.py @@ -0,0 +1,162 @@ +from __future__ import annotations + +from enum import IntEnum + +__all__ = ["codes"] + + +class codes(IntEnum): + """HTTP status codes and reason phrases + + Status codes from the following RFCs are all observed: + + * RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616 + * RFC 6585: Additional HTTP Status Codes + * RFC 3229: Delta encoding in HTTP + * RFC 4918: HTTP Extensions for WebDAV, obsoletes 2518 + * RFC 5842: Binding Extensions to WebDAV + * RFC 7238: Permanent Redirect + * RFC 2295: Transparent Content Negotiation in HTTP + * RFC 2774: An HTTP Extension Framework + * RFC 7540: Hypertext Transfer Protocol Version 2 (HTTP/2) + * RFC 2324: Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0) + * RFC 7725: An HTTP Status Code to Report Legal Obstacles + * RFC 8297: An HTTP Status Code for Indicating Hints + * RFC 8470: Using Early Data in HTTP + """ + + def __new__(cls, value: int, phrase: str = "") -> codes: + obj = int.__new__(cls, value) + obj._value_ = value + + obj.phrase = phrase # type: ignore[attr-defined] + return obj + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def get_reason_phrase(cls, value: int) -> str: + try: + return codes(value).phrase # type: ignore + except ValueError: + return "" + + @classmethod + def is_informational(cls, value: int) -> bool: + """ + Returns `True` for 1xx status codes, `False` otherwise. + """ + return 100 <= value <= 199 + + @classmethod + def is_success(cls, value: int) -> bool: + """ + Returns `True` for 2xx status codes, `False` otherwise. + """ + return 200 <= value <= 299 + + @classmethod + def is_redirect(cls, value: int) -> bool: + """ + Returns `True` for 3xx status codes, `False` otherwise. + """ + return 300 <= value <= 399 + + @classmethod + def is_client_error(cls, value: int) -> bool: + """ + Returns `True` for 4xx status codes, `False` otherwise. + """ + return 400 <= value <= 499 + + @classmethod + def is_server_error(cls, value: int) -> bool: + """ + Returns `True` for 5xx status codes, `False` otherwise. + """ + return 500 <= value <= 599 + + @classmethod + def is_error(cls, value: int) -> bool: + """ + Returns `True` for 4xx or 5xx status codes, `False` otherwise. + """ + return 400 <= value <= 599 + + # informational + CONTINUE = 100, "Continue" + SWITCHING_PROTOCOLS = 101, "Switching Protocols" + PROCESSING = 102, "Processing" + EARLY_HINTS = 103, "Early Hints" + + # success + OK = 200, "OK" + CREATED = 201, "Created" + ACCEPTED = 202, "Accepted" + NON_AUTHORITATIVE_INFORMATION = 203, "Non-Authoritative Information" + NO_CONTENT = 204, "No Content" + RESET_CONTENT = 205, "Reset Content" + PARTIAL_CONTENT = 206, "Partial Content" + MULTI_STATUS = 207, "Multi-Status" + ALREADY_REPORTED = 208, "Already Reported" + IM_USED = 226, "IM Used" + + # redirection + MULTIPLE_CHOICES = 300, "Multiple Choices" + MOVED_PERMANENTLY = 301, "Moved Permanently" + FOUND = 302, "Found" + SEE_OTHER = 303, "See Other" + NOT_MODIFIED = 304, "Not Modified" + USE_PROXY = 305, "Use Proxy" + TEMPORARY_REDIRECT = 307, "Temporary Redirect" + PERMANENT_REDIRECT = 308, "Permanent Redirect" + + # client error + BAD_REQUEST = 400, "Bad Request" + UNAUTHORIZED = 401, "Unauthorized" + PAYMENT_REQUIRED = 402, "Payment Required" + FORBIDDEN = 403, "Forbidden" + NOT_FOUND = 404, "Not Found" + METHOD_NOT_ALLOWED = 405, "Method Not Allowed" + NOT_ACCEPTABLE = 406, "Not Acceptable" + PROXY_AUTHENTICATION_REQUIRED = 407, "Proxy Authentication Required" + REQUEST_TIMEOUT = 408, "Request Timeout" + CONFLICT = 409, "Conflict" + GONE = 410, "Gone" + LENGTH_REQUIRED = 411, "Length Required" + PRECONDITION_FAILED = 412, "Precondition Failed" + REQUEST_ENTITY_TOO_LARGE = 413, "Request Entity Too Large" + REQUEST_URI_TOO_LONG = 414, "Request-URI Too Long" + UNSUPPORTED_MEDIA_TYPE = 415, "Unsupported Media Type" + REQUESTED_RANGE_NOT_SATISFIABLE = 416, "Requested Range Not Satisfiable" + EXPECTATION_FAILED = 417, "Expectation Failed" + IM_A_TEAPOT = 418, "I'm a teapot" + MISDIRECTED_REQUEST = 421, "Misdirected Request" + UNPROCESSABLE_ENTITY = 422, "Unprocessable Entity" + LOCKED = 423, "Locked" + FAILED_DEPENDENCY = 424, "Failed Dependency" + TOO_EARLY = 425, "Too Early" + UPGRADE_REQUIRED = 426, "Upgrade Required" + PRECONDITION_REQUIRED = 428, "Precondition Required" + TOO_MANY_REQUESTS = 429, "Too Many Requests" + REQUEST_HEADER_FIELDS_TOO_LARGE = 431, "Request Header Fields Too Large" + UNAVAILABLE_FOR_LEGAL_REASONS = 451, "Unavailable For Legal Reasons" + + # server errors + INTERNAL_SERVER_ERROR = 500, "Internal Server Error" + NOT_IMPLEMENTED = 501, "Not Implemented" + BAD_GATEWAY = 502, "Bad Gateway" + SERVICE_UNAVAILABLE = 503, "Service Unavailable" + GATEWAY_TIMEOUT = 504, "Gateway Timeout" + HTTP_VERSION_NOT_SUPPORTED = 505, "HTTP Version Not Supported" + VARIANT_ALSO_NEGOTIATES = 506, "Variant Also Negotiates" + INSUFFICIENT_STORAGE = 507, "Insufficient Storage" + LOOP_DETECTED = 508, "Loop Detected" + NOT_EXTENDED = 510, "Not Extended" + NETWORK_AUTHENTICATION_REQUIRED = 511, "Network Authentication Required" + + +# Include lower-case styles for `requests` compatibility. +for code in codes: + setattr(codes, code._name_.lower(), int(code)) diff --git a/.venv/lib/python3.13/site-packages/httpx/_transports/__init__.py b/.venv/lib/python3.13/site-packages/httpx/_transports/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7a321053b29bcd48698cf2bd74a1d19c8556aefb --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_transports/__init__.py @@ -0,0 +1,15 @@ +from .asgi import * +from .base import * +from .default import * +from .mock import * +from .wsgi import * + +__all__ = [ + "ASGITransport", + "AsyncBaseTransport", + "BaseTransport", + "AsyncHTTPTransport", + "HTTPTransport", + "MockTransport", + "WSGITransport", +] diff --git a/.venv/lib/python3.13/site-packages/httpx/_transports/asgi.py b/.venv/lib/python3.13/site-packages/httpx/_transports/asgi.py new file mode 100644 index 0000000000000000000000000000000000000000..2bc4efae0e1b14620f75f712eb15ecf500d14eef --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_transports/asgi.py @@ -0,0 +1,187 @@ +from __future__ import annotations + +import typing + +from .._models import Request, Response +from .._types import AsyncByteStream +from .base import AsyncBaseTransport + +if typing.TYPE_CHECKING: # pragma: no cover + import asyncio + + import trio + + Event = typing.Union[asyncio.Event, trio.Event] + + +_Message = typing.MutableMapping[str, typing.Any] +_Receive = typing.Callable[[], typing.Awaitable[_Message]] +_Send = typing.Callable[ + [typing.MutableMapping[str, typing.Any]], typing.Awaitable[None] +] +_ASGIApp = typing.Callable[ + [typing.MutableMapping[str, typing.Any], _Receive, _Send], typing.Awaitable[None] +] + +__all__ = ["ASGITransport"] + + +def is_running_trio() -> bool: + try: + # sniffio is a dependency of trio. + + # See https://github.com/python-trio/trio/issues/2802 + import sniffio + + if sniffio.current_async_library() == "trio": + return True + except ImportError: # pragma: nocover + pass + + return False + + +def create_event() -> Event: + if is_running_trio(): + import trio + + return trio.Event() + + import asyncio + + return asyncio.Event() + + +class ASGIResponseStream(AsyncByteStream): + def __init__(self, body: list[bytes]) -> None: + self._body = body + + async def __aiter__(self) -> typing.AsyncIterator[bytes]: + yield b"".join(self._body) + + +class ASGITransport(AsyncBaseTransport): + """ + A custom AsyncTransport that handles sending requests directly to an ASGI app. + + ```python + transport = httpx.ASGITransport( + app=app, + root_path="/submount", + client=("1.2.3.4", 123) + ) + client = httpx.AsyncClient(transport=transport) + ``` + + Arguments: + + * `app` - The ASGI application. + * `raise_app_exceptions` - Boolean indicating if exceptions in the application + should be raised. Default to `True`. Can be set to `False` for use cases + such as testing the content of a client 500 response. + * `root_path` - The root path on which the ASGI application should be mounted. + * `client` - A two-tuple indicating the client IP and port of incoming requests. + ``` + """ + + def __init__( + self, + app: _ASGIApp, + raise_app_exceptions: bool = True, + root_path: str = "", + client: tuple[str, int] = ("127.0.0.1", 123), + ) -> None: + self.app = app + self.raise_app_exceptions = raise_app_exceptions + self.root_path = root_path + self.client = client + + async def handle_async_request( + self, + request: Request, + ) -> Response: + assert isinstance(request.stream, AsyncByteStream) + + # ASGI scope. + scope = { + "type": "http", + "asgi": {"version": "3.0"}, + "http_version": "1.1", + "method": request.method, + "headers": [(k.lower(), v) for (k, v) in request.headers.raw], + "scheme": request.url.scheme, + "path": request.url.path, + "raw_path": request.url.raw_path.split(b"?")[0], + "query_string": request.url.query, + "server": (request.url.host, request.url.port), + "client": self.client, + "root_path": self.root_path, + } + + # Request. + request_body_chunks = request.stream.__aiter__() + request_complete = False + + # Response. + status_code = None + response_headers = None + body_parts = [] + response_started = False + response_complete = create_event() + + # ASGI callables. + + async def receive() -> dict[str, typing.Any]: + nonlocal request_complete + + if request_complete: + await response_complete.wait() + return {"type": "http.disconnect"} + + try: + body = await request_body_chunks.__anext__() + except StopAsyncIteration: + request_complete = True + return {"type": "http.request", "body": b"", "more_body": False} + return {"type": "http.request", "body": body, "more_body": True} + + async def send(message: typing.MutableMapping[str, typing.Any]) -> None: + nonlocal status_code, response_headers, response_started + + if message["type"] == "http.response.start": + assert not response_started + + status_code = message["status"] + response_headers = message.get("headers", []) + response_started = True + + elif message["type"] == "http.response.body": + assert not response_complete.is_set() + body = message.get("body", b"") + more_body = message.get("more_body", False) + + if body and request.method != "HEAD": + body_parts.append(body) + + if not more_body: + response_complete.set() + + try: + await self.app(scope, receive, send) + except Exception: # noqa: PIE-786 + if self.raise_app_exceptions: + raise + + response_complete.set() + if status_code is None: + status_code = 500 + if response_headers is None: + response_headers = {} + + assert response_complete.is_set() + assert status_code is not None + assert response_headers is not None + + stream = ASGIResponseStream(body_parts) + + return Response(status_code, headers=response_headers, stream=stream) diff --git a/.venv/lib/python3.13/site-packages/httpx/_transports/base.py b/.venv/lib/python3.13/site-packages/httpx/_transports/base.py new file mode 100644 index 0000000000000000000000000000000000000000..66fd99d702480b555c06694fe14715ea6df3dfc3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_transports/base.py @@ -0,0 +1,86 @@ +from __future__ import annotations + +import typing +from types import TracebackType + +from .._models import Request, Response + +T = typing.TypeVar("T", bound="BaseTransport") +A = typing.TypeVar("A", bound="AsyncBaseTransport") + +__all__ = ["AsyncBaseTransport", "BaseTransport"] + + +class BaseTransport: + def __enter__(self: T) -> T: + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: TracebackType | None = None, + ) -> None: + self.close() + + def handle_request(self, request: Request) -> Response: + """ + Send a single HTTP request and return a response. + + Developers shouldn't typically ever need to call into this API directly, + since the Client class provides all the higher level user-facing API + niceties. + + In order to properly release any network resources, the response + stream should *either* be consumed immediately, with a call to + `response.stream.read()`, or else the `handle_request` call should + be followed with a try/finally block to ensuring the stream is + always closed. + + Example usage: + + with httpx.HTTPTransport() as transport: + req = httpx.Request( + method=b"GET", + url=(b"https", b"www.example.com", 443, b"/"), + headers=[(b"Host", b"www.example.com")], + ) + resp = transport.handle_request(req) + body = resp.stream.read() + print(resp.status_code, resp.headers, body) + + + Takes a `Request` instance as the only argument. + + Returns a `Response` instance. + """ + raise NotImplementedError( + "The 'handle_request' method must be implemented." + ) # pragma: no cover + + def close(self) -> None: + pass + + +class AsyncBaseTransport: + async def __aenter__(self: A) -> A: + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: TracebackType | None = None, + ) -> None: + await self.aclose() + + async def handle_async_request( + self, + request: Request, + ) -> Response: + raise NotImplementedError( + "The 'handle_async_request' method must be implemented." + ) # pragma: no cover + + async def aclose(self) -> None: + pass diff --git a/.venv/lib/python3.13/site-packages/httpx/_transports/default.py b/.venv/lib/python3.13/site-packages/httpx/_transports/default.py new file mode 100644 index 0000000000000000000000000000000000000000..d5aa05ff234fd3fbf4fee88c4a7d3e3c151a538f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_transports/default.py @@ -0,0 +1,406 @@ +""" +Custom transports, with nicely configured defaults. + +The following additional keyword arguments are currently supported by httpcore... + +* uds: str +* local_address: str +* retries: int + +Example usages... + +# Disable HTTP/2 on a single specific domain. +mounts = { + "all://": httpx.HTTPTransport(http2=True), + "all://*example.org": httpx.HTTPTransport() +} + +# Using advanced httpcore configuration, with connection retries. +transport = httpx.HTTPTransport(retries=1) +client = httpx.Client(transport=transport) + +# Using advanced httpcore configuration, with unix domain sockets. +transport = httpx.HTTPTransport(uds="socket.uds") +client = httpx.Client(transport=transport) +""" + +from __future__ import annotations + +import contextlib +import typing +from types import TracebackType + +if typing.TYPE_CHECKING: + import ssl # pragma: no cover + + import httpx # pragma: no cover + +from .._config import DEFAULT_LIMITS, Limits, Proxy, create_ssl_context +from .._exceptions import ( + ConnectError, + ConnectTimeout, + LocalProtocolError, + NetworkError, + PoolTimeout, + ProtocolError, + ProxyError, + ReadError, + ReadTimeout, + RemoteProtocolError, + TimeoutException, + UnsupportedProtocol, + WriteError, + WriteTimeout, +) +from .._models import Request, Response +from .._types import AsyncByteStream, CertTypes, ProxyTypes, SyncByteStream +from .._urls import URL +from .base import AsyncBaseTransport, BaseTransport + +T = typing.TypeVar("T", bound="HTTPTransport") +A = typing.TypeVar("A", bound="AsyncHTTPTransport") + +SOCKET_OPTION = typing.Union[ + typing.Tuple[int, int, int], + typing.Tuple[int, int, typing.Union[bytes, bytearray]], + typing.Tuple[int, int, None, int], +] + +__all__ = ["AsyncHTTPTransport", "HTTPTransport"] + +HTTPCORE_EXC_MAP: dict[type[Exception], type[httpx.HTTPError]] = {} + + +def _load_httpcore_exceptions() -> dict[type[Exception], type[httpx.HTTPError]]: + import httpcore + + return { + httpcore.TimeoutException: TimeoutException, + httpcore.ConnectTimeout: ConnectTimeout, + httpcore.ReadTimeout: ReadTimeout, + httpcore.WriteTimeout: WriteTimeout, + httpcore.PoolTimeout: PoolTimeout, + httpcore.NetworkError: NetworkError, + httpcore.ConnectError: ConnectError, + httpcore.ReadError: ReadError, + httpcore.WriteError: WriteError, + httpcore.ProxyError: ProxyError, + httpcore.UnsupportedProtocol: UnsupportedProtocol, + httpcore.ProtocolError: ProtocolError, + httpcore.LocalProtocolError: LocalProtocolError, + httpcore.RemoteProtocolError: RemoteProtocolError, + } + + +@contextlib.contextmanager +def map_httpcore_exceptions() -> typing.Iterator[None]: + global HTTPCORE_EXC_MAP + if len(HTTPCORE_EXC_MAP) == 0: + HTTPCORE_EXC_MAP = _load_httpcore_exceptions() + try: + yield + except Exception as exc: + mapped_exc = None + + for from_exc, to_exc in HTTPCORE_EXC_MAP.items(): + if not isinstance(exc, from_exc): + continue + # We want to map to the most specific exception we can find. + # Eg if `exc` is an `httpcore.ReadTimeout`, we want to map to + # `httpx.ReadTimeout`, not just `httpx.TimeoutException`. + if mapped_exc is None or issubclass(to_exc, mapped_exc): + mapped_exc = to_exc + + if mapped_exc is None: # pragma: no cover + raise + + message = str(exc) + raise mapped_exc(message) from exc + + +class ResponseStream(SyncByteStream): + def __init__(self, httpcore_stream: typing.Iterable[bytes]) -> None: + self._httpcore_stream = httpcore_stream + + def __iter__(self) -> typing.Iterator[bytes]: + with map_httpcore_exceptions(): + for part in self._httpcore_stream: + yield part + + def close(self) -> None: + if hasattr(self._httpcore_stream, "close"): + self._httpcore_stream.close() + + +class HTTPTransport(BaseTransport): + def __init__( + self, + verify: ssl.SSLContext | str | bool = True, + cert: CertTypes | None = None, + trust_env: bool = True, + http1: bool = True, + http2: bool = False, + limits: Limits = DEFAULT_LIMITS, + proxy: ProxyTypes | None = None, + uds: str | None = None, + local_address: str | None = None, + retries: int = 0, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> None: + import httpcore + + proxy = Proxy(url=proxy) if isinstance(proxy, (str, URL)) else proxy + ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env) + + if proxy is None: + self._pool = httpcore.ConnectionPool( + ssl_context=ssl_context, + max_connections=limits.max_connections, + max_keepalive_connections=limits.max_keepalive_connections, + keepalive_expiry=limits.keepalive_expiry, + http1=http1, + http2=http2, + uds=uds, + local_address=local_address, + retries=retries, + socket_options=socket_options, + ) + elif proxy.url.scheme in ("http", "https"): + self._pool = httpcore.HTTPProxy( + proxy_url=httpcore.URL( + scheme=proxy.url.raw_scheme, + host=proxy.url.raw_host, + port=proxy.url.port, + target=proxy.url.raw_path, + ), + proxy_auth=proxy.raw_auth, + proxy_headers=proxy.headers.raw, + ssl_context=ssl_context, + proxy_ssl_context=proxy.ssl_context, + max_connections=limits.max_connections, + max_keepalive_connections=limits.max_keepalive_connections, + keepalive_expiry=limits.keepalive_expiry, + http1=http1, + http2=http2, + socket_options=socket_options, + ) + elif proxy.url.scheme in ("socks5", "socks5h"): + try: + import socksio # noqa + except ImportError: # pragma: no cover + raise ImportError( + "Using SOCKS proxy, but the 'socksio' package is not installed. " + "Make sure to install httpx using `pip install httpx[socks]`." + ) from None + + self._pool = httpcore.SOCKSProxy( + proxy_url=httpcore.URL( + scheme=proxy.url.raw_scheme, + host=proxy.url.raw_host, + port=proxy.url.port, + target=proxy.url.raw_path, + ), + proxy_auth=proxy.raw_auth, + ssl_context=ssl_context, + max_connections=limits.max_connections, + max_keepalive_connections=limits.max_keepalive_connections, + keepalive_expiry=limits.keepalive_expiry, + http1=http1, + http2=http2, + ) + else: # pragma: no cover + raise ValueError( + "Proxy protocol must be either 'http', 'https', 'socks5', or 'socks5h'," + f" but got {proxy.url.scheme!r}." + ) + + def __enter__(self: T) -> T: # Use generics for subclass support. + self._pool.__enter__() + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: TracebackType | None = None, + ) -> None: + with map_httpcore_exceptions(): + self._pool.__exit__(exc_type, exc_value, traceback) + + def handle_request( + self, + request: Request, + ) -> Response: + assert isinstance(request.stream, SyncByteStream) + import httpcore + + req = httpcore.Request( + method=request.method, + url=httpcore.URL( + scheme=request.url.raw_scheme, + host=request.url.raw_host, + port=request.url.port, + target=request.url.raw_path, + ), + headers=request.headers.raw, + content=request.stream, + extensions=request.extensions, + ) + with map_httpcore_exceptions(): + resp = self._pool.handle_request(req) + + assert isinstance(resp.stream, typing.Iterable) + + return Response( + status_code=resp.status, + headers=resp.headers, + stream=ResponseStream(resp.stream), + extensions=resp.extensions, + ) + + def close(self) -> None: + self._pool.close() + + +class AsyncResponseStream(AsyncByteStream): + def __init__(self, httpcore_stream: typing.AsyncIterable[bytes]) -> None: + self._httpcore_stream = httpcore_stream + + async def __aiter__(self) -> typing.AsyncIterator[bytes]: + with map_httpcore_exceptions(): + async for part in self._httpcore_stream: + yield part + + async def aclose(self) -> None: + if hasattr(self._httpcore_stream, "aclose"): + await self._httpcore_stream.aclose() + + +class AsyncHTTPTransport(AsyncBaseTransport): + def __init__( + self, + verify: ssl.SSLContext | str | bool = True, + cert: CertTypes | None = None, + trust_env: bool = True, + http1: bool = True, + http2: bool = False, + limits: Limits = DEFAULT_LIMITS, + proxy: ProxyTypes | None = None, + uds: str | None = None, + local_address: str | None = None, + retries: int = 0, + socket_options: typing.Iterable[SOCKET_OPTION] | None = None, + ) -> None: + import httpcore + + proxy = Proxy(url=proxy) if isinstance(proxy, (str, URL)) else proxy + ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env) + + if proxy is None: + self._pool = httpcore.AsyncConnectionPool( + ssl_context=ssl_context, + max_connections=limits.max_connections, + max_keepalive_connections=limits.max_keepalive_connections, + keepalive_expiry=limits.keepalive_expiry, + http1=http1, + http2=http2, + uds=uds, + local_address=local_address, + retries=retries, + socket_options=socket_options, + ) + elif proxy.url.scheme in ("http", "https"): + self._pool = httpcore.AsyncHTTPProxy( + proxy_url=httpcore.URL( + scheme=proxy.url.raw_scheme, + host=proxy.url.raw_host, + port=proxy.url.port, + target=proxy.url.raw_path, + ), + proxy_auth=proxy.raw_auth, + proxy_headers=proxy.headers.raw, + proxy_ssl_context=proxy.ssl_context, + ssl_context=ssl_context, + max_connections=limits.max_connections, + max_keepalive_connections=limits.max_keepalive_connections, + keepalive_expiry=limits.keepalive_expiry, + http1=http1, + http2=http2, + socket_options=socket_options, + ) + elif proxy.url.scheme in ("socks5", "socks5h"): + try: + import socksio # noqa + except ImportError: # pragma: no cover + raise ImportError( + "Using SOCKS proxy, but the 'socksio' package is not installed. " + "Make sure to install httpx using `pip install httpx[socks]`." + ) from None + + self._pool = httpcore.AsyncSOCKSProxy( + proxy_url=httpcore.URL( + scheme=proxy.url.raw_scheme, + host=proxy.url.raw_host, + port=proxy.url.port, + target=proxy.url.raw_path, + ), + proxy_auth=proxy.raw_auth, + ssl_context=ssl_context, + max_connections=limits.max_connections, + max_keepalive_connections=limits.max_keepalive_connections, + keepalive_expiry=limits.keepalive_expiry, + http1=http1, + http2=http2, + ) + else: # pragma: no cover + raise ValueError( + "Proxy protocol must be either 'http', 'https', 'socks5', or 'socks5h'," + " but got {proxy.url.scheme!r}." + ) + + async def __aenter__(self: A) -> A: # Use generics for subclass support. + await self._pool.__aenter__() + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: TracebackType | None = None, + ) -> None: + with map_httpcore_exceptions(): + await self._pool.__aexit__(exc_type, exc_value, traceback) + + async def handle_async_request( + self, + request: Request, + ) -> Response: + assert isinstance(request.stream, AsyncByteStream) + import httpcore + + req = httpcore.Request( + method=request.method, + url=httpcore.URL( + scheme=request.url.raw_scheme, + host=request.url.raw_host, + port=request.url.port, + target=request.url.raw_path, + ), + headers=request.headers.raw, + content=request.stream, + extensions=request.extensions, + ) + with map_httpcore_exceptions(): + resp = await self._pool.handle_async_request(req) + + assert isinstance(resp.stream, typing.AsyncIterable) + + return Response( + status_code=resp.status, + headers=resp.headers, + stream=AsyncResponseStream(resp.stream), + extensions=resp.extensions, + ) + + async def aclose(self) -> None: + await self._pool.aclose() diff --git a/.venv/lib/python3.13/site-packages/httpx/_transports/mock.py b/.venv/lib/python3.13/site-packages/httpx/_transports/mock.py new file mode 100644 index 0000000000000000000000000000000000000000..8c418f59e06cae43abdbb626ec21cafc7e8c6277 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_transports/mock.py @@ -0,0 +1,43 @@ +from __future__ import annotations + +import typing + +from .._models import Request, Response +from .base import AsyncBaseTransport, BaseTransport + +SyncHandler = typing.Callable[[Request], Response] +AsyncHandler = typing.Callable[[Request], typing.Coroutine[None, None, Response]] + + +__all__ = ["MockTransport"] + + +class MockTransport(AsyncBaseTransport, BaseTransport): + def __init__(self, handler: SyncHandler | AsyncHandler) -> None: + self.handler = handler + + def handle_request( + self, + request: Request, + ) -> Response: + request.read() + response = self.handler(request) + if not isinstance(response, Response): # pragma: no cover + raise TypeError("Cannot use an async handler in a sync Client") + return response + + async def handle_async_request( + self, + request: Request, + ) -> Response: + await request.aread() + response = self.handler(request) + + # Allow handler to *optionally* be an `async` function. + # If it is, then the `response` variable need to be awaited to actually + # return the result. + + if not isinstance(response, Response): + response = await response + + return response diff --git a/.venv/lib/python3.13/site-packages/httpx/_transports/wsgi.py b/.venv/lib/python3.13/site-packages/httpx/_transports/wsgi.py new file mode 100644 index 0000000000000000000000000000000000000000..8592ffe017a87367cc7578184540096a9682908d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_transports/wsgi.py @@ -0,0 +1,149 @@ +from __future__ import annotations + +import io +import itertools +import sys +import typing + +from .._models import Request, Response +from .._types import SyncByteStream +from .base import BaseTransport + +if typing.TYPE_CHECKING: + from _typeshed import OptExcInfo # pragma: no cover + from _typeshed.wsgi import WSGIApplication # pragma: no cover + +_T = typing.TypeVar("_T") + + +__all__ = ["WSGITransport"] + + +def _skip_leading_empty_chunks(body: typing.Iterable[_T]) -> typing.Iterable[_T]: + body = iter(body) + for chunk in body: + if chunk: + return itertools.chain([chunk], body) + return [] + + +class WSGIByteStream(SyncByteStream): + def __init__(self, result: typing.Iterable[bytes]) -> None: + self._close = getattr(result, "close", None) + self._result = _skip_leading_empty_chunks(result) + + def __iter__(self) -> typing.Iterator[bytes]: + for part in self._result: + yield part + + def close(self) -> None: + if self._close is not None: + self._close() + + +class WSGITransport(BaseTransport): + """ + A custom transport that handles sending requests directly to an WSGI app. + The simplest way to use this functionality is to use the `app` argument. + + ``` + client = httpx.Client(app=app) + ``` + + Alternatively, you can setup the transport instance explicitly. + This allows you to include any additional configuration arguments specific + to the WSGITransport class: + + ``` + transport = httpx.WSGITransport( + app=app, + script_name="/submount", + remote_addr="1.2.3.4" + ) + client = httpx.Client(transport=transport) + ``` + + Arguments: + + * `app` - The WSGI application. + * `raise_app_exceptions` - Boolean indicating if exceptions in the application + should be raised. Default to `True`. Can be set to `False` for use cases + such as testing the content of a client 500 response. + * `script_name` - The root path on which the WSGI application should be mounted. + * `remote_addr` - A string indicating the client IP of incoming requests. + ``` + """ + + def __init__( + self, + app: WSGIApplication, + raise_app_exceptions: bool = True, + script_name: str = "", + remote_addr: str = "127.0.0.1", + wsgi_errors: typing.TextIO | None = None, + ) -> None: + self.app = app + self.raise_app_exceptions = raise_app_exceptions + self.script_name = script_name + self.remote_addr = remote_addr + self.wsgi_errors = wsgi_errors + + def handle_request(self, request: Request) -> Response: + request.read() + wsgi_input = io.BytesIO(request.content) + + port = request.url.port or {"http": 80, "https": 443}[request.url.scheme] + environ = { + "wsgi.version": (1, 0), + "wsgi.url_scheme": request.url.scheme, + "wsgi.input": wsgi_input, + "wsgi.errors": self.wsgi_errors or sys.stderr, + "wsgi.multithread": True, + "wsgi.multiprocess": False, + "wsgi.run_once": False, + "REQUEST_METHOD": request.method, + "SCRIPT_NAME": self.script_name, + "PATH_INFO": request.url.path, + "QUERY_STRING": request.url.query.decode("ascii"), + "SERVER_NAME": request.url.host, + "SERVER_PORT": str(port), + "SERVER_PROTOCOL": "HTTP/1.1", + "REMOTE_ADDR": self.remote_addr, + } + for header_key, header_value in request.headers.raw: + key = header_key.decode("ascii").upper().replace("-", "_") + if key not in ("CONTENT_TYPE", "CONTENT_LENGTH"): + key = "HTTP_" + key + environ[key] = header_value.decode("ascii") + + seen_status = None + seen_response_headers = None + seen_exc_info = None + + def start_response( + status: str, + response_headers: list[tuple[str, str]], + exc_info: OptExcInfo | None = None, + ) -> typing.Callable[[bytes], typing.Any]: + nonlocal seen_status, seen_response_headers, seen_exc_info + seen_status = status + seen_response_headers = response_headers + seen_exc_info = exc_info + return lambda _: None + + result = self.app(environ, start_response) + + stream = WSGIByteStream(result) + + assert seen_status is not None + assert seen_response_headers is not None + if seen_exc_info and seen_exc_info[0] and self.raise_app_exceptions: + raise seen_exc_info[1] + + status_code = int(seen_status.split()[0]) + headers = [ + (key.encode("ascii"), value.encode("ascii")) + for key, value in seen_response_headers + ] + + return Response(status_code, headers=headers, stream=stream) diff --git a/.venv/lib/python3.13/site-packages/httpx/_types.py b/.venv/lib/python3.13/site-packages/httpx/_types.py new file mode 100644 index 0000000000000000000000000000000000000000..704dfdffc8ba61eb913fa918072381e410b23c00 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_types.py @@ -0,0 +1,114 @@ +""" +Type definitions for type checking purposes. +""" + +from http.cookiejar import CookieJar +from typing import ( + IO, + TYPE_CHECKING, + Any, + AsyncIterable, + AsyncIterator, + Callable, + Dict, + Iterable, + Iterator, + List, + Mapping, + Optional, + Sequence, + Tuple, + Union, +) + +if TYPE_CHECKING: # pragma: no cover + from ._auth import Auth # noqa: F401 + from ._config import Proxy, Timeout # noqa: F401 + from ._models import Cookies, Headers, Request # noqa: F401 + from ._urls import URL, QueryParams # noqa: F401 + + +PrimitiveData = Optional[Union[str, int, float, bool]] + +URLTypes = Union["URL", str] + +QueryParamTypes = Union[ + "QueryParams", + Mapping[str, Union[PrimitiveData, Sequence[PrimitiveData]]], + List[Tuple[str, PrimitiveData]], + Tuple[Tuple[str, PrimitiveData], ...], + str, + bytes, +] + +HeaderTypes = Union[ + "Headers", + Mapping[str, str], + Mapping[bytes, bytes], + Sequence[Tuple[str, str]], + Sequence[Tuple[bytes, bytes]], +] + +CookieTypes = Union["Cookies", CookieJar, Dict[str, str], List[Tuple[str, str]]] + +TimeoutTypes = Union[ + Optional[float], + Tuple[Optional[float], Optional[float], Optional[float], Optional[float]], + "Timeout", +] +ProxyTypes = Union["URL", str, "Proxy"] +CertTypes = Union[str, Tuple[str, str], Tuple[str, str, str]] + +AuthTypes = Union[ + Tuple[Union[str, bytes], Union[str, bytes]], + Callable[["Request"], "Request"], + "Auth", +] + +RequestContent = Union[str, bytes, Iterable[bytes], AsyncIterable[bytes]] +ResponseContent = Union[str, bytes, Iterable[bytes], AsyncIterable[bytes]] +ResponseExtensions = Mapping[str, Any] + +RequestData = Mapping[str, Any] + +FileContent = Union[IO[bytes], bytes, str] +FileTypes = Union[ + # file (or bytes) + FileContent, + # (filename, file (or bytes)) + Tuple[Optional[str], FileContent], + # (filename, file (or bytes), content_type) + Tuple[Optional[str], FileContent, Optional[str]], + # (filename, file (or bytes), content_type, headers) + Tuple[Optional[str], FileContent, Optional[str], Mapping[str, str]], +] +RequestFiles = Union[Mapping[str, FileTypes], Sequence[Tuple[str, FileTypes]]] + +RequestExtensions = Mapping[str, Any] + +__all__ = ["AsyncByteStream", "SyncByteStream"] + + +class SyncByteStream: + def __iter__(self) -> Iterator[bytes]: + raise NotImplementedError( + "The '__iter__' method must be implemented." + ) # pragma: no cover + yield b"" # pragma: no cover + + def close(self) -> None: + """ + Subclasses can override this method to release any network resources + after a request/response cycle is complete. + """ + + +class AsyncByteStream: + async def __aiter__(self) -> AsyncIterator[bytes]: + raise NotImplementedError( + "The '__aiter__' method must be implemented." + ) # pragma: no cover + yield b"" # pragma: no cover + + async def aclose(self) -> None: + pass diff --git a/.venv/lib/python3.13/site-packages/httpx/_urlparse.py b/.venv/lib/python3.13/site-packages/httpx/_urlparse.py new file mode 100644 index 0000000000000000000000000000000000000000..bf190fd560ee4fc8a11af371a15fc5f1dc284d34 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_urlparse.py @@ -0,0 +1,527 @@ +""" +An implementation of `urlparse` that provides URL validation and normalization +as described by RFC3986. + +We rely on this implementation rather than the one in Python's stdlib, because: + +* It provides more complete URL validation. +* It properly differentiates between an empty querystring and an absent querystring, + to distinguish URLs with a trailing '?'. +* It handles scheme, hostname, port, and path normalization. +* It supports IDNA hostnames, normalizing them to their encoded form. +* The API supports passing individual components, as well as the complete URL string. + +Previously we relied on the excellent `rfc3986` package to handle URL parsing and +validation, but this module provides a simpler alternative, with less indirection +required. +""" + +from __future__ import annotations + +import ipaddress +import re +import typing + +import idna + +from ._exceptions import InvalidURL + +MAX_URL_LENGTH = 65536 + +# https://datatracker.ietf.org/doc/html/rfc3986.html#section-2.3 +UNRESERVED_CHARACTERS = ( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~" +) +SUB_DELIMS = "!$&'()*+,;=" + +PERCENT_ENCODED_REGEX = re.compile("%[A-Fa-f0-9]{2}") + +# https://url.spec.whatwg.org/#percent-encoded-bytes + +# The fragment percent-encode set is the C0 control percent-encode set +# and U+0020 SPACE, U+0022 ("), U+003C (<), U+003E (>), and U+0060 (`). +FRAG_SAFE = "".join( + [chr(i) for i in range(0x20, 0x7F) if i not in (0x20, 0x22, 0x3C, 0x3E, 0x60)] +) + +# The query percent-encode set is the C0 control percent-encode set +# and U+0020 SPACE, U+0022 ("), U+0023 (#), U+003C (<), and U+003E (>). +QUERY_SAFE = "".join( + [chr(i) for i in range(0x20, 0x7F) if i not in (0x20, 0x22, 0x23, 0x3C, 0x3E)] +) + +# The path percent-encode set is the query percent-encode set +# and U+003F (?), U+0060 (`), U+007B ({), and U+007D (}). +PATH_SAFE = "".join( + [ + chr(i) + for i in range(0x20, 0x7F) + if i not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + (0x3F, 0x60, 0x7B, 0x7D) + ] +) + +# The userinfo percent-encode set is the path percent-encode set +# and U+002F (/), U+003A (:), U+003B (;), U+003D (=), U+0040 (@), +# U+005B ([) to U+005E (^), inclusive, and U+007C (|). +USERNAME_SAFE = "".join( + [ + chr(i) + for i in range(0x20, 0x7F) + if i + not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + + (0x3F, 0x60, 0x7B, 0x7D) + + (0x2F, 0x3A, 0x3B, 0x3D, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x7C) + ] +) +PASSWORD_SAFE = "".join( + [ + chr(i) + for i in range(0x20, 0x7F) + if i + not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + + (0x3F, 0x60, 0x7B, 0x7D) + + (0x2F, 0x3A, 0x3B, 0x3D, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x7C) + ] +) +# Note... The terminology 'userinfo' percent-encode set in the WHATWG document +# is used for the username and password quoting. For the joint userinfo component +# we remove U+003A (:) from the safe set. +USERINFO_SAFE = "".join( + [ + chr(i) + for i in range(0x20, 0x7F) + if i + not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + + (0x3F, 0x60, 0x7B, 0x7D) + + (0x2F, 0x3B, 0x3D, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x7C) + ] +) + + +# {scheme}: (optional) +# //{authority} (optional) +# {path} +# ?{query} (optional) +# #{fragment} (optional) +URL_REGEX = re.compile( + ( + r"(?:(?P{scheme}):)?" + r"(?://(?P{authority}))?" + r"(?P{path})" + r"(?:\?(?P{query}))?" + r"(?:#(?P{fragment}))?" + ).format( + scheme="([a-zA-Z][a-zA-Z0-9+.-]*)?", + authority="[^/?#]*", + path="[^?#]*", + query="[^#]*", + fragment=".*", + ) +) + +# {userinfo}@ (optional) +# {host} +# :{port} (optional) +AUTHORITY_REGEX = re.compile( + ( + r"(?:(?P{userinfo})@)?" r"(?P{host})" r":?(?P{port})?" + ).format( + userinfo=".*", # Any character sequence. + host="(\\[.*\\]|[^:@]*)", # Either any character sequence excluding ':' or '@', + # or an IPv6 address enclosed within square brackets. + port=".*", # Any character sequence. + ) +) + + +# If we call urlparse with an individual component, then we need to regex +# validate that component individually. +# Note that we're duplicating the same strings as above. Shock! Horror!! +COMPONENT_REGEX = { + "scheme": re.compile("([a-zA-Z][a-zA-Z0-9+.-]*)?"), + "authority": re.compile("[^/?#]*"), + "path": re.compile("[^?#]*"), + "query": re.compile("[^#]*"), + "fragment": re.compile(".*"), + "userinfo": re.compile("[^@]*"), + "host": re.compile("(\\[.*\\]|[^:]*)"), + "port": re.compile(".*"), +} + + +# We use these simple regexs as a first pass before handing off to +# the stdlib 'ipaddress' module for IP address validation. +IPv4_STYLE_HOSTNAME = re.compile(r"^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$") +IPv6_STYLE_HOSTNAME = re.compile(r"^\[.*\]$") + + +class ParseResult(typing.NamedTuple): + scheme: str + userinfo: str + host: str + port: int | None + path: str + query: str | None + fragment: str | None + + @property + def authority(self) -> str: + return "".join( + [ + f"{self.userinfo}@" if self.userinfo else "", + f"[{self.host}]" if ":" in self.host else self.host, + f":{self.port}" if self.port is not None else "", + ] + ) + + @property + def netloc(self) -> str: + return "".join( + [ + f"[{self.host}]" if ":" in self.host else self.host, + f":{self.port}" if self.port is not None else "", + ] + ) + + def copy_with(self, **kwargs: str | None) -> ParseResult: + if not kwargs: + return self + + defaults = { + "scheme": self.scheme, + "authority": self.authority, + "path": self.path, + "query": self.query, + "fragment": self.fragment, + } + defaults.update(kwargs) + return urlparse("", **defaults) + + def __str__(self) -> str: + authority = self.authority + return "".join( + [ + f"{self.scheme}:" if self.scheme else "", + f"//{authority}" if authority else "", + self.path, + f"?{self.query}" if self.query is not None else "", + f"#{self.fragment}" if self.fragment is not None else "", + ] + ) + + +def urlparse(url: str = "", **kwargs: str | None) -> ParseResult: + # Initial basic checks on allowable URLs. + # --------------------------------------- + + # Hard limit the maximum allowable URL length. + if len(url) > MAX_URL_LENGTH: + raise InvalidURL("URL too long") + + # If a URL includes any ASCII control characters including \t, \r, \n, + # then treat it as invalid. + if any(char.isascii() and not char.isprintable() for char in url): + char = next(char for char in url if char.isascii() and not char.isprintable()) + idx = url.find(char) + error = ( + f"Invalid non-printable ASCII character in URL, {char!r} at position {idx}." + ) + raise InvalidURL(error) + + # Some keyword arguments require special handling. + # ------------------------------------------------ + + # Coerce "port" to a string, if it is provided as an integer. + if "port" in kwargs: + port = kwargs["port"] + kwargs["port"] = str(port) if isinstance(port, int) else port + + # Replace "netloc" with "host and "port". + if "netloc" in kwargs: + netloc = kwargs.pop("netloc") or "" + kwargs["host"], _, kwargs["port"] = netloc.partition(":") + + # Replace "username" and/or "password" with "userinfo". + if "username" in kwargs or "password" in kwargs: + username = quote(kwargs.pop("username", "") or "", safe=USERNAME_SAFE) + password = quote(kwargs.pop("password", "") or "", safe=PASSWORD_SAFE) + kwargs["userinfo"] = f"{username}:{password}" if password else username + + # Replace "raw_path" with "path" and "query". + if "raw_path" in kwargs: + raw_path = kwargs.pop("raw_path") or "" + kwargs["path"], seperator, kwargs["query"] = raw_path.partition("?") + if not seperator: + kwargs["query"] = None + + # Ensure that IPv6 "host" addresses are always escaped with "[...]". + if "host" in kwargs: + host = kwargs.get("host") or "" + if ":" in host and not (host.startswith("[") and host.endswith("]")): + kwargs["host"] = f"[{host}]" + + # If any keyword arguments are provided, ensure they are valid. + # ------------------------------------------------------------- + + for key, value in kwargs.items(): + if value is not None: + if len(value) > MAX_URL_LENGTH: + raise InvalidURL(f"URL component '{key}' too long") + + # If a component includes any ASCII control characters including \t, \r, \n, + # then treat it as invalid. + if any(char.isascii() and not char.isprintable() for char in value): + char = next( + char for char in value if char.isascii() and not char.isprintable() + ) + idx = value.find(char) + error = ( + f"Invalid non-printable ASCII character in URL {key} component, " + f"{char!r} at position {idx}." + ) + raise InvalidURL(error) + + # Ensure that keyword arguments match as a valid regex. + if not COMPONENT_REGEX[key].fullmatch(value): + raise InvalidURL(f"Invalid URL component '{key}'") + + # The URL_REGEX will always match, but may have empty components. + url_match = URL_REGEX.match(url) + assert url_match is not None + url_dict = url_match.groupdict() + + # * 'scheme', 'authority', and 'path' may be empty strings. + # * 'query' may be 'None', indicating no trailing "?" portion. + # Any string including the empty string, indicates a trailing "?". + # * 'fragment' may be 'None', indicating no trailing "#" portion. + # Any string including the empty string, indicates a trailing "#". + scheme = kwargs.get("scheme", url_dict["scheme"]) or "" + authority = kwargs.get("authority", url_dict["authority"]) or "" + path = kwargs.get("path", url_dict["path"]) or "" + query = kwargs.get("query", url_dict["query"]) + frag = kwargs.get("fragment", url_dict["fragment"]) + + # The AUTHORITY_REGEX will always match, but may have empty components. + authority_match = AUTHORITY_REGEX.match(authority) + assert authority_match is not None + authority_dict = authority_match.groupdict() + + # * 'userinfo' and 'host' may be empty strings. + # * 'port' may be 'None'. + userinfo = kwargs.get("userinfo", authority_dict["userinfo"]) or "" + host = kwargs.get("host", authority_dict["host"]) or "" + port = kwargs.get("port", authority_dict["port"]) + + # Normalize and validate each component. + # We end up with a parsed representation of the URL, + # with components that are plain ASCII bytestrings. + parsed_scheme: str = scheme.lower() + parsed_userinfo: str = quote(userinfo, safe=USERINFO_SAFE) + parsed_host: str = encode_host(host) + parsed_port: int | None = normalize_port(port, scheme) + + has_scheme = parsed_scheme != "" + has_authority = ( + parsed_userinfo != "" or parsed_host != "" or parsed_port is not None + ) + validate_path(path, has_scheme=has_scheme, has_authority=has_authority) + if has_scheme or has_authority: + path = normalize_path(path) + + parsed_path: str = quote(path, safe=PATH_SAFE) + parsed_query: str | None = None if query is None else quote(query, safe=QUERY_SAFE) + parsed_frag: str | None = None if frag is None else quote(frag, safe=FRAG_SAFE) + + # The parsed ASCII bytestrings are our canonical form. + # All properties of the URL are derived from these. + return ParseResult( + parsed_scheme, + parsed_userinfo, + parsed_host, + parsed_port, + parsed_path, + parsed_query, + parsed_frag, + ) + + +def encode_host(host: str) -> str: + if not host: + return "" + + elif IPv4_STYLE_HOSTNAME.match(host): + # Validate IPv4 hostnames like #.#.#.# + # + # From https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.2 + # + # IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet + try: + ipaddress.IPv4Address(host) + except ipaddress.AddressValueError: + raise InvalidURL(f"Invalid IPv4 address: {host!r}") + return host + + elif IPv6_STYLE_HOSTNAME.match(host): + # Validate IPv6 hostnames like [...] + # + # From https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.2 + # + # "A host identified by an Internet Protocol literal address, version 6 + # [RFC3513] or later, is distinguished by enclosing the IP literal + # within square brackets ("[" and "]"). This is the only place where + # square bracket characters are allowed in the URI syntax." + try: + ipaddress.IPv6Address(host[1:-1]) + except ipaddress.AddressValueError: + raise InvalidURL(f"Invalid IPv6 address: {host!r}") + return host[1:-1] + + elif host.isascii(): + # Regular ASCII hostnames + # + # From https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.2 + # + # reg-name = *( unreserved / pct-encoded / sub-delims ) + WHATWG_SAFE = '"`{}%|\\' + return quote(host.lower(), safe=SUB_DELIMS + WHATWG_SAFE) + + # IDNA hostnames + try: + return idna.encode(host.lower()).decode("ascii") + except idna.IDNAError: + raise InvalidURL(f"Invalid IDNA hostname: {host!r}") + + +def normalize_port(port: str | int | None, scheme: str) -> int | None: + # From https://tools.ietf.org/html/rfc3986#section-3.2.3 + # + # "A scheme may define a default port. For example, the "http" scheme + # defines a default port of "80", corresponding to its reserved TCP + # port number. The type of port designated by the port number (e.g., + # TCP, UDP, SCTP) is defined by the URI scheme. URI producers and + # normalizers should omit the port component and its ":" delimiter if + # port is empty or if its value would be the same as that of the + # scheme's default." + if port is None or port == "": + return None + + try: + port_as_int = int(port) + except ValueError: + raise InvalidURL(f"Invalid port: {port!r}") + + # See https://url.spec.whatwg.org/#url-miscellaneous + default_port = {"ftp": 21, "http": 80, "https": 443, "ws": 80, "wss": 443}.get( + scheme + ) + if port_as_int == default_port: + return None + return port_as_int + + +def validate_path(path: str, has_scheme: bool, has_authority: bool) -> None: + """ + Path validation rules that depend on if the URL contains + a scheme or authority component. + + See https://datatracker.ietf.org/doc/html/rfc3986.html#section-3.3 + """ + if has_authority: + # If a URI contains an authority component, then the path component + # must either be empty or begin with a slash ("/") character." + if path and not path.startswith("/"): + raise InvalidURL("For absolute URLs, path must be empty or begin with '/'") + + if not has_scheme and not has_authority: + # If a URI does not contain an authority component, then the path cannot begin + # with two slash characters ("//"). + if path.startswith("//"): + raise InvalidURL("Relative URLs cannot have a path starting with '//'") + + # In addition, a URI reference (Section 4.1) may be a relative-path reference, + # in which case the first path segment cannot contain a colon (":") character. + if path.startswith(":"): + raise InvalidURL("Relative URLs cannot have a path starting with ':'") + + +def normalize_path(path: str) -> str: + """ + Drop "." and ".." segments from a URL path. + + For example: + + normalize_path("/path/./to/somewhere/..") == "/path/to" + """ + # Fast return when no '.' characters in the path. + if "." not in path: + return path + + components = path.split("/") + + # Fast return when no '.' or '..' components in the path. + if "." not in components and ".." not in components: + return path + + # https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4 + output: list[str] = [] + for component in components: + if component == ".": + pass + elif component == "..": + if output and output != [""]: + output.pop() + else: + output.append(component) + return "/".join(output) + + +def PERCENT(string: str) -> str: + return "".join([f"%{byte:02X}" for byte in string.encode("utf-8")]) + + +def percent_encoded(string: str, safe: str) -> str: + """ + Use percent-encoding to quote a string. + """ + NON_ESCAPED_CHARS = UNRESERVED_CHARACTERS + safe + + # Fast path for strings that don't need escaping. + if not string.rstrip(NON_ESCAPED_CHARS): + return string + + return "".join( + [char if char in NON_ESCAPED_CHARS else PERCENT(char) for char in string] + ) + + +def quote(string: str, safe: str) -> str: + """ + Use percent-encoding to quote a string, omitting existing '%xx' escape sequences. + + See: https://www.rfc-editor.org/rfc/rfc3986#section-2.1 + + * `string`: The string to be percent-escaped. + * `safe`: A string containing characters that may be treated as safe, and do not + need to be escaped. Unreserved characters are always treated as safe. + See: https://www.rfc-editor.org/rfc/rfc3986#section-2.3 + """ + parts = [] + current_position = 0 + for match in re.finditer(PERCENT_ENCODED_REGEX, string): + start_position, end_position = match.start(), match.end() + matched_text = match.group(0) + # Add any text up to the '%xx' escape sequence. + if start_position != current_position: + leading_text = string[current_position:start_position] + parts.append(percent_encoded(leading_text, safe=safe)) + + # Add the '%xx' escape sequence. + parts.append(matched_text) + current_position = end_position + + # Add any text after the final '%xx' escape sequence. + if current_position != len(string): + trailing_text = string[current_position:] + parts.append(percent_encoded(trailing_text, safe=safe)) + + return "".join(parts) diff --git a/.venv/lib/python3.13/site-packages/httpx/_urls.py b/.venv/lib/python3.13/site-packages/httpx/_urls.py new file mode 100644 index 0000000000000000000000000000000000000000..147a8fa333acaf31618d37ba2896e3a5bf5e4d02 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_urls.py @@ -0,0 +1,641 @@ +from __future__ import annotations + +import typing +from urllib.parse import parse_qs, unquote, urlencode + +import idna + +from ._types import QueryParamTypes +from ._urlparse import urlparse +from ._utils import primitive_value_to_str + +__all__ = ["URL", "QueryParams"] + + +class URL: + """ + url = httpx.URL("HTTPS://jo%40email.com:a%20secret@müller.de:1234/pa%20th?search=ab#anchorlink") + + assert url.scheme == "https" + assert url.username == "jo@email.com" + assert url.password == "a secret" + assert url.userinfo == b"jo%40email.com:a%20secret" + assert url.host == "müller.de" + assert url.raw_host == b"xn--mller-kva.de" + assert url.port == 1234 + assert url.netloc == b"xn--mller-kva.de:1234" + assert url.path == "/pa th" + assert url.query == b"?search=ab" + assert url.raw_path == b"/pa%20th?search=ab" + assert url.fragment == "anchorlink" + + The components of a URL are broken down like this: + + https://jo%40email.com:a%20secret@müller.de:1234/pa%20th?search=ab#anchorlink + [scheme] [ username ] [password] [ host ][port][ path ] [ query ] [fragment] + [ userinfo ] [ netloc ][ raw_path ] + + Note that: + + * `url.scheme` is normalized to always be lowercased. + + * `url.host` is normalized to always be lowercased. Internationalized domain + names are represented in unicode, without IDNA encoding applied. For instance: + + url = httpx.URL("http://中国.icom.museum") + assert url.host == "中国.icom.museum" + url = httpx.URL("http://xn--fiqs8s.icom.museum") + assert url.host == "中国.icom.museum" + + * `url.raw_host` is normalized to always be lowercased, and is IDNA encoded. + + url = httpx.URL("http://中国.icom.museum") + assert url.raw_host == b"xn--fiqs8s.icom.museum" + url = httpx.URL("http://xn--fiqs8s.icom.museum") + assert url.raw_host == b"xn--fiqs8s.icom.museum" + + * `url.port` is either None or an integer. URLs that include the default port for + "http", "https", "ws", "wss", and "ftp" schemes have their port + normalized to `None`. + + assert httpx.URL("http://example.com") == httpx.URL("http://example.com:80") + assert httpx.URL("http://example.com").port is None + assert httpx.URL("http://example.com:80").port is None + + * `url.userinfo` is raw bytes, without URL escaping. Usually you'll want to work + with `url.username` and `url.password` instead, which handle the URL escaping. + + * `url.raw_path` is raw bytes of both the path and query, without URL escaping. + This portion is used as the target when constructing HTTP requests. Usually you'll + want to work with `url.path` instead. + + * `url.query` is raw bytes, without URL escaping. A URL query string portion can + only be properly URL escaped when decoding the parameter names and values + themselves. + """ + + def __init__(self, url: URL | str = "", **kwargs: typing.Any) -> None: + if kwargs: + allowed = { + "scheme": str, + "username": str, + "password": str, + "userinfo": bytes, + "host": str, + "port": int, + "netloc": bytes, + "path": str, + "query": bytes, + "raw_path": bytes, + "fragment": str, + "params": object, + } + + # Perform type checking for all supported keyword arguments. + for key, value in kwargs.items(): + if key not in allowed: + message = f"{key!r} is an invalid keyword argument for URL()" + raise TypeError(message) + if value is not None and not isinstance(value, allowed[key]): + expected = allowed[key].__name__ + seen = type(value).__name__ + message = f"Argument {key!r} must be {expected} but got {seen}" + raise TypeError(message) + if isinstance(value, bytes): + kwargs[key] = value.decode("ascii") + + if "params" in kwargs: + # Replace any "params" keyword with the raw "query" instead. + # + # Ensure that empty params use `kwargs["query"] = None` rather + # than `kwargs["query"] = ""`, so that generated URLs do not + # include an empty trailing "?". + params = kwargs.pop("params") + kwargs["query"] = None if not params else str(QueryParams(params)) + + if isinstance(url, str): + self._uri_reference = urlparse(url, **kwargs) + elif isinstance(url, URL): + self._uri_reference = url._uri_reference.copy_with(**kwargs) + else: + raise TypeError( + "Invalid type for url. Expected str or httpx.URL," + f" got {type(url)}: {url!r}" + ) + + @property + def scheme(self) -> str: + """ + The URL scheme, such as "http", "https". + Always normalised to lowercase. + """ + return self._uri_reference.scheme + + @property + def raw_scheme(self) -> bytes: + """ + The raw bytes representation of the URL scheme, such as b"http", b"https". + Always normalised to lowercase. + """ + return self._uri_reference.scheme.encode("ascii") + + @property + def userinfo(self) -> bytes: + """ + The URL userinfo as a raw bytestring. + For example: b"jo%40email.com:a%20secret". + """ + return self._uri_reference.userinfo.encode("ascii") + + @property + def username(self) -> str: + """ + The URL username as a string, with URL decoding applied. + For example: "jo@email.com" + """ + userinfo = self._uri_reference.userinfo + return unquote(userinfo.partition(":")[0]) + + @property + def password(self) -> str: + """ + The URL password as a string, with URL decoding applied. + For example: "a secret" + """ + userinfo = self._uri_reference.userinfo + return unquote(userinfo.partition(":")[2]) + + @property + def host(self) -> str: + """ + The URL host as a string. + Always normalized to lowercase, with IDNA hosts decoded into unicode. + + Examples: + + url = httpx.URL("http://www.EXAMPLE.org") + assert url.host == "www.example.org" + + url = httpx.URL("http://中国.icom.museum") + assert url.host == "中国.icom.museum" + + url = httpx.URL("http://xn--fiqs8s.icom.museum") + assert url.host == "中国.icom.museum" + + url = httpx.URL("https://[::ffff:192.168.0.1]") + assert url.host == "::ffff:192.168.0.1" + """ + host: str = self._uri_reference.host + + if host.startswith("xn--"): + host = idna.decode(host) + + return host + + @property + def raw_host(self) -> bytes: + """ + The raw bytes representation of the URL host. + Always normalized to lowercase, and IDNA encoded. + + Examples: + + url = httpx.URL("http://www.EXAMPLE.org") + assert url.raw_host == b"www.example.org" + + url = httpx.URL("http://中国.icom.museum") + assert url.raw_host == b"xn--fiqs8s.icom.museum" + + url = httpx.URL("http://xn--fiqs8s.icom.museum") + assert url.raw_host == b"xn--fiqs8s.icom.museum" + + url = httpx.URL("https://[::ffff:192.168.0.1]") + assert url.raw_host == b"::ffff:192.168.0.1" + """ + return self._uri_reference.host.encode("ascii") + + @property + def port(self) -> int | None: + """ + The URL port as an integer. + + Note that the URL class performs port normalization as per the WHATWG spec. + Default ports for "http", "https", "ws", "wss", and "ftp" schemes are always + treated as `None`. + + For example: + + assert httpx.URL("http://www.example.com") == httpx.URL("http://www.example.com:80") + assert httpx.URL("http://www.example.com:80").port is None + """ + return self._uri_reference.port + + @property + def netloc(self) -> bytes: + """ + Either `` or `:` as bytes. + Always normalized to lowercase, and IDNA encoded. + + This property may be used for generating the value of a request + "Host" header. + """ + return self._uri_reference.netloc.encode("ascii") + + @property + def path(self) -> str: + """ + The URL path as a string. Excluding the query string, and URL decoded. + + For example: + + url = httpx.URL("https://example.com/pa%20th") + assert url.path == "/pa th" + """ + path = self._uri_reference.path or "/" + return unquote(path) + + @property + def query(self) -> bytes: + """ + The URL query string, as raw bytes, excluding the leading b"?". + + This is necessarily a bytewise interface, because we cannot + perform URL decoding of this representation until we've parsed + the keys and values into a QueryParams instance. + + For example: + + url = httpx.URL("https://example.com/?filter=some%20search%20terms") + assert url.query == b"filter=some%20search%20terms" + """ + query = self._uri_reference.query or "" + return query.encode("ascii") + + @property + def params(self) -> QueryParams: + """ + The URL query parameters, neatly parsed and packaged into an immutable + multidict representation. + """ + return QueryParams(self._uri_reference.query) + + @property + def raw_path(self) -> bytes: + """ + The complete URL path and query string as raw bytes. + Used as the target when constructing HTTP requests. + + For example: + + GET /users?search=some%20text HTTP/1.1 + Host: www.example.org + Connection: close + """ + path = self._uri_reference.path or "/" + if self._uri_reference.query is not None: + path += "?" + self._uri_reference.query + return path.encode("ascii") + + @property + def fragment(self) -> str: + """ + The URL fragments, as used in HTML anchors. + As a string, without the leading '#'. + """ + return unquote(self._uri_reference.fragment or "") + + @property + def is_absolute_url(self) -> bool: + """ + Return `True` for absolute URLs such as 'http://example.com/path', + and `False` for relative URLs such as '/path'. + """ + # We don't use `.is_absolute` from `rfc3986` because it treats + # URLs with a fragment portion as not absolute. + # What we actually care about is if the URL provides + # a scheme and hostname to which connections should be made. + return bool(self._uri_reference.scheme and self._uri_reference.host) + + @property + def is_relative_url(self) -> bool: + """ + Return `False` for absolute URLs such as 'http://example.com/path', + and `True` for relative URLs such as '/path'. + """ + return not self.is_absolute_url + + def copy_with(self, **kwargs: typing.Any) -> URL: + """ + Copy this URL, returning a new URL with some components altered. + Accepts the same set of parameters as the components that are made + available via properties on the `URL` class. + + For example: + + url = httpx.URL("https://www.example.com").copy_with( + username="jo@gmail.com", password="a secret" + ) + assert url == "https://jo%40email.com:a%20secret@www.example.com" + """ + return URL(self, **kwargs) + + def copy_set_param(self, key: str, value: typing.Any = None) -> URL: + return self.copy_with(params=self.params.set(key, value)) + + def copy_add_param(self, key: str, value: typing.Any = None) -> URL: + return self.copy_with(params=self.params.add(key, value)) + + def copy_remove_param(self, key: str) -> URL: + return self.copy_with(params=self.params.remove(key)) + + def copy_merge_params(self, params: QueryParamTypes) -> URL: + return self.copy_with(params=self.params.merge(params)) + + def join(self, url: URL | str) -> URL: + """ + Return an absolute URL, using this URL as the base. + + Eg. + + url = httpx.URL("https://www.example.com/test") + url = url.join("/new/path") + assert url == "https://www.example.com/new/path" + """ + from urllib.parse import urljoin + + return URL(urljoin(str(self), str(URL(url)))) + + def __hash__(self) -> int: + return hash(str(self)) + + def __eq__(self, other: typing.Any) -> bool: + return isinstance(other, (URL, str)) and str(self) == str(URL(other)) + + def __str__(self) -> str: + return str(self._uri_reference) + + def __repr__(self) -> str: + scheme, userinfo, host, port, path, query, fragment = self._uri_reference + + if ":" in userinfo: + # Mask any password component. + userinfo = f'{userinfo.split(":")[0]}:[secure]' + + authority = "".join( + [ + f"{userinfo}@" if userinfo else "", + f"[{host}]" if ":" in host else host, + f":{port}" if port is not None else "", + ] + ) + url = "".join( + [ + f"{self.scheme}:" if scheme else "", + f"//{authority}" if authority else "", + path, + f"?{query}" if query is not None else "", + f"#{fragment}" if fragment is not None else "", + ] + ) + + return f"{self.__class__.__name__}({url!r})" + + @property + def raw(self) -> tuple[bytes, bytes, int, bytes]: # pragma: nocover + import collections + import warnings + + warnings.warn("URL.raw is deprecated.") + RawURL = collections.namedtuple( + "RawURL", ["raw_scheme", "raw_host", "port", "raw_path"] + ) + return RawURL( + raw_scheme=self.raw_scheme, + raw_host=self.raw_host, + port=self.port, + raw_path=self.raw_path, + ) + + +class QueryParams(typing.Mapping[str, str]): + """ + URL query parameters, as a multi-dict. + """ + + def __init__(self, *args: QueryParamTypes | None, **kwargs: typing.Any) -> None: + assert len(args) < 2, "Too many arguments." + assert not (args and kwargs), "Cannot mix named and unnamed arguments." + + value = args[0] if args else kwargs + + if value is None or isinstance(value, (str, bytes)): + value = value.decode("ascii") if isinstance(value, bytes) else value + self._dict = parse_qs(value, keep_blank_values=True) + elif isinstance(value, QueryParams): + self._dict = {k: list(v) for k, v in value._dict.items()} + else: + dict_value: dict[typing.Any, list[typing.Any]] = {} + if isinstance(value, (list, tuple)): + # Convert list inputs like: + # [("a", "123"), ("a", "456"), ("b", "789")] + # To a dict representation, like: + # {"a": ["123", "456"], "b": ["789"]} + for item in value: + dict_value.setdefault(item[0], []).append(item[1]) + else: + # Convert dict inputs like: + # {"a": "123", "b": ["456", "789"]} + # To dict inputs where values are always lists, like: + # {"a": ["123"], "b": ["456", "789"]} + dict_value = { + k: list(v) if isinstance(v, (list, tuple)) else [v] + for k, v in value.items() + } + + # Ensure that keys and values are neatly coerced to strings. + # We coerce values `True` and `False` to JSON-like "true" and "false" + # representations, and coerce `None` values to the empty string. + self._dict = { + str(k): [primitive_value_to_str(item) for item in v] + for k, v in dict_value.items() + } + + def keys(self) -> typing.KeysView[str]: + """ + Return all the keys in the query params. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert list(q.keys()) == ["a", "b"] + """ + return self._dict.keys() + + def values(self) -> typing.ValuesView[str]: + """ + Return all the values in the query params. If a key occurs more than once + only the first item for that key is returned. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert list(q.values()) == ["123", "789"] + """ + return {k: v[0] for k, v in self._dict.items()}.values() + + def items(self) -> typing.ItemsView[str, str]: + """ + Return all items in the query params. If a key occurs more than once + only the first item for that key is returned. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert list(q.items()) == [("a", "123"), ("b", "789")] + """ + return {k: v[0] for k, v in self._dict.items()}.items() + + def multi_items(self) -> list[tuple[str, str]]: + """ + Return all items in the query params. Allow duplicate keys to occur. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert list(q.multi_items()) == [("a", "123"), ("a", "456"), ("b", "789")] + """ + multi_items: list[tuple[str, str]] = [] + for k, v in self._dict.items(): + multi_items.extend([(k, i) for i in v]) + return multi_items + + def get(self, key: typing.Any, default: typing.Any = None) -> typing.Any: + """ + Get a value from the query param for a given key. If the key occurs + more than once, then only the first value is returned. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert q.get("a") == "123" + """ + if key in self._dict: + return self._dict[str(key)][0] + return default + + def get_list(self, key: str) -> list[str]: + """ + Get all values from the query param for a given key. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert q.get_list("a") == ["123", "456"] + """ + return list(self._dict.get(str(key), [])) + + def set(self, key: str, value: typing.Any = None) -> QueryParams: + """ + Return a new QueryParams instance, setting the value of a key. + + Usage: + + q = httpx.QueryParams("a=123") + q = q.set("a", "456") + assert q == httpx.QueryParams("a=456") + """ + q = QueryParams() + q._dict = dict(self._dict) + q._dict[str(key)] = [primitive_value_to_str(value)] + return q + + def add(self, key: str, value: typing.Any = None) -> QueryParams: + """ + Return a new QueryParams instance, setting or appending the value of a key. + + Usage: + + q = httpx.QueryParams("a=123") + q = q.add("a", "456") + assert q == httpx.QueryParams("a=123&a=456") + """ + q = QueryParams() + q._dict = dict(self._dict) + q._dict[str(key)] = q.get_list(key) + [primitive_value_to_str(value)] + return q + + def remove(self, key: str) -> QueryParams: + """ + Return a new QueryParams instance, removing the value of a key. + + Usage: + + q = httpx.QueryParams("a=123") + q = q.remove("a") + assert q == httpx.QueryParams("") + """ + q = QueryParams() + q._dict = dict(self._dict) + q._dict.pop(str(key), None) + return q + + def merge(self, params: QueryParamTypes | None = None) -> QueryParams: + """ + Return a new QueryParams instance, updated with. + + Usage: + + q = httpx.QueryParams("a=123") + q = q.merge({"b": "456"}) + assert q == httpx.QueryParams("a=123&b=456") + + q = httpx.QueryParams("a=123") + q = q.merge({"a": "456", "b": "789"}) + assert q == httpx.QueryParams("a=456&b=789") + """ + q = QueryParams(params) + q._dict = {**self._dict, **q._dict} + return q + + def __getitem__(self, key: typing.Any) -> str: + return self._dict[key][0] + + def __contains__(self, key: typing.Any) -> bool: + return key in self._dict + + def __iter__(self) -> typing.Iterator[typing.Any]: + return iter(self.keys()) + + def __len__(self) -> int: + return len(self._dict) + + def __bool__(self) -> bool: + return bool(self._dict) + + def __hash__(self) -> int: + return hash(str(self)) + + def __eq__(self, other: typing.Any) -> bool: + if not isinstance(other, self.__class__): + return False + return sorted(self.multi_items()) == sorted(other.multi_items()) + + def __str__(self) -> str: + return urlencode(self.multi_items()) + + def __repr__(self) -> str: + class_name = self.__class__.__name__ + query_string = str(self) + return f"{class_name}({query_string!r})" + + def update(self, params: QueryParamTypes | None = None) -> None: + raise RuntimeError( + "QueryParams are immutable since 0.18.0. " + "Use `q = q.merge(...)` to create an updated copy." + ) + + def __setitem__(self, key: str, value: str) -> None: + raise RuntimeError( + "QueryParams are immutable since 0.18.0. " + "Use `q = q.set(key, value)` to create an updated copy." + ) diff --git a/.venv/lib/python3.13/site-packages/httpx/_utils.py b/.venv/lib/python3.13/site-packages/httpx/_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..7fe827da4d071b32ea6da44328629699d6fc88ce --- /dev/null +++ b/.venv/lib/python3.13/site-packages/httpx/_utils.py @@ -0,0 +1,242 @@ +from __future__ import annotations + +import ipaddress +import os +import re +import typing +from urllib.request import getproxies + +from ._types import PrimitiveData + +if typing.TYPE_CHECKING: # pragma: no cover + from ._urls import URL + + +def primitive_value_to_str(value: PrimitiveData) -> str: + """ + Coerce a primitive data type into a string value. + + Note that we prefer JSON-style 'true'/'false' for boolean values here. + """ + if value is True: + return "true" + elif value is False: + return "false" + elif value is None: + return "" + return str(value) + + +def get_environment_proxies() -> dict[str, str | None]: + """Gets proxy information from the environment""" + + # urllib.request.getproxies() falls back on System + # Registry and Config for proxies on Windows and macOS. + # We don't want to propagate non-HTTP proxies into + # our configuration such as 'TRAVIS_APT_PROXY'. + proxy_info = getproxies() + mounts: dict[str, str | None] = {} + + for scheme in ("http", "https", "all"): + if proxy_info.get(scheme): + hostname = proxy_info[scheme] + mounts[f"{scheme}://"] = ( + hostname if "://" in hostname else f"http://{hostname}" + ) + + no_proxy_hosts = [host.strip() for host in proxy_info.get("no", "").split(",")] + for hostname in no_proxy_hosts: + # See https://curl.haxx.se/libcurl/c/CURLOPT_NOPROXY.html for details + # on how names in `NO_PROXY` are handled. + if hostname == "*": + # If NO_PROXY=* is used or if "*" occurs as any one of the comma + # separated hostnames, then we should just bypass any information + # from HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, and always ignore + # proxies. + return {} + elif hostname: + # NO_PROXY=.google.com is marked as "all://*.google.com, + # which disables "www.google.com" but not "google.com" + # NO_PROXY=google.com is marked as "all://*google.com, + # which disables "www.google.com" and "google.com". + # (But not "wwwgoogle.com") + # NO_PROXY can include domains, IPv6, IPv4 addresses and "localhost" + # NO_PROXY=example.com,::1,localhost,192.168.0.0/16 + if "://" in hostname: + mounts[hostname] = None + elif is_ipv4_hostname(hostname): + mounts[f"all://{hostname}"] = None + elif is_ipv6_hostname(hostname): + mounts[f"all://[{hostname}]"] = None + elif hostname.lower() == "localhost": + mounts[f"all://{hostname}"] = None + else: + mounts[f"all://*{hostname}"] = None + + return mounts + + +def to_bytes(value: str | bytes, encoding: str = "utf-8") -> bytes: + return value.encode(encoding) if isinstance(value, str) else value + + +def to_str(value: str | bytes, encoding: str = "utf-8") -> str: + return value if isinstance(value, str) else value.decode(encoding) + + +def to_bytes_or_str(value: str, match_type_of: typing.AnyStr) -> typing.AnyStr: + return value if isinstance(match_type_of, str) else value.encode() + + +def unquote(value: str) -> str: + return value[1:-1] if value[0] == value[-1] == '"' else value + + +def peek_filelike_length(stream: typing.Any) -> int | None: + """ + Given a file-like stream object, return its length in number of bytes + without reading it into memory. + """ + try: + # Is it an actual file? + fd = stream.fileno() + # Yup, seems to be an actual file. + length = os.fstat(fd).st_size + except (AttributeError, OSError): + # No... Maybe it's something that supports random access, like `io.BytesIO`? + try: + # Assuming so, go to end of stream to figure out its length, + # then put it back in place. + offset = stream.tell() + length = stream.seek(0, os.SEEK_END) + stream.seek(offset) + except (AttributeError, OSError): + # Not even that? Sorry, we're doomed... + return None + + return length + + +class URLPattern: + """ + A utility class currently used for making lookups against proxy keys... + + # Wildcard matching... + >>> pattern = URLPattern("all://") + >>> pattern.matches(httpx.URL("http://example.com")) + True + + # Witch scheme matching... + >>> pattern = URLPattern("https://") + >>> pattern.matches(httpx.URL("https://example.com")) + True + >>> pattern.matches(httpx.URL("http://example.com")) + False + + # With domain matching... + >>> pattern = URLPattern("https://example.com") + >>> pattern.matches(httpx.URL("https://example.com")) + True + >>> pattern.matches(httpx.URL("http://example.com")) + False + >>> pattern.matches(httpx.URL("https://other.com")) + False + + # Wildcard scheme, with domain matching... + >>> pattern = URLPattern("all://example.com") + >>> pattern.matches(httpx.URL("https://example.com")) + True + >>> pattern.matches(httpx.URL("http://example.com")) + True + >>> pattern.matches(httpx.URL("https://other.com")) + False + + # With port matching... + >>> pattern = URLPattern("https://example.com:1234") + >>> pattern.matches(httpx.URL("https://example.com:1234")) + True + >>> pattern.matches(httpx.URL("https://example.com")) + False + """ + + def __init__(self, pattern: str) -> None: + from ._urls import URL + + if pattern and ":" not in pattern: + raise ValueError( + f"Proxy keys should use proper URL forms rather " + f"than plain scheme strings. " + f'Instead of "{pattern}", use "{pattern}://"' + ) + + url = URL(pattern) + self.pattern = pattern + self.scheme = "" if url.scheme == "all" else url.scheme + self.host = "" if url.host == "*" else url.host + self.port = url.port + if not url.host or url.host == "*": + self.host_regex: typing.Pattern[str] | None = None + elif url.host.startswith("*."): + # *.example.com should match "www.example.com", but not "example.com" + domain = re.escape(url.host[2:]) + self.host_regex = re.compile(f"^.+\\.{domain}$") + elif url.host.startswith("*"): + # *example.com should match "www.example.com" and "example.com" + domain = re.escape(url.host[1:]) + self.host_regex = re.compile(f"^(.+\\.)?{domain}$") + else: + # example.com should match "example.com" but not "www.example.com" + domain = re.escape(url.host) + self.host_regex = re.compile(f"^{domain}$") + + def matches(self, other: URL) -> bool: + if self.scheme and self.scheme != other.scheme: + return False + if ( + self.host + and self.host_regex is not None + and not self.host_regex.match(other.host) + ): + return False + if self.port is not None and self.port != other.port: + return False + return True + + @property + def priority(self) -> tuple[int, int, int]: + """ + The priority allows URLPattern instances to be sortable, so that + we can match from most specific to least specific. + """ + # URLs with a port should take priority over URLs without a port. + port_priority = 0 if self.port is not None else 1 + # Longer hostnames should match first. + host_priority = -len(self.host) + # Longer schemes should match first. + scheme_priority = -len(self.scheme) + return (port_priority, host_priority, scheme_priority) + + def __hash__(self) -> int: + return hash(self.pattern) + + def __lt__(self, other: URLPattern) -> bool: + return self.priority < other.priority + + def __eq__(self, other: typing.Any) -> bool: + return isinstance(other, URLPattern) and self.pattern == other.pattern + + +def is_ipv4_hostname(hostname: str) -> bool: + try: + ipaddress.IPv4Address(hostname.split("/")[0]) + except Exception: + return False + return True + + +def is_ipv6_hostname(hostname: str) -> bool: + try: + ipaddress.IPv6Address(hostname.split("/")[0]) + except Exception: + return False + return True diff --git a/.venv/lib/python3.13/site-packages/httpx/py.typed b/.venv/lib/python3.13/site-packages/httpx/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/INSTALLER b/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/METADATA b/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..538811dffe1b20cb18f4484b6ea98a10ac6e3aa8 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/METADATA @@ -0,0 +1,329 @@ +Metadata-Version: 2.4 +Name: huggingface_hub +Version: 1.23.0 +Summary: Client library to download and publish models, datasets and other repos on the huggingface.co hub +Home-page: https://github.com/huggingface/huggingface_hub +Author: Hugging Face, Inc. +Author-email: julien@huggingface.co +License: Apache-2.0 +Keywords: model-hub machine-learning models natural-language-processing deep-learning pytorch pretrained-models +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Education +Classifier: Intended Audience :: Science/Research +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Operating System :: OS Independent +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: Topic :: Scientific/Engineering :: Artificial Intelligence +Requires-Python: >=3.10.0 +Description-Content-Type: text/markdown +License-File: LICENSE +Requires-Dist: click<9.0.0,>=8.4.2 +Requires-Dist: filelock>=3.10.0 +Requires-Dist: fsspec>=2023.5.0 +Requires-Dist: hf-xet<2.0.0,>=1.5.1; platform_machine == "x86_64" or platform_machine == "amd64" or platform_machine == "AMD64" or platform_machine == "arm64" or platform_machine == "aarch64" +Requires-Dist: httpx<1,>=0.23.0 +Requires-Dist: packaging>=20.9 +Requires-Dist: pyyaml>=5.1 +Requires-Dist: tqdm>=4.42.1 +Requires-Dist: typing-extensions>=4.1.0 +Provides-Extra: oauth +Requires-Dist: authlib>=1.3.2; extra == "oauth" +Requires-Dist: fastapi; extra == "oauth" +Requires-Dist: httpx; extra == "oauth" +Requires-Dist: itsdangerous; extra == "oauth" +Provides-Extra: torch +Requires-Dist: torch; extra == "torch" +Requires-Dist: safetensors[torch]; extra == "torch" +Provides-Extra: fastai +Requires-Dist: toml; extra == "fastai" +Requires-Dist: fastai>=2.4; extra == "fastai" +Requires-Dist: fastcore>=1.3.27; extra == "fastai" +Provides-Extra: hf-xet +Requires-Dist: hf-xet<2.0.0,>=1.5.1; extra == "hf-xet" +Provides-Extra: mcp +Requires-Dist: mcp>=1.8.0; extra == "mcp" +Provides-Extra: testing +Requires-Dist: authlib>=1.3.2; extra == "testing" +Requires-Dist: fastapi; extra == "testing" +Requires-Dist: httpx; extra == "testing" +Requires-Dist: itsdangerous; extra == "testing" +Requires-Dist: jedi; extra == "testing" +Requires-Dist: Jinja2; extra == "testing" +Requires-Dist: pytest>=8.4.2; extra == "testing" +Requires-Dist: pytest-cov; extra == "testing" +Requires-Dist: pytest-env; extra == "testing" +Requires-Dist: pytest-xdist; extra == "testing" +Requires-Dist: pytest-vcr; extra == "testing" +Requires-Dist: pytest-asyncio; extra == "testing" +Requires-Dist: pytest-rerunfailures<16.0; extra == "testing" +Requires-Dist: pytest-mock; extra == "testing" +Requires-Dist: urllib3<2.0; extra == "testing" +Requires-Dist: soundfile; extra == "testing" +Requires-Dist: Pillow; extra == "testing" +Requires-Dist: numpy; extra == "testing" +Requires-Dist: duckdb; extra == "testing" +Requires-Dist: fastapi; extra == "testing" +Provides-Extra: gradio +Requires-Dist: gradio>=5.0.0; extra == "gradio" +Requires-Dist: requests; extra == "gradio" +Provides-Extra: typing +Requires-Dist: typing-extensions>=4.8.0; extra == "typing" +Requires-Dist: types-PyYAML; extra == "typing" +Requires-Dist: types-simplejson; extra == "typing" +Requires-Dist: types-toml; extra == "typing" +Requires-Dist: types-tqdm; extra == "typing" +Requires-Dist: types-urllib3; extra == "typing" +Provides-Extra: quality +Requires-Dist: ruff>=0.9.0; extra == "quality" +Requires-Dist: mypy==1.15.0; extra == "quality" +Requires-Dist: libcst>=1.4.0; extra == "quality" +Requires-Dist: ty; extra == "quality" +Provides-Extra: all +Requires-Dist: authlib>=1.3.2; extra == "all" +Requires-Dist: fastapi; extra == "all" +Requires-Dist: httpx; extra == "all" +Requires-Dist: itsdangerous; extra == "all" +Requires-Dist: jedi; extra == "all" +Requires-Dist: Jinja2; extra == "all" +Requires-Dist: pytest>=8.4.2; extra == "all" +Requires-Dist: pytest-cov; extra == "all" +Requires-Dist: pytest-env; extra == "all" +Requires-Dist: pytest-xdist; extra == "all" +Requires-Dist: pytest-vcr; extra == "all" +Requires-Dist: pytest-asyncio; extra == "all" +Requires-Dist: pytest-rerunfailures<16.0; extra == "all" +Requires-Dist: pytest-mock; extra == "all" +Requires-Dist: urllib3<2.0; extra == "all" +Requires-Dist: soundfile; extra == "all" +Requires-Dist: Pillow; extra == "all" +Requires-Dist: numpy; extra == "all" +Requires-Dist: duckdb; extra == "all" +Requires-Dist: fastapi; extra == "all" +Requires-Dist: ruff>=0.9.0; extra == "all" +Requires-Dist: mypy==1.15.0; extra == "all" +Requires-Dist: libcst>=1.4.0; extra == "all" +Requires-Dist: ty; extra == "all" +Requires-Dist: typing-extensions>=4.8.0; extra == "all" +Requires-Dist: types-PyYAML; extra == "all" +Requires-Dist: types-simplejson; extra == "all" +Requires-Dist: types-toml; extra == "all" +Requires-Dist: types-tqdm; extra == "all" +Requires-Dist: types-urllib3; extra == "all" +Provides-Extra: dev +Requires-Dist: authlib>=1.3.2; extra == "dev" +Requires-Dist: fastapi; extra == "dev" +Requires-Dist: httpx; extra == "dev" +Requires-Dist: itsdangerous; extra == "dev" +Requires-Dist: jedi; extra == "dev" +Requires-Dist: Jinja2; extra == "dev" +Requires-Dist: pytest>=8.4.2; extra == "dev" +Requires-Dist: pytest-cov; extra == "dev" +Requires-Dist: pytest-env; extra == "dev" +Requires-Dist: pytest-xdist; extra == "dev" +Requires-Dist: pytest-vcr; extra == "dev" +Requires-Dist: pytest-asyncio; extra == "dev" +Requires-Dist: pytest-rerunfailures<16.0; extra == "dev" +Requires-Dist: pytest-mock; extra == "dev" +Requires-Dist: urllib3<2.0; extra == "dev" +Requires-Dist: soundfile; extra == "dev" +Requires-Dist: Pillow; extra == "dev" +Requires-Dist: numpy; extra == "dev" +Requires-Dist: duckdb; extra == "dev" +Requires-Dist: fastapi; extra == "dev" +Requires-Dist: ruff>=0.9.0; extra == "dev" +Requires-Dist: mypy==1.15.0; extra == "dev" +Requires-Dist: libcst>=1.4.0; extra == "dev" +Requires-Dist: ty; extra == "dev" +Requires-Dist: typing-extensions>=4.8.0; extra == "dev" +Requires-Dist: types-PyYAML; extra == "dev" +Requires-Dist: types-simplejson; extra == "dev" +Requires-Dist: types-toml; extra == "dev" +Requires-Dist: types-tqdm; extra == "dev" +Requires-Dist: types-urllib3; extra == "dev" +Dynamic: author +Dynamic: author-email +Dynamic: classifier +Dynamic: description +Dynamic: description-content-type +Dynamic: home-page +Dynamic: keywords +Dynamic: license +Dynamic: license-file +Dynamic: provides-extra +Dynamic: requires-dist +Dynamic: requires-python +Dynamic: summary + +

+ + + + huggingface_hub library logo + +
+
+

+ +

+ The official Python client for the Huggingface Hub. +

+ +

+ Documentation + GitHub release + PyPi version + PyPI - Downloads + Code coverage +

+ +

+

+ English | + Deutsch | + Français | + हिंदी | + 한국어 | + 中文 (简体) + ಕನ್ನಡ +

+

+ +--- + +**Documentation**: https://hf.co/docs/huggingface_hub + +**Source Code**: https://github.com/huggingface/huggingface_hub + +--- + +## Welcome to the huggingface_hub library + +The `huggingface_hub` library allows you to interact with the [Hugging Face Hub](https://huggingface.co/), a platform democratizing open-source Machine Learning for creators and collaborators. Discover pre-trained models and datasets for your projects or play with the thousands of machine learning apps hosted on the Hub. You can also create and share your own models, datasets and demos with the community. The `huggingface_hub` library provides a simple way to do all these things with Python. + +## Key features + +- [Download files](https://huggingface.co/docs/huggingface_hub/en/guides/download) from the Hub. +- [Upload files](https://huggingface.co/docs/huggingface_hub/en/guides/upload) to the Hub. +- [Manage your repositories](https://huggingface.co/docs/huggingface_hub/en/guides/repository). +- [Run Inference](https://huggingface.co/docs/huggingface_hub/en/guides/inference) on deployed models. +- [Search](https://huggingface.co/docs/huggingface_hub/en/guides/search) for models, datasets and Spaces. +- [Share Model Cards](https://huggingface.co/docs/huggingface_hub/en/guides/model-cards) to document your models. +- [Engage with the community](https://huggingface.co/docs/huggingface_hub/en/guides/community) through PRs and comments. + +## Installation + +Install the `huggingface_hub` package with [pip](https://pypi.org/project/huggingface-hub/): + +```bash +pip install huggingface_hub +``` + +We recommend using [`uv`](https://docs.astral.sh/uv/) for a fast and reliable install: + +```bash +uv pip install huggingface_hub +``` + +In order to keep the package minimal by default, `huggingface_hub` comes with optional dependencies useful for some use cases. For example, if you want to use the MCP module, run: + +```bash +pip install "huggingface_hub[mcp]" +``` + +To learn more about installation and optional dependencies, check out the [installation guide](https://huggingface.co/docs/huggingface_hub/en/installation). + +## Quick start + +### Download files + +Download a single file + +```py +from huggingface_hub import hf_hub_download + +hf_hub_download(repo_id="tiiuae/falcon-7b-instruct", filename="config.json") +``` + +Or an entire repository + +```py +from huggingface_hub import snapshot_download + +snapshot_download("stabilityai/stable-diffusion-2-1") +``` + +Files will be downloaded in a local cache folder. More details in [this guide](https://huggingface.co/docs/huggingface_hub/en/guides/manage-cache). + +### Login + +The Hugging Face Hub uses tokens to authenticate applications (see [docs](https://huggingface.co/docs/hub/security-tokens)). To log in your machine, run the following CLI: + +```bash +hf auth login +# or using an environment variable +hf auth login --token $HUGGINGFACE_TOKEN +``` + +### Create a repository + +```py +from huggingface_hub import create_repo + +create_repo(repo_id="super-cool-model") +``` + +### Upload files + +Upload a single file + +```py +from huggingface_hub import upload_file + +upload_file( + path_or_fileobj="/home/lysandre/dummy-test/README.md", + path_in_repo="README.md", + repo_id="lysandre/test-model", +) +``` + +Or an entire folder + +```py +from huggingface_hub import upload_folder + +upload_folder( + folder_path="/path/to/local/space", + repo_id="username/my-cool-space", + repo_type="space", +) +``` + +For details in the [upload guide](https://huggingface.co/docs/huggingface_hub/en/guides/upload). + +## Integrating to the Hub. + +We're partnering with cool open source ML libraries to provide free model hosting and versioning. You can find the existing integrations [here](https://huggingface.co/docs/hub/libraries). + +The advantages are: + +- Free model or dataset hosting for libraries and their users. +- Built-in file versioning, even with very large files, thanks to a git-based approach. +- In-browser widgets to play with the uploaded models. +- Anyone can upload a new model for your library, they just need to add the corresponding tag for the model to be discoverable. +- Fast downloads! We use Cloudfront (a CDN) to geo-replicate downloads so they're blazing fast from anywhere on the globe. +- Usage stats and more features to come. + +If you would like to integrate your library, feel free to open an issue to begin the discussion. We wrote a [step-by-step guide](https://huggingface.co/docs/hub/adding-a-library) with ❤️ showing how to do this integration. + +## Contributions (feature requests, bugs, etc.) are super welcome 💙💚💛💜🧡❤️ + +Everyone is welcome to contribute, and we value everybody's contribution. Code is not the only way to help the community. +Answering questions, helping others, reaching out and improving the documentations are immensely valuable to the community. +We wrote a [contribution guide](https://github.com/huggingface/huggingface_hub/blob/main/CONTRIBUTING.md) to summarize +how to get started to contribute to this repository. diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/RECORD b/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..977034d3203b1c1bb58d5c21d81422ebd72dad99 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/RECORD @@ -0,0 +1,375 @@ +../../../bin/hf,sha256=58OPRQp2Dh8olhd_u8es7kPai2Z8aTopdh1goC3kFew,200 +../../../bin/huggingface-cli,sha256=N1rCjXQlSKU2D4-DOtQ9phm5RoUGadM_O8c2dWVUJCo,212 +../../../bin/tiny-agents,sha256=n6ld6XDZ91G8-_SY5H58NxitycfnxQ6XUmSu5xlaGQ0,210 +huggingface_hub-1.23.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +huggingface_hub-1.23.0.dist-info/METADATA,sha256=D0HlnxT-6le6P_ubp-nfoDxQ6mHmr5H1WM9tKu6vN0c,14148 +huggingface_hub-1.23.0.dist-info/RECORD,, +huggingface_hub-1.23.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91 +huggingface_hub-1.23.0.dist-info/entry_points.txt,sha256=zP7F_bBSdircPQFysHQZ9F3Lcn5_dCSOEZxVlGCsG0w,212 +huggingface_hub-1.23.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357 +huggingface_hub-1.23.0.dist-info/top_level.txt,sha256=8KzlQJAY4miUvjAssOAJodqKOw3harNzuiwGQ9qLSSk,16 +huggingface_hub/__init__.py,sha256=m3m7FkZKphGg6olhIeTGELfOhvPNt4xRsETWwaBsWRs,60255 +huggingface_hub/__pycache__/__init__.cpython-313.pyc,, +huggingface_hub/__pycache__/_buckets.cpython-313.pyc,, +huggingface_hub/__pycache__/_commit_api.cpython-313.pyc,, +huggingface_hub/__pycache__/_commit_scheduler.cpython-313.pyc,, +huggingface_hub/__pycache__/_dataset_viewer.cpython-313.pyc,, +huggingface_hub/__pycache__/_eval_results.cpython-313.pyc,, +huggingface_hub/__pycache__/_inference_endpoints.cpython-313.pyc,, +huggingface_hub/__pycache__/_jobs_api.cpython-313.pyc,, +huggingface_hub/__pycache__/_local_folder.cpython-313.pyc,, +huggingface_hub/__pycache__/_login.cpython-313.pyc,, +huggingface_hub/__pycache__/_oauth.cpython-313.pyc,, +huggingface_hub/__pycache__/_oidc.cpython-313.pyc,, +huggingface_hub/__pycache__/_sandbox.cpython-313.pyc,, +huggingface_hub/__pycache__/_sandbox_cache.cpython-313.pyc,, +huggingface_hub/__pycache__/_snapshot_download.cpython-313.pyc,, +huggingface_hub/__pycache__/_space_api.cpython-313.pyc,, +huggingface_hub/__pycache__/_tensorboard_logger.cpython-313.pyc,, +huggingface_hub/__pycache__/_tree_cache.cpython-313.pyc,, +huggingface_hub/__pycache__/_upload_large_folder.cpython-313.pyc,, +huggingface_hub/__pycache__/_upload_pipeline.cpython-313.pyc,, +huggingface_hub/__pycache__/_webhooks_payload.cpython-313.pyc,, +huggingface_hub/__pycache__/_webhooks_server.cpython-313.pyc,, +huggingface_hub/__pycache__/community.cpython-313.pyc,, +huggingface_hub/__pycache__/constants.cpython-313.pyc,, +huggingface_hub/__pycache__/dataclasses.cpython-313.pyc,, +huggingface_hub/__pycache__/errors.cpython-313.pyc,, +huggingface_hub/__pycache__/fastai_utils.cpython-313.pyc,, +huggingface_hub/__pycache__/file_download.cpython-313.pyc,, +huggingface_hub/__pycache__/hf_api.cpython-313.pyc,, +huggingface_hub/__pycache__/hf_file_system.cpython-313.pyc,, +huggingface_hub/__pycache__/hub_mixin.cpython-313.pyc,, +huggingface_hub/__pycache__/lfs.cpython-313.pyc,, +huggingface_hub/__pycache__/repocard.cpython-313.pyc,, +huggingface_hub/__pycache__/repocard_data.cpython-313.pyc,, +huggingface_hub/_buckets.py,sha256=XyLbsLzS2fpQz0aAIjKzV-1YbQ4XYZ4-HXQTVq0TXoU,45311 +huggingface_hub/_commit_api.py,sha256=yW99ZJbIuiRt604bQ2TpDzsfxTO-IxdFW8nf-NY2MyE,45389 +huggingface_hub/_commit_scheduler.py,sha256=VG3zjb7xb66NrFMq_pB9dWIsoqSPoF6CntovV7vUiWg,14684 +huggingface_hub/_dataset_viewer.py,sha256=LE9k4s0WJ0JNdriJ8L6qV_-xfbUVC1VEh7CBd0jOjLI,5675 +huggingface_hub/_eval_results.py,sha256=Og7p7bCl2HQG6ZWlSDyir-CRTXjNWPu3S3q65cTGffs,8126 +huggingface_hub/_hot_reload/__init__.py,sha256=nQEuyVZLAS_463Dff1JH5MorTpkYsBVFCyPhYWY3UyI,606 +huggingface_hub/_hot_reload/__pycache__/__init__.cpython-313.pyc,, +huggingface_hub/_hot_reload/__pycache__/client.cpython-313.pyc,, +huggingface_hub/_hot_reload/__pycache__/sse_client.cpython-313.pyc,, +huggingface_hub/_hot_reload/__pycache__/types.cpython-313.pyc,, +huggingface_hub/_hot_reload/client.py,sha256=Ax7qT4CUi5wrg3mDzqkAG8ZzDsCwdcIIS1FIXK0SqD8,4269 +huggingface_hub/_hot_reload/sse_client.py,sha256=49kmsB2P9sxgbZ16ed6F4aLDs3rsHrNpbp6iKlvF90c,4948 +huggingface_hub/_hot_reload/types.py,sha256=d3AOJCLUxT41Fhz4jUrFevm9bfpooe_3PQhpBdgNYSs,2725 +huggingface_hub/_inference_endpoints.py,sha256=TNCEvHfu5M790bQPl4BccRzcii8WS5FlDYGrGqQzdW4,17724 +huggingface_hub/_jobs_api.py,sha256=mJ2tmCcgAv1-sgcd8_q7rGxBQZYrKtRP1BWL7-A6Et4,20912 +huggingface_hub/_local_folder.py,sha256=Fc_hikyMaZRHtXIDZj38hL7MNkq5nZZVxQF-dd-EkMo,18279 +huggingface_hub/_login.py,sha256=wAMdhqMSSh3GBJDozodmk4IIsAvb9J6LaLY9KnXFoyY,21818 +huggingface_hub/_oauth.py,sha256=S8evEd8JLJHz-JiSjGH4WiIi_A7oDox_xH7E9rN1Jic,18628 +huggingface_hub/_oidc.py,sha256=3kcCLavWQ5FQOwizUPzLaBb1ft2FIJo0bSXL24S3r4U,7098 +huggingface_hub/_sandbox.py,sha256=F6ZMchoqH8cnzdmGECqszL8JR4hcWIgGDq4QgV8W-TQ,80138 +huggingface_hub/_sandbox_cache.py,sha256=UYpvHOWZj7CRhacYs5Ot-5N1wFcAapiAyniYdoX-jX8,5742 +huggingface_hub/_snapshot_download.py,sha256=lPM92xJmc9-ejZyAU_bYl7TBAyT28Hu2jsgy7Kz1ixg,30325 +huggingface_hub/_space_api.py,sha256=MF3ezhgl0Vpt3RP1wuwZ7VI9_rSyIlIJ5SmDzIwQlcQ,13424 +huggingface_hub/_tensorboard_logger.py,sha256=GA-LhoG4Z-0Zq7w5B9vTIDJbWUkAhiG2d8a-ktlwGDY,8377 +huggingface_hub/_tree_cache.py,sha256=9JU2uOX5oQT3wK2BSUj5Yb33UUNpmybGav5d5FduzGk,5336 +huggingface_hub/_upload_large_folder.py,sha256=BWA1zyOK9W_3YUerX9YWQa3wAYtHRe_ypgsO79JEkqo,31235 +huggingface_hub/_upload_pipeline.py,sha256=19UxsZ10NB05kOXEvTN663TDE--9EBJjvxR4uI-Lg9c,28946 +huggingface_hub/_webhooks_payload.py,sha256=B9zqljcm20DGeVxJKba570i6RP-cR9CEupMGBuNDHHA,3544 +huggingface_hub/_webhooks_server.py,sha256=VXOk3FHkbIc28phxknJfaFy5B_EoKOKihoCKyOaWZQk,15767 +huggingface_hub/cli/__init__.py,sha256=tWu3Is-m2tlJwXhM_vT2mPRgpnt9KhU9qvw5aRsnjU0,664 +huggingface_hub/cli/__pycache__/__init__.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/_city_game.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/_cli_utils.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/_completion.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/_cp.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/_errors.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/_file_listing.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/_framework.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/_help_formatter.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/_output.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/_skills.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/auth.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/buckets.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/cache.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/collections.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/datasets.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/deprecated_cli.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/discussions.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/download.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/extensions.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/hf.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/inference_endpoints.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/jobs.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/lfs.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/models.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/papers.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/repo_files.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/repos.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/sandbox.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/skills.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/spaces.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/system.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/upload.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/upload_large_folder.cpython-313.pyc,, +huggingface_hub/cli/__pycache__/webhooks.cpython-313.pyc,, +huggingface_hub/cli/_city_game.py,sha256=2qkC9dCtPwf4-aqrnbN-vApf0YqIcGGjn2v-etrTfqg,20585 +huggingface_hub/cli/_cli_utils.py,sha256=Q5795puu89Kf4fEvQYPjyJmDnyqFEyEr5SW1xQXQk8I,41313 +huggingface_hub/cli/_completion.py,sha256=BDP6Vob9TLFp6K3lr0XOY98FyD-rm22KrjwsO_YGNbE,3759 +huggingface_hub/cli/_cp.py,sha256=Z-2Z_tBs1e4XBqRO5R9QnabU4qTi9HDlbA52jTBaCkY,10436 +huggingface_hub/cli/_errors.py,sha256=X0rUTO-3eCK5v_MLGEza1BxcuXGccPY-h7ShzmuQc34,5907 +huggingface_hub/cli/_file_listing.py,sha256=QRGm9oZS_g0Cv_jLQcUR6iNwBzMrsmbhs1kxwuY6rwk,7910 +huggingface_hub/cli/_framework.py,sha256=HqfAEYGWRSjKABAZi2zVNgryyU9QKW8u-tRXfR_4nQ8,27364 +huggingface_hub/cli/_help_formatter.py,sha256=-vsa3HfHQFkKWms77EGyp9i22t44ETmVt2L-e8qP-KM,1288 +huggingface_hub/cli/_output.py,sha256=A_yLkT0lzIovZV-fS7NZx7hCGiwiqJNtvUr-IbYPgpQ,13908 +huggingface_hub/cli/_skills.py,sha256=b1dlasxALM5KsDG5R1azcETksQ6ssYYZN-kaz-RdHwg,12134 +huggingface_hub/cli/auth.py,sha256=Ew79M60pTMCnS1ewKVK3fd8ZyfHrNjREOmNWuFXy37M,6056 +huggingface_hub/cli/buckets.py,sha256=J8xMP88fQ6ri3f65Z8XEImI2GNA4KKWloLJJQCBezZw,21062 +huggingface_hub/cli/cache.py,sha256=Oa3g53dUYlNIKy6crlXXGxG7lOZFa6iob0-8mMalCDc,28059 +huggingface_hub/cli/collections.py,sha256=ECTb__1zduL3F02ezGkQIaaSmUOVaeBbsGMs_8MTPcI,10078 +huggingface_hub/cli/datasets.py,sha256=X1xMJTFhHH5NJtmjTS6NN1g4ffai6Abh_obDEJM5mvo,10497 +huggingface_hub/cli/deprecated_cli.py,sha256=vAK_CR4NE9uzNJ0I59SyBnIln5nlypG4CPoohMoPMVg,1090 +huggingface_hub/cli/discussions.py,sha256=obvvN4mtsFnfMs67YTZaMvHkVaM6A-FYr5n-wGkF_jE,14029 +huggingface_hub/cli/download.py,sha256=o6fMKJoNQMxCm1RQUnX3blihJ17mantxkf0F68rZIxs,9669 +huggingface_hub/cli/extensions.py,sha256=qNM1DmzcQXt8kPWQfISc8Pvyku8BxAs-BOVP6sKRBOM,25572 +huggingface_hub/cli/hf.py,sha256=G2R-Mgo2AX09aRiAb-13eZbO441m9yDTwMCtSUf1iac,5208 +huggingface_hub/cli/inference_endpoints.py,sha256=4pfvPm5PVQizStyXGRBnrev62KvhzSNEL65UEVtRcKw,17418 +huggingface_hub/cli/jobs.py,sha256=RinTRUqX7z5xRIoFYejeenkWvq72DJy0skCWJNI_nts,47301 +huggingface_hub/cli/lfs.py,sha256=MAccazVPX0n-ySRaPocaQUHP7oBnVrvWZt0RhmNIavs,5936 +huggingface_hub/cli/models.py,sha256=eG7H5yDjCVrdL7W_-wpcl70qXlv8bC-roSEu8AroPws,10148 +huggingface_hub/cli/papers.py,sha256=HvT-8zj2fi14ua6awWpHphlbJ362FEJIwSCBJRQZ_cM,4982 +huggingface_hub/cli/repo_files.py,sha256=sGbD5wND3miF71ThfOBJm4xzPRUpJBeLFdvyj229NAM,2443 +huggingface_hub/cli/repos.py,sha256=QS3xYKvspLhCfO5VvpORrSiF6XhSVFclmBxsacVDP2c,20192 +huggingface_hub/cli/sandbox.py,sha256=rTCZf6WhoDa7UiNhsTU_4Lh5uKqKYOs73xXGAAqJGdA,18379 +huggingface_hub/cli/skills.py,sha256=JQkqD43bfr8IapIVp8rvQpd8NKA0dXSbGJD8g-u51w8,19473 +huggingface_hub/cli/spaces.py,sha256=AU655GGrQmF1s1yO8yO6ml2Z8veE7zsh4UMuR5b13RI,40800 +huggingface_hub/cli/system.py,sha256=NtICLnQ49BHFpm2Cl37IV_h21L6mufxVDfse8Lp38HA,1760 +huggingface_hub/cli/upload.py,sha256=P6sq8Dj81a2wazUgZEqbliRleVAAmJrf8ajFDDzHrBE,11318 +huggingface_hub/cli/upload_large_folder.py,sha256=A-2qxAdLrYd8IogfZS2nDhSR1cpA_aaxhXst638WkAk,4081 +huggingface_hub/cli/webhooks.py,sha256=HdpPp01c6Ece_EuNNJr46rnRki3vF4j4o9-SqYRUHnM,8550 +huggingface_hub/community.py,sha256=N5OE5Rbc2BMwpNXCFOPQAwn0otqQunsXdEnSE_0J2Xo,12325 +huggingface_hub/constants.py,sha256=eI3-JDy6jkG1EuXAjUdVdG67kbj6gxGNlr9In2-5AMc,13182 +huggingface_hub/dataclasses.py,sha256=47qPdMJMuzFFjPwqa_bRvzh7nxwXx_lXE8h3eblkxp8,25940 +huggingface_hub/errors.py,sha256=eso8GCrCcDv1Yb6NDBqyFt_Vr9PLCOsueNylNlDXMD4,18391 +huggingface_hub/fastai_utils.py,sha256=jwKeVXH_VP0zxnOKVNQCVCkF-stH70l-bExbbrYkBKQ,16583 +huggingface_hub/file_download.py,sha256=SknEqBTG26XoJS17tMTdgtqe8brUSq_AFpuq2IXS02Q,87255 +huggingface_hub/hf_api.py,sha256=NVcYiSAt2E2M73Q5jed1LAbfJYLtdIGymnx3xfUYkRE,657977 +huggingface_hub/hf_file_system.py,sha256=1Y6BqYHafnwulGNufJtzWfMU3Q3sbaW7oOqUcrNlvc4,60581 +huggingface_hub/hub_mixin.py,sha256=ljKAtm3qQsY-ARtxY-PCFx0koFXLI37JytMrzpqfnQo,36912 +huggingface_hub/inference/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +huggingface_hub/inference/__pycache__/__init__.cpython-313.pyc,, +huggingface_hub/inference/__pycache__/_client.cpython-313.pyc,, +huggingface_hub/inference/__pycache__/_common.cpython-313.pyc,, +huggingface_hub/inference/_client.py,sha256=bN5cj4tBHPD6v603uq4CJjMB_mmmpdVcfXtl9XIOVqc,157679 +huggingface_hub/inference/_common.py,sha256=X-fBP8s6xuNTAuQsGVIethE8dNQaa-mK7Ds54qVVDz8,14999 +huggingface_hub/inference/_generated/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +huggingface_hub/inference/_generated/__pycache__/__init__.cpython-313.pyc,, +huggingface_hub/inference/_generated/__pycache__/_async_client.cpython-313.pyc,, +huggingface_hub/inference/_generated/_async_client.py,sha256=imtfJD9m3qxeo_59gox3nnV8Tr8dfQF3dQF0Joy5K4g,160890 +huggingface_hub/inference/_generated/types/__init__.py,sha256=e625ENOmTUM4uUL1eAlsZOK7CovNoGBDH-TxSNQhaC4,6869 +huggingface_hub/inference/_generated/types/__pycache__/__init__.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/audio_classification.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/audio_to_audio.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/automatic_speech_recognition.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/base.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/chat_completion.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/depth_estimation.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/document_question_answering.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/feature_extraction.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/fill_mask.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/image_classification.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/image_segmentation.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/image_text_to_image.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/image_text_to_video.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/image_to_image.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/image_to_text.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/image_to_video.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/object_detection.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/question_answering.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/sentence_similarity.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/summarization.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/table_question_answering.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/text2text_generation.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/text_classification.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/text_generation.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/text_to_audio.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/text_to_image.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/text_to_speech.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/text_to_video.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/token_classification.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/translation.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/video_classification.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/visual_question_answering.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/zero_shot_classification.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/zero_shot_image_classification.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/__pycache__/zero_shot_object_detection.cpython-313.pyc,, +huggingface_hub/inference/_generated/types/audio_classification.py,sha256=DGWEvrRPX7xpXlbYY4LMojGcULdEZFTshhNR81rTNcQ,1567 +huggingface_hub/inference/_generated/types/audio_to_audio.py,sha256=2Ep4WkePL7oJwcp5nRJqApwviumGHbft9HhXE9XLHj4,891 +huggingface_hub/inference/_generated/types/automatic_speech_recognition.py,sha256=X0uCj9qwAcOmlKtV3vWH5cAgLGY0PuYIy2eSH7GE1qs,5439 +huggingface_hub/inference/_generated/types/base.py,sha256=EPWp1qudjeEimEAyQ-ptdxpAACoRM8tW342-Ds7pP3I,6938 +huggingface_hub/inference/_generated/types/chat_completion.py,sha256=3yc06ZI0NCZzsaeoxSMWyIHqGc8Vn_6aExncuXa1llE,11100 +huggingface_hub/inference/_generated/types/depth_estimation.py,sha256=5Kn4xNGJg235Cofr1lzO59eRGCuLTZun8z5t6a2do8Q,910 +huggingface_hub/inference/_generated/types/document_question_answering.py,sha256=aUZcrDGexjw8Fnm2rACm_3my77V15NnQHZxj-sa7bjo,3146 +huggingface_hub/inference/_generated/types/feature_extraction.py,sha256=DiO47PqwhdNta_KPDBsXfCPIL6BWNhyCLymxORlqUA0,1509 +huggingface_hub/inference/_generated/types/fill_mask.py,sha256=NhEskgoiMst7U_0cV_S-wryga4_2T5LgpbyQ23vHMp0,1680 +huggingface_hub/inference/_generated/types/image_classification.py,sha256=xWr4OY65EcIIhd7MI610a7xlaAVHQeydi8Gc7tlaPTU,1579 +huggingface_hub/inference/_generated/types/image_segmentation.py,sha256=lZKzbn_gkSi1sYGLb9ryeRr0aDAVrfYh0H5Iiv5JNsY,1935 +huggingface_hub/inference/_generated/types/image_text_to_image.py,sha256=pRQgYKXJbIpEjRBxuIE6NRDtk_km9DSTQ2s2qxkYJRM,2585 +huggingface_hub/inference/_generated/types/image_text_to_video.py,sha256=MVhP8D4eYjpT3hWYkkpuiME-hWY09o7C4rIn_wmnAmY,2450 +huggingface_hub/inference/_generated/types/image_to_image.py,sha256=P9TeMFSnZI_pa6DyinzDPWL0PNm_INJwsqFUEzpwIcU,2262 +huggingface_hub/inference/_generated/types/image_to_text.py,sha256=DCDS0Nqi-4AuATitvZm4EgrzYQuQEQ5lzBcaHuCmHnY,4740 +huggingface_hub/inference/_generated/types/image_to_video.py,sha256=iMCjiFTUza9AW_MyJ1videhYgvMY9QSzQ59kNdTE9QY,2206 +huggingface_hub/inference/_generated/types/object_detection.py,sha256=zNILlyZJh59rNNfqXM5x9uprDCPfEU-bvBtabeKSMzI,1965 +huggingface_hub/inference/_generated/types/question_answering.py,sha256=lIRf8DjRiAsjzWUBEsGt354SB4bvejLokf-8luHw6_o,2845 +huggingface_hub/inference/_generated/types/sentence_similarity.py,sha256=eNGiO4dR-Lft9yOLE0E97jfVyOT_ExDWZW5GeJGdatU,1027 +huggingface_hub/inference/_generated/types/summarization.py,sha256=5Dpt6LRteT-hO9esa3Ty_-xSL5U-zTtVZzy3iKwZRng,1472 +huggingface_hub/inference/_generated/types/table_question_answering.py,sha256=bwn616XJ-eLa5JKzn3m9rZZ3z63INGEUwRSOCWlEh-4,2269 +huggingface_hub/inference/_generated/types/text2text_generation.py,sha256=fotSlPWtIlp_LG26AQvNRXxU-jCUfda5PWsxCkbFeKM,1591 +huggingface_hub/inference/_generated/types/text_classification.py,sha256=uamBzz4YzWQ9mb6yuriykX8r47ZHf0K3eJpOLzB2qJw,1439 +huggingface_hub/inference/_generated/types/text_generation.py,sha256=FRUljypvCSQ2RaiylhlHeLJfHNy8qZvuty6SCB_zcaA,5813 +huggingface_hub/inference/_generated/types/text_to_audio.py,sha256=CiaTUSBdFtOs3gGTosqyQrjCwrN8mVJLRxDDWUtwZpQ,4677 +huggingface_hub/inference/_generated/types/text_to_image.py,sha256=Ju25WIDHE-1n8jlZ_udG4rpAaPYpmghR7-cDgVfuf48,1869 +huggingface_hub/inference/_generated/types/text_to_speech.py,sha256=WqDzWkhZsDcjapkoFrkyjF903SKs7aHhjypsYrn8oBw,4693 +huggingface_hub/inference/_generated/types/text_to_video.py,sha256=KjcDbtChwrIxIdTH6vcesUaMcjL2xjPf2nWEnHazj4Y,1756 +huggingface_hub/inference/_generated/types/token_classification.py,sha256=8KRBlqgFDszaUnPMvdRkZNQaZBtDfBhKZ6SggQldQMM,1894 +huggingface_hub/inference/_generated/types/translation.py,sha256=-j2PC1-qfoxvGMaKesqf5jXelqj0BDlEpfvZ7dsIEJM,1742 +huggingface_hub/inference/_generated/types/video_classification.py,sha256=vfaCqp8MuRMMtGvYCX0x4-AcwEd71kPHgSYJTNIOxLQ,1668 +huggingface_hub/inference/_generated/types/visual_question_answering.py,sha256=sWIB-SuEpW21oU6O5qQF3tt5PavUFsFOa8Xg4upTtek,1654 +huggingface_hub/inference/_generated/types/zero_shot_classification.py,sha256=gx-7WHad7xsNa89iSKSteKHjaHrKbIyzN_nSdJN3HCY,1697 +huggingface_hub/inference/_generated/types/zero_shot_image_classification.py,sha256=JZTQvcbSGrOQlWcPuJvAMT8YziDpBRn1O2RQSw507uY,1449 +huggingface_hub/inference/_generated/types/zero_shot_object_detection.py,sha256=sjdpVUN5zW9aYBymLVUs6i5HVk2qkUBO9ysEjHmsXVM,1605 +huggingface_hub/inference/_mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +huggingface_hub/inference/_mcp/__pycache__/__init__.cpython-313.pyc,, +huggingface_hub/inference/_mcp/__pycache__/_cli_hacks.cpython-313.pyc,, +huggingface_hub/inference/_mcp/__pycache__/agent.cpython-313.pyc,, +huggingface_hub/inference/_mcp/__pycache__/cli.cpython-313.pyc,, +huggingface_hub/inference/_mcp/__pycache__/constants.cpython-313.pyc,, +huggingface_hub/inference/_mcp/__pycache__/mcp_client.cpython-313.pyc,, +huggingface_hub/inference/_mcp/__pycache__/types.cpython-313.pyc,, +huggingface_hub/inference/_mcp/__pycache__/utils.cpython-313.pyc,, +huggingface_hub/inference/_mcp/_cli_hacks.py,sha256=kIA8FfRfOWS3SrZrMTbuVOjE6yxfKfMK75Co5egTWHA,3284 +huggingface_hub/inference/_mcp/agent.py,sha256=ufIzMGHore5n252hV5GZPM0ouDXIl6tv5Jl_5gHXnbg,4250 +huggingface_hub/inference/_mcp/cli.py,sha256=RKdVQ_VdEgf1AL_QBCvwrsUQ0Ux4R1yerrE46DrV5C0,9642 +huggingface_hub/inference/_mcp/constants.py,sha256=0Ih6ivEvG-pfF8NwErFngzP4Rof4lQoz6ms_eKSAkUI,2463 +huggingface_hub/inference/_mcp/mcp_client.py,sha256=dGp8PhN6aVw4bDnuSySFSiguHUiz-nzhgv89CVdO7pI,17243 +huggingface_hub/inference/_mcp/types.py,sha256=yHNfPsM9MhD06oeKdkbmrBsW-3WhUeqA26fyfRfx_bk,929 +huggingface_hub/inference/_mcp/utils.py,sha256=gxSB_rBjQ6VrkApKFsxk6-UzhijxkDVNuZrsjW5pL8k,4318 +huggingface_hub/inference/_providers/__init__.py,sha256=TNWnSNPk0RmToBysTc5D1COm0vHEJoGom0Yh7oG2wC4,9838 +huggingface_hub/inference/_providers/__pycache__/__init__.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/_common.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/cerebras.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/cohere.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/deepinfra.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/fal_ai.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/featherless_ai.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/fireworks_ai.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/groq.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/hf_inference.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/novita.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/nscale.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/openai.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/ovhcloud.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/publicai.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/replicate.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/scaleway.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/together.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/wavespeed.cpython-313.pyc,, +huggingface_hub/inference/_providers/__pycache__/zai_org.cpython-313.pyc,, +huggingface_hub/inference/_providers/_common.py,sha256=9CjlMAtb7W0-GdB1Z-VkV0GKZ0Zm68rIuicdGE-765M,13716 +huggingface_hub/inference/_providers/cerebras.py,sha256=QOJ-1U-os7uE7p6eUnn_P_APq-yQhx28be7c3Tq2EuA,210 +huggingface_hub/inference/_providers/cohere.py,sha256=P9kbIuvQ2rXI1yNmgbw5VKFFTE0huLq2k-BCyDkDico,1226 +huggingface_hub/inference/_providers/deepinfra.py,sha256=4Behgf5V7FTv7CbN6vPEIYwv1z4gztdRRU-KVoOgxVE,4703 +huggingface_hub/inference/_providers/fal_ai.py,sha256=Y2vo5Dl3e8EoehplwNshu8LbDT1e7V4ZyhAMqs0wXws,11705 +huggingface_hub/inference/_providers/featherless_ai.py,sha256=C8OHdFpoFyA--pawLTekUmUSRq4sw_r0D-cSPekD4kE,1347 +huggingface_hub/inference/_providers/fireworks_ai.py,sha256=go6XPum8u0-g768HJ_r0S4Gb445gZJxnuY_acktz-9c,1188 +huggingface_hub/inference/_providers/groq.py,sha256=JTk2JV4ZOlaohho7zLAFQtk92kGVsPmLJ1hmzcwsqvQ,315 +huggingface_hub/inference/_providers/hf_inference.py,sha256=d2vdCKSi5CtyQqYndHHvH7SY131-7YHUK3yE7653eIc,9467 +huggingface_hub/inference/_providers/novita.py,sha256=ATEoSdPAPLMfx3JpBc0sOyLh4upJYP6xHBuo4YEDYvg,2470 +huggingface_hub/inference/_providers/nscale.py,sha256=T1L2JLI9LqYT9_YEdW76YEtxfDNtdGkoFhH-p2LmSxg,1767 +huggingface_hub/inference/_providers/openai.py,sha256=wwjaaQ55xLmDsDnHpZk52xbuLoGZfWzJkFsE8AdFVaI,1054 +huggingface_hub/inference/_providers/ovhcloud.py,sha256=tdmymlkbddMJKV7NRZ-tH2wymbLPFDTqUSXpWJUXyDQ,314 +huggingface_hub/inference/_providers/publicai.py,sha256=1I2W6rORloB5QHSvky4njZO2XKLTwA-kPdNoauoT5rg,210 +huggingface_hub/inference/_providers/replicate.py,sha256=hte0ZB2RtGFwpAuLrFp2Gbgsn3EOlccCnJkWTDTW__A,6027 +huggingface_hub/inference/_providers/scaleway.py,sha256=MfIc7ZND1sPr__rOmNHZVg0VpECQo0bVyksgIm_32xQ,1174 +huggingface_hub/inference/_providers/together.py,sha256=lrymDZ86n5yoR_Zz7o3AzzSePyo0s7BOBU5digLxb5o,12220 +huggingface_hub/inference/_providers/wavespeed.py,sha256=MGM7Y7r2nQiH_EH0t5UE1o1fT-o3sS7RaQlicS9WHsg,5028 +huggingface_hub/inference/_providers/zai_org.py,sha256=gLJZOEmCPmUZvdM7VDn2nxm4ac3veHdoMgQNR63UeWE,4739 +huggingface_hub/lfs.py,sha256=8ymYNHRXgvgUUM9w0EAnC-vkSOOq_1EFJEJNoevoeE8,16588 +huggingface_hub/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +huggingface_hub/repocard.py,sha256=ytBgqomIuM3zOeTPfzQNk_stlswh8DttLDvTbX_woPI,35582 +huggingface_hub/repocard_data.py,sha256=CRW3puz-efDcoGjKIgZv6p3LKKKYVgcy-FGr96zAFOg,34251 +huggingface_hub/serialization/__init__.py,sha256=jCiw_vVQYW52gwVfWiqgocf2Q19kGTQlRGVpf-4SLP8,963 +huggingface_hub/serialization/__pycache__/__init__.cpython-313.pyc,, +huggingface_hub/serialization/__pycache__/_base.cpython-313.pyc,, +huggingface_hub/serialization/__pycache__/_dduf.cpython-313.pyc,, +huggingface_hub/serialization/__pycache__/_torch.cpython-313.pyc,, +huggingface_hub/serialization/_base.py,sha256=8vYeDIsqgyOO3I_uii44Bkb50LsMz3kkD4gwAPzhfWU,8436 +huggingface_hub/serialization/_dduf.py,sha256=FmGRg5wkXI5sNCgZgCNJFmqb_nVrrQYOHf4Lqq0d64I,15385 +huggingface_hub/serialization/_torch.py,sha256=BtaCP-G3oYRP6Pj9MhI-ygBsk3JbBPnVDW9huSOgtkk,46897 +huggingface_hub/templates/datasetcard_template.md,sha256=W-EMqR6wndbrnZorkVv56URWPG49l7MATGeI015kTvs,5503 +huggingface_hub/templates/modelcard_template.md,sha256=4AqArS3cqdtbit5Bo-DhjcnDFR-pza5hErLLTPM4Yuc,6870 +huggingface_hub/utils/__init__.py,sha256=SHfYVviFx_oyeA0EFOz4kXFeRg-SAbDlgyb8tk4TpeU,4026 +huggingface_hub/utils/__pycache__/__init__.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_auth.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_cache_assets.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_cache_manager.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_chunk_utils.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_datetime.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_deprecation.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_detect_agent.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_dotenv.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_experimental.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_fixes.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_git_credential.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_headers.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_hf_uris.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_http.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_lfs.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_oauth_device.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_pagination.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_parsing.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_paths.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_runtime.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_safetensors.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_subprocess.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_telemetry.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_terminal.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_typing.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_validators.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_verification.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_xet.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/_xet_progress_reporting.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/endpoint_helpers.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/insecure_hashlib.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/logging.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/sha.cpython-313.pyc,, +huggingface_hub/utils/__pycache__/tqdm.cpython-313.pyc,, +huggingface_hub/utils/_auth.py,sha256=Ykuq3yi67jxHmFdyLSc43xvGuCAIR7-h-dajX8IxpGQ,19958 +huggingface_hub/utils/_cache_assets.py,sha256=nnzHRtQAR50dQeIK6qKddsmjjTW9v9HZ7b9bq7PJqss,5691 +huggingface_hub/utils/_cache_manager.py,sha256=2StxP-nHZ5W9_hi8N9wBFqRNLw5HwO0h9HC7NTAGaFE,34955 +huggingface_hub/utils/_chunk_utils.py,sha256=pTjy8Z-KLU4W_6D3OUh3E8lCodWDCd6aJwjNDU0C5U8,2121 +huggingface_hub/utils/_datetime.py,sha256=tbNyI0Dkh27oScPUtLIT_8apqIIkXZYbigjOn9S3aMw,2755 +huggingface_hub/utils/_deprecation.py,sha256=n4kNHbGipquSObJ-gxodcfd6lqoe_8s-VIsTuo3Oruk,4865 +huggingface_hub/utils/_detect_agent.py,sha256=Iw2KW9BUZWfIypn9CtiTmEibHwKK9xx5Ar48z1cMU-Q,7337 +huggingface_hub/utils/_dotenv.py,sha256=NdlEM8OXtzwlwmJCmdc6oGubFObrpgr408y8gnSs7ls,2604 +huggingface_hub/utils/_experimental.py,sha256=q9vUvc1JybVFRQ0GRREG-BLouZEJC_40MxcwbAlOud0,2464 +huggingface_hub/utils/_fixes.py,sha256=jTK1VLmc0ZC9ROSXjKoL5F6kOZFByzirRWIdXxhBfWU,4124 +huggingface_hub/utils/_git_credential.py,sha256=1BhjvIScCOAToDORLOKrR3Szs-m0E5AYHPmC0SD7Nrs,4548 +huggingface_hub/utils/_headers.py,sha256=Q9bu9mvOpm-9rfv-YRlr_Ywy_aMZkmRcN3MbVEcJAJA,8234 +huggingface_hub/utils/_hf_uris.py,sha256=RTHrVKLT5vVU-ca8roXHrKwbN3njowanvxHjx5B4sUg,27558 +huggingface_hub/utils/_http.py,sha256=C_mC63TsaxpmzyYBPHCneXKFLACEytAkBwxRwMNxcB4,46014 +huggingface_hub/utils/_lfs.py,sha256=xMU-ROgNAUpDkzbH6yRZsE-eVYUYTNMGrgVb_QdTv-k,3942 +huggingface_hub/utils/_oauth_device.py,sha256=o7ICmI01yDt1oAFNMUJvN1ThSfaCDpC8AHYSQgcnFGw,7983 +huggingface_hub/utils/_pagination.py,sha256=h-TJjFbX3FqkA1T0tGZ0EhxMvuRSCg-UfL_a-BMs54I,1943 +huggingface_hub/utils/_parsing.py,sha256=DVWuO6s_XMiGfXyc0jyX5hi_yGgBHpF9KLoeQM-VVK0,3586 +huggingface_hub/utils/_paths.py,sha256=kWpUMIK9rmKb2LHgHCkk2DnroDzucrwbj-urCJCgfGw,5962 +huggingface_hub/utils/_runtime.py,sha256=GVJ_Dt6y_48TZWl0ui9yPdW8M7rqGblRGyUqKaXxkCo,13493 +huggingface_hub/utils/_safetensors.py,sha256=qFE7OA-vjU8X0zBBtOeNRzLu147KF-PdFoaxkYfWB4M,4426 +huggingface_hub/utils/_subprocess.py,sha256=tFVBBNot_HLVqQ79y873TGb12C4PUTMwub-GhzDTemE,4542 +huggingface_hub/utils/_telemetry.py,sha256=Tpa3YmOLhK_MEnL2i2fRLQy8aqAEZWbj6MKC18Hs8BA,4824 +huggingface_hub/utils/_terminal.py,sha256=whHgs0Co-1LatoCmJE_ojqE_cWP6b5dWPWpU-uSFWUU,8969 +huggingface_hub/utils/_typing.py,sha256=1LeE785YedppXSR9a1fQDu5rhTxX5v9kBYBaHrP65rA,3542 +huggingface_hub/utils/_validators.py,sha256=tuC1U4yxB-4XKIajZMnKZUSKvZ6qPpydY8LItfa0g40,8419 +huggingface_hub/utils/_verification.py,sha256=ZSilnolSkYmHB3vmBlWuuVr53xz59P5uGnxC3H-Hjc0,5434 +huggingface_hub/utils/_xet.py,sha256=YtEzhvXi21VB4DtrnqGiSh2_Ox77XhVzLlDIwcnYxj0,6305 +huggingface_hub/utils/_xet_progress_reporting.py,sha256=MoEdaxjKpuKip8YWPfPdIDf9JVmNlj7DuBlUbaqCx8o,13683 +huggingface_hub/utils/endpoint_helpers.py,sha256=9VtIAlxQ5H_4y30sjCAgbu7XCqAtNLC7aRYxaNn0hLI,2366 +huggingface_hub/utils/insecure_hashlib.py,sha256=z3dVUFvdBZ8kQI_8Vzvvlr3ims-EBiY-SYPdnzIKOkw,1008 +huggingface_hub/utils/logging.py,sha256=WaXk5gRa8Ml_LUIH34QCr8suYj8i_8Wot4IDnYJyWyM,4870 +huggingface_hub/utils/sha.py,sha256=h8wxheZpcv671RhtiIFcFmQTDSrogN3kwQx3ZaNEUHg,2121 +huggingface_hub/utils/tqdm.py,sha256=KbHhkB5g76JgGOGCcjAQOaR-oc-wzd4Sr3wqd41ny7k,13350 diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/WHEEL b/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..1d472b6c22838de58d1c3c0dd2c795a5cde9e415 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (83.0.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/entry_points.txt b/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/entry_points.txt new file mode 100644 index 0000000000000000000000000000000000000000..62018f2f5622f61920179a20b80488f21dbb1686 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/entry_points.txt @@ -0,0 +1,7 @@ +[console_scripts] +hf = huggingface_hub.cli.hf:main +huggingface-cli = huggingface_hub.cli.deprecated_cli:main +tiny-agents = huggingface_hub.inference._mcp.cli:app + +[fsspec.specs] +hf = huggingface_hub.HfFileSystem diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/licenses/LICENSE b/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/licenses/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/licenses/LICENSE @@ -0,0 +1,201 @@ + 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/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/top_level.txt b/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..6b964ccca3c1b6766042b3fe3b2707ba25372924 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub-1.23.0.dist-info/top_level.txt @@ -0,0 +1 @@ +huggingface_hub diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/__init__.py b/.venv/lib/python3.13/site-packages/huggingface_hub/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..272daf9d63e45b7fe82b619554e5aa59801b308a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/__init__.py @@ -0,0 +1,1804 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# 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. + +# *********** +# `huggingface_hub` init has 2 modes: +# - Normal usage: +# If imported to use it, all modules and functions are lazy-loaded. This means +# they exist at top level in module but are imported only the first time they are +# used. This way, `from huggingface_hub import something` will import `something` +# quickly without the hassle of importing all the features from `huggingface_hub`. +# - Static check: +# If statically analyzed, all modules and functions are loaded normally. This way +# static typing check works properly as well as autocomplete in text editors and +# IDEs. +# +# The static model imports are done inside the `if TYPE_CHECKING:` statement at +# the bottom of this file. Since module/functions imports are duplicated, it is +# mandatory to make sure to add them twice when adding one. This is checked in the +# `make quality` command. +# +# To update the static imports, please run the following command and commit the changes. +# ``` +# # Use script +# python utils/check_static_imports.py --update-file +# +# # Or run style on codebase +# make style +# ``` +# +# *********** +# Lazy loader vendored from https://github.com/scientific-python/lazy_loader +import importlib +import os +import sys +from typing import TYPE_CHECKING + + +__version__ = "1.23.0" + +# Alphabetical order of definitions is ensured in tests +# WARNING: any comment added in this dictionary definition will be lost when +# re-generating the file ! +_SUBMOD_ATTRS = { + "_buckets": [ + "BucketFile", + "BucketFileMetadata", + "BucketFolder", + "BucketInfo", + "BucketUrl", + "SyncOperation", + "SyncPlan", + ], + "_commit_scheduler": [ + "CommitScheduler", + ], + "_eval_results": [ + "EvalResultEntry", + "eval_result_entries_to_yaml", + "parse_eval_result_entries", + ], + "_inference_endpoints": [ + "InferenceEndpoint", + "InferenceEndpointError", + "InferenceEndpointStatus", + "InferenceEndpointTimeoutError", + "InferenceEndpointType", + ], + "_jobs_api": [ + "JobAccelerator", + "JobDurations", + "JobHardware", + "JobHardwareInfo", + "JobInfo", + "JobInitiator", + "JobOwner", + "JobStage", + "JobStatus", + ], + "_login": [ + "auth_list", + "auth_switch", + "interpreter_login", + "login", + "logout", + "notebook_login", + ], + "_oauth": [ + "OAuthInfo", + "OAuthOrgInfo", + "OAuthUserInfo", + "attach_huggingface_oauth", + "parse_huggingface_oauth", + ], + "_sandbox": [ + "Sandbox", + "SandboxCommandResult", + "SandboxPool", + "SandboxProcess", + ], + "_snapshot_download": [ + "get_cached_repo_tree", + "snapshot_download", + ], + "_space_api": [ + "SpaceHardware", + "SpaceRuntime", + "SpaceSecret", + "SpaceStage", + "SpaceStorage", + "SpaceVariable", + "Volume", + ], + "_tensorboard_logger": [ + "HFSummaryWriter", + ], + "_webhooks_payload": [ + "WebhookPayload", + "WebhookPayloadComment", + "WebhookPayloadDiscussion", + "WebhookPayloadDiscussionChanges", + "WebhookPayloadEvent", + "WebhookPayloadMovedTo", + "WebhookPayloadRepo", + "WebhookPayloadUrl", + "WebhookPayloadWebhook", + ], + "_webhooks_server": [ + "WebhooksServer", + "webhook_endpoint", + ], + "cli._cli_utils": [ + "check_cli_update", + "typer_factory", + ], + "community": [ + "Discussion", + "DiscussionComment", + "DiscussionCommit", + "DiscussionEvent", + "DiscussionStatusChange", + "DiscussionTitleChange", + "DiscussionWithDetails", + ], + "constants": [ + "CONFIG_NAME", + "FLAX_WEIGHTS_NAME", + "HUGGINGFACE_CO_URL_HOME", + "HUGGINGFACE_CO_URL_TEMPLATE", + "PYTORCH_WEIGHTS_NAME", + "REPO_TYPE_DATASET", + "REPO_TYPE_MODEL", + "REPO_TYPE_SPACE", + "TF2_WEIGHTS_NAME", + "TF_WEIGHTS_NAME", + "is_offline_mode", + ], + "fastai_utils": [ + "_save_pretrained_fastai", + "from_pretrained_fastai", + "push_to_hub_fastai", + ], + "file_download": [ + "DryRunFileInfo", + "HfFileMetadata", + "_CACHED_NO_EXIST", + "get_hf_file_metadata", + "hf_hub_download", + "hf_hub_url", + "try_to_load_from_cache", + ], + "hf_api": [ + "Collection", + "CollectionItem", + "CommitInfo", + "CommitOperation", + "CommitOperationAdd", + "CommitOperationCopy", + "CommitOperationDelete", + "DatasetInfo", + "DatasetLeaderboardEntry", + "GitCommitInfo", + "GitRefInfo", + "GitRefs", + "HfApi", + "KernelInfo", + "ModelInfo", + "Organization", + "RepoFile", + "RepoFolder", + "RepoStorageInfo", + "RepoUrl", + "SpaceInfo", + "SpaceSearchResult", + "SpaceTemplate", + "User", + "UserLikes", + "WebhookInfo", + "WebhookWatchedItem", + "accept_access_request", + "add_collection_item", + "add_space_secret", + "add_space_variable", + "auth_check", + "batch_bucket_files", + "bucket_info", + "cancel_access_request", + "cancel_job", + "change_discussion_status", + "comment_discussion", + "copy_files", + "create_branch", + "create_bucket", + "create_collection", + "create_commit", + "create_discussion", + "create_inference_endpoint", + "create_inference_endpoint_from_catalog", + "create_pull_request", + "create_repo", + "create_scheduled_job", + "create_scheduled_uv_job", + "create_tag", + "create_webhook", + "dataset_info", + "delete_branch", + "delete_bucket", + "delete_collection", + "delete_collection_item", + "delete_file", + "delete_folder", + "delete_inference_endpoint", + "delete_repo", + "delete_scheduled_job", + "delete_space_secret", + "delete_space_storage", + "delete_space_variable", + "delete_space_volumes", + "delete_tag", + "delete_webhook", + "disable_space_dev_mode", + "disable_webhook", + "download_bucket_files", + "duplicate_repo", + "duplicate_space", + "edit_discussion_comment", + "enable_space_dev_mode", + "enable_webhook", + "fetch_job_logs", + "fetch_job_metrics", + "fetch_space_logs", + "file_exists", + "get_bucket_file_metadata", + "get_bucket_paths_info", + "get_collection", + "get_dataset_leaderboard", + "get_dataset_tags", + "get_discussion_details", + "get_full_repo_name", + "get_inference_endpoint", + "get_local_safetensors_metadata", + "get_model_tags", + "get_organization_overview", + "get_paths_info", + "get_repo_discussions", + "get_safetensors_metadata", + "get_space_runtime", + "get_space_secrets", + "get_space_variables", + "get_user_overview", + "get_webhook", + "grant_access", + "inspect_job", + "inspect_scheduled_job", + "kernel_info", + "list_accepted_access_requests", + "list_bucket_tree", + "list_buckets", + "list_collections", + "list_daily_papers", + "list_dataset_parquet_files", + "list_datasets", + "list_inference_catalog", + "list_inference_endpoints", + "list_jobs", + "list_jobs_hardware", + "list_lfs_files", + "list_liked_repos", + "list_models", + "list_organization_followers", + "list_organization_members", + "list_papers", + "list_pending_access_requests", + "list_rejected_access_requests", + "list_repo_commits", + "list_repo_files", + "list_repo_likers", + "list_repo_refs", + "list_repo_tree", + "list_space_templates", + "list_spaces", + "list_spaces_hardware", + "list_user_followers", + "list_user_following", + "list_user_repos", + "list_webhooks", + "merge_pull_request", + "model_info", + "move_bucket", + "move_repo", + "paper_info", + "parse_local_safetensors_file_metadata", + "parse_safetensors_file_metadata", + "pause_inference_endpoint", + "pause_space", + "permanently_delete_lfs_files", + "preupload_lfs_files", + "read_paper", + "reject_access_request", + "rename_discussion", + "repo_exists", + "repo_info", + "repo_type_and_id_from_hf_id", + "request_space_hardware", + "request_space_storage", + "restart_space", + "resume_inference_endpoint", + "resume_scheduled_job", + "revision_exists", + "run_as_future", + "run_job", + "run_uv_job", + "scale_to_zero_inference_endpoint", + "search_spaces", + "set_space_sleep_time", + "set_space_volumes", + "space_info", + "super_squash_history", + "suspend_scheduled_job", + "sync_bucket", + "sync_job_volume", + "trigger_scheduled_job", + "unlike", + "update_collection_item", + "update_collection_metadata", + "update_inference_endpoint", + "update_job_labels", + "update_repo_settings", + "update_scheduled_job_labels", + "update_webhook", + "upload_file", + "upload_folder", + "upload_large_folder", + "verify_repo_checksums", + "wait_for_job", + "wait_for_space", + "whoami", + ], + "hf_file_system": [ + "HfFileSystem", + "HfFileSystemFile", + "HfFileSystemResolvedPath", + "HfFileSystemStreamFile", + "hffs", + ], + "hub_mixin": [ + "ModelHubMixin", + "PyTorchModelHubMixin", + ], + "inference._client": [ + "InferenceClient", + "InferenceTimeoutError", + ], + "inference._generated._async_client": [ + "AsyncInferenceClient", + ], + "inference._generated.types": [ + "AudioClassificationInput", + "AudioClassificationOutputElement", + "AudioClassificationOutputTransform", + "AudioClassificationParameters", + "AudioToAudioInput", + "AudioToAudioOutputElement", + "AutomaticSpeechRecognitionEarlyStoppingEnum", + "AutomaticSpeechRecognitionGenerationParameters", + "AutomaticSpeechRecognitionInput", + "AutomaticSpeechRecognitionOutput", + "AutomaticSpeechRecognitionOutputChunk", + "AutomaticSpeechRecognitionParameters", + "ChatCompletionInput", + "ChatCompletionInputFunctionDefinition", + "ChatCompletionInputFunctionName", + "ChatCompletionInputGrammarType", + "ChatCompletionInputJSONSchema", + "ChatCompletionInputMessage", + "ChatCompletionInputMessageChunk", + "ChatCompletionInputMessageChunkType", + "ChatCompletionInputResponseFormatJSONObject", + "ChatCompletionInputResponseFormatJSONSchema", + "ChatCompletionInputResponseFormatText", + "ChatCompletionInputStreamOptions", + "ChatCompletionInputTool", + "ChatCompletionInputToolCall", + "ChatCompletionInputToolChoiceClass", + "ChatCompletionInputToolChoiceEnum", + "ChatCompletionInputURL", + "ChatCompletionOutput", + "ChatCompletionOutputComplete", + "ChatCompletionOutputFunctionDefinition", + "ChatCompletionOutputLogprob", + "ChatCompletionOutputLogprobs", + "ChatCompletionOutputMessage", + "ChatCompletionOutputToolCall", + "ChatCompletionOutputTopLogprob", + "ChatCompletionOutputUsage", + "ChatCompletionStreamOutput", + "ChatCompletionStreamOutputChoice", + "ChatCompletionStreamOutputDelta", + "ChatCompletionStreamOutputDeltaToolCall", + "ChatCompletionStreamOutputFunction", + "ChatCompletionStreamOutputLogprob", + "ChatCompletionStreamOutputLogprobs", + "ChatCompletionStreamOutputTopLogprob", + "ChatCompletionStreamOutputUsage", + "DepthEstimationInput", + "DepthEstimationOutput", + "DocumentQuestionAnsweringInput", + "DocumentQuestionAnsweringInputData", + "DocumentQuestionAnsweringOutputElement", + "DocumentQuestionAnsweringParameters", + "FeatureExtractionInput", + "FeatureExtractionInputTruncationDirection", + "FillMaskInput", + "FillMaskOutputElement", + "FillMaskParameters", + "ImageClassificationInput", + "ImageClassificationOutputElement", + "ImageClassificationOutputTransform", + "ImageClassificationParameters", + "ImageSegmentationInput", + "ImageSegmentationOutputElement", + "ImageSegmentationParameters", + "ImageSegmentationSubtask", + "ImageTextToImageInput", + "ImageTextToImageOutput", + "ImageTextToImageParameters", + "ImageTextToImageTargetSize", + "ImageTextToVideoInput", + "ImageTextToVideoOutput", + "ImageTextToVideoParameters", + "ImageTextToVideoTargetSize", + "ImageToImageInput", + "ImageToImageOutput", + "ImageToImageParameters", + "ImageToImageTargetSize", + "ImageToTextEarlyStoppingEnum", + "ImageToTextGenerationParameters", + "ImageToTextInput", + "ImageToTextOutput", + "ImageToTextParameters", + "ImageToVideoInput", + "ImageToVideoOutput", + "ImageToVideoParameters", + "ImageToVideoTargetSize", + "ObjectDetectionBoundingBox", + "ObjectDetectionInput", + "ObjectDetectionOutputElement", + "ObjectDetectionParameters", + "Padding", + "QuestionAnsweringInput", + "QuestionAnsweringInputData", + "QuestionAnsweringOutputElement", + "QuestionAnsweringParameters", + "SentenceSimilarityInput", + "SentenceSimilarityInputData", + "SummarizationInput", + "SummarizationOutput", + "SummarizationParameters", + "SummarizationTruncationStrategy", + "TableQuestionAnsweringInput", + "TableQuestionAnsweringInputData", + "TableQuestionAnsweringOutputElement", + "TableQuestionAnsweringParameters", + "Text2TextGenerationInput", + "Text2TextGenerationOutput", + "Text2TextGenerationParameters", + "Text2TextGenerationTruncationStrategy", + "TextClassificationInput", + "TextClassificationOutputElement", + "TextClassificationOutputTransform", + "TextClassificationParameters", + "TextGenerationInput", + "TextGenerationInputGenerateParameters", + "TextGenerationInputGrammarType", + "TextGenerationOutput", + "TextGenerationOutputBestOfSequence", + "TextGenerationOutputDetails", + "TextGenerationOutputFinishReason", + "TextGenerationOutputPrefillToken", + "TextGenerationOutputToken", + "TextGenerationStreamOutput", + "TextGenerationStreamOutputStreamDetails", + "TextGenerationStreamOutputToken", + "TextToAudioEarlyStoppingEnum", + "TextToAudioGenerationParameters", + "TextToAudioInput", + "TextToAudioOutput", + "TextToAudioParameters", + "TextToImageInput", + "TextToImageOutput", + "TextToImageParameters", + "TextToSpeechEarlyStoppingEnum", + "TextToSpeechGenerationParameters", + "TextToSpeechInput", + "TextToSpeechOutput", + "TextToSpeechParameters", + "TextToVideoInput", + "TextToVideoOutput", + "TextToVideoParameters", + "TokenClassificationAggregationStrategy", + "TokenClassificationInput", + "TokenClassificationOutputElement", + "TokenClassificationParameters", + "TranslationInput", + "TranslationOutput", + "TranslationParameters", + "TranslationTruncationStrategy", + "TypeEnum", + "VideoClassificationInput", + "VideoClassificationOutputElement", + "VideoClassificationOutputTransform", + "VideoClassificationParameters", + "VisualQuestionAnsweringInput", + "VisualQuestionAnsweringInputData", + "VisualQuestionAnsweringOutputElement", + "VisualQuestionAnsweringParameters", + "ZeroShotClassificationInput", + "ZeroShotClassificationOutputElement", + "ZeroShotClassificationParameters", + "ZeroShotImageClassificationInput", + "ZeroShotImageClassificationOutputElement", + "ZeroShotImageClassificationParameters", + "ZeroShotObjectDetectionBoundingBox", + "ZeroShotObjectDetectionInput", + "ZeroShotObjectDetectionOutputElement", + "ZeroShotObjectDetectionParameters", + ], + "inference._mcp.agent": [ + "Agent", + ], + "inference._mcp.mcp_client": [ + "MCPClient", + ], + "repocard": [ + "DatasetCard", + "ModelCard", + "RepoCard", + "SpaceCard", + "metadata_eval_result", + "metadata_load", + "metadata_save", + "metadata_update", + ], + "repocard_data": [ + "CardData", + "DatasetCardData", + "EvalResult", + "ModelCardData", + "SpaceCardData", + ], + "serialization": [ + "StateDictSplit", + "get_torch_storage_id", + "get_torch_storage_size", + "load_state_dict_from_file", + "load_torch_model", + "save_torch_model", + "save_torch_state_dict", + "split_state_dict_into_shards_factory", + "split_torch_state_dict_into_shards", + ], + "serialization._dduf": [ + "DDUFEntry", + "export_entries_as_dduf", + "export_folder_as_dduf", + "read_dduf_file", + ], + "utils": [ + "ASYNC_CLIENT_FACTORY_T", + "CLIENT_FACTORY_T", + "CacheNotFound", + "CachedFileInfo", + "CachedIncompleteFileInfo", + "CachedRepoInfo", + "CachedRevisionInfo", + "CorruptedCacheException", + "DeleteCacheStrategy", + "HFCacheInfo", + "HfUri", + "cached_assets_path", + "close_session", + "dump_environment_info", + "get_async_session", + "get_session", + "get_token", + "hf_raise_for_status", + "logging", + "parse_hf_uri", + "scan_cache_dir", + "set_async_client_factory", + "set_client_factory", + ], +} + +# WARNING: __all__ is generated automatically, Any manual edit will be lost when re-generating this file ! +# +# To update the static imports, please run the following command and commit the changes. +# ``` +# # Use script +# python utils/check_all_variable.py --update +# +# # Or run style on codebase +# make style +# ``` + +__all__ = [ + "ASYNC_CLIENT_FACTORY_T", + "Agent", + "AsyncInferenceClient", + "AudioClassificationInput", + "AudioClassificationOutputElement", + "AudioClassificationOutputTransform", + "AudioClassificationParameters", + "AudioToAudioInput", + "AudioToAudioOutputElement", + "AutomaticSpeechRecognitionEarlyStoppingEnum", + "AutomaticSpeechRecognitionGenerationParameters", + "AutomaticSpeechRecognitionInput", + "AutomaticSpeechRecognitionOutput", + "AutomaticSpeechRecognitionOutputChunk", + "AutomaticSpeechRecognitionParameters", + "BucketFile", + "BucketFileMetadata", + "BucketFolder", + "BucketInfo", + "BucketUrl", + "CLIENT_FACTORY_T", + "CONFIG_NAME", + "CacheNotFound", + "CachedFileInfo", + "CachedIncompleteFileInfo", + "CachedRepoInfo", + "CachedRevisionInfo", + "CardData", + "ChatCompletionInput", + "ChatCompletionInputFunctionDefinition", + "ChatCompletionInputFunctionName", + "ChatCompletionInputGrammarType", + "ChatCompletionInputJSONSchema", + "ChatCompletionInputMessage", + "ChatCompletionInputMessageChunk", + "ChatCompletionInputMessageChunkType", + "ChatCompletionInputResponseFormatJSONObject", + "ChatCompletionInputResponseFormatJSONSchema", + "ChatCompletionInputResponseFormatText", + "ChatCompletionInputStreamOptions", + "ChatCompletionInputTool", + "ChatCompletionInputToolCall", + "ChatCompletionInputToolChoiceClass", + "ChatCompletionInputToolChoiceEnum", + "ChatCompletionInputURL", + "ChatCompletionOutput", + "ChatCompletionOutputComplete", + "ChatCompletionOutputFunctionDefinition", + "ChatCompletionOutputLogprob", + "ChatCompletionOutputLogprobs", + "ChatCompletionOutputMessage", + "ChatCompletionOutputToolCall", + "ChatCompletionOutputTopLogprob", + "ChatCompletionOutputUsage", + "ChatCompletionStreamOutput", + "ChatCompletionStreamOutputChoice", + "ChatCompletionStreamOutputDelta", + "ChatCompletionStreamOutputDeltaToolCall", + "ChatCompletionStreamOutputFunction", + "ChatCompletionStreamOutputLogprob", + "ChatCompletionStreamOutputLogprobs", + "ChatCompletionStreamOutputTopLogprob", + "ChatCompletionStreamOutputUsage", + "Collection", + "CollectionItem", + "CommitInfo", + "CommitOperation", + "CommitOperationAdd", + "CommitOperationCopy", + "CommitOperationDelete", + "CommitScheduler", + "CorruptedCacheException", + "DDUFEntry", + "DatasetCard", + "DatasetCardData", + "DatasetInfo", + "DatasetLeaderboardEntry", + "DeleteCacheStrategy", + "DepthEstimationInput", + "DepthEstimationOutput", + "Discussion", + "DiscussionComment", + "DiscussionCommit", + "DiscussionEvent", + "DiscussionStatusChange", + "DiscussionTitleChange", + "DiscussionWithDetails", + "DocumentQuestionAnsweringInput", + "DocumentQuestionAnsweringInputData", + "DocumentQuestionAnsweringOutputElement", + "DocumentQuestionAnsweringParameters", + "DryRunFileInfo", + "EvalResult", + "EvalResultEntry", + "FLAX_WEIGHTS_NAME", + "FeatureExtractionInput", + "FeatureExtractionInputTruncationDirection", + "FillMaskInput", + "FillMaskOutputElement", + "FillMaskParameters", + "GitCommitInfo", + "GitRefInfo", + "GitRefs", + "HFCacheInfo", + "HFSummaryWriter", + "HUGGINGFACE_CO_URL_HOME", + "HUGGINGFACE_CO_URL_TEMPLATE", + "HfApi", + "HfFileMetadata", + "HfFileSystem", + "HfFileSystemFile", + "HfFileSystemResolvedPath", + "HfFileSystemStreamFile", + "HfUri", + "ImageClassificationInput", + "ImageClassificationOutputElement", + "ImageClassificationOutputTransform", + "ImageClassificationParameters", + "ImageSegmentationInput", + "ImageSegmentationOutputElement", + "ImageSegmentationParameters", + "ImageSegmentationSubtask", + "ImageTextToImageInput", + "ImageTextToImageOutput", + "ImageTextToImageParameters", + "ImageTextToImageTargetSize", + "ImageTextToVideoInput", + "ImageTextToVideoOutput", + "ImageTextToVideoParameters", + "ImageTextToVideoTargetSize", + "ImageToImageInput", + "ImageToImageOutput", + "ImageToImageParameters", + "ImageToImageTargetSize", + "ImageToTextEarlyStoppingEnum", + "ImageToTextGenerationParameters", + "ImageToTextInput", + "ImageToTextOutput", + "ImageToTextParameters", + "ImageToVideoInput", + "ImageToVideoOutput", + "ImageToVideoParameters", + "ImageToVideoTargetSize", + "InferenceClient", + "InferenceEndpoint", + "InferenceEndpointError", + "InferenceEndpointStatus", + "InferenceEndpointTimeoutError", + "InferenceEndpointType", + "InferenceTimeoutError", + "JobAccelerator", + "JobDurations", + "JobHardware", + "JobHardwareInfo", + "JobInfo", + "JobInitiator", + "JobOwner", + "JobStage", + "JobStatus", + "KernelInfo", + "MCPClient", + "ModelCard", + "ModelCardData", + "ModelHubMixin", + "ModelInfo", + "OAuthInfo", + "OAuthOrgInfo", + "OAuthUserInfo", + "ObjectDetectionBoundingBox", + "ObjectDetectionInput", + "ObjectDetectionOutputElement", + "ObjectDetectionParameters", + "Organization", + "PYTORCH_WEIGHTS_NAME", + "Padding", + "PyTorchModelHubMixin", + "QuestionAnsweringInput", + "QuestionAnsweringInputData", + "QuestionAnsweringOutputElement", + "QuestionAnsweringParameters", + "REPO_TYPE_DATASET", + "REPO_TYPE_MODEL", + "REPO_TYPE_SPACE", + "RepoCard", + "RepoFile", + "RepoFolder", + "RepoStorageInfo", + "RepoUrl", + "Sandbox", + "SandboxCommandResult", + "SandboxPool", + "SandboxProcess", + "SentenceSimilarityInput", + "SentenceSimilarityInputData", + "SpaceCard", + "SpaceCardData", + "SpaceHardware", + "SpaceInfo", + "SpaceRuntime", + "SpaceSearchResult", + "SpaceSecret", + "SpaceStage", + "SpaceStorage", + "SpaceTemplate", + "SpaceVariable", + "StateDictSplit", + "SummarizationInput", + "SummarizationOutput", + "SummarizationParameters", + "SummarizationTruncationStrategy", + "SyncOperation", + "SyncPlan", + "TF2_WEIGHTS_NAME", + "TF_WEIGHTS_NAME", + "TableQuestionAnsweringInput", + "TableQuestionAnsweringInputData", + "TableQuestionAnsweringOutputElement", + "TableQuestionAnsweringParameters", + "Text2TextGenerationInput", + "Text2TextGenerationOutput", + "Text2TextGenerationParameters", + "Text2TextGenerationTruncationStrategy", + "TextClassificationInput", + "TextClassificationOutputElement", + "TextClassificationOutputTransform", + "TextClassificationParameters", + "TextGenerationInput", + "TextGenerationInputGenerateParameters", + "TextGenerationInputGrammarType", + "TextGenerationOutput", + "TextGenerationOutputBestOfSequence", + "TextGenerationOutputDetails", + "TextGenerationOutputFinishReason", + "TextGenerationOutputPrefillToken", + "TextGenerationOutputToken", + "TextGenerationStreamOutput", + "TextGenerationStreamOutputStreamDetails", + "TextGenerationStreamOutputToken", + "TextToAudioEarlyStoppingEnum", + "TextToAudioGenerationParameters", + "TextToAudioInput", + "TextToAudioOutput", + "TextToAudioParameters", + "TextToImageInput", + "TextToImageOutput", + "TextToImageParameters", + "TextToSpeechEarlyStoppingEnum", + "TextToSpeechGenerationParameters", + "TextToSpeechInput", + "TextToSpeechOutput", + "TextToSpeechParameters", + "TextToVideoInput", + "TextToVideoOutput", + "TextToVideoParameters", + "TokenClassificationAggregationStrategy", + "TokenClassificationInput", + "TokenClassificationOutputElement", + "TokenClassificationParameters", + "TranslationInput", + "TranslationOutput", + "TranslationParameters", + "TranslationTruncationStrategy", + "TypeEnum", + "User", + "UserLikes", + "VideoClassificationInput", + "VideoClassificationOutputElement", + "VideoClassificationOutputTransform", + "VideoClassificationParameters", + "VisualQuestionAnsweringInput", + "VisualQuestionAnsweringInputData", + "VisualQuestionAnsweringOutputElement", + "VisualQuestionAnsweringParameters", + "Volume", + "WebhookInfo", + "WebhookPayload", + "WebhookPayloadComment", + "WebhookPayloadDiscussion", + "WebhookPayloadDiscussionChanges", + "WebhookPayloadEvent", + "WebhookPayloadMovedTo", + "WebhookPayloadRepo", + "WebhookPayloadUrl", + "WebhookPayloadWebhook", + "WebhookWatchedItem", + "WebhooksServer", + "ZeroShotClassificationInput", + "ZeroShotClassificationOutputElement", + "ZeroShotClassificationParameters", + "ZeroShotImageClassificationInput", + "ZeroShotImageClassificationOutputElement", + "ZeroShotImageClassificationParameters", + "ZeroShotObjectDetectionBoundingBox", + "ZeroShotObjectDetectionInput", + "ZeroShotObjectDetectionOutputElement", + "ZeroShotObjectDetectionParameters", + "_CACHED_NO_EXIST", + "_save_pretrained_fastai", + "accept_access_request", + "add_collection_item", + "add_space_secret", + "add_space_variable", + "attach_huggingface_oauth", + "auth_check", + "auth_list", + "auth_switch", + "batch_bucket_files", + "bucket_info", + "cached_assets_path", + "cancel_access_request", + "cancel_job", + "change_discussion_status", + "check_cli_update", + "close_session", + "comment_discussion", + "copy_files", + "create_branch", + "create_bucket", + "create_collection", + "create_commit", + "create_discussion", + "create_inference_endpoint", + "create_inference_endpoint_from_catalog", + "create_pull_request", + "create_repo", + "create_scheduled_job", + "create_scheduled_uv_job", + "create_tag", + "create_webhook", + "dataset_info", + "delete_branch", + "delete_bucket", + "delete_collection", + "delete_collection_item", + "delete_file", + "delete_folder", + "delete_inference_endpoint", + "delete_repo", + "delete_scheduled_job", + "delete_space_secret", + "delete_space_storage", + "delete_space_variable", + "delete_space_volumes", + "delete_tag", + "delete_webhook", + "disable_space_dev_mode", + "disable_webhook", + "download_bucket_files", + "dump_environment_info", + "duplicate_repo", + "duplicate_space", + "edit_discussion_comment", + "enable_space_dev_mode", + "enable_webhook", + "eval_result_entries_to_yaml", + "export_entries_as_dduf", + "export_folder_as_dduf", + "fetch_job_logs", + "fetch_job_metrics", + "fetch_space_logs", + "file_exists", + "from_pretrained_fastai", + "get_async_session", + "get_bucket_file_metadata", + "get_bucket_paths_info", + "get_cached_repo_tree", + "get_collection", + "get_dataset_leaderboard", + "get_dataset_tags", + "get_discussion_details", + "get_full_repo_name", + "get_hf_file_metadata", + "get_inference_endpoint", + "get_local_safetensors_metadata", + "get_model_tags", + "get_organization_overview", + "get_paths_info", + "get_repo_discussions", + "get_safetensors_metadata", + "get_session", + "get_space_runtime", + "get_space_secrets", + "get_space_variables", + "get_token", + "get_torch_storage_id", + "get_torch_storage_size", + "get_user_overview", + "get_webhook", + "grant_access", + "hf_hub_download", + "hf_hub_url", + "hf_raise_for_status", + "hffs", + "inspect_job", + "inspect_scheduled_job", + "interpreter_login", + "is_offline_mode", + "kernel_info", + "list_accepted_access_requests", + "list_bucket_tree", + "list_buckets", + "list_collections", + "list_daily_papers", + "list_dataset_parquet_files", + "list_datasets", + "list_inference_catalog", + "list_inference_endpoints", + "list_jobs", + "list_jobs_hardware", + "list_lfs_files", + "list_liked_repos", + "list_models", + "list_organization_followers", + "list_organization_members", + "list_papers", + "list_pending_access_requests", + "list_rejected_access_requests", + "list_repo_commits", + "list_repo_files", + "list_repo_likers", + "list_repo_refs", + "list_repo_tree", + "list_space_templates", + "list_spaces", + "list_spaces_hardware", + "list_user_followers", + "list_user_following", + "list_user_repos", + "list_webhooks", + "load_state_dict_from_file", + "load_torch_model", + "logging", + "login", + "logout", + "merge_pull_request", + "metadata_eval_result", + "metadata_load", + "metadata_save", + "metadata_update", + "model_info", + "move_bucket", + "move_repo", + "notebook_login", + "paper_info", + "parse_eval_result_entries", + "parse_hf_uri", + "parse_huggingface_oauth", + "parse_local_safetensors_file_metadata", + "parse_safetensors_file_metadata", + "pause_inference_endpoint", + "pause_space", + "permanently_delete_lfs_files", + "preupload_lfs_files", + "push_to_hub_fastai", + "read_dduf_file", + "read_paper", + "reject_access_request", + "rename_discussion", + "repo_exists", + "repo_info", + "repo_type_and_id_from_hf_id", + "request_space_hardware", + "request_space_storage", + "restart_space", + "resume_inference_endpoint", + "resume_scheduled_job", + "revision_exists", + "run_as_future", + "run_job", + "run_uv_job", + "save_torch_model", + "save_torch_state_dict", + "scale_to_zero_inference_endpoint", + "scan_cache_dir", + "search_spaces", + "set_async_client_factory", + "set_client_factory", + "set_space_sleep_time", + "set_space_volumes", + "snapshot_download", + "space_info", + "split_state_dict_into_shards_factory", + "split_torch_state_dict_into_shards", + "super_squash_history", + "suspend_scheduled_job", + "sync_bucket", + "sync_job_volume", + "trigger_scheduled_job", + "try_to_load_from_cache", + "typer_factory", + "unlike", + "update_collection_item", + "update_collection_metadata", + "update_inference_endpoint", + "update_job_labels", + "update_repo_settings", + "update_scheduled_job_labels", + "update_webhook", + "upload_file", + "upload_folder", + "upload_large_folder", + "verify_repo_checksums", + "wait_for_job", + "wait_for_space", + "webhook_endpoint", + "whoami", +] + + +def _attach(package_name, submodules=None, submod_attrs=None): + """Attach lazily loaded submodules, functions, or other attributes. + + Typically, modules import submodules and attributes as follows: + + ```py + import mysubmodule + import anothersubmodule + + from .foo import someattr + ``` + + The idea is to replace a package's `__getattr__`, `__dir__`, such that all imports + work exactly the way they would with normal imports, except that the import occurs + upon first use. + + The typical way to call this function, replacing the above imports, is: + + ```python + __getattr__, __dir__ = lazy.attach( + __name__, + ['mysubmodule', 'anothersubmodule'], + {'foo': ['someattr']} + ) + ``` + This functionality requires Python 3.7 or higher. + + Args: + package_name (`str`): + Typically use `__name__`. + submodules (`set`): + List of submodules to attach. + submod_attrs (`dict`): + Dictionary of submodule -> list of attributes / functions. + These attributes are imported as they are used. + + Returns: + __getattr__, __dir__, __all__ + + """ + if submod_attrs is None: + submod_attrs = {} + + if submodules is None: + submodules = set() + else: + submodules = set(submodules) + + attr_to_modules = {attr: mod for mod, attrs in submod_attrs.items() for attr in attrs} + + def __getattr__(name): + if name in submodules: + try: + return importlib.import_module(f"{package_name}.{name}") + except Exception as e: + print(f"Error importing {package_name}.{name}: {e}") + raise + elif name in attr_to_modules: + submod_path = f"{package_name}.{attr_to_modules[name]}" + try: + submod = importlib.import_module(submod_path) + except Exception as e: + print(f"Error importing {submod_path}: {e}") + raise + attr = getattr(submod, name) + + # If the attribute lives in a file (module) with the same + # name as the attribute, ensure that the attribute and *not* + # the module is accessible on the package. + if name == attr_to_modules[name]: + pkg = sys.modules[package_name] + pkg.__dict__[name] = attr + + return attr + else: + raise AttributeError(f"No {package_name} attribute {name}") + + def __dir__(): + return __all__ + + return __getattr__, __dir__ + + +__getattr__, __dir__ = _attach(__name__, submodules=[], submod_attrs=_SUBMOD_ATTRS) + +if os.environ.get("EAGER_IMPORT", ""): + for attr in __all__: + __getattr__(attr) + +# WARNING: any content below this statement is generated automatically. Any manual edit +# will be lost when re-generating this file ! +# +# To update the static imports, please run the following command and commit the changes. +# ``` +# # Use script +# python utils/check_static_imports.py --update +# +# # Or run style on codebase +# make style +# ``` +if TYPE_CHECKING: # pragma: no cover + from ._buckets import ( + BucketFile, # noqa: F401 + BucketFileMetadata, # noqa: F401 + BucketFolder, # noqa: F401 + BucketInfo, # noqa: F401 + BucketUrl, # noqa: F401 + SyncOperation, # noqa: F401 + SyncPlan, # noqa: F401 + ) + from ._commit_scheduler import CommitScheduler # noqa: F401 + from ._eval_results import ( + EvalResultEntry, # noqa: F401 + eval_result_entries_to_yaml, # noqa: F401 + parse_eval_result_entries, # noqa: F401 + ) + from ._inference_endpoints import ( + InferenceEndpoint, # noqa: F401 + InferenceEndpointError, # noqa: F401 + InferenceEndpointStatus, # noqa: F401 + InferenceEndpointTimeoutError, # noqa: F401 + InferenceEndpointType, # noqa: F401 + ) + from ._jobs_api import ( + JobAccelerator, # noqa: F401 + JobDurations, # noqa: F401 + JobHardware, # noqa: F401 + JobHardwareInfo, # noqa: F401 + JobInfo, # noqa: F401 + JobInitiator, # noqa: F401 + JobOwner, # noqa: F401 + JobStage, # noqa: F401 + JobStatus, # noqa: F401 + ) + from ._login import ( + auth_list, # noqa: F401 + auth_switch, # noqa: F401 + interpreter_login, # noqa: F401 + login, # noqa: F401 + logout, # noqa: F401 + notebook_login, # noqa: F401 + ) + from ._oauth import ( + OAuthInfo, # noqa: F401 + OAuthOrgInfo, # noqa: F401 + OAuthUserInfo, # noqa: F401 + attach_huggingface_oauth, # noqa: F401 + parse_huggingface_oauth, # noqa: F401 + ) + from ._sandbox import ( + Sandbox, # noqa: F401 + SandboxCommandResult, # noqa: F401 + SandboxPool, # noqa: F401 + SandboxProcess, # noqa: F401 + ) + from ._snapshot_download import ( + get_cached_repo_tree, # noqa: F401 + snapshot_download, # noqa: F401 + ) + from ._space_api import ( + SpaceHardware, # noqa: F401 + SpaceRuntime, # noqa: F401 + SpaceSecret, # noqa: F401 + SpaceStage, # noqa: F401 + SpaceStorage, # noqa: F401 + SpaceVariable, # noqa: F401 + Volume, # noqa: F401 + ) + from ._tensorboard_logger import HFSummaryWriter # noqa: F401 + from ._webhooks_payload import ( + WebhookPayload, # noqa: F401 + WebhookPayloadComment, # noqa: F401 + WebhookPayloadDiscussion, # noqa: F401 + WebhookPayloadDiscussionChanges, # noqa: F401 + WebhookPayloadEvent, # noqa: F401 + WebhookPayloadMovedTo, # noqa: F401 + WebhookPayloadRepo, # noqa: F401 + WebhookPayloadUrl, # noqa: F401 + WebhookPayloadWebhook, # noqa: F401 + ) + from ._webhooks_server import ( + WebhooksServer, # noqa: F401 + webhook_endpoint, # noqa: F401 + ) + from .cli._cli_utils import ( + check_cli_update, # noqa: F401 + typer_factory, # noqa: F401 + ) + from .community import ( + Discussion, # noqa: F401 + DiscussionComment, # noqa: F401 + DiscussionCommit, # noqa: F401 + DiscussionEvent, # noqa: F401 + DiscussionStatusChange, # noqa: F401 + DiscussionTitleChange, # noqa: F401 + DiscussionWithDetails, # noqa: F401 + ) + from .constants import ( + CONFIG_NAME, # noqa: F401 + FLAX_WEIGHTS_NAME, # noqa: F401 + HUGGINGFACE_CO_URL_HOME, # noqa: F401 + HUGGINGFACE_CO_URL_TEMPLATE, # noqa: F401 + PYTORCH_WEIGHTS_NAME, # noqa: F401 + REPO_TYPE_DATASET, # noqa: F401 + REPO_TYPE_MODEL, # noqa: F401 + REPO_TYPE_SPACE, # noqa: F401 + TF2_WEIGHTS_NAME, # noqa: F401 + TF_WEIGHTS_NAME, # noqa: F401 + is_offline_mode, # noqa: F401 + ) + from .fastai_utils import ( + _save_pretrained_fastai, # noqa: F401 + from_pretrained_fastai, # noqa: F401 + push_to_hub_fastai, # noqa: F401 + ) + from .file_download import ( + _CACHED_NO_EXIST, # noqa: F401 + DryRunFileInfo, # noqa: F401 + HfFileMetadata, # noqa: F401 + get_hf_file_metadata, # noqa: F401 + hf_hub_download, # noqa: F401 + hf_hub_url, # noqa: F401 + try_to_load_from_cache, # noqa: F401 + ) + from .hf_api import ( + Collection, # noqa: F401 + CollectionItem, # noqa: F401 + CommitInfo, # noqa: F401 + CommitOperation, # noqa: F401 + CommitOperationAdd, # noqa: F401 + CommitOperationCopy, # noqa: F401 + CommitOperationDelete, # noqa: F401 + DatasetInfo, # noqa: F401 + DatasetLeaderboardEntry, # noqa: F401 + GitCommitInfo, # noqa: F401 + GitRefInfo, # noqa: F401 + GitRefs, # noqa: F401 + HfApi, # noqa: F401 + KernelInfo, # noqa: F401 + ModelInfo, # noqa: F401 + Organization, # noqa: F401 + RepoFile, # noqa: F401 + RepoFolder, # noqa: F401 + RepoStorageInfo, # noqa: F401 + RepoUrl, # noqa: F401 + SpaceInfo, # noqa: F401 + SpaceSearchResult, # noqa: F401 + SpaceTemplate, # noqa: F401 + User, # noqa: F401 + UserLikes, # noqa: F401 + WebhookInfo, # noqa: F401 + WebhookWatchedItem, # noqa: F401 + accept_access_request, # noqa: F401 + add_collection_item, # noqa: F401 + add_space_secret, # noqa: F401 + add_space_variable, # noqa: F401 + auth_check, # noqa: F401 + batch_bucket_files, # noqa: F401 + bucket_info, # noqa: F401 + cancel_access_request, # noqa: F401 + cancel_job, # noqa: F401 + change_discussion_status, # noqa: F401 + comment_discussion, # noqa: F401 + copy_files, # noqa: F401 + create_branch, # noqa: F401 + create_bucket, # noqa: F401 + create_collection, # noqa: F401 + create_commit, # noqa: F401 + create_discussion, # noqa: F401 + create_inference_endpoint, # noqa: F401 + create_inference_endpoint_from_catalog, # noqa: F401 + create_pull_request, # noqa: F401 + create_repo, # noqa: F401 + create_scheduled_job, # noqa: F401 + create_scheduled_uv_job, # noqa: F401 + create_tag, # noqa: F401 + create_webhook, # noqa: F401 + dataset_info, # noqa: F401 + delete_branch, # noqa: F401 + delete_bucket, # noqa: F401 + delete_collection, # noqa: F401 + delete_collection_item, # noqa: F401 + delete_file, # noqa: F401 + delete_folder, # noqa: F401 + delete_inference_endpoint, # noqa: F401 + delete_repo, # noqa: F401 + delete_scheduled_job, # noqa: F401 + delete_space_secret, # noqa: F401 + delete_space_storage, # noqa: F401 + delete_space_variable, # noqa: F401 + delete_space_volumes, # noqa: F401 + delete_tag, # noqa: F401 + delete_webhook, # noqa: F401 + disable_space_dev_mode, # noqa: F401 + disable_webhook, # noqa: F401 + download_bucket_files, # noqa: F401 + duplicate_repo, # noqa: F401 + duplicate_space, # noqa: F401 + edit_discussion_comment, # noqa: F401 + enable_space_dev_mode, # noqa: F401 + enable_webhook, # noqa: F401 + fetch_job_logs, # noqa: F401 + fetch_job_metrics, # noqa: F401 + fetch_space_logs, # noqa: F401 + file_exists, # noqa: F401 + get_bucket_file_metadata, # noqa: F401 + get_bucket_paths_info, # noqa: F401 + get_collection, # noqa: F401 + get_dataset_leaderboard, # noqa: F401 + get_dataset_tags, # noqa: F401 + get_discussion_details, # noqa: F401 + get_full_repo_name, # noqa: F401 + get_inference_endpoint, # noqa: F401 + get_local_safetensors_metadata, # noqa: F401 + get_model_tags, # noqa: F401 + get_organization_overview, # noqa: F401 + get_paths_info, # noqa: F401 + get_repo_discussions, # noqa: F401 + get_safetensors_metadata, # noqa: F401 + get_space_runtime, # noqa: F401 + get_space_secrets, # noqa: F401 + get_space_variables, # noqa: F401 + get_user_overview, # noqa: F401 + get_webhook, # noqa: F401 + grant_access, # noqa: F401 + inspect_job, # noqa: F401 + inspect_scheduled_job, # noqa: F401 + kernel_info, # noqa: F401 + list_accepted_access_requests, # noqa: F401 + list_bucket_tree, # noqa: F401 + list_buckets, # noqa: F401 + list_collections, # noqa: F401 + list_daily_papers, # noqa: F401 + list_dataset_parquet_files, # noqa: F401 + list_datasets, # noqa: F401 + list_inference_catalog, # noqa: F401 + list_inference_endpoints, # noqa: F401 + list_jobs, # noqa: F401 + list_jobs_hardware, # noqa: F401 + list_lfs_files, # noqa: F401 + list_liked_repos, # noqa: F401 + list_models, # noqa: F401 + list_organization_followers, # noqa: F401 + list_organization_members, # noqa: F401 + list_papers, # noqa: F401 + list_pending_access_requests, # noqa: F401 + list_rejected_access_requests, # noqa: F401 + list_repo_commits, # noqa: F401 + list_repo_files, # noqa: F401 + list_repo_likers, # noqa: F401 + list_repo_refs, # noqa: F401 + list_repo_tree, # noqa: F401 + list_space_templates, # noqa: F401 + list_spaces, # noqa: F401 + list_spaces_hardware, # noqa: F401 + list_user_followers, # noqa: F401 + list_user_following, # noqa: F401 + list_user_repos, # noqa: F401 + list_webhooks, # noqa: F401 + merge_pull_request, # noqa: F401 + model_info, # noqa: F401 + move_bucket, # noqa: F401 + move_repo, # noqa: F401 + paper_info, # noqa: F401 + parse_local_safetensors_file_metadata, # noqa: F401 + parse_safetensors_file_metadata, # noqa: F401 + pause_inference_endpoint, # noqa: F401 + pause_space, # noqa: F401 + permanently_delete_lfs_files, # noqa: F401 + preupload_lfs_files, # noqa: F401 + read_paper, # noqa: F401 + reject_access_request, # noqa: F401 + rename_discussion, # noqa: F401 + repo_exists, # noqa: F401 + repo_info, # noqa: F401 + repo_type_and_id_from_hf_id, # noqa: F401 + request_space_hardware, # noqa: F401 + request_space_storage, # noqa: F401 + restart_space, # noqa: F401 + resume_inference_endpoint, # noqa: F401 + resume_scheduled_job, # noqa: F401 + revision_exists, # noqa: F401 + run_as_future, # noqa: F401 + run_job, # noqa: F401 + run_uv_job, # noqa: F401 + scale_to_zero_inference_endpoint, # noqa: F401 + search_spaces, # noqa: F401 + set_space_sleep_time, # noqa: F401 + set_space_volumes, # noqa: F401 + space_info, # noqa: F401 + super_squash_history, # noqa: F401 + suspend_scheduled_job, # noqa: F401 + sync_bucket, # noqa: F401 + sync_job_volume, # noqa: F401 + trigger_scheduled_job, # noqa: F401 + unlike, # noqa: F401 + update_collection_item, # noqa: F401 + update_collection_metadata, # noqa: F401 + update_inference_endpoint, # noqa: F401 + update_job_labels, # noqa: F401 + update_repo_settings, # noqa: F401 + update_scheduled_job_labels, # noqa: F401 + update_webhook, # noqa: F401 + upload_file, # noqa: F401 + upload_folder, # noqa: F401 + upload_large_folder, # noqa: F401 + verify_repo_checksums, # noqa: F401 + wait_for_job, # noqa: F401 + wait_for_space, # noqa: F401 + whoami, # noqa: F401 + ) + from .hf_file_system import ( + HfFileSystem, # noqa: F401 + HfFileSystemFile, # noqa: F401 + HfFileSystemResolvedPath, # noqa: F401 + HfFileSystemStreamFile, # noqa: F401 + hffs, # noqa: F401 + ) + from .hub_mixin import ( + ModelHubMixin, # noqa: F401 + PyTorchModelHubMixin, # noqa: F401 + ) + from .inference._client import ( + InferenceClient, # noqa: F401 + InferenceTimeoutError, # noqa: F401 + ) + from .inference._generated._async_client import AsyncInferenceClient # noqa: F401 + from .inference._generated.types import ( + AudioClassificationInput, # noqa: F401 + AudioClassificationOutputElement, # noqa: F401 + AudioClassificationOutputTransform, # noqa: F401 + AudioClassificationParameters, # noqa: F401 + AudioToAudioInput, # noqa: F401 + AudioToAudioOutputElement, # noqa: F401 + AutomaticSpeechRecognitionEarlyStoppingEnum, # noqa: F401 + AutomaticSpeechRecognitionGenerationParameters, # noqa: F401 + AutomaticSpeechRecognitionInput, # noqa: F401 + AutomaticSpeechRecognitionOutput, # noqa: F401 + AutomaticSpeechRecognitionOutputChunk, # noqa: F401 + AutomaticSpeechRecognitionParameters, # noqa: F401 + ChatCompletionInput, # noqa: F401 + ChatCompletionInputFunctionDefinition, # noqa: F401 + ChatCompletionInputFunctionName, # noqa: F401 + ChatCompletionInputGrammarType, # noqa: F401 + ChatCompletionInputJSONSchema, # noqa: F401 + ChatCompletionInputMessage, # noqa: F401 + ChatCompletionInputMessageChunk, # noqa: F401 + ChatCompletionInputMessageChunkType, # noqa: F401 + ChatCompletionInputResponseFormatJSONObject, # noqa: F401 + ChatCompletionInputResponseFormatJSONSchema, # noqa: F401 + ChatCompletionInputResponseFormatText, # noqa: F401 + ChatCompletionInputStreamOptions, # noqa: F401 + ChatCompletionInputTool, # noqa: F401 + ChatCompletionInputToolCall, # noqa: F401 + ChatCompletionInputToolChoiceClass, # noqa: F401 + ChatCompletionInputToolChoiceEnum, # noqa: F401 + ChatCompletionInputURL, # noqa: F401 + ChatCompletionOutput, # noqa: F401 + ChatCompletionOutputComplete, # noqa: F401 + ChatCompletionOutputFunctionDefinition, # noqa: F401 + ChatCompletionOutputLogprob, # noqa: F401 + ChatCompletionOutputLogprobs, # noqa: F401 + ChatCompletionOutputMessage, # noqa: F401 + ChatCompletionOutputToolCall, # noqa: F401 + ChatCompletionOutputTopLogprob, # noqa: F401 + ChatCompletionOutputUsage, # noqa: F401 + ChatCompletionStreamOutput, # noqa: F401 + ChatCompletionStreamOutputChoice, # noqa: F401 + ChatCompletionStreamOutputDelta, # noqa: F401 + ChatCompletionStreamOutputDeltaToolCall, # noqa: F401 + ChatCompletionStreamOutputFunction, # noqa: F401 + ChatCompletionStreamOutputLogprob, # noqa: F401 + ChatCompletionStreamOutputLogprobs, # noqa: F401 + ChatCompletionStreamOutputTopLogprob, # noqa: F401 + ChatCompletionStreamOutputUsage, # noqa: F401 + DepthEstimationInput, # noqa: F401 + DepthEstimationOutput, # noqa: F401 + DocumentQuestionAnsweringInput, # noqa: F401 + DocumentQuestionAnsweringInputData, # noqa: F401 + DocumentQuestionAnsweringOutputElement, # noqa: F401 + DocumentQuestionAnsweringParameters, # noqa: F401 + FeatureExtractionInput, # noqa: F401 + FeatureExtractionInputTruncationDirection, # noqa: F401 + FillMaskInput, # noqa: F401 + FillMaskOutputElement, # noqa: F401 + FillMaskParameters, # noqa: F401 + ImageClassificationInput, # noqa: F401 + ImageClassificationOutputElement, # noqa: F401 + ImageClassificationOutputTransform, # noqa: F401 + ImageClassificationParameters, # noqa: F401 + ImageSegmentationInput, # noqa: F401 + ImageSegmentationOutputElement, # noqa: F401 + ImageSegmentationParameters, # noqa: F401 + ImageSegmentationSubtask, # noqa: F401 + ImageTextToImageInput, # noqa: F401 + ImageTextToImageOutput, # noqa: F401 + ImageTextToImageParameters, # noqa: F401 + ImageTextToImageTargetSize, # noqa: F401 + ImageTextToVideoInput, # noqa: F401 + ImageTextToVideoOutput, # noqa: F401 + ImageTextToVideoParameters, # noqa: F401 + ImageTextToVideoTargetSize, # noqa: F401 + ImageToImageInput, # noqa: F401 + ImageToImageOutput, # noqa: F401 + ImageToImageParameters, # noqa: F401 + ImageToImageTargetSize, # noqa: F401 + ImageToTextEarlyStoppingEnum, # noqa: F401 + ImageToTextGenerationParameters, # noqa: F401 + ImageToTextInput, # noqa: F401 + ImageToTextOutput, # noqa: F401 + ImageToTextParameters, # noqa: F401 + ImageToVideoInput, # noqa: F401 + ImageToVideoOutput, # noqa: F401 + ImageToVideoParameters, # noqa: F401 + ImageToVideoTargetSize, # noqa: F401 + ObjectDetectionBoundingBox, # noqa: F401 + ObjectDetectionInput, # noqa: F401 + ObjectDetectionOutputElement, # noqa: F401 + ObjectDetectionParameters, # noqa: F401 + Padding, # noqa: F401 + QuestionAnsweringInput, # noqa: F401 + QuestionAnsweringInputData, # noqa: F401 + QuestionAnsweringOutputElement, # noqa: F401 + QuestionAnsweringParameters, # noqa: F401 + SentenceSimilarityInput, # noqa: F401 + SentenceSimilarityInputData, # noqa: F401 + SummarizationInput, # noqa: F401 + SummarizationOutput, # noqa: F401 + SummarizationParameters, # noqa: F401 + SummarizationTruncationStrategy, # noqa: F401 + TableQuestionAnsweringInput, # noqa: F401 + TableQuestionAnsweringInputData, # noqa: F401 + TableQuestionAnsweringOutputElement, # noqa: F401 + TableQuestionAnsweringParameters, # noqa: F401 + Text2TextGenerationInput, # noqa: F401 + Text2TextGenerationOutput, # noqa: F401 + Text2TextGenerationParameters, # noqa: F401 + Text2TextGenerationTruncationStrategy, # noqa: F401 + TextClassificationInput, # noqa: F401 + TextClassificationOutputElement, # noqa: F401 + TextClassificationOutputTransform, # noqa: F401 + TextClassificationParameters, # noqa: F401 + TextGenerationInput, # noqa: F401 + TextGenerationInputGenerateParameters, # noqa: F401 + TextGenerationInputGrammarType, # noqa: F401 + TextGenerationOutput, # noqa: F401 + TextGenerationOutputBestOfSequence, # noqa: F401 + TextGenerationOutputDetails, # noqa: F401 + TextGenerationOutputFinishReason, # noqa: F401 + TextGenerationOutputPrefillToken, # noqa: F401 + TextGenerationOutputToken, # noqa: F401 + TextGenerationStreamOutput, # noqa: F401 + TextGenerationStreamOutputStreamDetails, # noqa: F401 + TextGenerationStreamOutputToken, # noqa: F401 + TextToAudioEarlyStoppingEnum, # noqa: F401 + TextToAudioGenerationParameters, # noqa: F401 + TextToAudioInput, # noqa: F401 + TextToAudioOutput, # noqa: F401 + TextToAudioParameters, # noqa: F401 + TextToImageInput, # noqa: F401 + TextToImageOutput, # noqa: F401 + TextToImageParameters, # noqa: F401 + TextToSpeechEarlyStoppingEnum, # noqa: F401 + TextToSpeechGenerationParameters, # noqa: F401 + TextToSpeechInput, # noqa: F401 + TextToSpeechOutput, # noqa: F401 + TextToSpeechParameters, # noqa: F401 + TextToVideoInput, # noqa: F401 + TextToVideoOutput, # noqa: F401 + TextToVideoParameters, # noqa: F401 + TokenClassificationAggregationStrategy, # noqa: F401 + TokenClassificationInput, # noqa: F401 + TokenClassificationOutputElement, # noqa: F401 + TokenClassificationParameters, # noqa: F401 + TranslationInput, # noqa: F401 + TranslationOutput, # noqa: F401 + TranslationParameters, # noqa: F401 + TranslationTruncationStrategy, # noqa: F401 + TypeEnum, # noqa: F401 + VideoClassificationInput, # noqa: F401 + VideoClassificationOutputElement, # noqa: F401 + VideoClassificationOutputTransform, # noqa: F401 + VideoClassificationParameters, # noqa: F401 + VisualQuestionAnsweringInput, # noqa: F401 + VisualQuestionAnsweringInputData, # noqa: F401 + VisualQuestionAnsweringOutputElement, # noqa: F401 + VisualQuestionAnsweringParameters, # noqa: F401 + ZeroShotClassificationInput, # noqa: F401 + ZeroShotClassificationOutputElement, # noqa: F401 + ZeroShotClassificationParameters, # noqa: F401 + ZeroShotImageClassificationInput, # noqa: F401 + ZeroShotImageClassificationOutputElement, # noqa: F401 + ZeroShotImageClassificationParameters, # noqa: F401 + ZeroShotObjectDetectionBoundingBox, # noqa: F401 + ZeroShotObjectDetectionInput, # noqa: F401 + ZeroShotObjectDetectionOutputElement, # noqa: F401 + ZeroShotObjectDetectionParameters, # noqa: F401 + ) + from .inference._mcp.agent import Agent # noqa: F401 + from .inference._mcp.mcp_client import MCPClient # noqa: F401 + from .repocard import ( + DatasetCard, # noqa: F401 + ModelCard, # noqa: F401 + RepoCard, # noqa: F401 + SpaceCard, # noqa: F401 + metadata_eval_result, # noqa: F401 + metadata_load, # noqa: F401 + metadata_save, # noqa: F401 + metadata_update, # noqa: F401 + ) + from .repocard_data import ( + CardData, # noqa: F401 + DatasetCardData, # noqa: F401 + EvalResult, # noqa: F401 + ModelCardData, # noqa: F401 + SpaceCardData, # noqa: F401 + ) + from .serialization import ( + StateDictSplit, # noqa: F401 + get_torch_storage_id, # noqa: F401 + get_torch_storage_size, # noqa: F401 + load_state_dict_from_file, # noqa: F401 + load_torch_model, # noqa: F401 + save_torch_model, # noqa: F401 + save_torch_state_dict, # noqa: F401 + split_state_dict_into_shards_factory, # noqa: F401 + split_torch_state_dict_into_shards, # noqa: F401 + ) + from .serialization._dduf import ( + DDUFEntry, # noqa: F401 + export_entries_as_dduf, # noqa: F401 + export_folder_as_dduf, # noqa: F401 + read_dduf_file, # noqa: F401 + ) + from .utils import ( + ASYNC_CLIENT_FACTORY_T, # noqa: F401 + CLIENT_FACTORY_T, # noqa: F401 + CachedFileInfo, # noqa: F401 + CachedIncompleteFileInfo, # noqa: F401 + CachedRepoInfo, # noqa: F401 + CachedRevisionInfo, # noqa: F401 + CacheNotFound, # noqa: F401 + CorruptedCacheException, # noqa: F401 + DeleteCacheStrategy, # noqa: F401 + HFCacheInfo, # noqa: F401 + HfUri, # noqa: F401 + cached_assets_path, # noqa: F401 + close_session, # noqa: F401 + dump_environment_info, # noqa: F401 + get_async_session, # noqa: F401 + get_session, # noqa: F401 + get_token, # noqa: F401 + hf_raise_for_status, # noqa: F401 + logging, # noqa: F401 + parse_hf_uri, # noqa: F401 + scan_cache_dir, # noqa: F401 + set_async_client_factory, # noqa: F401 + set_client_factory, # noqa: F401 + ) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_buckets.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_buckets.py new file mode 100644 index 0000000000000000000000000000000000000000..6a1ac867af35eae74eb56489ab90c9bcbf746b46 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_buckets.py @@ -0,0 +1,1244 @@ +# Copyright 2026-present, the HuggingFace Inc. team. +# +# 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. +"""Shared logic for bucket operations. + +This module contains the core buckets logic used by both the CLI and the Python API. +""" + +import fnmatch +import json +import mimetypes +import os +import stat +import sys +import time +from collections.abc import Iterator +from dataclasses import dataclass, field +from datetime import datetime, timezone +from pathlib import Path +from typing import TYPE_CHECKING, Any, Literal + +from . import constants, logging +from .errors import BucketNotFoundError +from .utils import ( + HfUri, + StatusLine, + XetFileData, + disable_progress_bars, + enable_progress_bars, + parse_datetime, + parse_hf_uri, +) +from .utils._hf_uris import _looks_like_hf_url + + +if TYPE_CHECKING: + from .hf_api import HfApi + + +logger = logging.get_logger(__name__) + + +BUCKET_PREFIX = "hf://buckets/" +_SYNC_TIME_WINDOW_MS = 1000 # 1s safety-window for file modification time comparisons + + +# ============================================================================= +# Bucket data structures +# ============================================================================= + + +@dataclass +class BucketInfo: + """ + Contains information about a bucket on the Hub. This object is returned by [`bucket_info`] and [`list_buckets`]. + + Attributes: + id (`str`): + ID of the bucket. + private (`bool`): + Is the bucket private. + created_at (`datetime`): + Date of creation of the bucket on the Hub. + size (`int`): + Size of the bucket in bytes. + total_files (`int`): + Total number of files in the bucket. + """ + + id: str + private: bool + created_at: datetime + size: int + total_files: int + + def __init__(self, **kwargs): + self.id = kwargs.pop("id") + self.private = kwargs.pop("private") + self.created_at = parse_datetime(kwargs.pop("createdAt")) + self.size = kwargs.pop("size") + self.total_files = kwargs.pop("totalFiles") + self.__dict__.update(**kwargs) + + +@dataclass +class _BucketAddFile: + source: str | Path | bytes + destination: str + + xet_hash: str | None = field(default=None) + size: int | None = field(default=None) + mtime: int = field(init=False) + content_type: str | None = field(init=False) + + def __post_init__(self) -> None: + self.content_type = None + if isinstance(self.source, (str, Path)): # guess content type from source path + self.content_type = mimetypes.guess_type(self.source)[0] + if self.content_type is None: # or default to destination path content type + self.content_type = mimetypes.guess_type(self.destination)[0] + + self.mtime = int( + os.path.getmtime(self.source) * 1000 if not isinstance(self.source, bytes) else time.time() * 1000 + ) + + +@dataclass +class _BucketCopyFile: + destination: str + xet_hash: str + source_repo_type: str # "model", "dataset", "space", "bucket" + source_repo_id: str + size: int | None = field(default=None) + mtime: int = field(init=False) + content_type: str | None = field(init=False) + + def __post_init__(self) -> None: + self.content_type = mimetypes.guess_type(self.destination)[0] + self.mtime = int(time.time() * 1000) + + +@dataclass +class _BucketDeleteFile: + path: str + + +@dataclass(frozen=True) +class BucketFileMetadata: + """Data structure containing information about a file in a bucket. + + Returned by [`get_bucket_file_metadata`]. + + Args: + size (`int`): + Size of the file in bytes. + xet_file_data (`XetFileData`): + Xet information for the file (hash and refresh route). + """ + + size: int + xet_file_data: XetFileData + + +@dataclass +class BucketUrl: + """Describes a bucket URL on the Hub. + + `BucketUrl` is returned by [`create_bucket`]. At initialization, the URL is parsed to populate properties: + - endpoint (`str`) + - namespace (`str`) + - bucket_id (`str`) + - url (`str`) + - uri (`HfUri`) + + Args: + url (`str`): + String value of the bucket url. + endpoint (`str`, *optional*): + Endpoint of the Hub. Defaults to . + """ + + url: str + endpoint: str = "" + namespace: str = field(init=False) + bucket_id: str = field(init=False) + uri: HfUri = field(init=False) + + def __post_init__(self) -> None: + self.endpoint = self.endpoint or constants.ENDPOINT + + # Parse URL: expected format is `{endpoint}/buckets/{namespace}/{bucket_name}` + url_path = self.url.replace(self.endpoint, "").strip("/") + # Remove leading "buckets/" prefix + if url_path.startswith("buckets/"): + url_path = url_path[len("buckets/") :] + parsed = _parse_bucket_uri(url_path) + if parsed.path_in_repo: + raise ValueError(f"Unable to parse bucket URL: {self.url}") + self.namespace = parsed.id.split("/")[0] + self.bucket_id = parsed.id + self.uri = parsed + + +@dataclass +class BucketFile: + """ + Contains information about a file in a bucket on the Hub. This object is returned by [`list_bucket_tree`]. + + Similar to [`RepoFile`] but for files in buckets. + """ + + type: Literal["file"] + path: str + size: int + xet_hash: str + mtime: datetime | None + uploaded_at: datetime | None + + def __init__(self, **kwargs): + self.type = kwargs.pop("type") + self.path = kwargs.pop("path") + self.size = kwargs.pop("size") + self.xet_hash = kwargs.pop("xetHash") + mtime = kwargs.pop("mtime", None) + self.mtime = parse_datetime(mtime) if mtime else None + uploaded_at = kwargs.pop("uploadedAt", None) + self.uploaded_at = parse_datetime(uploaded_at) if uploaded_at else None + + +@dataclass +class BucketFolder: + """ + Contains information about a directory in a bucket on the Hub. This object is returned by [`list_bucket_tree`]. + + Similar to [`RepoFolder`] but for directories in buckets. + """ + + type: Literal["directory"] + path: str + uploaded_at: datetime | None + + def __init__(self, **kwargs): + self.type = kwargs.pop("type") + self.path = kwargs.pop("path") + uploaded_at = kwargs.pop("uploadedAt", None) or kwargs.pop("uploaded_at", None) + self.uploaded_at = ( + (uploaded_at if isinstance(uploaded_at, datetime) else parse_datetime(uploaded_at)) + if uploaded_at + else None + ) + + +# ============================================================================= +# Bucket path parsing +# ============================================================================= + + +def _parse_bucket_uri(path: str) -> HfUri: + """Parse a bucket path into a HfUri. + + Accepts: + - `hf://buckets/namespace/name(/path/in/repo)` URIs, + - Hugging Face web URLs such as `https://huggingface.co/buckets/namespace/name(/tree/path)`, + - plain `namespace/name(/path/in/repo)` paths. + """ + if path.startswith(constants.HF_PROTOCOL) or _looks_like_hf_url(path): + # Don't use 'if is_hf_uri(...)' here as we prefer 'parse_hf_uri(...)' to raise the exact error message. + parsed = parse_hf_uri(path) + if not parsed.is_bucket: + raise ValueError(f"Invalid bucket path: {path}. Must be a bucket URI (hf://buckets/...).") + return parsed + parts = path.split("/", 2) + if len(parts) < 2 or not parts[0] or not parts[1]: + raise ValueError(f"Invalid bucket path: '{path}'. Expected format: namespace/bucket_name") + bucket_id = f"{parts[0]}/{parts[1]}" + prefix = "/".join(parts[2:]) + return HfUri(type="bucket", id=bucket_id, path_in_repo=prefix) + + +def _is_bucket_path(path: str) -> bool: + """Check if a path is a bucket path. + + Do not raise if the path is not a hf:// URI. + Raise if the path is a hf:// URI but with an incorrect format. + """ + if not path.startswith(constants.HF_PROTOCOL): + return False + return parse_hf_uri(path).is_bucket + + +# ============================================================================= +# Sync data structures +# ============================================================================= + + +@dataclass +class SyncOperation: + """Represents a sync operation to be performed.""" + + action: Literal["upload", "download", "delete", "skip"] + path: str + size: int | None = None + reason: str = "" + local_mtime: str | None = None + remote_mtime: str | None = None + bucket_file: BucketFile | None = None # BucketFile when available (not serialized to plan file) + + +@dataclass +class SyncPlan: + """Represents a complete sync plan.""" + + source: str + dest: str + timestamp: str + operations: list[SyncOperation] = field(default_factory=list) + + def summary(self) -> dict[str, int | str]: + uploads = sum(1 for op in self.operations if op.action == "upload") + downloads = sum(1 for op in self.operations if op.action == "download") + deletes = sum(1 for op in self.operations if op.action == "delete") + skips = sum(1 for op in self.operations if op.action == "skip") + total_size = sum(op.size or 0 for op in self.operations if op.action in ("upload", "download")) + return { + "uploads": uploads, + "downloads": downloads, + "deletes": deletes, + "skips": skips, + "total_size": total_size, + } + + +# ============================================================================= +# Filter matching +# ============================================================================= + + +class FilterMatcher: + """Matches file paths against include/exclude patterns.""" + + def __init__( + self, + include_patterns: list[str] | None = None, + exclude_patterns: list[str] | None = None, + filter_rules: list[tuple[str, str]] | None = None, + ): + """Initialize the filter matcher. + + Args: + include_patterns: Patterns to include (from --include) + exclude_patterns: Patterns to exclude (from --exclude) + filter_rules: Rules from filter file as list of ("+"/"-", pattern) tuples + """ + self.include_patterns = include_patterns or [] + self.exclude_patterns = exclude_patterns or [] + self.filter_rules = filter_rules or [] + + def matches(self, path: str) -> bool: + """Check if a path should be included based on the filter rules. + + Filtering rules: + - Filters are evaluated in order, first matching rule decides + - If no rules match, include by default (unless include patterns are specified) + """ + # First check filter rules from file (in order) + for sign, pattern in self.filter_rules: + if fnmatch.fnmatch(path, pattern): + return sign == "+" + + # Then check CLI patterns + for pattern in self.exclude_patterns: + if fnmatch.fnmatch(path, pattern): + return False + + for pattern in self.include_patterns: + if fnmatch.fnmatch(path, pattern): + return True + + # If include patterns were specified but none matched, exclude + if self.include_patterns: + return False + + # Default: include + return True + + +def _parse_filter_file(filter_file: str) -> list[tuple[str, str]]: + """Parse a filter file and return a list of (sign, pattern) tuples. + + Filter file format: + - Lines starting with "+" are include patterns + - Lines starting with "-" are exclude patterns + - Empty lines and lines starting with "#" are ignored + """ + rules = [] + with open(filter_file) as f: + for line in f: + line = line.strip() + if not line or line.startswith("#"): + continue + if line.startswith("+"): + rules.append(("+", line[1:].strip())) + elif line.startswith("-"): + rules.append(("-", line[1:].strip())) + else: + # Default to include if no prefix + rules.append(("+", line)) + return rules + + +# ============================================================================= +# File listing +# ============================================================================= + + +def _stat_local(path: str) -> tuple[int, float] | None: + """Stat a local file and return (size, mtime_ms). + + Returns None if the path is missing or is a directory. Uses a single + ``os.stat`` call so callers don't pay for multiple syscalls per file. + """ + try: + st = os.stat(path) + except OSError: + return None + if stat.S_ISDIR(st.st_mode): + return None + return st.st_size, st.st_mtime * 1000 + + +def _list_local_files(local_path: str) -> Iterator[tuple[str, int, float]]: + """List all files in a local directory. + + Yields: + tuple: (relative_path, size, mtime_ms) for each file + """ + local_path = os.path.abspath(local_path) + if not os.path.isdir(local_path): + raise ValueError(f"Local path must be a directory: {local_path}") + + for root, _, files in os.walk(local_path): + for filename in files: + full_path = os.path.join(root, filename) + stat_info = _stat_local(full_path) + if stat_info is None: + continue + rel_path = os.path.relpath(full_path, local_path) + # Normalize to forward slashes for consistency + rel_path = rel_path.replace(os.sep, "/") + yield rel_path, stat_info[0], stat_info[1] + + +def _list_remote_files(api: "HfApi", bucket_id: str, prefix: str) -> Iterator[tuple[str, int, float, Any]]: + """List all files in a bucket with a given prefix. + + Yields: + tuple: (relative_path, size, mtime_ms, bucket_file) for each file. + bucket_file is the BucketFile object from list_bucket_tree. + """ + for item in api.list_bucket_tree(bucket_id, prefix=prefix or None, recursive=True): + if isinstance(item, BucketFolder): + continue + path = item.path + # Remove prefix from path to get relative path + # Only strip prefix if it's followed by "/" (directory boundary) or is exact match + if prefix: + if path.startswith(prefix + "/"): + rel_path = path[len(prefix) + 1 :] + elif path == prefix: + # Exact match: the file IS the prefix (e.g., single file download) + rel_path = path.rsplit("/", 1)[-1] if "/" in path else path + else: + # Path doesn't match prefix pattern (e.g., "submarine.txt" for prefix "sub") + # Skip this file - it was returned by the API but doesn't belong to this prefix + continue + else: + rel_path = path + mtime_ms = item.mtime.timestamp() * 1000 if item.mtime else 0 + yield rel_path, item.size, mtime_ms, item + + +# ============================================================================= +# Sync plan computation +# ============================================================================= + + +def _mtime_to_iso(mtime_ms: float) -> str: + """Convert mtime in milliseconds to ISO format string.""" + return datetime.fromtimestamp(mtime_ms / 1000, tz=timezone.utc).isoformat() + + +def _compare_files_for_sync( + *, + path: str, + action: Literal["upload", "download"], + source_size: int, + source_mtime: float, + dest_size: int, + dest_mtime: float, + source_newer_label: str, + dest_newer_label: str, + ignore_sizes: bool, + ignore_times: bool, + ignore_existing: bool, + bucket_file: Any | None = None, +) -> SyncOperation: + """Compare source and dest files and return the appropriate sync operation. + + This is a unified helper for both upload and download directions. + + Args: + path: Relative file path + action: "upload" or "download" + source_size: Size of the source file (bytes) + source_mtime: Mtime of the source file (milliseconds) + dest_size: Size of the destination file (bytes) + dest_mtime: Mtime of the destination file (milliseconds) + source_newer_label: Label when source is newer (e.g., "local newer" or "remote newer") + dest_newer_label: Label when dest is newer (e.g., "remote newer" or "local newer") + ignore_sizes: Only compare mtime + ignore_times: Only compare size + ignore_existing: Skip files that exist on receiver + bucket_file: BucketFile object (for downloads only) + + Returns: + SyncOperation describing the action to take + """ + local_mtime_iso = _mtime_to_iso(source_mtime if action == "upload" else dest_mtime) + remote_mtime_iso = _mtime_to_iso(dest_mtime if action == "upload" else source_mtime) + + base_kwargs: dict[str, Any] = { + "path": path, + "size": source_size, + "local_mtime": local_mtime_iso, + "remote_mtime": remote_mtime_iso, + } + + if ignore_existing: + return SyncOperation(action="skip", reason="exists on receiver (--ignore-existing)", **base_kwargs) + + size_differs = source_size != dest_size + source_newer = (source_mtime - dest_mtime) > _SYNC_TIME_WINDOW_MS + + if ignore_sizes: + if source_newer: + return SyncOperation(action=action, reason=source_newer_label, bucket_file=bucket_file, **base_kwargs) + else: + dest_newer = (dest_mtime - source_mtime) > _SYNC_TIME_WINDOW_MS + skip_reason = dest_newer_label if dest_newer else "same mtime" + return SyncOperation(action="skip", reason=skip_reason, **base_kwargs) + elif ignore_times: + if size_differs: + return SyncOperation(action=action, reason="size differs", bucket_file=bucket_file, **base_kwargs) + else: + return SyncOperation(action="skip", reason="same size", **base_kwargs) + else: + if size_differs or source_newer: + reason = "size differs" if size_differs else source_newer_label + return SyncOperation(action=action, reason=reason, bucket_file=bucket_file, **base_kwargs) + else: + return SyncOperation(action="skip", reason="identical", **base_kwargs) + + +def _compute_sync_plan( + source: str, + dest: str, + api: "HfApi", + delete: bool = False, + ignore_times: bool = False, + ignore_sizes: bool = False, + existing: bool = False, + ignore_existing: bool = False, + filter_matcher: FilterMatcher | None = None, + status: Any | None = None, +) -> SyncPlan: + """Compute the sync plan by comparing source and destination. + + Returns: + SyncPlan with all operations to be performed + """ + filter_matcher = filter_matcher or FilterMatcher() + is_upload = not _is_bucket_path(source) and _is_bucket_path(dest) + is_download = _is_bucket_path(source) and not _is_bucket_path(dest) + + if not is_upload and not is_download: + raise ValueError("One of source or dest must be a bucket path (hf://buckets/...) and the other must be local.") + + plan = SyncPlan( + source=source, + dest=dest, + timestamp=datetime.now(timezone.utc).isoformat(), + ) + + remote_total: int | None = None + if is_upload: + # Local -> Remote + local_path = os.path.abspath(source) + parsed = _parse_bucket_uri(dest) + bucket_id, prefix = parsed.id, parsed.path_in_repo + + if not os.path.isdir(local_path): + raise ValueError(f"Source must be a directory: {local_path}") + + # Get local and remote file lists + local_files = {} + for rel_path, size, mtime_ms in _list_local_files(local_path): + if filter_matcher.matches(rel_path): + local_files[rel_path] = (size, mtime_ms) + if status: + status.update(f"Scanning local directory ({len(local_files)} files)") + if status: + status.done(f"Scanning local directory ({len(local_files)} files)") + + remote_files = {} + if status: + try: + remote_total = api.bucket_info(bucket_id).total_files + except Exception: + pass + try: + for rel_path, size, mtime_ms, _ in _list_remote_files(api, bucket_id, prefix): + if filter_matcher.matches(rel_path): + remote_files[rel_path] = (size, mtime_ms) + if status: + total_str = f"/{remote_total}" if remote_total is not None else "" + status.update(f"Scanning remote bucket ({len(remote_files)}{total_str} files)") + except BucketNotFoundError: + # Bucket doesn't exist yet - this is expected for new uploads + logger.debug(f"Bucket '{bucket_id}' not found, treating as empty.") + if status: + status.done(f"Scanning remote bucket ({len(remote_files)} files)") + + # Compare files + all_paths = set(local_files.keys()) | set(remote_files.keys()) + if status: + status.done(f"Comparing files ({len(all_paths)} paths)") + for path in sorted(all_paths): + local_info = local_files.get(path) + remote_info = remote_files.get(path) + + if local_info and not remote_info: + # New file + if existing: + # --existing: skip new files + plan.operations.append( + SyncOperation( + action="skip", + path=path, + size=local_info[0], + reason="new file (--existing)", + local_mtime=_mtime_to_iso(local_info[1]), + ) + ) + else: + plan.operations.append( + SyncOperation( + action="upload", + path=path, + size=local_info[0], + reason="new file", + local_mtime=_mtime_to_iso(local_info[1]), + ) + ) + elif local_info and remote_info: + # File exists in both - use helper to determine action + local_size, local_mtime = local_info + remote_size, remote_mtime = remote_info + plan.operations.append( + _compare_files_for_sync( + path=path, + action="upload", + source_size=local_size, + source_mtime=local_mtime, + dest_size=remote_size, + dest_mtime=remote_mtime, + source_newer_label="local newer", + dest_newer_label="remote newer", + ignore_sizes=ignore_sizes, + ignore_times=ignore_times, + ignore_existing=ignore_existing, + ) + ) + elif not local_info and remote_info and delete: + # File only in remote and --delete mode + plan.operations.append( + SyncOperation( + action="delete", + path=path, + size=remote_info[0], + reason="not in source (--delete)", + remote_mtime=_mtime_to_iso(remote_info[1]), + ) + ) + + else: + # Remote -> Local (download) + parsed = _parse_bucket_uri(source) + bucket_id, prefix = parsed.id, parsed.path_in_repo + local_path = os.path.abspath(dest) + + # Get remote and local file lists + remote_files = {} + bucket_file_map: dict[str, Any] = {} + if status: + try: + remote_total = api.bucket_info(bucket_id).total_files + except Exception: + pass + for rel_path, size, mtime_ms, bucket_file in _list_remote_files(api, bucket_id, prefix): + if filter_matcher.matches(rel_path): + remote_files[rel_path] = (size, mtime_ms) + bucket_file_map[rel_path] = bucket_file + if status: + total_str = f"/{remote_total}" if remote_total is not None else "" + status.update(f"Scanning remote bucket ({len(remote_files)}{total_str} files)") + if status: + status.done(f"Scanning remote bucket ({len(remote_files)} files)") + + local_files = {} + if os.path.isdir(local_path): + if delete: + # Full walk needed to discover local-only files for deletion. + for rel_path, size, mtime_ms in _list_local_files(local_path): + if filter_matcher.matches(rel_path): + local_files[rel_path] = (size, mtime_ms) + if status: + status.update(f"Scanning local directory ({len(local_files)} files)") + else: + # Without --delete, the plan only depends on paths that exist + # remotely. Stat just those instead of walking the whole tree, + # which can take minutes when dest sits in a large directory + # like ~/.cache/huggingface/. + for rel_path in remote_files: + local_file = os.path.join(local_path, rel_path) + stat_info = _stat_local(local_file) + if stat_info is None: + continue + local_files[rel_path] = stat_info + if status: + status.update(f"Scanning local directory ({len(local_files)} files)") + if status: + status.done(f"Scanning local directory ({len(local_files)} files)") + + # Compare files + all_paths = set(remote_files.keys()) | set(local_files.keys()) + if status: + status.done(f"Comparing files ({len(all_paths)} paths)") + for path in sorted(all_paths): + remote_info = remote_files.get(path) + local_info = local_files.get(path) + + if remote_info and not local_info: + # New file + if existing: + # --existing: skip new files + plan.operations.append( + SyncOperation( + action="skip", + path=path, + size=remote_info[0], + reason="new file (--existing)", + remote_mtime=_mtime_to_iso(remote_info[1]), + ) + ) + else: + plan.operations.append( + SyncOperation( + action="download", + path=path, + size=remote_info[0], + reason="new file", + remote_mtime=_mtime_to_iso(remote_info[1]), + bucket_file=bucket_file_map.get(path), + ) + ) + elif remote_info and local_info: + # File exists in both - use helper to determine action + remote_size, remote_mtime = remote_info + local_size, local_mtime = local_info + plan.operations.append( + _compare_files_for_sync( + path=path, + action="download", + source_size=remote_size, + source_mtime=remote_mtime, + dest_size=local_size, + dest_mtime=local_mtime, + source_newer_label="remote newer", + dest_newer_label="local newer", + ignore_sizes=ignore_sizes, + ignore_times=ignore_times, + ignore_existing=ignore_existing, + bucket_file=bucket_file_map.get(path), + ) + ) + elif not remote_info and local_info and delete: + # File only in local and --delete mode + plan.operations.append( + SyncOperation( + action="delete", + path=path, + size=local_info[0], + reason="not in source (--delete)", + local_mtime=_mtime_to_iso(local_info[1]), + ) + ) + + return plan + + +# ============================================================================= +# Plan serialization +# ============================================================================= + + +def _write_plan(plan: SyncPlan, f) -> None: + """Write a sync plan as JSONL to a file-like object.""" + # Write header + header = { + "type": "header", + "source": plan.source, + "dest": plan.dest, + "timestamp": plan.timestamp, + "summary": plan.summary(), + } + f.write(json.dumps(header) + "\n") + + # Write operations + for op in plan.operations: + op_dict: dict[str, Any] = { + "type": "operation", + "action": op.action, + "path": op.path, + "reason": op.reason, + } + if op.size is not None: + op_dict["size"] = op.size + if op.local_mtime is not None: + op_dict["local_mtime"] = op.local_mtime + if op.remote_mtime is not None: + op_dict["remote_mtime"] = op.remote_mtime + f.write(json.dumps(op_dict) + "\n") + + +def _save_plan(plan: SyncPlan, plan_file: str) -> None: + """Save a sync plan to a JSONL file.""" + with open(plan_file, "w") as f: + _write_plan(plan, f) + + +def _load_plan(plan_file: str) -> SyncPlan: + """Load a sync plan from a JSONL file.""" + with open(plan_file) as f: + lines = f.readlines() + + if not lines: + raise ValueError(f"Empty plan file: {plan_file}") + + # Parse header + header = json.loads(lines[0]) + if header.get("type") != "header": + raise ValueError("Invalid plan file: expected header as first line") + + plan = SyncPlan( + source=header["source"], + dest=header["dest"], + timestamp=header["timestamp"], + ) + + # Parse operations + for line in lines[1:]: + op_dict = json.loads(line) + if op_dict.get("type") != "operation": + continue + plan.operations.append( + SyncOperation( + action=op_dict["action"], + path=op_dict["path"], + size=op_dict.get("size"), + reason=op_dict.get("reason", ""), + local_mtime=op_dict.get("local_mtime"), + remote_mtime=op_dict.get("remote_mtime"), + ) + ) + + return plan + + +# ============================================================================= +# Plan execution +# ============================================================================= + + +def _execute_plan(plan: SyncPlan, api: "HfApi", verbose: bool = False, status: Any | None = None) -> None: + """Execute a sync plan.""" + is_upload = not _is_bucket_path(plan.source) and _is_bucket_path(plan.dest) + is_download = _is_bucket_path(plan.source) and not _is_bucket_path(plan.dest) + + if is_upload: + local_path = os.path.abspath(plan.source) + parsed = _parse_bucket_uri(plan.dest) + bucket_id, prefix = parsed.id, parsed.path_in_repo + + # Collect operations + add_files: list[tuple[str | Path | bytes, str]] = [] + delete_paths: list[str] = [] + + for op in plan.operations: + match op.action: + case "upload": + local_file = os.path.join(local_path, op.path) + remote_path = f"{prefix}/{op.path}" if prefix else op.path + if verbose: + print(f" Uploading: {op.path} ({op.reason})") + add_files.append((local_file, remote_path)) + case "delete": + remote_path = f"{prefix}/{op.path}" if prefix else op.path + if verbose: + print(f" Deleting: {op.path} ({op.reason})") + delete_paths.append(remote_path) + case "skip" if verbose: + print(f" Skipping: {op.path} ({op.reason})") + + # Execute batch operations + if add_files or delete_paths: + if status: + parts = [] + if add_files: + parts.append(f"uploading {len(add_files)} files") + if delete_paths: + parts.append(f"deleting {len(delete_paths)} files") + status.done(", ".join(parts).capitalize()) + api.batch_bucket_files( + bucket_id, + add=add_files or None, + delete=delete_paths or None, + ) + + elif is_download: + parsed = _parse_bucket_uri(plan.source) + bucket_id, prefix = parsed.id, parsed.path_in_repo + local_path = os.path.abspath(plan.dest) + + # Ensure local directory exists + os.makedirs(local_path, exist_ok=True) + + # Collect download operations + download_files: list[tuple[str | BucketFile, str | Path]] = [] + delete_files: list[str] = [] + + for op in plan.operations: + if op.action == "download": + local_file = os.path.join(local_path, op.path) + # Ensure parent directory exists + os.makedirs(os.path.dirname(local_file), exist_ok=True) + if verbose: + print(f" Downloading: {op.path} ({op.reason})") + # Use BucketFile when available (avoids extra metadata fetch per file) + if op.bucket_file is not None: + download_files.append((op.bucket_file, local_file)) + else: + remote_path = f"{prefix}/{op.path}" if prefix else op.path + download_files.append((remote_path, local_file)) + elif op.action == "delete": + local_file = os.path.join(local_path, op.path) + if verbose: + print(f" Deleting: {op.path} ({op.reason})") + delete_files.append(local_file) + elif op.action == "skip" and verbose: + print(f" Skipping: {op.path} ({op.reason})") + + # Execute downloads + if len(download_files) > 0: + if status: + status.done(f"Downloading {len(download_files)} files") + api.download_bucket_files(bucket_id, download_files) + + # Execute deletes + if status and delete_files: + status.done(f"Deleting {len(delete_files)} local files") + for file_path in delete_files: + if os.path.exists(file_path): + os.remove(file_path) + # Remove empty parent directories + parent = os.path.dirname(file_path) + while parent != local_path: + try: + os.rmdir(parent) + parent = os.path.dirname(parent) + except OSError: + break + + +def _print_plan_summary(plan: SyncPlan) -> None: + """Print a summary of the sync plan.""" + summary = plan.summary() + print(f"Sync plan: {plan.source} -> {plan.dest}") + print(f" Uploads: {summary['uploads']}") + print(f" Downloads: {summary['downloads']}") + print(f" Deletes: {summary['deletes']}") + print(f" Skips: {summary['skips']}") + + +# ============================================================================= +# Public sync function (Python API) +# ============================================================================= + + +def sync_bucket_internal( + source: str | None = None, + dest: str | None = None, + *, + api: "HfApi", + delete: bool = False, + ignore_times: bool = False, + ignore_sizes: bool = False, + existing: bool = False, + ignore_existing: bool = False, + include: list[str] | None = None, + exclude: list[str] | None = None, + filter_from: str | None = None, + plan: str | None = None, + apply: str | None = None, + dry_run: bool = False, + verbose: bool = False, + quiet: bool = False, + token: bool | str | None = None, +) -> SyncPlan: + """Sync files between a local directory and a bucket. + + This is equivalent to the ``hf buckets sync`` CLI command. One of ``source`` or ``dest`` must be a bucket path + (``hf://buckets/...``) and the other must be a local directory path. + + Args: + source (`str`, *optional*): + Source path: local directory or ``hf://buckets/namespace/bucket_name(/prefix)``. + Required unless using ``apply``. + dest (`str`, *optional*): + Destination path: local directory or ``hf://buckets/namespace/bucket_name(/prefix)``. + Required unless using ``apply``. + api ([`HfApi`]): + The HfApi instance to use for API calls. + delete (`bool`, *optional*, defaults to `False`): + Delete destination files not present in source. + ignore_times (`bool`, *optional*, defaults to `False`): + Skip files only based on size, ignoring modification times. + ignore_sizes (`bool`, *optional*, defaults to `False`): + Skip files only based on modification times, ignoring sizes. + existing (`bool`, *optional*, defaults to `False`): + Skip creating new files on receiver (only update existing files). + ignore_existing (`bool`, *optional*, defaults to `False`): + Skip updating files that exist on receiver (only create new files). + include (`list[str]`, *optional*): + Include files matching patterns (fnmatch-style). + exclude (`list[str]`, *optional*): + Exclude files matching patterns (fnmatch-style). + filter_from (`str`, *optional*): + Path to a filter file with include/exclude rules. + plan (`str`, *optional*): + Save sync plan to this JSONL file instead of executing. + apply (`str`, *optional*): + Apply a previously saved plan file. When set, ``source`` and ``dest`` are not needed. + dry_run (`bool`, *optional*, defaults to `False`): + Print sync plan to stdout as JSONL without executing. + verbose (`bool`, *optional*, defaults to `False`): + Show detailed per-file operations. + quiet (`bool`, *optional*, defaults to `False`): + Suppress all output and progress bars. + token (Union[bool, str, None], optional): + A valid user access token. If not provided, the locally saved token will be used. + + Returns: + [`SyncPlan`]: The computed (or loaded) sync plan. + + Raises: + `ValueError`: If arguments are invalid (e.g., both paths are remote, conflicting options). + + Example: + ```python + >>> from huggingface_hub import HfApi + >>> api = HfApi() + + # Upload local directory to bucket + >>> api.sync_bucket("./data", "hf://buckets/username/my-bucket") + + # Download bucket to local directory + >>> api.sync_bucket("hf://buckets/username/my-bucket", "./data") + + # Sync with delete and filtering + >>> api.sync_bucket( + ... "./data", + ... "hf://buckets/username/my-bucket", + ... delete=True, + ... include=["*.safetensors"], + ... ) + + # Dry run: preview what would be synced + >>> plan = api.sync_bucket("./data", "hf://buckets/username/my-bucket", dry_run=True) + >>> plan.summary() + {'uploads': 3, 'downloads': 0, 'deletes': 0, 'skips': 1, 'total_size': 4096} + + # Save plan for review, then apply + >>> api.sync_bucket("./data", "hf://buckets/username/my-bucket", plan="sync-plan.jsonl") + >>> api.sync_bucket(apply="sync-plan.jsonl") + ``` + """ + # Build API with token if needed + if token is not None: + from .hf_api import HfApi + + api = HfApi( + endpoint=api.endpoint, + token=token, + library_name=api.library_name, + library_version=api.library_version, + user_agent=api.user_agent, + headers=api.headers, + ) + # --- Apply mode --- + if apply: + if source or dest: + raise ValueError("Cannot specify source/dest when using apply.") + if plan is not None: + raise ValueError("Cannot specify both plan and apply.") + if delete: + raise ValueError("Cannot specify delete when using apply.") + if ignore_times: + raise ValueError("Cannot specify ignore_times when using apply.") + if ignore_sizes: + raise ValueError("Cannot specify ignore_sizes when using apply.") + if include: + raise ValueError("Cannot specify include when using apply.") + if exclude: + raise ValueError("Cannot specify exclude when using apply.") + if filter_from: + raise ValueError("Cannot specify filter_from when using apply.") + if existing: + raise ValueError("Cannot specify existing when using apply.") + if ignore_existing: + raise ValueError("Cannot specify ignore_existing when using apply.") + if dry_run: + raise ValueError("Cannot specify dry_run when using apply.") + + sync_plan = _load_plan(apply) + status = StatusLine(enabled=not quiet) + if not quiet: + _print_plan_summary(sync_plan) + print("Executing plan...") + + if quiet: + disable_progress_bars() + try: + _execute_plan(sync_plan, api, verbose=verbose, status=status) + finally: + if quiet: + enable_progress_bars() + + if not quiet: + print("Sync completed.") + + return sync_plan + + # --- Normal mode --- + if not source or not dest: + raise ValueError("Both source and dest are required (unless using apply).") + + source_is_bucket = _is_bucket_path(source) + dest_is_bucket = _is_bucket_path(dest) + + if source_is_bucket and dest_is_bucket: + raise ValueError("Remote to remote sync is not supported. One path must be local.") + + if not source_is_bucket and not dest_is_bucket: + raise ValueError("One of source or dest must be a bucket path (hf://buckets/...).") + + if ignore_times and ignore_sizes: + raise ValueError("Cannot specify both ignore_times and ignore_sizes.") + + if existing and ignore_existing: + raise ValueError("Cannot specify both existing and ignore_existing.") + + if dry_run and plan: + raise ValueError("Cannot specify both dry_run and plan.") + + # Validate local path + if source_is_bucket: + if os.path.exists(dest) and not os.path.isdir(dest): + raise ValueError(f"Destination must be a directory: {dest}") + else: + if not os.path.isdir(source): + raise ValueError(f"Source must be an existing directory: {source}") + + # Build filter matcher + filter_rules = None + if filter_from: + filter_rules = _parse_filter_file(filter_from) + + filter_matcher = FilterMatcher( + include_patterns=include, + exclude_patterns=exclude, + filter_rules=filter_rules, + ) + + # Compute sync plan + status = StatusLine(enabled=not quiet and not dry_run) + sync_plan = _compute_sync_plan( + source=source, + dest=dest, + api=api, + delete=delete, + ignore_times=ignore_times, + ignore_sizes=ignore_sizes, + existing=existing, + ignore_existing=ignore_existing, + filter_matcher=filter_matcher, + status=status, + ) + + if dry_run: + _write_plan(sync_plan, sys.stdout) + return sync_plan + + if plan: + _save_plan(sync_plan, plan) + if not quiet: + _print_plan_summary(sync_plan) + print(f"Plan saved to: {plan}") + return sync_plan + + # Execute plan + if not quiet: + _print_plan_summary(sync_plan) + + summary = sync_plan.summary() + if summary["uploads"] == 0 and summary["downloads"] == 0 and summary["deletes"] == 0: + if not quiet: + print("Nothing to sync.") + return sync_plan + + if not quiet: + print("Syncing...") + + if quiet: + disable_progress_bars() + try: + _execute_plan(sync_plan, api, verbose=verbose, status=status) + finally: + if quiet: + enable_progress_bars() + + if not quiet: + print("Sync completed.") + + return sync_plan diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_commit_api.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_commit_api.py new file mode 100644 index 0000000000000000000000000000000000000000..2305ea36ac155620fbee6ce4f47040d192dd2b90 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_commit_api.py @@ -0,0 +1,1075 @@ +""" +Type definitions and utilities for the `create_commit` API +""" + +import base64 +import io +import json +import os +import warnings +from collections import defaultdict +from collections.abc import Iterable, Iterator +from concurrent.futures import ThreadPoolExecutor +from contextlib import contextmanager +from dataclasses import dataclass, field +from itertools import groupby +from pathlib import Path, PurePosixPath +from typing import TYPE_CHECKING, Any, BinaryIO, Literal, NamedTuple, Union + +from tqdm.contrib.concurrent import thread_map + +from . import constants +from .errors import EntryNotFoundError +from .file_download import hf_hub_url +from .lfs import UploadInfo, lfs_upload, post_lfs_batch_info +from .utils import ( + FORBIDDEN_FOLDERS, + are_progress_bars_disabled, + chunk_iterable, + get_session, + hf_raise_for_status, + http_backoff, + logging, + sha, + tqdm_stream_file, + validate_hf_hub_args, +) +from .utils import tqdm as hf_tqdm +from .utils._runtime import is_xet_available + + +if TYPE_CHECKING: + from .hf_api import CommitInfo, RepoFile + + +logger = logging.get_logger(__name__) + + +UploadMode = Literal["lfs", "regular"] + +# Max is 1,000 per request on the Hub for HfApi.get_paths_info +# Otherwise we get: +# HfHubHTTPError: 413 Client Error: Payload Too Large for url: https://huggingface.co/api/datasets/xxx (Request ID: xxx)\n\ntoo many parameters +# See https://github.com/huggingface/huggingface_hub/issues/1503 +FETCH_LFS_BATCH_SIZE = 500 +DUPLICATE_LFS_BATCH_SIZE = 500 + +UPLOAD_BATCH_MAX_NUM_FILES = 256 + + +@dataclass +class CommitOperationDelete: + """ + Data structure holding necessary info to delete a file or a folder from a repository + on the Hub. + + Args: + path_in_repo (`str`): + Relative filepath in the repo, for example: `"checkpoints/1fec34a/weights.bin"` + for a file or `"checkpoints/1fec34a/"` for a folder. + is_folder (`bool` or `Literal["auto"]`, *optional*) + Whether the Delete Operation applies to a folder or not. If "auto", the path + type (file or folder) is guessed automatically by looking if path ends with + a "/" (folder) or not (file). To explicitly set the path type, you can set + `is_folder=True` or `is_folder=False`. + """ + + path_in_repo: str + is_folder: bool | Literal["auto"] = "auto" + + def __post_init__(self): + self.path_in_repo = _validate_path_in_repo(self.path_in_repo) + + if self.is_folder == "auto": + self.is_folder = self.path_in_repo.endswith("/") + if not isinstance(self.is_folder, bool): + raise ValueError( + f"Wrong value for `is_folder`. Must be one of [`True`, `False`, `'auto'`]. Got '{self.is_folder}'." + ) + + +@dataclass +class CommitOperationCopy: + """ + Data structure holding necessary info to copy a file in a repository on the Hub. + + Both LFS files and regular files are supported. LFS files are copied server-side while regular files are + downloaded and re-uploaded as part of the commit. + + Cross-repository copies are supported by setting `src_repo_id` and `src_repo_type`. For cross-repo LFS copies, + the LFS objects are duplicated to the destination repository before the commit is created. This is handled + automatically by [`create_commit`]. Note that cross-repository copies only work within the same + [storage region](https://huggingface.co/docs/hub/storage-regions); copying across regions is not supported. + + Note: you can combine a [`CommitOperationCopy`] and a [`CommitOperationDelete`] to rename an LFS file on the Hub. + + Args: + src_path_in_repo (`str`): + Relative filepath in the repo of the file to be copied, e.g. `"checkpoints/1fec34a/weights.bin"`. + path_in_repo (`str`): + Relative filepath in the repo where to copy the file, e.g. `"checkpoints/1fec34a/weights_copy.bin"`. + src_revision (`str`, *optional*): + The git revision of the file to be copied. Can be any valid git revision. + Default to the target commit revision. + src_repo_id (`str`, *optional*): + The source repository to copy from (e.g. `"username/source-model"`). + Default to the destination repository (intra-repo copy). + src_repo_type (`str`, *optional*): + The type of the source repository (`"model"`, `"dataset"` or `"space"`). + Required when `src_repo_id` is set. + """ + + src_path_in_repo: str + path_in_repo: str + src_revision: str | None = None + src_repo_id: str | None = None + src_repo_type: str | None = None + # set to the OID of the file to be copied if it has already been uploaded + # useful to determine if a commit will be empty or not. + _src_oid: str | None = None + # set to the OID of the file to copy to if it has already been uploaded + # useful to determine if a commit will be empty or not. + _dest_oid: str | None = None + # set to True once cross-repo LFS files have been duplicated to the destination repo + _is_duplicated: bool = False + + def __post_init__(self): + self.src_path_in_repo = _validate_path_in_repo(self.src_path_in_repo) + self.path_in_repo = _validate_path_in_repo(self.path_in_repo) + if self.src_repo_id is not None and self.src_repo_type is None: + raise ValueError("`src_repo_type` is required when `src_repo_id` is set.") + if self.src_repo_type is not None and self.src_repo_id is None: + raise ValueError("`src_repo_id` is required when `src_repo_type` is set.") + + +@dataclass +class CommitOperationAdd: + """ + Data structure holding necessary info to upload a file to a repository on the Hub. + + Args: + path_in_repo (`str`): + Relative filepath in the repo, for example: `"checkpoints/1fec34a/weights.bin"` + path_or_fileobj (`str`, `Path`, `bytes`, or `BinaryIO`): + Either: + - a path to a local file (as `str` or `pathlib.Path`) to upload + - a buffer of bytes (`bytes`) holding the content of the file to upload + - a "file object" (subclass of `io.BufferedIOBase`), typically obtained + with `open(path, "rb")`. It must support `seek()` and `tell()` methods. + + Raises: + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If `path_or_fileobj` is not one of `str`, `Path`, `bytes` or `io.BufferedIOBase`. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If `path_or_fileobj` is a `str` or `Path` but not a path to an existing file. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If `path_or_fileobj` is a `io.BufferedIOBase` but it doesn't support both + `seek()` and `tell()`. + """ + + path_in_repo: str + path_or_fileobj: str | Path | bytes | BinaryIO + upload_info: UploadInfo = field(init=False, repr=False) + + # Internal attributes + + # set to "lfs" or "regular" once known + _upload_mode: UploadMode | None = field(init=False, repr=False, default=None) + + # set to True if .gitignore rules prevent the file from being uploaded as LFS + # (server-side check) + _should_ignore: bool | None = field(init=False, repr=False, default=None) + + # set to the remote OID of the file if it has already been uploaded + # useful to determine if a commit will be empty or not + _remote_oid: str | None = field(init=False, repr=False, default=None) + + # set to True once the file has been uploaded as LFS + _is_uploaded: bool = field(init=False, repr=False, default=False) + + # set to True once the file has been committed + _is_committed: bool = field(init=False, repr=False, default=False) + + def __post_init__(self) -> None: + """Validates `path_or_fileobj` and compute `upload_info`.""" + self.path_in_repo = _validate_path_in_repo(self.path_in_repo) + + # Validate `path_or_fileobj` value + if isinstance(self.path_or_fileobj, Path): + self.path_or_fileobj = str(self.path_or_fileobj) + if isinstance(self.path_or_fileobj, str): + path_or_fileobj = os.path.normpath(os.path.expanduser(self.path_or_fileobj)) + if not os.path.isfile(path_or_fileobj): + raise ValueError(f"Provided path: '{path_or_fileobj}' is not a file on the local file system") + elif not isinstance(self.path_or_fileobj, (io.BufferedIOBase, bytes)): + # ^^ Inspired from: https://stackoverflow.com/questions/44584829/how-to-determine-if-file-is-opened-in-binary-or-text-mode + raise ValueError( + "path_or_fileobj must be either an instance of str, bytes or" + " io.BufferedIOBase. If you passed a file-like object, make sure it is" + " in binary mode." + ) + if isinstance(self.path_or_fileobj, io.BufferedIOBase): + try: + self.path_or_fileobj.tell() + self.path_or_fileobj.seek(0, os.SEEK_CUR) + except (OSError, AttributeError) as exc: + raise ValueError( + "path_or_fileobj is a file-like object but does not implement seek() and tell()" + ) from exc + + # Compute "upload_info" attribute + if isinstance(self.path_or_fileobj, str): + self.upload_info = UploadInfo.from_path(self.path_or_fileobj) + elif isinstance(self.path_or_fileobj, bytes): + self.upload_info = UploadInfo.from_bytes(self.path_or_fileobj) + else: + self.upload_info = UploadInfo.from_fileobj(self.path_or_fileobj) + + @contextmanager + def as_file(self, with_tqdm: bool = False) -> Iterator[BinaryIO]: + """ + A context manager that yields a file-like object allowing to read the underlying + data behind `path_or_fileobj`. + + Args: + with_tqdm (`bool`, *optional*, defaults to `False`): + If True, iterating over the file object will display a progress bar. Only + works if the file-like object is a path to a file. Pure bytes and buffers + are not supported. + + Example: + + ```python + >>> operation = CommitOperationAdd( + ... path_in_repo="remote/dir/weights.h5", + ... path_or_fileobj="./local/weights.h5", + ... ) + CommitOperationAdd(path_in_repo='remote/dir/weights.h5', path_or_fileobj='./local/weights.h5') + + >>> with operation.as_file() as file: + ... content = file.read() + + >>> with operation.as_file(with_tqdm=True) as file: + ... while True: + ... data = file.read(1024) + ... if not data: + ... break + config.json: 100%|█████████████████████████| 8.19k/8.19k [00:02<00:00, 3.72kB/s] + + >>> with operation.as_file(with_tqdm=True) as file: + ... httpx.put(..., data=file) + config.json: 100%|█████████████████████████| 8.19k/8.19k [00:02<00:00, 3.72kB/s] + ``` + """ + if isinstance(self.path_or_fileobj, str) or isinstance(self.path_or_fileobj, Path): + if with_tqdm: + with tqdm_stream_file(self.path_or_fileobj) as file: + yield file + else: + with open(self.path_or_fileobj, "rb") as file: + yield file + elif isinstance(self.path_or_fileobj, bytes): + yield io.BytesIO(self.path_or_fileobj) + elif isinstance(self.path_or_fileobj, io.BufferedIOBase): + prev_pos = self.path_or_fileobj.tell() + yield self.path_or_fileobj + self.path_or_fileobj.seek(prev_pos, io.SEEK_SET) + + def b64content(self) -> bytes: + """ + The base64-encoded content of `path_or_fileobj` + + Returns: `bytes` + """ + with self.as_file() as file: + return base64.b64encode(file.read()) + + @property + def _local_oid(self) -> str | None: + """Return the OID of the local file. + + This OID is then compared to `self._remote_oid` to check if the file has changed compared to the remote one. + If the file did not change, we won't upload it again to prevent empty commits. + + For LFS files, the OID corresponds to the SHA256 of the file content (used a LFS ref). + For regular files, the OID corresponds to the SHA1 of the file content. + Note: this is slightly different to git OID computation since the oid of an LFS file is usually the git-SHA1 of the + pointer file content (not the actual file content). However, using the SHA256 is enough to detect changes + and more convenient client-side. + """ + if self._upload_mode is None: + return None + elif self._upload_mode == "lfs": + return self.upload_info.sha256.hex() + else: + # Regular file => compute sha1 + # => no need to read by chunk since the file is guaranteed to be <=5MB. + with self.as_file() as file: + return sha.git_hash(file.read()) + + +def _validate_path_in_repo(path_in_repo: str) -> str: + # Validate `path_in_repo` value to prevent a server-side issue + if path_in_repo.startswith("/"): + path_in_repo = path_in_repo[1:] + if path_in_repo == "." or path_in_repo == ".." or path_in_repo.startswith("../"): + raise ValueError(f"Invalid `path_in_repo` in CommitOperation: '{path_in_repo}'") + if path_in_repo.startswith("./"): + path_in_repo = path_in_repo[2:] + for forbidden in FORBIDDEN_FOLDERS: + if any(part == forbidden for part in path_in_repo.split("/")): + raise ValueError( + f"Invalid `path_in_repo` in CommitOperation: cannot update files under a '{forbidden}/' folder (path:" + f" '{path_in_repo}')." + ) + return path_in_repo + + +CommitOperation = Union[CommitOperationAdd, CommitOperationCopy, CommitOperationDelete] + + +def _warn_on_overwriting_operations(operations: list[CommitOperation]) -> None: + """ + Warn user when a list of operations is expected to overwrite itself in a single + commit. + + Rules: + - If a filepath is updated by multiple `CommitOperationAdd` operations, a warning + message is triggered. + - If a filepath is updated at least once by a `CommitOperationAdd` and then deleted + by a `CommitOperationDelete`, a warning is triggered. + - If a `CommitOperationDelete` deletes a filepath that is then updated by a + `CommitOperationAdd`, no warning is triggered. This is usually useless (no need to + delete before upload) but can happen if a user deletes an entire folder and then + add new files to it. + """ + nb_additions_per_path: dict[str, int] = defaultdict(int) + for operation in operations: + path_in_repo = operation.path_in_repo + if isinstance(operation, CommitOperationAdd): + if nb_additions_per_path[path_in_repo] > 0: + warnings.warn( + "About to update multiple times the same file in the same commit:" + f" '{path_in_repo}'. This can cause undesired inconsistencies in" + " your repo." + ) + nb_additions_per_path[path_in_repo] += 1 + for parent in PurePosixPath(path_in_repo).parents: + # Also keep track of number of updated files per folder + # => warns if deleting a folder overwrite some contained files + nb_additions_per_path[str(parent)] += 1 + if isinstance(operation, CommitOperationDelete): + if nb_additions_per_path[str(PurePosixPath(path_in_repo))] > 0: + if operation.is_folder: + warnings.warn( + "About to delete a folder containing files that have just been" + f" updated within the same commit: '{path_in_repo}'. This can" + " cause undesired inconsistencies in your repo." + ) + else: + warnings.warn( + "About to delete a file that have just been updated within the" + f" same commit: '{path_in_repo}'. This can cause undesired" + " inconsistencies in your repo." + ) + + +@validate_hf_hub_args +def _upload_files( + *, + additions: list[CommitOperationAdd], + repo_type: str, + repo_id: str, + headers: dict[str, str], + endpoint: str | None = None, + num_threads: int = 5, + revision: str | None = None, + create_pr: bool | None = None, +): + """ + Uploads the files through the Xet protocol if possible, otherwise through the legacy LFS protocol. + + The Xet path does not require any Python-side sha256 computation: hashing happens inside `hf_xet` + while chunking the files (single read pass) and is backfilled on the operations afterwards. + """ + has_buffered_io_data = any(isinstance(op.path_or_fileobj, io.BufferedIOBase) for op in additions) + if is_xet_available(): + if not has_buffered_io_data: + _upload_xet_files( + additions=additions, + repo_type=repo_type, + repo_id=repo_id, + headers=headers, + endpoint=endpoint, + revision=revision, + create_pr=create_pr, + ) + return + logger.warning( + "Uploading files as a binary IO buffer is not supported by Xet Storage. Falling back to HTTP upload." + ) + + # Legacy LFS path: sha256 is required by the LFS batch endpoint => compute missing ones (in parallel). + _compute_missing_sha256s(additions, num_threads=num_threads) + + lfs_actions: list[dict[str, Any]] = [] + lfs_oid2addop: dict[str, CommitOperationAdd] = {} + for chunk in chunk_iterable(additions, chunk_size=UPLOAD_BATCH_MAX_NUM_FILES): + chunk_list = [op for op in chunk] + actions_chunk, errors_chunk, _ = post_lfs_batch_info( + upload_infos=[op.upload_info for op in chunk_list], + repo_id=repo_id, + repo_type=repo_type, + revision=revision, + endpoint=endpoint, + headers=headers, + token=None, # already passed in 'headers' + transfers=["basic", "multipart"], + ) + if errors_chunk: + message = "\n".join( + [ + f"Encountered error for file with OID {err.get('oid')}: `{err.get('error', {}).get('message')}" + for err in errors_chunk + ] + ) + raise ValueError(f"LFS batch API returned errors:\n{message}") + lfs_actions.extend(actions_chunk) + for op in chunk_list: + lfs_oid2addop[op.upload_info.sha256.hex()] = op + + if len(lfs_actions) > 0: + _upload_lfs_files( + actions=lfs_actions, + oid2addop=lfs_oid2addop, + headers=headers, + endpoint=endpoint, + num_threads=num_threads, + ) + + +def _compute_missing_sha256s(additions: list[CommitOperationAdd], num_threads: int) -> None: + """Compute the sha256 of the operations that don't have one yet, in parallel.""" + not_hashed = [op for op in additions if not op.upload_info.is_hashed] + if len(not_hashed) == 0: + return + logger.info(f"Computing sha256 for {len(not_hashed)} files.") + if len(not_hashed) == 1: + _ = not_hashed[0].upload_info.sha256 + return + with ThreadPoolExecutor(max_workers=num_threads) as executor: + list(executor.map(lambda op: op.upload_info.sha256, not_hashed)) + + +@validate_hf_hub_args +def _upload_lfs_files( + *, + actions: list[dict[str, Any]], + oid2addop: dict[str, CommitOperationAdd], + headers: dict[str, str], + endpoint: str | None = None, + num_threads: int = 5, +): + """ + Uploads the content of `additions` to the Hub using the large file storage protocol. + + Relevant external documentation: + - LFS Batch API: https://github.com/git-lfs/git-lfs/blob/main/docs/api/batch.md + + Args: + actions (`list[dict[str, Any]]`): + LFS batch actions returned by the server. + oid2addop (`dict[str, CommitOperationAdd]`): + A dictionary mapping the OID of the file to the corresponding `CommitOperationAdd` object. + headers (`dict[str, str]`): + Headers to use for the request, including authorization headers and user agent. + endpoint (`str`, *optional*): + The endpoint to use for the request. Defaults to `constants.ENDPOINT`. + num_threads (`int`, *optional*): + The number of concurrent threads to use when uploading. Defaults to 5. + + Raises: + [`EnvironmentError`](https://docs.python.org/3/library/exceptions.html#EnvironmentError) + If an upload failed for any reason + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + Type of the repo to upload to: `"model"`, `"dataset"` or `"space"`. + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + headers (`dict[str, str]`): + Headers to use for the request, including authorization headers and user agent. + num_threads (`int`, *optional*): + The number of concurrent threads to use when uploading. Defaults to 5. + revision (`str`, *optional*): + The git revision to upload to. + + Raises: + [`EnvironmentError`](https://docs.python.org/3/library/exceptions.html#EnvironmentError) + If an upload failed for any reason + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If the server returns malformed responses + [`HfHubHTTPError`] + If the LFS batch endpoint returned an HTTP error. + """ + # Filter out files already present upstream + filtered_actions = [] + for action in actions: + if action.get("actions") is None: + logger.debug( + f"Content of file {oid2addop[action['oid']].path_in_repo} is already present upstream - skipping upload." + ) + else: + filtered_actions.append(action) + + # Upload according to server-provided actions + def _wrapped_lfs_upload(batch_action) -> None: + try: + operation = oid2addop[batch_action["oid"]] + lfs_upload(operation=operation, lfs_batch_action=batch_action, headers=headers, endpoint=endpoint) + except Exception as exc: + raise RuntimeError(f"Error while uploading '{operation.path_in_repo}' to the Hub.") from exc + + if len(filtered_actions) == 1: + logger.debug("Uploading 1 LFS file to the Hub") + _wrapped_lfs_upload(filtered_actions[0]) + else: + logger.debug( + f"Uploading {len(filtered_actions)} LFS files to the Hub using up to {num_threads} threads concurrently" + ) + thread_map( + _wrapped_lfs_upload, + filtered_actions, + desc=f"Upload {len(filtered_actions)} LFS files", + max_workers=num_threads, + tqdm_class=hf_tqdm, + ) + + +@validate_hf_hub_args +def _upload_xet_files( + *, + additions: list[CommitOperationAdd], + repo_type: str, + repo_id: str, + headers: dict[str, str], + endpoint: str | None = None, + revision: str | None = None, + create_pr: bool | None = None, +): + """ + Uploads the content of `additions` to the Hub using the xet storage protocol. + This chunks the files and deduplicates the chunks before uploading them to xetcas storage. + + Args: + additions (`` of `CommitOperationAdd`): + The files to be uploaded. + repo_type (`str`): + Type of the repo (e.g. `"model"`, `"dataset"`, `"space"`). + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + headers (`dict[str, str]`): + Headers to use for the request, including authorization headers and user agent. + endpoint: (`str`, *optional*): + The endpoint to use for the xetcas service. Defaults to `constants.ENDPOINT`. + revision (`str`, *optional*): + The git revision to upload to. + create_pr (`bool`, *optional*): + Whether or not to create a Pull Request with that commit. + + Raises: + [`EnvironmentError`](https://docs.python.org/3/library/exceptions.html#EnvironmentError) + If an upload failed for any reason. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If the server returns malformed responses or if the user is unauthorized to upload to xet storage. + [`HfHubHTTPError`] + If the LFS batch endpoint returned an HTTP error. + + **How it works:** + The file upload system uses Xet storage, which is a content-addressable storage system that breaks files into chunks + for efficient storage and transfer. + + ``session.new_upload_commit()`` manages uploading files by: + - Registering upload tasks and starting upload immediately in the background + - Breaking files into smaller chunks for efficient storage + - Avoiding duplicate storage by recognizing identical chunks across files + - Connecting to a storage server (CAS server) that manages these chunks + + Authentication works transparently: the upload commit accepts a ``token_refresh_url`` + that is used to refresh the short-lived xet write token as needed. + + The upload process works like this: + 1. Upload tasks run in parallel: + 1.1. Read the file content from a path, bytes array, or a stream. + 1.2. Split the file content into smaller chunks based on content patterns: each chunk gets a unique ID based on what's in it. + 1.3. For each chunk: + - Check if it already exists in storage. + - Skip uploading chunks that already exist. + 1.4. Group chunks into larger blocks for efficient transfer. + 1.5. Upload these blocks to the storage server. + 1.6. Assemble the file manifest locally and send it to the server for validation. + 2. Return reference files that contain information about the uploaded files, which can be used later to download them. + """ + if len(additions) == 0: + return + + # at this point, we know that hf_xet is installed + from .utils._xet import ( + XetTokenType, + abort_xet_session, + get_xet_session, + xet_connection_info_refresh_url, + xet_headers_without_auth, + ) + from .utils._xet_progress_reporting import XetUploadProgressReporter + + refresh_url = xet_connection_info_refresh_url( + token_type=XetTokenType.WRITE, + repo_id=repo_id, + repo_type=repo_type, + revision=revision, + endpoint=endpoint, + ) + if create_pr: + refresh_url += "?create_pr=1" + + xet_headers = xet_headers_without_auth(headers) + + import hf_xet + + session = get_xet_session() + progress = None + + def _sha256_arg(op: CommitOperationAdd): + # If the sha256 is already known, pass it to avoid recomputation. Otherwise let hf_xet + # compute it while chunking the file (single read pass) and backfill it afterwards. + return op.upload_info.sha256.hex() if op.upload_info.is_hashed else hf_xet.COMPUTE_SHA256 + + try: + if not are_progress_bars_disabled(): + progress = XetUploadProgressReporter() + progress_callback = progress.update_progress + else: + progress_callback = None + + all_bytes_ops = [op for op in additions if isinstance(op.path_or_fileobj, bytes)] + all_paths_ops = [op for op in additions if isinstance(op.path_or_fileobj, (str, Path))] + + handles: list[tuple[CommitOperationAdd, Any]] = [] + with session.new_upload_commit( + token_refresh_url=refresh_url, + token_refresh_headers=headers, + custom_headers=xet_headers, + progress_callback=progress_callback, + ) as commit: + for op in all_paths_ops: + handles.append((op, commit.start_upload_file(str(op.path_or_fileobj), sha256=_sha256_arg(op)))) + for op in all_bytes_ops: + handles.append((op, commit.start_upload_bytes(op.path_or_fileobj, sha256=_sha256_arg(op)))) + + # Backfill sha256 computed by hf_xet (needed later for the commit payload). + for op, handle in handles: + if not op.upload_info.is_hashed: + op.upload_info.sha256 = bytes.fromhex(handle.result().xet_info.sha256) + except KeyboardInterrupt: + abort_xet_session() + raise + finally: + if progress is not None: + progress.close() + + +def _validate_preupload_info(preupload_info: dict): + files = preupload_info.get("files") + if not isinstance(files, list): + raise ValueError("preupload_info is improperly formatted") + for file_info in files: + if not ( + isinstance(file_info, dict) + and isinstance(file_info.get("path"), str) + and isinstance(file_info.get("uploadMode"), str) + and (file_info["uploadMode"] in ("lfs", "regular")) + ): + raise ValueError("preupload_info is improperly formatted:") + return preupload_info + + +@validate_hf_hub_args +def _fetch_upload_modes( + additions: Iterable[CommitOperationAdd], + repo_type: str, + repo_id: str, + headers: dict[str, str], + revision: str, + endpoint: str | None = None, + create_pr: bool = False, + gitignore_content: str | None = None, +) -> None: + """ + Requests the Hub "preupload" endpoint to determine whether each input file should be uploaded as a regular git blob, + as a git LFS blob, or as a XET file. Input `additions` are mutated in-place with the upload mode. + + Args: + additions (`Iterable` of :class:`CommitOperationAdd`): + Iterable of :class:`CommitOperationAdd` describing the files to + upload to the Hub. + repo_type (`str`): + Type of the repo to upload to: `"model"`, `"dataset"` or `"space"`. + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + headers (`dict[str, str]`): + Headers to use for the request, including authorization headers and user agent. + revision (`str`): + The git revision to upload the files to. Can be any valid git revision. + gitignore_content (`str`, *optional*): + The content of the `.gitignore` file to know which files should be ignored. The order of priority + is to first check if `gitignore_content` is passed, then check if the `.gitignore` file is present + in the list of files to commit and finally default to the `.gitignore` file already hosted on the Hub + (if any). + Raises: + [`~utils.HfHubHTTPError`] + If the Hub API returned an error. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If the Hub API response is improperly formatted. + """ + endpoint = endpoint if endpoint is not None else constants.ENDPOINT + + # Fetch upload mode (LFS or regular) chunk by chunk. + upload_modes: dict[str, UploadMode] = {} + should_ignore_info: dict[str, bool] = {} + oid_info: dict[str, str | None] = {} + + for chunk in chunk_iterable(additions, 256): + payload: dict = { + "files": [ + { + "path": op.path_in_repo, + "sample": base64.b64encode(op.upload_info.sample).decode("ascii"), + "size": op.upload_info.size, + } + for op in chunk + ] + } + if gitignore_content is not None: + payload["gitIgnore"] = gitignore_content + + resp = http_backoff( + "POST", + f"{endpoint}/api/{repo_type}s/{repo_id}/preupload/{revision}", + json=payload, + headers=headers, + params={"create_pr": "1"} if create_pr else None, + ) + hf_raise_for_status(resp) + preupload_info = _validate_preupload_info(resp.json()) + upload_modes.update(**{file["path"]: file["uploadMode"] for file in preupload_info["files"]}) + should_ignore_info.update(**{file["path"]: file["shouldIgnore"] for file in preupload_info["files"]}) + oid_info.update(**{file["path"]: file.get("oid") for file in preupload_info["files"]}) + + # Set upload mode for each addition operation + for addition in additions: + addition._upload_mode = upload_modes[addition.path_in_repo] + addition._should_ignore = should_ignore_info[addition.path_in_repo] + addition._remote_oid = oid_info[addition.path_in_repo] + + # Empty files cannot be uploaded as LFS (S3 would fail with a 501 Not Implemented) + # => empty files are uploaded as "regular" to still allow users to commit them. + for addition in additions: + if addition.upload_info.size == 0: + addition._upload_mode = "regular" + + +class _CopySource(NamedTuple): + src_repo_id: str | None + src_repo_type: str | None + path: str + revision: str | None + + +@validate_hf_hub_args +def _fetch_files_to_copy( + copies: Iterable[CommitOperationCopy], + repo_type: str, + repo_id: str, + headers: dict[str, str], + revision: str, + endpoint: str | None = None, +) -> dict[_CopySource, Union["RepoFile", bytes]]: + """ + Fetch information about the files to copy. + + For LFS files, we only need their metadata (file size and sha256) while for regular files + we need to download the raw content from the Hub. + + Args: + copies (`Iterable` of :class:`CommitOperationCopy`): + Iterable of :class:`CommitOperationCopy` describing the files to + copy on the Hub. + repo_type (`str`): + Type of the repo to upload to: `"model"`, `"dataset"` or `"space"`. + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + headers (`dict[str, str]`): + Headers to use for the request, including authorization headers and user agent. + revision (`str`): + The git revision to upload the files to. Can be any valid git revision. + + Returns: `dict[_CopySource, Union[RepoFile, bytes]]]` + Key is `(src_repo_id, src_repo_type, path, revision)`. For intra-repo copies, + `src_repo_id` and `src_repo_type` are `None`. + Value is the raw content as bytes (for regular files) or the file information as a RepoFile (for LFS files). + + Raises: + [`~utils.HfHubHTTPError`] + If the Hub API returned an error. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If the Hub API response is improperly formatted. + """ + from .hf_api import HfApi, RepoFolder + + hf_api = HfApi(endpoint=endpoint, headers=headers) + copies = list(copies) + files_to_copy: dict[_CopySource, Union["RepoFile", bytes]] = {} + oid_info: dict[tuple[str, str | None], str | None] = {} + + # 1. Fetch OIDs for destination paths in batches. + dest_paths = [op.path_in_repo for op in copies] + for batch in chunk_iterable(dest_paths, FETCH_LFS_BATCH_SIZE): + dest_repo_files = hf_api.get_paths_info( + repo_id=repo_id, + paths=list(batch), + revision=revision, + repo_type=repo_type, + ) + for file in dest_repo_files: + if not isinstance(file, RepoFolder): + oid_info[(file.path, revision)] = file.blob_id + + # 2. Fetch source file info, grouped by (src_repo_id, src_repo_type, src_revision). + copies.sort(key=lambda op: (op.src_repo_id or "", op.src_repo_type or "", op.src_revision or "")) + for (src_repo_id_key, src_repo_type_key, src_revision_key), group in groupby( + copies, key=lambda op: (op.src_repo_id, op.src_repo_type, op.src_revision) + ): + operations = list(group) + is_cross_repo = src_repo_id_key is not None + eff_repo_id = src_repo_id_key or repo_id + eff_repo_type = src_repo_type_key or repo_type + eff_revision = src_revision_key or ("main" if is_cross_repo else revision) + + src_paths = [op.src_path_in_repo for op in operations] + for paths_batch in chunk_iterable(src_paths, FETCH_LFS_BATCH_SIZE): + src_repo_files = hf_api.get_paths_info( + repo_id=eff_repo_id, + paths=list(paths_batch), + revision=eff_revision, + repo_type=eff_repo_type, + ) + for src_repo_file in src_repo_files: + if isinstance(src_repo_file, RepoFolder): + raise NotImplementedError("Copying a folder is not implemented.") + source = _CopySource(src_repo_id_key, src_repo_type_key, src_repo_file.path, src_revision_key) + if src_repo_file.lfs: + files_to_copy[source] = src_repo_file + else: + url = hf_hub_url( + endpoint=endpoint, + repo_type=eff_repo_type, + repo_id=eff_repo_id, + revision=eff_revision, + filename=src_repo_file.path, + ) + response = get_session().get(url, headers=headers) + hf_raise_for_status(response) + files_to_copy[source] = response.content + if not is_cross_repo: + oid_info[(src_repo_file.path, src_revision_key)] = src_repo_file.blob_id + + for operation in operations: + key = _CopySource(src_repo_id_key, src_repo_type_key, operation.src_path_in_repo, src_revision_key) + if key not in files_to_copy: + source_desc = f" from {eff_repo_type}s/{eff_repo_id}" if is_cross_repo else "" + raise EntryNotFoundError( + f"Cannot copy {operation.src_path_in_repo} at revision " + f"{eff_revision}{source_desc}: file is missing on repo." + ) + operation._dest_oid = oid_info.get((operation.path_in_repo, revision)) + if not is_cross_repo: + operation._src_oid = oid_info.get((operation.src_path_in_repo, operation.src_revision)) + + return files_to_copy + + +def _prepare_commit_payload( + operations: Iterable[CommitOperation], + files_to_copy: dict[_CopySource, Union["RepoFile", bytes]], + commit_message: str, + commit_description: str | None = None, + parent_commit: str | None = None, +) -> Iterable[dict[str, Any]]: + """ + Builds the payload to POST to the `/commit` API of the Hub. + + Payload is returned as an iterator so that it can be streamed as a ndjson in the + POST request. + + For more information, see: + - https://github.com/huggingface/huggingface_hub/issues/1085#issuecomment-1265208073 + - http://ndjson.org/ + """ + commit_description = commit_description if commit_description is not None else "" + + # 1. Send a header item with the commit metadata + header_value = {"summary": commit_message, "description": commit_description} + if parent_commit is not None: + header_value["parentCommit"] = parent_commit + yield {"key": "header", "value": header_value} + + nb_ignored_files = 0 + + # 2. Send operations, one per line + for operation in operations: + # Skip ignored files + if isinstance(operation, CommitOperationAdd) and operation._should_ignore: + logger.debug(f"Skipping file '{operation.path_in_repo}' in commit (ignored by gitignore file).") + nb_ignored_files += 1 + continue + + # 2.a. Case adding a regular file + if isinstance(operation, CommitOperationAdd) and operation._upload_mode == "regular": + yield { + "key": "file", + "value": { + "content": operation.b64content().decode(), + "path": operation.path_in_repo, + "encoding": "base64", + }, + } + # 2.b. Case adding an LFS file + elif isinstance(operation, CommitOperationAdd) and operation._upload_mode == "lfs": + yield { + "key": "lfsFile", + "value": { + "path": operation.path_in_repo, + "algo": "sha256", + "oid": operation.upload_info.sha256.hex(), + "size": operation.upload_info.size, + }, + } + # 2.c. Case deleting a file or folder + elif isinstance(operation, CommitOperationDelete): + yield { + "key": "deletedFolder" if operation.is_folder else "deletedFile", + "value": {"path": operation.path_in_repo}, + } + # 2.d. Case copying a file or folder + elif isinstance(operation, CommitOperationCopy): + source = _CopySource( + operation.src_repo_id, + operation.src_repo_type, + operation.src_path_in_repo, + operation.src_revision, + ) + file_to_copy = files_to_copy[source] + if isinstance(file_to_copy, bytes): + yield { + "key": "file", + "value": { + "content": base64.b64encode(file_to_copy).decode(), + "path": operation.path_in_repo, + "encoding": "base64", + }, + } + elif file_to_copy.lfs: + yield { + "key": "lfsFile", + "value": { + "path": operation.path_in_repo, + "algo": "sha256", + "oid": file_to_copy.lfs.sha256, + }, + } + else: + raise ValueError( + "Malformed files_to_copy (should be raw file content as bytes or RepoFile objects with LFS info." + ) + # 2.e. Never expected to happen + else: + raise ValueError( + f"Unknown operation to commit. Operation: {operation}. Upload mode:" + f" {getattr(operation, '_upload_mode', None)}" + ) + + if nb_ignored_files > 0: + logger.info(f"Skipped {nb_ignored_files} file(s) in commit (ignored by gitignore file).") + + +def _send_commit( + *, + operations: Iterable[CommitOperation], + files_to_copy: dict[_CopySource, Union["RepoFile", bytes]], + commit_message: str, + commit_description: str, + repo_type: str, + repo_id: str, + headers: dict[str, str], + revision: str, + endpoint: str | None = None, + parent_commit: str | None = None, + create_pr: bool = False, + hot_reload: bool = False, + retry_on_error: bool = False, +) -> "CommitInfo": + """ + Build the ndjson payload for `operations` and POST it to the `/commit` endpoint of the Hub. + + `revision` must already be URL-quoted. Operations must be ready to commit: upload modes fetched + and LFS/Xet content uploaded. + + If `retry_on_error` is `True`, the POST is retried with exponential backoff on transient errors. + Caution: if a commit succeeds but its response is lost, the retry will create a duplicate commit + (and a duplicate pull request if `create_pr` is set) — only enable it when this is acceptable. + + Returns a [`CommitInfo`] built from the server response. + + Raises: + [`~utils.HfHubHTTPError`] + If the Hub API returned an error. + """ + endpoint = endpoint if endpoint is not None else constants.ENDPOINT + payload = _prepare_commit_payload( + operations=operations, + files_to_copy=files_to_copy, + commit_message=commit_message, + commit_description=commit_description, + parent_commit=parent_commit, + ) + data = b"".join(json.dumps(item).encode() + b"\n" for item in payload) + # See https://github.com/huggingface/huggingface_hub/issues/1085#issuecomment-1265208073 + headers = {"Content-Type": "application/x-ndjson", **headers} + url = f"{endpoint}/api/{repo_type}s/{repo_id}/commit/{revision}" + + params: dict[str, str] = {} + if create_pr: + params["create_pr"] = "1" + if hot_reload: + params["hot_reload"] = "1" + + if retry_on_error: + response = http_backoff("POST", url, headers=headers, content=data, params=params) + else: + response = get_session().post(url, headers=headers, content=data, params=params) + hf_raise_for_status(response, endpoint_name="commit") + + commit_data = response.json() + from .hf_api import CommitInfo + + return CommitInfo( + commit_url=commit_data["commitUrl"], + commit_message=commit_message, + commit_description=commit_description, + oid=commit_data["commitOid"], + pr_url=commit_data["pullRequestUrl"] if create_pr else None, + _endpoint=endpoint, + ) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_commit_scheduler.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_commit_scheduler.py new file mode 100644 index 0000000000000000000000000000000000000000..4aa4b8bf19400f318251838da0245f1aad2f1dbc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_commit_scheduler.py @@ -0,0 +1,353 @@ +import atexit +import logging +import os +import time +from concurrent.futures import Future +from dataclasses import dataclass +from io import SEEK_END, SEEK_SET, BytesIO +from pathlib import Path +from threading import Lock, Thread +from typing import Optional + +from .hf_api import DEFAULT_IGNORE_PATTERNS, CommitInfo, CommitOperationAdd, HfApi +from .utils import filter_repo_objects + + +logger = logging.getLogger(__name__) + + +@dataclass(frozen=True) +class _FileToUpload: + """Temporary dataclass to store info about files to upload. Not meant to be used directly.""" + + local_path: Path + path_in_repo: str + size_limit: int + last_modified: float + + +class CommitScheduler: + """ + Scheduler to upload a local folder to the Hub at regular intervals (e.g. push to hub every 5 minutes). + + The recommended way to use the scheduler is to use it as a context manager. This ensures that the scheduler is + properly stopped and the last commit is triggered when the script ends. The scheduler can also be stopped manually + with the `stop` method. Checkout the [upload guide](https://huggingface.co/docs/huggingface_hub/guides/upload#scheduled-uploads) + to learn more about how to use it. + + Args: + repo_id (`str`): + The id of the repo to commit to. + folder_path (`str` or `Path`): + Path to the local folder to upload regularly. + every (`int` or `float`, *optional*): + The number of minutes between each commit. Defaults to 5 minutes. + path_in_repo (`str`, *optional*): + Relative path of the directory in the repo, for example: `"checkpoints/"`. Defaults to the root folder + of the repository. + repo_type (`str`, *optional*): + The type of the repo to commit to. Defaults to `model`. + revision (`str`, *optional*): + The revision of the repo to commit to. Defaults to `main`. + private (`bool`, *optional*): + Whether to make the repo private. If `None` (default), the repo will be public unless the organization's default is private. This value is ignored if the repo already exists. + token (`str`, *optional*): + The token to use to commit to the repo. Defaults to the token saved on the machine. + allow_patterns (`list[str]` or `str`, *optional*): + If provided, only files matching at least one pattern are uploaded. + ignore_patterns (`list[str]` or `str`, *optional*): + If provided, files matching any of the patterns are not uploaded. + squash_history (`bool`, *optional*): + Whether to squash the history of the repo after each commit. Defaults to `False`. Squashing commits is + useful to avoid degraded performances on the repo when it grows too large. + hf_api (`HfApi`, *optional*): + The [`HfApi`] client to use to commit to the Hub. Can be set with custom settings (user agent, token,...). + + Example: + ```py + >>> from pathlib import Path + >>> from huggingface_hub import CommitScheduler + + # Scheduler uploads every 10 minutes + >>> csv_path = Path("watched_folder/data.csv") + >>> CommitScheduler(repo_id="test_scheduler", repo_type="dataset", folder_path=csv_path.parent, every=10) + + >>> with csv_path.open("a") as f: + ... f.write("first line") + + # Some time later (...) + >>> with csv_path.open("a") as f: + ... f.write("second line") + ``` + + Example using a context manager: + ```py + >>> from pathlib import Path + >>> from huggingface_hub import CommitScheduler + + >>> with CommitScheduler(repo_id="test_scheduler", repo_type="dataset", folder_path="watched_folder", every=10) as scheduler: + ... csv_path = Path("watched_folder/data.csv") + ... with csv_path.open("a") as f: + ... f.write("first line") + ... (...) + ... with csv_path.open("a") as f: + ... f.write("second line") + + # Scheduler is now stopped and last commit have been triggered + ``` + """ + + def __init__( + self, + *, + repo_id: str, + folder_path: str | Path, + every: int | float = 5, + path_in_repo: str | None = None, + repo_type: str | None = None, + revision: str | None = None, + private: bool | None = None, + token: str | None = None, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + squash_history: bool = False, + hf_api: Optional["HfApi"] = None, + ) -> None: + self.api = hf_api or HfApi(token=token) + + # Folder + self.folder_path = Path(folder_path).expanduser().resolve() + self.path_in_repo = path_in_repo or "" + self.allow_patterns = allow_patterns + + if ignore_patterns is None: + ignore_patterns = [] + elif isinstance(ignore_patterns, str): + ignore_patterns = [ignore_patterns] + self.ignore_patterns = ignore_patterns + DEFAULT_IGNORE_PATTERNS + + if self.folder_path.is_file(): + raise ValueError(f"'folder_path' must be a directory, not a file: '{self.folder_path}'.") + self.folder_path.mkdir(parents=True, exist_ok=True) + + # Repository + repo_url = self.api.create_repo(repo_id=repo_id, private=private, repo_type=repo_type, exist_ok=True) + self.repo_id = repo_url.repo_id + self.repo_type = repo_type + self.revision = revision + self.token = token + + # Keep track of already uploaded files + self.last_uploaded: dict[Path, float] = {} # key is local path, value is timestamp + + # Scheduler + if not every > 0: + raise ValueError(f"'every' must be a positive integer, not '{every}'.") + self.lock = Lock() + self.every = every + self.squash_history = squash_history + + logger.info(f"Scheduled job to push '{self.folder_path}' to '{self.repo_id}' every {self.every} minutes.") + self._scheduler_thread = Thread(target=self._run_scheduler, daemon=True) + self._scheduler_thread.start() + atexit.register(self._push_to_hub) + + self.__stopped = False + + def stop(self) -> None: + """Stop the scheduler. + + A stopped scheduler cannot be restarted. Mostly for tests purposes. + """ + self.__stopped = True + + def __enter__(self) -> "CommitScheduler": + return self + + def __exit__(self, exc_type, exc_value, traceback) -> None: + # Upload last changes before exiting + self.trigger().result() + self.stop() + return + + def _run_scheduler(self) -> None: + """Dumb thread waiting between each scheduled push to Hub.""" + while True: + self.last_future = self.trigger() + time.sleep(self.every * 60) + if self.__stopped: + break + + def trigger(self) -> Future: + """Trigger a `push_to_hub` and return a future. + + This method is automatically called every `every` minutes. You can also call it manually to trigger a commit + immediately, without waiting for the next scheduled commit. + """ + return self.api.run_as_future(self._push_to_hub) + + def _push_to_hub(self) -> CommitInfo | None: + if self.__stopped: # If stopped, already scheduled commits are ignored + return None + + logger.info("(Background) scheduled commit triggered.") + try: + value = self.push_to_hub() + if self.squash_history: + logger.info("(Background) squashing repo history.") + self.api.super_squash_history(repo_id=self.repo_id, repo_type=self.repo_type, branch=self.revision) + return value + except Exception as e: + logger.error(f"Error while pushing to Hub: {e}") # Depending on the setup, error might be silenced + raise + + def push_to_hub(self) -> CommitInfo | None: + """ + Push folder to the Hub and return the commit info. + + > [!WARNING] + > This method is not meant to be called directly. It is run in the background by the scheduler, respecting a + > queue mechanism to avoid concurrent commits. Making a direct call to the method might lead to concurrency + > issues. + + The default behavior of `push_to_hub` is to assume an append-only folder. It lists all files in the folder and + uploads only changed files. If no changes are found, the method returns without committing anything. If you want + to change this behavior, you can inherit from [`CommitScheduler`] and override this method. This can be useful + for example to compress data together in a single file before committing. For more details and examples, check + out our [integration guide](https://huggingface.co/docs/huggingface_hub/main/en/guides/upload#scheduled-uploads). + """ + # Check files to upload (with lock) + with self.lock: + logger.debug("Listing files to upload for scheduled commit.") + + # List files from folder (taken from `_prepare_upload_folder_additions`) + relpath_to_abspath = { + path.relative_to(self.folder_path).as_posix(): path + for path in sorted(self.folder_path.glob("**/*")) # sorted to be deterministic + if path.is_file() + } + prefix = f"{self.path_in_repo.strip('/')}/" if self.path_in_repo else "" + + # Filter with pattern + filter out unchanged files + retrieve current file size + files_to_upload: list[_FileToUpload] = [] + for relpath in filter_repo_objects( + relpath_to_abspath.keys(), allow_patterns=self.allow_patterns, ignore_patterns=self.ignore_patterns + ): + local_path = relpath_to_abspath[relpath] + stat = local_path.stat() + if self.last_uploaded.get(local_path) is None or self.last_uploaded[local_path] != stat.st_mtime: + files_to_upload.append( + _FileToUpload( + local_path=local_path, + path_in_repo=prefix + relpath, + size_limit=stat.st_size, + last_modified=stat.st_mtime, + ) + ) + + # Return if nothing to upload + if len(files_to_upload) == 0: + logger.debug("Dropping schedule commit: no changed file to upload.") + return None + + # Convert `_FileToUpload` as `CommitOperationAdd` (=> compute file shas + limit to file size) + logger.debug("Removing unchanged files since previous scheduled commit.") + add_operations = [ + CommitOperationAdd( + # Cap the file to its current size, even if the user append data to it while a scheduled commit is happening + path_or_fileobj=PartialFileIO(file_to_upload.local_path, size_limit=file_to_upload.size_limit), + path_in_repo=file_to_upload.path_in_repo, + ) + for file_to_upload in files_to_upload + ] + + # Upload files (append mode expected - no need for lock) + logger.debug("Uploading files for scheduled commit.") + commit_info = self.api.create_commit( + repo_id=self.repo_id, + repo_type=self.repo_type, + operations=add_operations, + commit_message="Scheduled Commit", + revision=self.revision, + ) + + # Successful commit: keep track of the latest "last_modified" for each file + for file in files_to_upload: + self.last_uploaded[file.local_path] = file.last_modified + return commit_info + + +class PartialFileIO(BytesIO): + """A file-like object that reads only the first part of a file. + + Useful to upload a file to the Hub when the user might still be appending data to it. Only the first part of the + file is uploaded (i.e. the part that was available when the filesystem was first scanned). + + In practice, only used internally by the CommitScheduler to regularly push a folder to the Hub with minimal + disturbance for the user. The object is passed to `CommitOperationAdd`. + + Only supports `read`, `tell` and `seek` methods. + + Args: + file_path (`str` or `Path`): + Path to the file to read. + size_limit (`int`): + The maximum number of bytes to read from the file. If the file is larger than this, only the first part + will be read (and uploaded). + """ + + def __init__(self, file_path: str | Path, size_limit: int) -> None: + self._file_path = Path(file_path) + self._file = self._file_path.open("rb") + self._size_limit = min(size_limit, os.fstat(self._file.fileno()).st_size) + + def __del__(self) -> None: + self._file.close() + return super().__del__() + + def __repr__(self) -> str: + return f"" + + def __len__(self) -> int: + return self._size_limit + + def __getattribute__(self, name: str): + if name.startswith("_") or name in ("read", "tell", "seek", "fileno"): # only 4 public methods supported + return super().__getattribute__(name) + raise NotImplementedError(f"PartialFileIO does not support '{name}'.") + + def fileno(self): + raise AttributeError("PartialFileIO does not have a fileno.") + + def tell(self) -> int: + """Return the current file position.""" + return self._file.tell() + + def seek(self, __offset: int, __whence: int = SEEK_SET) -> int: + """Change the stream position to the given offset. + + Behavior is the same as a regular file, except that the position is capped to the size limit. + """ + if __whence == SEEK_END: + # SEEK_END => set from the truncated end + __offset = len(self) + __offset + __whence = SEEK_SET + + pos = self._file.seek(__offset, __whence) + if pos > self._size_limit: + return self._file.seek(self._size_limit) + return pos + + def read(self, __size: int | None = -1) -> bytes: + """Read at most `__size` bytes from the file. + + Behavior is the same as a regular file, except that it is capped to the size limit. + """ + current = self._file.tell() + if __size is None or __size < 0: + # Read until file limit + truncated_size = self._size_limit - current + else: + # Read until file limit or __size + truncated_size = min(__size, self._size_limit - current) + return self._file.read(truncated_size) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_dataset_viewer.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_dataset_viewer.py new file mode 100644 index 0000000000000000000000000000000000000000..ada15a7f0c3fd2d8d67d4fe9d803598b32896bb2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_dataset_viewer.py @@ -0,0 +1,172 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +import json +import os +import shutil +import subprocess +from dataclasses import dataclass +from typing import TYPE_CHECKING, Any, Union + +from . import constants +from .utils import get_token + + +if TYPE_CHECKING: + import duckdb + + +@dataclass(frozen=True) +class DatasetParquetEntry: + """Represents a single parquet file available for a dataset on the Hub.""" + + config: str + split: str + url: str + size: int + + +def execute_raw_sql_query(sql_query: str, *, token: str | bool | None = None) -> list[dict[str, Any]]: + normalized_query = sql_query.strip().rstrip(";").strip() + _raise_on_forbidden_query(normalized_query) + + connection = None + try: + connection = _get_duckdb_connection(token=token) + relation = connection.sql(normalized_query) + if relation is None: + raise ValueError("SQL query must return rows.") + + if isinstance(relation, _DuckDBCliRelation): + # DuckDB binary => run CLI => parse JSON + return relation.execute() + else: + # DuckDB Python API => fetch columns + rows => convert to dicts + columns = tuple(column[0] for column in relation.description) + rows = tuple(tuple(row) for row in relation.fetchall()) + return [dict(zip(columns, row)) for row in rows] + finally: + if connection is not None: + connection.close() + + +def _raise_on_forbidden_query(query: str) -> None: + if len(query) == 0: + raise ValueError("SQL query cannot be empty.") + + # DuckDB CLI meta-commands are dot-prefixed words (e.g. `.shell`, `.output`). + # Let's forbid them for now but allow SQL expressions like `.5` that can legitimately start a line. + for line in query.splitlines(): + stripped = line.lstrip() + if stripped.startswith(".") and stripped[1:2].isalpha(): + raise ValueError("DuckDB CLI meta-commands are not allowed in SQL queries.") + + +def _get_duckdb_connection( + token: str | bool | None, +) -> Union["duckdb.DuckDBPyConnection", "_DuckDBCliConnection"]: + try: + # If DuckDB is installed as a Python package, use it! + import duckdb + except ImportError as error: + # Otherwise, use the DuckDB CLI binary. + duckdb_binary = shutil.which("duckdb") + if duckdb_binary is None: + raise ImportError( + "DuckDB is required for `hf datasets sql`. Install the Python package with `pip install duckdb` or " + "install the DuckDB CLI binary (for example `brew install duckdb`)." + ) from error + return _DuckDBCliConnection(binary_path=duckdb_binary, token=token) + + # Create a new connection (Python API). + connection = duckdb.connect() + try: + for statement in _build_duckdb_secret_statements(token): + connection.execute(statement) + return connection + except Exception: + connection.close() + raise + + +@dataclass +class _DuckDBCliConnection: + """DuckDB connection. + + Mimics the DuckDB Python API, but runs the queries via the DuckDB CLI binary. + """ + + binary_path: str + token: str | bool | None + + def __post_init__(self) -> None: + self._setup_statements = _build_duckdb_secret_statements(self.token) + + def sql(self, query: str) -> "_DuckDBCliRelation": + return _DuckDBCliRelation(binary_path=self.binary_path, setup_statements=self._setup_statements, query=query) + + def close(self) -> None: + pass + + +@dataclass +class _DuckDBCliRelation: + """DuckDB relation. + + Mimics the DuckDB Python API, but runs the queries via the DuckDB CLI binary. + """ + + binary_path: str + setup_statements: list[str] + query: str + + def execute(self) -> list[dict[str, Any]]: + # Build the DuckDB CLI input. + setup = [] + if self.setup_statements: + setup = [ + f".output {os.devnull}", + *(f"{stmt};" for stmt in self.setup_statements), + ".output", + ] + full_query = "\n".join(setup + [self.query + ";"]) + + # Run DuckDB binary + result = subprocess.run( + [self.binary_path, "-json"], + input=full_query, + capture_output=True, + text=True, + check=False, + ) + if result.returncode != 0: + error_message = result.stderr.strip() or result.stdout.strip() or "DuckDB CLI command failed." + raise RuntimeError(error_message) + + # Parse JSON output and return + return json.loads(result.stdout.strip()) + + +def _build_duckdb_secret_statements(token: str | bool | None) -> list[str]: + if token is None or token is True: + token = get_token() + + if not token: + return [] + + escaped_token = token.replace("'", "''") + escaped_endpoint = constants.ENDPOINT.replace("'", "''") + return [ + f"CREATE OR REPLACE SECRET hf_hub_token (TYPE HTTP, BEARER_TOKEN '{escaped_token}', SCOPE '{escaped_endpoint}')", + f"CREATE OR REPLACE SECRET hf_token (TYPE HUGGINGFACE, TOKEN '{escaped_token}')", + ] diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_eval_results.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_eval_results.py new file mode 100644 index 0000000000000000000000000000000000000000..77aee2b595e979a0d4e83a71f7bea81a6f2e4d33 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_eval_results.py @@ -0,0 +1,211 @@ +"""Evaluation results utilities for the `.eval_results/*.yaml` format. + +See https://huggingface.co/docs/hub/eval-results for more details. +Specifications are available at https://github.com/huggingface/hub-docs/blob/main/eval_results.yaml. +""" + +from dataclasses import dataclass +from typing import Any + + +@dataclass +class EvalResultEntry: + """ + Evaluation result entry for the `.eval_results/*.yaml` format. + + Represents evaluation scores stored in model repos that automatically appear on + the model page and the benchmark dataset's leaderboard. + + For the legacy `model-index` format in `README.md`, use [`EvalResult`] instead. + + See https://huggingface.co/docs/hub/eval-results for more details. + + Args: + dataset_id (`str`): + Benchmark dataset ID from the Hub. Example: "cais/hle", "Idavidrein/gpqa". + task_id (`str`): + Task identifier within the benchmark. Example: "gpqa_diamond". + value (`Any`): + The metric value. Example: 20.90. + dataset_revision (`str`, *optional*): + Git SHA of the benchmark dataset. + verify_token (`str`, *optional*): + A signature that can be used to prove that evaluation is provably auditable and reproducible. + date (`str`, *optional*): + When the evaluation was run (ISO-8601 datetime). Defaults to git commit time. + source_url (`str`, *optional*): + Link to the evaluation source (e.g., https://huggingface.co/spaces/SaylorTwift/smollm3-mmlu-pro). Required if `source_name`, `source_user`, or `source_org` is provided. + source_name (`str`, *optional*): + Display name for the source. Example: "Eval Logs". + source_user (`str`, *optional*): + HF user name for attribution. Example: "celinah". + source_org (`str`, *optional*): + HF org name for attribution. Example: "cais". + notes (`str`, *optional*): + Details about the evaluation setup. Example: "tools", "no-tools", "chain-of-thought". + + Example: + ```python + >>> from huggingface_hub import EvalResultEntry + >>> # Minimal example with required fields only + >>> result = EvalResultEntry( + ... dataset_id="Idavidrein/gpqa", + ... task_id="gpqa_diamond", + ... value=0.412, + ... ) + >>> # Full example with all fields + >>> result = EvalResultEntry( + ... dataset_id="cais/hle", + ... task_id="default", + ... value=20.90, + ... dataset_revision="5503434ddd753f426f4b38109466949a1217c2bb", + ... verify_token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + ... date="2025-01-15T10:30:00Z", + ... source_url="https://huggingface.co/datasets/cais/hle", + ... source_name="CAIS HLE", + ... source_org="cais", + ... notes="no-tools", + ... ) + + ``` + """ + + dataset_id: str + task_id: str + value: Any + dataset_revision: str | None = None + verify_token: str | None = None + date: str | None = None + source_url: str | None = None + source_name: str | None = None + source_user: str | None = None + source_org: str | None = None + notes: str | None = None + + def __post_init__(self) -> None: + if ( + self.source_name is not None or self.source_user is not None or self.source_org is not None + ) and self.source_url is None: + raise ValueError( + "If `source_name`, `source_user`, or `source_org` is provided, `source_url` must also be provided." + ) + + +def eval_result_entries_to_yaml(entries: list[EvalResultEntry]) -> list[dict[str, Any]]: + """Convert a list of [`EvalResultEntry`] objects to a YAML-serializable list of dicts. + + This produces the format expected in `.eval_results/*.yaml` files. + + Args: + entries (`list[EvalResultEntry]`): + List of evaluation result entries to serialize. + + Returns: + `list[dict[str, Any]]`: A list of dictionaries ready to be dumped to YAML. + + Example: + ```python + >>> from huggingface_hub import EvalResultEntry, eval_result_entries_to_yaml + >>> entries = [ + ... EvalResultEntry(dataset_id="cais/hle", task_id="default", value=20.90), + ... EvalResultEntry(dataset_id="Idavidrein/gpqa", task_id="gpqa_diamond", value=0.412), + ... ] + >>> yaml_data = eval_result_entries_to_yaml(entries) + >>> yaml_data[0] + {'dataset': {'id': 'cais/hle', 'task_id': 'default'}, 'value': 20.9} + + ``` + + To upload eval results to the Hub: + ```python + >>> import yaml + >>> from huggingface_hub import upload_file, EvalResultEntry, eval_result_entries_to_yaml + >>> entries = [ + ... EvalResultEntry(dataset_id="cais/hle", task_id="default", value=20.90), + ... ] + >>> yaml_content = yaml.dump(eval_result_entries_to_yaml(entries)) + >>> upload_file( + ... path_or_fileobj=yaml_content.encode(), + ... path_in_repo=".eval_results/hle.yaml", + ... repo_id="your-username/your-model", + ... ) + + ``` + """ + result = [] + for entry in entries: + # build the dataset object + dataset: dict[str, Any] = {"id": entry.dataset_id, "task_id": entry.task_id} + if entry.dataset_revision is not None: + dataset["revision"] = entry.dataset_revision + + data: dict[str, Any] = {"dataset": dataset, "value": entry.value} + if entry.verify_token is not None: + data["verifyToken"] = entry.verify_token + if entry.date is not None: + data["date"] = entry.date + # build the source object + if entry.source_url is not None: + source: dict[str, Any] = {"url": entry.source_url} + if entry.source_name is not None: + source["name"] = entry.source_name + if entry.source_user is not None: + source["user"] = entry.source_user + if entry.source_org is not None: + source["org"] = entry.source_org + data["source"] = source + if entry.notes is not None: + data["notes"] = entry.notes + + result.append(data) + return result + + +def parse_eval_result_entries(data: list[dict[str, Any]]) -> list[EvalResultEntry]: + """Parse a list of dicts into [`EvalResultEntry`] objects. + + This parses the `.eval_results/*.yaml` format. For the legacy `model-index` format, + use [`model_index_to_eval_results`] instead. + + Args: + data (`list[dict[str, Any]]`): + A list of dictionaries (e.g., parsed from YAML or API response). + + Returns: + `list[EvalResultEntry]`: A list of evaluation result entry objects. + + Example: + ```python + >>> from huggingface_hub import parse_eval_result_entries + >>> data = [ + ... {"dataset": {"id": "cais/hle", "task_id": "default"}, "value": 20.90}, + ... {"dataset": {"id": "Idavidrein/gpqa", "task_id": "gpqa_diamond"}, "value": 0.412}, + ... ] + >>> entries = parse_eval_result_entries(data) + >>> entries[0].dataset_id + 'cais/hle' + >>> entries[0].value + 20.9 + + ``` + """ + entries = [] + for item in data: + entry_data = item.get("data", item) + dataset = entry_data.get("dataset", {}) + source = entry_data.get("source", {}) + entry = EvalResultEntry( + dataset_id=dataset["id"], + value=entry_data["value"], + task_id=dataset["task_id"], + dataset_revision=dataset.get("revision"), + verify_token=entry_data.get("verifyToken"), + date=entry_data.get("date"), + source_url=source.get("url") if source else None, + source_name=source.get("name") if source else None, + source_user=source.get("user") if source else None, + source_org=source.get("org") if source else None, + notes=entry_data.get("notes"), + ) + entries.append(entry) + return entries diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_hot_reload/__init__.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_hot_reload/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ef08599ad40fcb6d55fac1c397597f68b8b52084 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_hot_reload/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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/python3.13/site-packages/huggingface_hub/_hot_reload/client.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_hot_reload/client.py new file mode 100644 index 0000000000000000000000000000000000000000..1c3dc30938ce81e32886d5e585bdab8a33fe5218 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_hot_reload/client.py @@ -0,0 +1,130 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. + + +import json +import time +from collections import deque +from collections.abc import Iterator +from typing import Literal, TypedDict + +import httpx + +from ..utils._headers import build_hf_headers +from ..utils._http import hf_raise_for_status +from .sse_client import SSEClient +from .types import ApiGetReloadEventSourceData, ApiGetReloadRequest + + +HOT_RELOADING_PORT = 7887 +CLIENT_TIMEOUT = 20 + + +class MultiReplicaStreamWarning(TypedDict): + kind: Literal["warning"] + message: str + + +class MultiReplicaStreamEvent(TypedDict): + kind: Literal["event"] + event: ApiGetReloadEventSourceData + + +class MultiReplicaStreamReplicaHash(TypedDict): + kind: Literal["replicaHash"] + hash: str + + +class MultiReplicaStreamFullMatch(TypedDict): + kind: Literal["fullMatch"] + + +class ReloadClient: + def __init__( + self, + *, + host: str, + subdomain: str, + replica_hash: str, + token: str | None, + ): + base_host = host.replace(subdomain, f"{subdomain}--{HOT_RELOADING_PORT}") + self.replica_hash = replica_hash + self.client = httpx.Client( + base_url=f"{base_host}/--replicas/+{replica_hash}", + headers=build_hf_headers(token=token), + timeout=CLIENT_TIMEOUT, + ) + + def get_reload(self, reload_id: str) -> Iterator[ApiGetReloadEventSourceData] | int: + req = ApiGetReloadRequest(reloadId=reload_id) + with self.client.stream("POST", "/get-reload", json=req) as res: + if res.status_code != 200: + return res.status_code + hf_raise_for_status(res) + for event in SSEClient(res.iter_bytes()).events(): + if event.event == "message": + yield json.loads(event.data) + return None + + +def multi_replica_reload_events( + commit_sha: str, + host: str, + subdomain: str, + replica_hashes: list[str], + token: str | None, + max_retries: int = 10, +) -> Iterator[ + MultiReplicaStreamWarning | MultiReplicaStreamEvent | MultiReplicaStreamReplicaHash | MultiReplicaStreamFullMatch +]: + clients = [ + ReloadClient( + host=host, + subdomain=subdomain, + replica_hash=hash, + token=token, + ) + for hash in replica_hashes + ] + + first_client_events: dict[int, ApiGetReloadEventSourceData] = {} + for client_index, client in enumerate(clients): + if len(clients) > 1: + yield {"kind": "replicaHash", "hash": client.replica_hash} + + retries = 0 + while isinstance((events := client.get_reload(commit_sha)), int): + if (retries := retries + 1) > max_retries: + raise Exception("Too many retries reached") + if (status_code := events) not in (200, 204): + raise Exception(f"Unexpected {status_code=} on `ReloadClient.get_reload`") + subject = "reloadId" if status_code == 204 else "replica" + yield {"kind": "warning", "message": f"Retrying on unexpected {subject} not found"} + time.sleep(2) + + full_match = True + replay: deque[ApiGetReloadEventSourceData] = deque() + for event_index, event in enumerate(events): + if client_index == 0: + first_client_events[event_index] = event + elif full_match := full_match and first_client_events.get(event_index) == event: + replay.append(event) + continue + while replay: + yield {"kind": "event", "event": replay.popleft()} + yield {"kind": "event", "event": event} + + if client_index > 0 and full_match: + yield {"kind": "fullMatch"} diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_hot_reload/sse_client.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_hot_reload/sse_client.py new file mode 100644 index 0000000000000000000000000000000000000000..2dab959bbd62045adff1d8d51438acd5bd062265 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_hot_reload/sse_client.py @@ -0,0 +1,144 @@ +""" +Vendored file: Server Side Events (SSE) client for Python. + +Source: +- Author: Maxime Petazzoni +- Repository: https://github.com/mpetazzoni/sseclient +- File: https://github.com/mpetazzoni/sseclient/blob/main/sseclient/__init__.py + +License: +- Apache-2.0 (from upstream project) + +Provides a generator of SSE received through an existing HTTP response. +""" + +import logging + +__author__ = 'Maxime Petazzoni ' +__email__ = 'maxime.petazzoni@bulix.org' +__all__ = ['SSEClient'] + +_FIELD_SEPARATOR = ':' + + +class SSEClient: + """Implementation of a SSE client. + + See http://www.w3.org/TR/2009/WD-eventsource-20091029/ for the + specification. + """ + + def __init__(self, event_source, char_enc='utf-8'): + """Initialize the SSE client over an existing, ready to consume + event source. + + The event source is expected to be a binary stream and have a close() + method. That would usually be something that implements + io.BinaryIOBase, like an httplib or urllib3 HTTPResponse object. + """ + self._logger = logging.getLogger(self.__class__.__module__) + self._logger.debug('Initialized SSE client from event source %s', + event_source) + self._event_source = event_source + self._char_enc = char_enc + + def _read(self): + """Read the incoming event source stream and yield event chunks. + + Unfortunately it is possible for some servers to decide to break an + event into multiple HTTP chunks in the response. It is thus necessary + to correctly stitch together consecutive response chunks and find the + SSE delimiter (empty new line) to yield full, correct event chunks.""" + data = b'' + for chunk in self._event_source: + for line in chunk.splitlines(True): + data += line + if data.endswith((b'\r\r', b'\n\n', b'\r\n\r\n')): + yield data + data = b'' + if data: + yield data + + def events(self): + for chunk in self._read(): + event = Event() + # Split before decoding so splitlines() only uses \r and \n + for line in chunk.splitlines(): + # Decode the line. + line = line.decode(self._char_enc) + + # Lines starting with a separator are comments and are to be + # ignored. + if not line.strip() or line.startswith(_FIELD_SEPARATOR): + continue + + data = line.split(_FIELD_SEPARATOR, 1) + field = data[0] + + # Ignore unknown fields. + if field not in event.__dict__: + self._logger.debug('Saw invalid field %s while parsing ' + 'Server Side Event', field) + continue + + if len(data) > 1: + # From the spec: + # "If value starts with a single U+0020 SPACE character, + # remove it from value." + if data[1].startswith(' '): + value = data[1][1:] + else: + value = data[1] + else: + # If no value is present after the separator, + # assume an empty value. + value = '' + + # The data field may come over multiple lines and their values + # are concatenated with each other. + if field == 'data': + event.__dict__[field] += value + '\n' + else: + event.__dict__[field] = value + + # Events with no data are not dispatched. + if not event.data: + continue + + # If the data field ends with a newline, remove it. + if event.data.endswith('\n'): + event.data = event.data[0:-1] + + # Empty event names default to 'message' + event.event = event.event or 'message' + + # Dispatch the event + self._logger.debug('Dispatching %s...', event) + yield event + + def close(self): + """Manually close the event source stream.""" + self._event_source.close() + + +class Event: + """Representation of an event from the event stream.""" + + def __init__(self, id=None, event='message', data='', retry=None): + self.id = id + self.event = event + self.data = data + self.retry = retry + + def __str__(self): + s = f'{self.event} event' + if self.id: + s += f' #{self.id}' + if self.data: + s += ', {} byte{}'.format(len(self.data), + 's' if len(self.data) else '') + else: + s += ', no data' + if self.retry: + s += f', retry in {self.retry}ms' + return s diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_hot_reload/types.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_hot_reload/types.py new file mode 100644 index 0000000000000000000000000000000000000000..c5f892d6287f5b581edca8fdf64c1827e114621b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_hot_reload/types.py @@ -0,0 +1,121 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. + + +from typing import Literal, TypedDict + +from typing_extensions import NotRequired + + +class ReloadRegion(TypedDict): + startLine: int + startCol: int + endLine: int + endCol: int + + +class ReloadOperationObject(TypedDict): + kind: Literal["add", "update", "delete"] + region: ReloadRegion + objectType: str + objectName: str + + +class ReloadOperationRun(TypedDict): + kind: Literal["run"] + region: ReloadRegion + codeLines: str + stdout: NotRequired[str] + stderr: NotRequired[str] + + +class ReloadOperationException(TypedDict): + kind: Literal["exception"] + region: ReloadRegion + traceback: str + + +class ReloadOperationError(TypedDict): + kind: Literal["error"] + traceback: str + + +class ReloadOperationUI(TypedDict): + kind: Literal["ui"] + updated: bool + + +class ReloadOperationFile(TypedDict): + kind: Literal["file"] + created: bool + + +class ApiCreateReloadRequest(TypedDict): + filepath: str + contents: str + reloadId: NotRequired[str] + + +class ApiCreateReloadResponseSuccess(TypedDict): + status: Literal["created"] + reloadId: str + + +class ApiCreateReloadResponseError(TypedDict): + status: Literal["alreadyReloading", "fileNotFound"] + + +class ApiCreateReloadResponse(TypedDict): + res: ApiCreateReloadResponseError | ApiCreateReloadResponseSuccess + + +class ApiGetReloadRequest(TypedDict): + reloadId: str + + +class ApiGetReloadEventSourceData(TypedDict): + data: ( + ReloadOperationError + | ReloadOperationException + | ReloadOperationObject + | ReloadOperationRun + | ReloadOperationUI + | ReloadOperationFile + ) + + +class ApiGetStatusRequest(TypedDict): + revision: str + + +class ApiGetStatusResponse(TypedDict): + reloading: bool + uncommited: list[str] + + +class ApiFetchContentsRequest(TypedDict): + filepath: str + + +class ApiFetchContentsResponseError(TypedDict): + status: Literal["fileNotFound"] + + +class ApiFetchContentsResponseSuccess(TypedDict): + status: Literal["ok"] + contents: str + + +class ApiFetchContentsResponse(TypedDict): + res: ApiFetchContentsResponseError | ApiFetchContentsResponseSuccess diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_inference_endpoints.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_inference_endpoints.py new file mode 100644 index 0000000000000000000000000000000000000000..3a48f47784551d91f36b0b73b84c1ad76283c500 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_inference_endpoints.py @@ -0,0 +1,419 @@ +import time +from dataclasses import dataclass, field +from datetime import datetime +from enum import Enum +from typing import TYPE_CHECKING, Optional + +from huggingface_hub.errors import InferenceEndpointError, InferenceEndpointTimeoutError + +from .utils import get_session, logging, parse_datetime + + +if TYPE_CHECKING: + from .hf_api import HfApi + from .inference._client import InferenceClient + from .inference._generated._async_client import AsyncInferenceClient + +logger = logging.get_logger(__name__) + + +class InferenceEndpointStatus(str, Enum): + PENDING = "pending" + INITIALIZING = "initializing" + UPDATING = "updating" + UPDATE_FAILED = "updateFailed" + RUNNING = "running" + PAUSED = "paused" + FAILED = "failed" + SCALED_TO_ZERO = "scaledToZero" + + +class InferenceEndpointType(str, Enum): + PUBlIC = "public" + PROTECTED = "protected" # deprecated, use AUTHENTICATED instead + AUTHENTICATED = "authenticated" + PRIVATE = "private" + + +class InferenceEndpointScalingMetric(str, Enum): + PENDING_REQUESTS = "pendingRequests" + HARDWARE_USAGE = "hardwareUsage" + + +@dataclass +class InferenceEndpoint: + """ + Contains information about a deployed Inference Endpoint. + + Args: + name (`str`): + The unique name of the Inference Endpoint. + namespace (`str`): + The namespace where the Inference Endpoint is located. + repository (`str`): + The name of the model repository deployed on this Inference Endpoint. + status ([`InferenceEndpointStatus`]): + The current status of the Inference Endpoint. + url (`str`, *optional*): + The URL of the Inference Endpoint, if available. Only a deployed Inference Endpoint will have a URL. + framework (`str`): + The machine learning framework used for the model. + revision (`str`): + The specific model revision deployed on the Inference Endpoint. + task (`str`): + The task associated with the deployed model. + created_at (`datetime.datetime`): + The timestamp when the Inference Endpoint was created. + updated_at (`datetime.datetime`): + The timestamp of the last update of the Inference Endpoint. + type ([`InferenceEndpointType`]): + The type of the Inference Endpoint (public, authenticated, private). + raw (`dict`): + The raw dictionary data returned from the API. + token (`str` or `bool`, *optional*): + Authentication token for the Inference Endpoint, if set when requesting the API. Will default to the + locally saved token if not provided. Pass `token=False` if you don't want to send your token to the server. + + Example: + ```python + >>> from huggingface_hub import get_inference_endpoint + >>> endpoint = get_inference_endpoint("my-text-to-image") + >>> endpoint + InferenceEndpoint(name='my-text-to-image', ...) + + # Get status + >>> endpoint.status + 'running' + >>> endpoint.url + 'https://my-text-to-image.region.vendor.endpoints.huggingface.cloud' + + # Run inference + >>> endpoint.client.text_to_image(...) + + # Pause endpoint to save $$$ + >>> endpoint.pause() + + # ... + # Resume and wait for deployment + >>> endpoint.resume() + >>> endpoint.wait() + >>> endpoint.client.text_to_image(...) + ``` + """ + + # Field in __repr__ + name: str = field(init=False) + namespace: str + repository: str = field(init=False) + status: InferenceEndpointStatus = field(init=False) + health_route: str = field(init=False) + url: str | None = field(init=False) + + # Other fields + framework: str = field(repr=False, init=False) + revision: str = field(repr=False, init=False) + task: str = field(repr=False, init=False) + created_at: datetime = field(repr=False, init=False) + updated_at: datetime = field(repr=False, init=False) + type: InferenceEndpointType = field(repr=False, init=False) + + # Raw dict from the API + raw: dict = field(repr=False) + + # Internal fields + _token: str | bool | None = field(repr=False, compare=False) + _api: "HfApi" = field(repr=False, compare=False) + + @classmethod + def from_raw( + cls, raw: dict, namespace: str, token: str | bool | None = None, api: Optional["HfApi"] = None + ) -> "InferenceEndpoint": + """Initialize object from raw dictionary.""" + if api is None: + from .hf_api import HfApi + + api = HfApi() + if token is None: + token = api.token + + # All other fields are populated in __post_init__ + return cls(raw=raw, namespace=namespace, _token=token, _api=api) + + def __post_init__(self) -> None: + """Populate fields from raw dictionary.""" + self._populate_from_raw() + + @property + def client(self) -> "InferenceClient": + """Returns a client to make predictions on this Inference Endpoint. + + Returns: + [`InferenceClient`]: an inference client pointing to the deployed endpoint. + + Raises: + [`InferenceEndpointError`]: If the Inference Endpoint is not yet deployed. + """ + if self.url is None: + raise InferenceEndpointError( + "Cannot create a client for this Inference Endpoint as it is not yet deployed. " + "Please wait for the Inference Endpoint to be deployed using `endpoint.wait()` and try again." + ) + from .inference._client import InferenceClient + + return InferenceClient( + model=self.url, + token=self._token, # type: ignore # boolean token shouldn't be possible. In practice it's ok. + ) + + @property + def async_client(self) -> "AsyncInferenceClient": + """Returns a client to make predictions on this Inference Endpoint. + + Returns: + [`AsyncInferenceClient`]: an asyncio-compatible inference client pointing to the deployed endpoint. + + Raises: + [`InferenceEndpointError`]: If the Inference Endpoint is not yet deployed. + """ + if self.url is None: + raise InferenceEndpointError( + "Cannot create a client for this Inference Endpoint as it is not yet deployed. " + "Please wait for the Inference Endpoint to be deployed using `endpoint.wait()` and try again." + ) + from .inference._generated._async_client import AsyncInferenceClient + + return AsyncInferenceClient( + model=self.url, + token=self._token, # type: ignore # boolean token shouldn't be possible. In practice it's ok. + ) + + def wait(self, timeout: int | None = None, refresh_every: int = 5) -> "InferenceEndpoint": + """Wait for the Inference Endpoint to be deployed. + + Information from the server will be fetched every 1s. If the Inference Endpoint is not deployed after `timeout` + seconds, a [`InferenceEndpointTimeoutError`] will be raised. The [`InferenceEndpoint`] will be mutated in place with the latest + data. + + Args: + timeout (`int`, *optional*): + The maximum time to wait for the Inference Endpoint to be deployed, in seconds. If `None`, will wait + indefinitely. + refresh_every (`int`, *optional*): + The time to wait between each fetch of the Inference Endpoint status, in seconds. Defaults to 5s. + + Returns: + [`InferenceEndpoint`]: the same Inference Endpoint, mutated in place with the latest data. + + Raises: + [`InferenceEndpointError`] + If the Inference Endpoint ended up in a failed state. + [`InferenceEndpointTimeoutError`] + If the Inference Endpoint is not deployed after `timeout` seconds. + """ + if timeout is not None and timeout < 0: + raise ValueError("`timeout` cannot be negative.") + if refresh_every <= 0: + raise ValueError("`refresh_every` must be positive.") + + start = time.time() + while True: + if self.status == InferenceEndpointStatus.FAILED: + raise InferenceEndpointError( + f"Inference Endpoint {self.name} failed to deploy. Please check the logs for more information." + ) + if self.status == InferenceEndpointStatus.UPDATE_FAILED: + raise InferenceEndpointError( + f"Inference Endpoint {self.name} failed to update. Please check the logs for more information." + ) + if self.status == InferenceEndpointStatus.RUNNING and self.url is not None: + # Verify the endpoint is actually reachable + _health_url = f"{self.url.rstrip('/')}/{self.health_route.lstrip('/')}" + response = get_session().get(_health_url, headers=self._api._build_hf_headers(token=self._token)) + if response.status_code == 200: + logger.info("Inference Endpoint is ready to be used.") + return self + + if timeout is not None: + if time.time() - start > timeout: + raise InferenceEndpointTimeoutError("Timeout while waiting for Inference Endpoint to be deployed.") + logger.info(f"Inference Endpoint is not deployed yet ({self.status}). Waiting {refresh_every}s...") + time.sleep(refresh_every) + self.fetch() + + def fetch(self) -> "InferenceEndpoint": + """Fetch latest information about the Inference Endpoint. + + Returns: + [`InferenceEndpoint`]: the same Inference Endpoint, mutated in place with the latest data. + """ + obj = self._api.get_inference_endpoint(name=self.name, namespace=self.namespace, token=self._token) # type: ignore [arg-type] + self.raw = obj.raw + self._populate_from_raw() + return self + + def update( + self, + *, + # Compute update + accelerator: str | None = None, + instance_size: str | None = None, + instance_type: str | None = None, + min_replica: int | None = None, + max_replica: int | None = None, + scale_to_zero_timeout: int | None = None, + # Model update + repository: str | None = None, + framework: str | None = None, + revision: str | None = None, + task: str | None = None, + custom_image: dict | None = None, + secrets: dict[str, str] | None = None, + ) -> "InferenceEndpoint": + """Update the Inference Endpoint. + + This method allows the update of either the compute configuration, the deployed model, or both. All arguments are + optional but at least one must be provided. + + This is an alias for [`HfApi.update_inference_endpoint`]. The current object is mutated in place with the + latest data from the server. + + Args: + accelerator (`str`, *optional*): + The hardware accelerator to be used for inference (e.g. `"cpu"`). + instance_size (`str`, *optional*): + The size or type of the instance to be used for hosting the model (e.g. `"x4"`). + instance_type (`str`, *optional*): + The cloud instance type where the Inference Endpoint will be deployed (e.g. `"intel-icl"`). + min_replica (`int`, *optional*): + The minimum number of replicas (instances) to keep running for the Inference Endpoint. + max_replica (`int`, *optional*): + The maximum number of replicas (instances) to scale to for the Inference Endpoint. + scale_to_zero_timeout (`int`, *optional*): + The duration in minutes before an inactive endpoint is scaled to zero. + + repository (`str`, *optional*): + The name of the model repository associated with the Inference Endpoint (e.g. `"gpt2"`). + framework (`str`, *optional*): + The machine learning framework used for the model (e.g. `"custom"`). + revision (`str`, *optional*): + The specific model revision to deploy on the Inference Endpoint (e.g. `"6c0e6080953db56375760c0471a8c5f2929baf11"`). + task (`str`, *optional*): + The task on which to deploy the model (e.g. `"text-classification"`). + custom_image (`dict`, *optional*): + A custom Docker image to use for the Inference Endpoint. This is useful if you want to deploy an + Inference Endpoint running on the `text-generation-inference` (TGI) framework (see examples). + secrets (`dict[str, str]`, *optional*): + Secret values to inject in the container environment. + Returns: + [`InferenceEndpoint`]: the same Inference Endpoint, mutated in place with the latest data. + """ + # Make API call + obj = self._api.update_inference_endpoint( + name=self.name, + namespace=self.namespace, + accelerator=accelerator, + instance_size=instance_size, + instance_type=instance_type, + min_replica=min_replica, + max_replica=max_replica, + scale_to_zero_timeout=scale_to_zero_timeout, + repository=repository, + framework=framework, + revision=revision, + task=task, + custom_image=custom_image, + secrets=secrets, + token=self._token, # type: ignore [arg-type] + ) + + # Mutate current object + self.raw = obj.raw + self._populate_from_raw() + return self + + def pause(self) -> "InferenceEndpoint": + """Pause the Inference Endpoint. + + A paused Inference Endpoint will not be charged. It can be resumed at any time using [`InferenceEndpoint.resume`]. + This is different from scaling the Inference Endpoint to zero with [`InferenceEndpoint.scale_to_zero`], which + would be automatically restarted when a request is made to it. + + This is an alias for [`HfApi.pause_inference_endpoint`]. The current object is mutated in place with the + latest data from the server. + + Returns: + [`InferenceEndpoint`]: the same Inference Endpoint, mutated in place with the latest data. + """ + obj = self._api.pause_inference_endpoint(name=self.name, namespace=self.namespace, token=self._token) # type: ignore [arg-type] + self.raw = obj.raw + self._populate_from_raw() + return self + + def resume(self, running_ok: bool = True) -> "InferenceEndpoint": + """Resume the Inference Endpoint. + + This is an alias for [`HfApi.resume_inference_endpoint`]. The current object is mutated in place with the + latest data from the server. + + Args: + running_ok (`bool`, *optional*): + If `True`, the method will not raise an error if the Inference Endpoint is already running. Defaults to + `True`. + + Returns: + [`InferenceEndpoint`]: the same Inference Endpoint, mutated in place with the latest data. + """ + obj = self._api.resume_inference_endpoint( + name=self.name, namespace=self.namespace, running_ok=running_ok, token=self._token + ) # type: ignore [arg-type] + self.raw = obj.raw + self._populate_from_raw() + return self + + def scale_to_zero(self) -> "InferenceEndpoint": + """Scale Inference Endpoint to zero. + + An Inference Endpoint scaled to zero will not be charged. It will be resumed on the next request to it, with a + cold start delay. This is different from pausing the Inference Endpoint with [`InferenceEndpoint.pause`], which + would require a manual resume with [`InferenceEndpoint.resume`]. + + This is an alias for [`HfApi.scale_to_zero_inference_endpoint`]. The current object is mutated in place with the + latest data from the server. + + Returns: + [`InferenceEndpoint`]: the same Inference Endpoint, mutated in place with the latest data. + """ + obj = self._api.scale_to_zero_inference_endpoint(name=self.name, namespace=self.namespace, token=self._token) # type: ignore [arg-type] + self.raw = obj.raw + self._populate_from_raw() + return self + + def delete(self) -> None: + """Delete the Inference Endpoint. + + This operation is not reversible. If you don't want to be charged for an Inference Endpoint, it is preferable + to pause it with [`InferenceEndpoint.pause`] or scale it to zero with [`InferenceEndpoint.scale_to_zero`]. + + This is an alias for [`HfApi.delete_inference_endpoint`]. + """ + self._api.delete_inference_endpoint(name=self.name, namespace=self.namespace, token=self._token) # type: ignore [arg-type] + + def _populate_from_raw(self) -> None: + """Populate fields from raw dictionary. + + Called in __post_init__ + each time the Inference Endpoint is updated. + """ + # Repr fields + self.name = self.raw["name"] + self.repository = self.raw["model"]["repository"] + self.status = self.raw["status"]["state"] + self.url = self.raw["status"].get("url") + self.health_route = self.raw["healthRoute"] + + # Other fields + self.framework = self.raw["model"]["framework"] + self.revision = self.raw["model"]["revision"] + self.task = self.raw["model"]["task"] + self.created_at = parse_datetime(self.raw["status"]["createdAt"]) + self.updated_at = parse_datetime(self.raw["status"]["updatedAt"]) + self.type = self.raw["type"] diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_jobs_api.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_jobs_api.py new file mode 100644 index 0000000000000000000000000000000000000000..302fc2b366f1f08a0e0bb0c45097bd4e71960d80 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_jobs_api.py @@ -0,0 +1,567 @@ +# Copyright 2025-present, the HuggingFace Inc. team. +# +# 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. +import hashlib +import platform +from dataclasses import dataclass +from datetime import datetime +from enum import Enum +from pathlib import Path +from typing import Any + +from huggingface_hub import constants +from huggingface_hub._space_api import Volume +from huggingface_hub.utils._datetime import parse_datetime + + +class JobHardware(str, Enum): + """ + Enumeration of hardware flavors available to run Jobs on the Hub. + + Value can be compared to a string: + ```py + assert JobHardware.CPU_BASIC == "cpu-basic" + ``` + + Both enums are kept in sync with the Hub API by `utils/check_hardware_flavors.py`. + """ + + # CPU + CPU_BASIC = "cpu-basic" + CPU_UPGRADE = "cpu-upgrade" + CPU_PERFORMANCE = "cpu-performance" + CPU_XL = "cpu-xl" + + # GPU + T4_SMALL = "t4-small" + T4_MEDIUM = "t4-medium" + L4X1 = "l4x1" + L4X4 = "l4x4" + L40SX1 = "l40sx1" + L40SX4 = "l40sx4" + L40SX8 = "l40sx8" + A10G_SMALL = "a10g-small" + A10G_LARGE = "a10g-large" + A10G_LARGEX2 = "a10g-largex2" + A10G_LARGEX4 = "a10g-largex4" + A100_LARGE = "a100-large" + A100X4 = "a100x4" + A100X8 = "a100x8" + H200 = "h200" + H200X2 = "h200x2" + H200X4 = "h200x4" + H200X8 = "h200x8" + RTX_PRO_6000 = "rtx-pro-6000" + RTX_PRO_6000X2 = "rtx-pro-6000x2" + RTX_PRO_6000X4 = "rtx-pro-6000x4" + RTX_PRO_6000X8 = "rtx-pro-6000x8" + + +class JobStage(str, Enum): + """ + Enumeration of possible stage of a Job on the Hub. + + Value can be compared to a string: + ```py + assert JobStage.COMPLETED == "COMPLETED" + ``` + Possible values are: `COMPLETED`, `CANCELED`, `ERROR`, `DELETED`, `SCHEDULING`, `RUNNING`. + Taken from https://github.com/huggingface/moon-landing/blob/main/server/job_types/JobInfo.ts#L61 (private url). + """ + + # Copied from moon-landing > server > lib > Job.ts + COMPLETED = "COMPLETED" + CANCELED = "CANCELED" + ERROR = "ERROR" + DELETED = "DELETED" + SCHEDULING = "SCHEDULING" + RUNNING = "RUNNING" + + +# Stages indicating the Job has reached a terminal state and will not run further. +TERMINAL_JOB_STAGES = (JobStage.COMPLETED, JobStage.CANCELED, JobStage.ERROR, JobStage.DELETED) + + +@dataclass +class JobStatus: + stage: JobStage + message: str | None + expose_urls: list[str] | None + ssh_url: str | None + + +@dataclass +class JobOwner: + id: str + name: str + type: str + + +@dataclass +class JobDurations: + """ + Timing breakdown for a Job, computed server-side. + + Args: + scheduling_secs (`int` or `None`): + Seconds the job spent in the scheduling stage before starting to run. + `None` if the job never reached the running stage. + running_secs (`int` or `None`): + Seconds the job has been or was running. Recomputed on each request + while the job is in progress. `None` if the job never started running. + total_secs (`int` or `None`): + Total seconds elapsed since the job was created. Recomputed on each + request while the job is in progress. + """ + + scheduling_secs: int | None + running_secs: int | None + total_secs: int | None + + def __init__(self, **kwargs) -> None: + self.scheduling_secs = kwargs.get("schedulingSecs", kwargs.get("scheduling_secs")) + self.running_secs = kwargs.get("runningSecs", kwargs.get("running_secs")) + self.total_secs = kwargs.get("totalSecs", kwargs.get("total_secs")) + + +@dataclass +class JobInitiator: + """ + Contains information about what triggered a Job. + + Args: + type (`str`): Initiator kind, for example `"user"`, `"org"`, `"scheduled-job"`, or `"duplicated-job"`. + id (`str`): Identifier of the initiator. + name (`str` or `None`): Human-readable name when available, usually for user/org initiators. + """ + + type: str + id: str + name: str | None = None + + +@dataclass +class JobInfo: + """ + Contains information about a Job. + + Args: + id (`str`): + Job ID. + created_at (`datetime` or `None`): + When the Job was created. + started_at (`datetime` or `None`): + When the Job started running. None while the Job is still scheduling. + finished_at (`datetime` or `None`): + When the Job finished. None while the Job is still scheduling or running. + docker_image (`str` or `None`): + The Docker image from Docker Hub used for the Job. + Can be None if space_id is present instead. + space_id (`str` or `None`): + The Docker image from Hugging Face Spaces used for the Job. + Can be None if docker_image is present instead. + command (`list[str]` or `None`): + Command of the Job, e.g. `["python", "-c", "print('hello world')"]` + arguments (`list[str]` or `None`): + Arguments passed to the command + environment (`dict[str]` or `None`): + Environment variables of the Job as a dictionary. + secrets (`dict[str]` or `None`): + Secret environment variables of the Job (encrypted). + flavor (`str` or `None`): + Flavor for the hardware. See [`JobHardware`] for possible values. + E.g. `"cpu-basic"`. + labels (`dict[str, str]` or `None`): + Labels to attach to the job (key-value pairs). + volumes (`list[Volume]` or `None`): + Volumes mounted in the job container (buckets, models, datasets, spaces). + status: (`JobStatus` or `None`): + Status of the Job, e.g. `JobStatus(stage="RUNNING", message=None)` + See [`JobStage`] for possible stage values. + durations (`JobDurations` or `None`): + Timing breakdown of the Job. Present for all job states including SCHEDULING. + owner: (`JobOwner` or `None`): + Owner of the Job, e.g. `JobOwner(id="5e9ecfc04957053f60648a3e", name="lhoestq", type="user")` + initiator (`JobInitiator` or `None`): + What triggered the Job, e.g. `JobInitiator(type="scheduled-job", id="...")` for a cron-triggered run. + expose_urls (`list[str]` or `None`): + Public URLs through which the Job's exposed ports are reachable (one per port exposed via `expose=`), + e.g. `["https://687fb701029421ae5549d998--8000.hf.jobs"]`. `None` when no port is exposed. + Accessing a URL requires an HF token with read access to the Job's namespace. + ssh_url (`str` or `None`): + SSH endpoint of the Job, e.g. `"ssh://687fb701029421ae5549d998@ssh.hf.jobs"`. Only present when the Job + was started with `ssh=True`. Connecting requires write access to the Job's namespace and an SSH public + key registered on the Hub (https://huggingface.co/settings/keys). + + Example: + + ```python + >>> from huggingface_hub import run_job + >>> job = run_job( + ... image="python:3.12", + ... command=["python", "-c", "print('Hello from the cloud!')"] + ... ) + >>> job + JobInfo(id='687fb701029421ae5549d998', created_at=datetime.datetime(2025, 7, 22, 16, 6, 25, 79000, tzinfo=datetime.timezone.utc), started_at=datetime.datetime(2025, 7, 22, 16, 6, 31, 79000, tzinfo=datetime.timezone.utc), finished_at=None, docker_image='python:3.12', space_id=None, command=['python', '-c', "print('Hello from the cloud!')"], arguments=[], environment={}, secrets={}, flavor='cpu-basic', labels=None, status=JobStatus(stage='RUNNING', message=None), durations=JobDurations(scheduling_secs=6, running_secs=2, total_secs=8), owner=JobOwner(id='5e9ecfc04957053f60648a3e', name='lhoestq', type='user'), initiator=JobInitiator(type='user', id='5e9ecfc04957053f60648a3e', name='lhoestq'), endpoint='https://huggingface.co', url='https://huggingface.co/jobs/lhoestq/687fb701029421ae5549d998') + >>> job.id + '687fb701029421ae5549d998' + >>> job.url + 'https://huggingface.co/jobs/lhoestq/687fb701029421ae5549d998' + >>> job.status.stage + 'RUNNING' + ``` + """ + + id: str + created_at: datetime | None + started_at: datetime | None + finished_at: datetime | None + docker_image: str | None + space_id: str | None + command: list[str] | None + arguments: list[str] | None + environment: dict[str, Any] | None + secrets: dict[str, Any] | None + flavor: JobHardware | None + labels: dict[str, str] | None + volumes: list[Volume] | None + status: JobStatus + durations: JobDurations | None + owner: JobOwner + initiator: JobInitiator | None + + # Inferred fields + endpoint: str + url: str + + def __init__(self, **kwargs) -> None: + self.id = kwargs["id"] + created_at = kwargs.get("createdAt") or kwargs.get("created_at") + self.created_at = parse_datetime(created_at) if created_at else None + started_at = kwargs.get("startedAt") or kwargs.get("started_at") + self.started_at = parse_datetime(started_at) if started_at else None + finished_at = kwargs.get("finishedAt") or kwargs.get("finished_at") + self.finished_at = parse_datetime(finished_at) if finished_at else None + self.docker_image = kwargs.get("dockerImage") or kwargs.get("docker_image") + self.space_id = kwargs.get("spaceId") or kwargs.get("space_id") + owner = kwargs.get("owner", {}) + self.owner = JobOwner(id=owner["id"], name=owner["name"], type=owner["type"]) + self.command = kwargs.get("command") + self.arguments = kwargs.get("arguments") + self.environment = kwargs.get("environment") + self.secrets = kwargs.get("secrets") + self.flavor = kwargs.get("flavor") + self.labels = kwargs.get("labels") + volumes = kwargs.get("volumes") + self.volumes = [Volume(**v) for v in volumes] if volumes else None + status = kwargs.get("status", {}) + self.status = JobStatus( + stage=status["stage"], + message=status.get("message"), + expose_urls=status.get("exposeUrls"), + ssh_url=status.get("sshUrl"), + ) + durations = kwargs.get("durations") + self.durations = JobDurations(**durations) if durations else None + initiator = kwargs.get("initiator") + self.initiator = ( + JobInitiator(type=initiator["type"], id=initiator["id"], name=initiator.get("name")) if initiator else None + ) + + # Inferred fields + self.endpoint = kwargs.get("endpoint", constants.ENDPOINT) + self.url = f"{self.endpoint}/jobs/{self.owner.name}/{self.id}" + + +@dataclass +class JobSpec: + docker_image: str | None + space_id: str | None + command: list[str] | None + arguments: list[str] | None + environment: dict[str, Any] | None + secrets: dict[str, Any] | None + flavor: JobHardware | None + timeout: int | None + tags: list[str] | None + arch: str | None + labels: dict[str, str] | None + volumes: list[Volume] | None + + def __init__(self, **kwargs) -> None: + self.docker_image = kwargs.get("dockerImage") or kwargs.get("docker_image") + self.space_id = kwargs.get("spaceId") or kwargs.get("space_id") + self.command = kwargs.get("command") + self.arguments = kwargs.get("arguments") + self.environment = kwargs.get("environment") + self.secrets = kwargs.get("secrets") + self.flavor = kwargs.get("flavor") + self.timeout = kwargs.get("timeout") + self.tags = kwargs.get("tags") + self.arch = kwargs.get("arch") + self.labels = kwargs.get("labels") + volumes = kwargs.get("volumes") + self.volumes = [Volume(**v) for v in volumes] if volumes else None + + +@dataclass +class LastJobInfo: + id: str + at: datetime + + def __init__(self, **kwargs) -> None: + self.id = kwargs["id"] + self.at = parse_datetime(kwargs["at"]) + + +@dataclass +class ScheduledJobStatus: + last_job: LastJobInfo | None + next_job_run_at: datetime | None + + def __init__(self, **kwargs) -> None: + last_job = kwargs.get("lastJob") or kwargs.get("last_job") + self.last_job = LastJobInfo(**last_job) if last_job else None + next_job_run_at = kwargs.get("nextJobRunAt") or kwargs.get("next_job_run_at") + self.next_job_run_at = parse_datetime(str(next_job_run_at)) if next_job_run_at else None + + +@dataclass +class ScheduledJobInfo: + """ + Contains information about a Job. + + Args: + id (`str`): + Scheduled Job ID. + created_at (`datetime` or `None`): + When the scheduled Job was created. + tags (`list[str]` or `None`): + The tags of the scheduled Job. + schedule (`str` or `None`): + One of "@annually", "@yearly", "@monthly", "@weekly", "@daily", "@hourly", or a + CRON schedule expression (e.g., '0 9 * * 1' for 9 AM every Monday). + suspend (`bool` or `None`): + Whether the scheduled job is suspended (paused). + concurrency (`bool` or `None`): + Whether multiple instances of this Job can run concurrently. + status (`ScheduledJobStatus` or `None`): + Status of the scheduled Job. + owner: (`JobOwner` or `None`): + Owner of the scheduled Job, e.g. `JobOwner(id="5e9ecfc04957053f60648a3e", name="lhoestq", type="user")` + job_spec: (`JobSpec` or `None`): + Specifications of the Job. + + Example: + + ```python + >>> from huggingface_hub import run_job + >>> scheduled_job = create_scheduled_job( + ... image="python:3.12", + ... command=["python", "-c", "print('Hello from the cloud!')"], + ... schedule="@hourly", + ... ) + >>> scheduled_job.id + '687fb701029421ae5549d999' + >>> scheduled_job.status.next_job_run_at + datetime.datetime(2025, 7, 22, 17, 6, 25, 79000, tzinfo=datetime.timezone.utc) + ``` + """ + + id: str + created_at: datetime | None + job_spec: JobSpec + schedule: str | None + suspend: bool | None + concurrency: bool | None + status: ScheduledJobStatus + owner: JobOwner + + def __init__(self, **kwargs) -> None: + self.id = kwargs["id"] + created_at = kwargs.get("createdAt") or kwargs.get("created_at") + self.created_at = parse_datetime(created_at) if created_at else None + self.job_spec = JobSpec(**(kwargs.get("job_spec") or kwargs.get("jobSpec", {}))) + self.schedule = kwargs.get("schedule") + self.suspend = kwargs.get("suspend") + self.concurrency = kwargs.get("concurrency") + status = kwargs.get("status", {}) + self.status = ScheduledJobStatus( + last_job=status.get("last_job") or status.get("lastJob"), + next_job_run_at=status.get("next_job_run_at") or status.get("nextJobRunAt"), + ) + owner = kwargs.get("owner", {}) + self.owner = JobOwner(id=owner["id"], name=owner["name"], type=owner["type"]) + + +@dataclass +class JobAccelerator: + """ + Contains information about a Job accelerator (GPU). + + Args: + type (`str`): + Type of accelerator, e.g. `"gpu"`. + model (`str`): + Model of accelerator, e.g. `"T4"`, `"A10G"`, `"A100"`, `"L4"`, `"L40S"`. + quantity (`str`): + Number of accelerators, e.g. `"1"`, `"2"`, `"4"`, `"8"`. + vram (`str`): + Total VRAM, e.g. `"16 GB"`, `"24 GB"`. + manufacturer (`str`): + Manufacturer of the accelerator, e.g. `"Nvidia"`. + """ + + type: str + model: str + quantity: str + vram: str + manufacturer: str + + def __init__(self, **kwargs) -> None: + self.type = kwargs["type"] + self.model = kwargs["model"] + self.quantity = kwargs["quantity"] + self.vram = kwargs["vram"] + self.manufacturer = kwargs["manufacturer"] + + +@dataclass +class JobHardwareInfo: + """ + Contains information about available Job hardware. + + Args: + name (`str`): + Machine identifier, e.g. `"cpu-basic"`, `"a10g-large"`. + pretty_name (`str`): + Human-readable name, e.g. `"CPU Basic"`, `"Nvidia A10G - large"`. + cpu (`str`): + CPU specification, e.g. `"2 vCPU"`, `"12 vCPU"`. + ram (`str`): + RAM specification, e.g. `"16 GB"`, `"46 GB"`. + ephemeral_storage (`str`): + Ephemeral storage specification, e.g. `"20 GB"`, `"100 GB"`. + accelerator (`JobAccelerator` or `None`): + GPU/accelerator details if available. + unit_cost_micro_usd (`int`): + Cost in micro-dollars per unit, e.g. `167` (= $0.000167). + unit_cost_usd (`float`): + Cost in USD per unit, e.g. `0.000167`. + unit_label (`str`): + Cost unit period, e.g. `"minute"`. + + Example: + + ```python + >>> from huggingface_hub import list_jobs_hardware + >>> hardware_list = list_jobs_hardware() + >>> hardware_list[0] + JobHardwareInfo(name='cpu-basic', pretty_name='CPU Basic', cpu='2 vCPU', ram='16 GB', ephemeral_storage='20 GB', accelerator=None, unit_cost_micro_usd=167, unit_cost_usd=0.000167, unit_label='minute') + >>> hardware_list[0].name + 'cpu-basic' + ``` + """ + + name: str + pretty_name: str + cpu: str + ram: str + ephemeral_storage: str + accelerator: JobAccelerator | None + unit_cost_micro_usd: int + unit_cost_usd: float + unit_label: str + + def __init__(self, **kwargs) -> None: + self.name = kwargs["name"] + self.pretty_name = kwargs["prettyName"] + self.cpu = kwargs["cpu"] + self.ram = kwargs["ram"] + self.ephemeral_storage = kwargs.get("ephemeralStorage", "N/A") + accelerator = kwargs.get("accelerator") + self.accelerator = JobAccelerator(**accelerator) if accelerator else None + self.unit_cost_micro_usd = kwargs["unitCostMicroUSD"] + self.unit_cost_usd = kwargs["unitCostUSD"] + self.unit_label = kwargs["unitLabel"] + + +def _derive_job_volume_name(source: str | Path) -> str: + """Derive a stable remote folder name for a local directory synced as a Job volume. + + The name is `{dirname}-{hash}` where the hash fingerprints the absolute path and the machine's + hostname: re-syncing the same directory from the same machine reuses the same remote folder + (so only changed files are re-uploaded), while same-named directories from different paths or + machines don't collide. + """ + resolved = Path(source).expanduser().resolve() + digest = hashlib.sha256(f"{platform.node()}:{resolved}".encode()).hexdigest()[:8] + dirname = resolved.name.replace(" ", "_") or "root" + return f"{dirname}-{digest}" + + +def _create_job_spec( + *, + image: str, + command: list[str], + env: dict[str, Any] | None, + secrets: dict[str, Any] | None, + flavor: JobHardware | str | None, + timeout: int | float | str | None, + labels: dict[str, str] | None = None, + volumes: list[Volume] | None = None, + expose: list[int] | None = None, + ssh: bool = False, +) -> dict[str, Any]: + # prepare job spec to send to HF Jobs API + job_spec: dict[str, Any] = { + "command": command, + "arguments": [], + "environment": env or {}, + "flavor": flavor or JobHardware.CPU_BASIC, + } + # secrets are optional + if secrets: + job_spec["secrets"] = secrets + # timeout is optional + if timeout: + time_units_factors = {"s": 1, "m": 60, "h": 3600, "d": 3600 * 24} + if isinstance(timeout, str) and timeout[-1] in time_units_factors: + job_spec["timeoutSeconds"] = int(float(timeout[:-1]) * time_units_factors[timeout[-1]]) + else: + job_spec["timeoutSeconds"] = int(timeout) + # labels are optional + if labels: + job_spec["labels"] = labels + # volumes are optional + if volumes: + job_spec["volumes"] = [vol.to_dict() for vol in volumes] + # expose ports through the jobs proxy + if expose: + job_spec["expose"] = {"ports": expose} + # make the job container reachable over SSH + if ssh: + job_spec["ssh"] = {"enabled": True} + # input is either from docker hub or from HF spaces + for prefix in ( + "https://huggingface.co/spaces/", + "https://hf.co/spaces/", + "huggingface.co/spaces/", + "hf.co/spaces/", + ): + if image.startswith(prefix): + job_spec["spaceId"] = image[len(prefix) :] + break + else: + job_spec["dockerImage"] = image + return job_spec diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_local_folder.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_local_folder.py new file mode 100644 index 0000000000000000000000000000000000000000..2e60361293d0bd45b8a877e55291882144279e42 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_local_folder.py @@ -0,0 +1,473 @@ +# Copyright 2024-present, the HuggingFace Inc. team. +# +# 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. +"""Contains utilities to handle the `../.cache/huggingface` folder in local directories. + +First discussed in https://github.com/huggingface/huggingface_hub/issues/1738 to store +download metadata when downloading files from the hub to a local directory (without +using the cache). + +./.cache/huggingface folder structure: +[4.0K] data +├── [4.0K] .cache +│ └── [4.0K] huggingface +│ └── [4.0K] download +│ ├── [ 16] file.parquet.metadata +│ ├── [ 16] file.txt.metadata +│ └── [4.0K] folder +│ └── [ 16] file.parquet.metadata +│ +├── [6.5G] file.parquet +├── [1.5K] file.txt +└── [4.0K] folder + └── [ 16] file.parquet + + +Download metadata file structure: +``` +# file.txt.metadata +11c5a3d5811f50298f278a704980280950aedb10 +a16a55fda99d2f2e7b69cce5cf93ff4ad3049930 +1712656091.123 + +# file.parquet.metadata +11c5a3d5811f50298f278a704980280950aedb10 +7c5d3f4b8b76583b422fcb9189ad6c89d5d97a094541ce8932dce3ecabde1421 +1712656091.123 +} +``` +""" + +import base64 +import hashlib +import logging +import os +import time +from dataclasses import dataclass +from pathlib import Path + +from .utils import WeakFileLock + + +logger = logging.getLogger(__name__) + +CACHEDIR_TAG_CONTENT = ( + "Signature: 8a477f597d28d172789f06886806bc55\n" + "# This file is a cache directory tag created by huggingface_hub.\n" + "# For information about cache directory tags, see:\n" + "#\thttps://bford.info/cachedir/\n" +) + + +@dataclass +class LocalDownloadFilePaths: + """ + Paths to the files related to a download process in a local dir. + + Returned by [`get_local_download_paths`]. + + Attributes: + file_path (`Path`): + Path where the file will be saved. + lock_path (`Path`): + Path to the lock file used to ensure atomicity when reading/writing metadata. + metadata_path (`Path`): + Path to the metadata file. + """ + + file_path: Path + lock_path: Path + metadata_path: Path + + def incomplete_path(self, etag: str) -> Path: + """Return the path where a file will be temporarily downloaded before being moved to `file_path`.""" + path = self.metadata_path.parent / f"{_short_hash(self.metadata_path.name)}.{etag}.incomplete" + resolved_path = str(path.resolve()) + # Some Windows versions do not allow for paths longer than 255 characters. + # In this case, we must specify it as an extended path by using the "\\?\" prefix. + if os.name == "nt" and len(resolved_path) > 255 and not resolved_path.startswith("\\\\?\\"): + path = Path("\\\\?\\" + resolved_path) + return path + + +@dataclass(frozen=True) +class LocalUploadFilePaths: + """ + Paths to the files related to an upload process in a local dir. + + Returned by [`get_local_upload_paths`]. + + Attributes: + path_in_repo (`str`): + Path of the file in the repo. + file_path (`Path`): + Path where the file will be saved. + lock_path (`Path`): + Path to the lock file used to ensure atomicity when reading/writing metadata. + metadata_path (`Path`): + Path to the metadata file. + """ + + path_in_repo: str + file_path: Path + lock_path: Path + metadata_path: Path + + +@dataclass +class LocalDownloadFileMetadata: + """ + Metadata about a file in the local directory related to a download process. + + Attributes: + filename (`str`): + Path of the file in the repo. + commit_hash (`str`): + Commit hash of the file in the repo. + etag (`str`): + ETag of the file in the repo. Used to check if the file has changed. + For LFS files, this is the sha256 of the file. For regular files, it corresponds to the git hash. + timestamp (`int`): + Unix timestamp of when the metadata was saved i.e. when the metadata was accurate. + """ + + filename: str + commit_hash: str + etag: str + timestamp: float + + +@dataclass +class LocalUploadFileMetadata: + """ + Metadata about a file in the local directory related to an upload process. + """ + + size: int + + # Default values correspond to "we don't know yet" + timestamp: float | None = None + should_ignore: bool | None = None + sha256: str | None = None + upload_mode: str | None = None + remote_oid: str | None = None + is_uploaded: bool = False + is_committed: bool = False + + def save(self, paths: LocalUploadFilePaths) -> None: + """Save the metadata to disk.""" + with WeakFileLock(paths.lock_path): + with paths.metadata_path.open("w") as f: + new_timestamp = time.time() + f.write(str(new_timestamp) + "\n") + + f.write(str(self.size)) # never None + f.write("\n") + + if self.should_ignore is not None: + f.write(str(int(self.should_ignore))) + f.write("\n") + + if self.sha256 is not None: + f.write(self.sha256) + f.write("\n") + + if self.upload_mode is not None: + f.write(self.upload_mode) + f.write("\n") + + if self.remote_oid is not None: + f.write(self.remote_oid) + f.write("\n") + + f.write(str(int(self.is_uploaded)) + "\n") + f.write(str(int(self.is_committed)) + "\n") + + self.timestamp = new_timestamp + + +def get_local_download_paths(local_dir: Path, filename: str) -> LocalDownloadFilePaths: + """Compute paths to the files related to a download process. + + Folders containing the paths are all guaranteed to exist. + + Args: + local_dir (`Path`): + Path to the local directory in which files are downloaded. + filename (`str`): + Path of the file in the repo. + + Return: + [`LocalDownloadFilePaths`]: the paths to the files (file_path, lock_path, metadata_path, incomplete_path). + """ + # filename is the path in the Hub repository (separated by '/') + # make sure to have a cross-platform transcription + sanitized_filename = os.path.join(*filename.split("/")) + if os.name == "nt": + if sanitized_filename.startswith("..\\") or "\\..\\" in sanitized_filename: + raise ValueError( + f"Invalid filename: cannot handle filename '{sanitized_filename}' on Windows. Please ask the repository" + " owner to rename this file." + ) + file_path = local_dir / sanitized_filename + metadata_path = _huggingface_dir(local_dir) / "download" / f"{sanitized_filename}.metadata" + lock_path = metadata_path.with_suffix(".lock") + + # Some Windows versions do not allow for paths longer than 255 characters. + # In this case, we must specify it as an extended path by using the "\\?\" prefix + if os.name == "nt": + if not str(local_dir).startswith("\\\\?\\") and len(os.path.abspath(lock_path)) > 255: + file_path = Path("\\\\?\\" + os.path.abspath(file_path)) + lock_path = Path("\\\\?\\" + os.path.abspath(lock_path)) + metadata_path = Path("\\\\?\\" + os.path.abspath(metadata_path)) + + file_path.parent.mkdir(parents=True, exist_ok=True) + metadata_path.parent.mkdir(parents=True, exist_ok=True) + return LocalDownloadFilePaths(file_path=file_path, lock_path=lock_path, metadata_path=metadata_path) + + +def get_local_upload_paths(local_dir: Path, filename: str) -> LocalUploadFilePaths: + """Compute paths to the files related to an upload process. + + Folders containing the paths are all guaranteed to exist. + + Args: + local_dir (`Path`): + Path to the local directory that is uploaded. + filename (`str`): + Path of the file in the repo. + + Return: + [`LocalUploadFilePaths`]: the paths to the files (file_path, lock_path, metadata_path). + """ + # filename is the path in the Hub repository (separated by '/') + # make sure to have a cross-platform transcription + sanitized_filename = os.path.join(*filename.split("/")) + if os.name == "nt": + if sanitized_filename.startswith("..\\") or "\\..\\" in sanitized_filename: + raise ValueError( + f"Invalid filename: cannot handle filename '{sanitized_filename}' on Windows. Please ask the repository" + " owner to rename this file." + ) + file_path = local_dir / sanitized_filename + metadata_path = _huggingface_dir(local_dir) / "upload" / f"{sanitized_filename}.metadata" + lock_path = metadata_path.with_suffix(".lock") + + # Some Windows versions do not allow for paths longer than 255 characters. + # In this case, we must specify it as an extended path by using the "\\?\" prefix + if os.name == "nt": + if not str(local_dir).startswith("\\\\?\\") and len(os.path.abspath(lock_path)) > 255: + file_path = Path("\\\\?\\" + os.path.abspath(file_path)) + lock_path = Path("\\\\?\\" + os.path.abspath(lock_path)) + metadata_path = Path("\\\\?\\" + os.path.abspath(metadata_path)) + + file_path.parent.mkdir(parents=True, exist_ok=True) + metadata_path.parent.mkdir(parents=True, exist_ok=True) + return LocalUploadFilePaths( + path_in_repo=filename, file_path=file_path, lock_path=lock_path, metadata_path=metadata_path + ) + + +def read_download_metadata(local_dir: Path, filename: str) -> LocalDownloadFileMetadata | None: + """Read metadata about a file in the local directory related to a download process. + + Args: + local_dir (`Path`): + Path to the local directory in which files are downloaded. + filename (`str`): + Path of the file in the repo. + + Return: + `[LocalDownloadFileMetadata]` or `None`: the metadata if it exists, `None` otherwise. + """ + paths = get_local_download_paths(local_dir, filename) + with WeakFileLock(paths.lock_path): + if paths.metadata_path.exists(): + try: + with paths.metadata_path.open() as f: + commit_hash = f.readline().strip() + etag = f.readline().strip() + timestamp = float(f.readline().strip()) + metadata = LocalDownloadFileMetadata( + filename=filename, + commit_hash=commit_hash, + etag=etag, + timestamp=timestamp, + ) + except Exception as e: + # remove the metadata file if it is corrupted / not the right format + logger.warning( + f"Invalid metadata file {paths.metadata_path}: {e}. Removing it from disk and continue." + ) + try: + paths.metadata_path.unlink() + except Exception as e: + logger.warning(f"Could not remove corrupted metadata file {paths.metadata_path}: {e}") + return None + + try: + # check if the file exists and hasn't been modified since the metadata was saved + stat = paths.file_path.stat() + if ( + stat.st_mtime - 1 <= metadata.timestamp + ): # allow 1s difference as stat.st_mtime might not be precise + return metadata + logger.info(f"Ignored metadata for '{filename}' (outdated). Will re-compute hash.") + except FileNotFoundError: + # file does not exist => metadata is outdated + return None + return None + + +def read_upload_metadata(local_dir: Path, filename: str) -> LocalUploadFileMetadata: + """Read metadata about a file in the local directory related to an upload process. + + TODO: factorize logic with `read_download_metadata`. + + Args: + local_dir (`Path`): + Path to the local directory in which files are downloaded. + filename (`str`): + Path of the file in the repo. + + Return: + `[LocalUploadFileMetadata]` or `None`: the metadata if it exists, `None` otherwise. + """ + paths = get_local_upload_paths(local_dir, filename) + with WeakFileLock(paths.lock_path): + if paths.metadata_path.exists(): + try: + with paths.metadata_path.open() as f: + timestamp = float(f.readline().strip()) + + size = int(f.readline().strip()) # never None + + _should_ignore = f.readline().strip() + should_ignore = None if _should_ignore == "" else bool(int(_should_ignore)) + + _sha256 = f.readline().strip() + sha256 = None if _sha256 == "" else _sha256 + + _upload_mode = f.readline().strip() + upload_mode = None if _upload_mode == "" else _upload_mode + if upload_mode not in (None, "regular", "lfs"): + raise ValueError(f"Invalid upload mode in metadata {paths.path_in_repo}: {upload_mode}") + + _remote_oid = f.readline().strip() + remote_oid = None if _remote_oid == "" else _remote_oid + + is_uploaded = bool(int(f.readline().strip())) + is_committed = bool(int(f.readline().strip())) + + metadata = LocalUploadFileMetadata( + timestamp=timestamp, + size=size, + should_ignore=should_ignore, + sha256=sha256, + upload_mode=upload_mode, + remote_oid=remote_oid, + is_uploaded=is_uploaded, + is_committed=is_committed, + ) + except Exception as e: + # remove the metadata file if it is corrupted / not the right format + logger.warning( + f"Invalid metadata file {paths.metadata_path}: {e}. Removing it from disk and continue." + ) + try: + paths.metadata_path.unlink() + except Exception as e: + logger.warning(f"Could not remove corrupted metadata file {paths.metadata_path}: {e}") + + # corrupted metadata => we don't know anything expect its size + return LocalUploadFileMetadata(size=paths.file_path.stat().st_size) + + # TODO: can we do better? + if ( + metadata.timestamp is not None + and metadata.is_uploaded # file was uploaded + and not metadata.is_committed # but not committed + and time.time() - metadata.timestamp > 20 * 3600 # and it's been more than 20 hours + ): # => we consider it as garbage-collected by S3 + metadata.is_uploaded = False + + # check if the file exists and hasn't been modified since the metadata was saved + try: + if metadata.timestamp is not None and paths.file_path.stat().st_mtime <= metadata.timestamp: + return metadata + logger.info(f"Ignored metadata for '{filename}' (outdated). Will re-compute hash.") + except FileNotFoundError: + # file does not exist => metadata is outdated + pass + + # empty metadata => we don't know anything expect its size + return LocalUploadFileMetadata(size=paths.file_path.stat().st_size) + + +def write_download_metadata(local_dir: Path, filename: str, commit_hash: str, etag: str) -> None: + """Write metadata about a file in the local directory related to a download process. + + Args: + local_dir (`Path`): + Path to the local directory in which files are downloaded. + """ + paths = get_local_download_paths(local_dir, filename) + with WeakFileLock(paths.lock_path): + with paths.metadata_path.open("w") as f: + f.write(f"{commit_hash}\n{etag}\n{time.time()}\n") + + +def _huggingface_dir(local_dir: Path) -> Path: + """Return the path to the `.cache/huggingface` directory in a local directory.""" + # Wrap in lru_cache to avoid overwriting the .gitignore file if called multiple times + path = local_dir / ".cache" / "huggingface" + path.mkdir(exist_ok=True, parents=True) + + # Create a CACHEDIR.TAG so backup tools can skip this directory. + _create_cachedir_tag(path) + + # Create a .gitignore file in the .cache/huggingface directory if it doesn't exist + # Should be thread-safe enough like this. + gitignore = path / ".gitignore" + gitignore_lock = path / ".gitignore.lock" + if not gitignore.exists(): + try: + with WeakFileLock(gitignore_lock, timeout=0.1): + gitignore.write_text("*") + except IndexError: + pass + except OSError: # TimeoutError, FileNotFoundError, PermissionError, etc. + pass + try: + gitignore_lock.unlink() + except OSError: + pass + return path + + +def _create_cachedir_tag(cache_dir: Path) -> None: + """Create a CACHEDIR.TAG file in ``cache_dir`` if one does not already exist. + + The tag follows the `Cache Directory Tagging Standard `_ + so that backup tools can recognize and skip cache directories. + """ + tag_path = cache_dir / "CACHEDIR.TAG" + if not tag_path.exists(): + try: + tag_path.write_text(CACHEDIR_TAG_CONTENT) + except OSError: + pass + + +def _short_hash(filename: str) -> str: + return base64.urlsafe_b64encode(hashlib.sha1(filename.encode()).digest()).decode() diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_login.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_login.py new file mode 100644 index 0000000000000000000000000000000000000000..f8fcdc55b778f9423701664aa29ca65f08c4a229 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_login.py @@ -0,0 +1,559 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains methods to log in to the Hub.""" + +import html +import os +import subprocess +import sys +import time +from datetime import datetime +from getpass import getpass +from pathlib import Path + +from . import constants +from .errors import DeviceCodeError +from .utils import ( + ANSI, + get_token, + is_google_colab, + is_notebook, + list_credential_helpers, + logging, + run_subprocess, + select_choice, + set_git_credential, + tabulate, + unset_git_credential, +) +from .utils._auth import ( + _get_token_by_name, + _get_token_from_environment, + _get_token_from_file, + _get_token_from_google_colab, + _read_stored_tokens_full, + _save_stored_tokens_full, + _save_token, + _write_secret, + get_stored_tokens, +) +from .utils._oauth_device import OAuthTokenResponse, poll_device_token, request_device_code + + +logger = logging.get_logger(__name__) + + +def login( + token: str | None = None, + *, + add_to_git_credential: bool = False, + skip_if_logged_in: bool = True, +) -> None: + """Login the machine to access the Hub. + + The `token` is persisted in cache and set as a git credential. Once done, the machine + is logged in and the access token will be available across all `huggingface_hub` + components. If `token` is not provided, a browser-based OAuth flow is used to + authenticate: open a URL, enter a short code, and the token is retrieved and saved. + In a terminal, you can also choose to paste an existing access token instead. + + To log in from outside of a script, one can also use `hf auth login` which is + a cli command that wraps [`login`]. + + > [!TIP] + > When the token is not passed, [`login`] will automatically detect if the script runs + > in a notebook or not. However, this detection might not be accurate due to the + > variety of notebooks that exists nowadays. If that is the case, you can always force + > the UI by using [`notebook_login`] or [`interpreter_login`]. + + Args: + token (`str`, *optional*): + User access token to generate from https://huggingface.co/settings/token. + add_to_git_credential (`bool`, defaults to `False`): + If `True`, token will be set as git credential. If no git credential helper + is configured, a warning will be displayed to the user. Only used when `token` + is provided; ignored by the browser-based flow. + skip_if_logged_in (`bool`, defaults to `True`): + If `True`, do not prompt for token if user is already logged in. + Set to `False` to force re-login. In CLI, use `--force` instead. + Raises: + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If an organization token is passed. Only personal account tokens are valid + to log in. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If token is invalid. + [`DeviceCodeError`] + If the browser-based login fails (authorization denied, code expired, ...). + """ + if token is not None: + if not add_to_git_credential: + logger.info( + "The token has not been saved to the git credentials helper. Pass " + "`add_to_git_credential=True` in this function directly or " + "`--add-to-git-credential` if using via `hf`CLI if " + "you want to set the git credential as well." + ) + _validate_and_save_token(token, add_to_git_credential=add_to_git_credential) + return + if add_to_git_credential: + logger.warning( + "`add_to_git_credential=True` is only supported when a token is passed directly. " + "It is ignored by the browser-based login." + ) + if is_notebook(): + notebook_login(skip_if_logged_in=skip_if_logged_in) + else: + interpreter_login(skip_if_logged_in=skip_if_logged_in) + + +def logout(token_name: str | None = None) -> None: + """Logout the machine from the Hub. + + Token is deleted from the machine and removed from git credential. + + Args: + token_name (`str`, *optional*): + Name of the access token to logout from. If `None`, will log out from all saved access tokens. + Raises: + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError): + If the access token name is not found. + """ + if get_token() is None and not get_stored_tokens(): # No active token and no saved access tokens + logger.warning("Not logged in!") + return + if not token_name: + # Delete all saved access tokens and token + for file_path in (constants.HF_TOKEN_PATH, constants.HF_STORED_TOKENS_PATH): + try: + Path(file_path).unlink() + except FileNotFoundError: + pass + logger.info("Successfully logged out from all access tokens.") + else: + _logout_from_token(token_name) + logger.info(f"Successfully logged out from access token: {token_name}.") + + unset_git_credential() + + # Check if still logged in + if _get_token_from_google_colab() is not None: + raise OSError( + "You are automatically logged in using a Google Colab secret.\n" + "To log out, you must unset the `HF_TOKEN` secret in your Colab settings." + ) + if _get_token_from_environment() is not None: + raise OSError( + "Token has been deleted from your machine but you are still logged in.\n" + "To log out, you must clear out both `HF_TOKEN` and `HUGGING_FACE_HUB_TOKEN` environment variables." + ) + + +def auth_switch(token_name: str, add_to_git_credential: bool = False) -> None: + """Switch to a different access token. + + Args: + token_name (`str`): + Name of the access token to switch to. + add_to_git_credential (`bool`, defaults to `False`): + If `True`, token will be set as git credential. If no git credential helper + is configured, a warning will be displayed to the user. If `token` is `None`, + the value of `add_to_git_credential` is ignored and will be prompted again + to the end user. + + Raises: + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError): + If the access token name is not found. + """ + token = _get_token_by_name(token_name) + if not token: + raise ValueError(f"Access token {token_name} not found in {constants.HF_STORED_TOKENS_PATH}") + # Write token to HF_TOKEN_PATH + _set_active_token(token_name, add_to_git_credential) + logger.info(f"The current active token is: {token_name}") + token_from_environment = _get_token_from_environment() + if token_from_environment is not None and token_from_environment != token: + logger.warning( + "The environment variable `HF_TOKEN` is set and will override the access token you've just switched to." + ) + + +def auth_list() -> None: + """List all stored access tokens.""" + # Resolve the current token before reading the file: `get_token()` may refresh an OAuth + # token and rewrite the stored tokens on the way. + current_token = get_token() + stored_tokens = _read_stored_tokens_full() + + if not stored_tokens: + if _get_token_from_environment(): + logger.info("No stored access tokens found.") + logger.warning("Note: Environment variable `HF_TOKEN` is set and is the current active token.") + else: + logger.info("No access tokens found.") + return + show_expires = any("expires_at" in fields for fields in stored_tokens.values()) + headers = [" ", "name", "token"] + (["expires"] if show_expires else []) + + current_token_name = None + rows: list[list[str | int]] = [] + for token_name, fields in stored_tokens.items(): + token = fields.get("hf_token", "") + if token == current_token: + current_token_name = token_name + masked_token = f"{token[:3]}****{token[-4:]}" if token != "" else token + row: list[str | int] = ["*" if token == current_token else "", token_name, masked_token] + if show_expires: + row.append(_format_expiration(fields.get("expires_at"))) + rows.append(row) + print(tabulate(rows, headers=headers)) + + if _get_token_from_environment(): + logger.warning( + "\nNote: Environment variable `HF_TOKEN` is set and is the current active token independently from the stored tokens listed above." + ) + elif current_token_name is None: + logger.warning( + "\nNote: No active token is set and no environment variable `HF_TOKEN` is found. Use `hf auth login` to log in." + ) + + +### +# Device Code OAuth login (RFC 8628) +### + + +def _device_code_login() -> None: + """Run the Device Code OAuth flow: request a code, prompt the user to authorize it in a browser, + poll for the token and save it.""" + device_info = request_device_code() + + # The complete URI has the code pre-filled when the server supports it. + print(f"\n Open this URL in your browser:\n {device_info['verification_uri_complete']}\n") + print(f" And enter the code: {device_info['user_code']}\n") + + print(" Waiting for authorization", end="", flush=True) + try: + response = poll_device_token(device_info, on_pending=lambda: print(".", end="", flush=True)) + finally: + print() # newline after the progress dots, also on failure + + _save_oauth_token(response) + + +def _save_oauth_token(response: OAuthTokenResponse) -> tuple[str, str]: + """Validate and persist a token response from the device code flow, including refresh metadata.""" + expires_in = response.get("expires_in") + token_name, username = _validate_and_save_token( + response["access_token"], + add_to_git_credential=False, + refresh_token=response.get("refresh_token"), + expires_at=int(time.time()) + int(expires_in) if expires_in else None, + ) + if note := _expiration_note(response): + logger.info(f"Note: {note}") + return token_name, username + + +def _expiration_note(response: OAuthTokenResponse) -> str | None: + """Human-readable note about the lifetime of a freshly obtained OAuth token, if known.""" + expires_in = response.get("expires_in") + if not expires_in: + return None + if response.get("refresh_token"): + return "This token will be refreshed automatically when it expires." + days = max(1, int(expires_in) // 86400) + return f"This token expires in {days} days. Log in again to renew it." + + +### +# Interpreter-based login (text) +### + + +def interpreter_login(*, skip_if_logged_in: bool = True) -> None: + """ + Displays a prompt to log in to the HF website and store the token. + + This is equivalent to [`login`] without passing a token when not run in a notebook. + [`interpreter_login`] is useful if you want to force the use of the terminal prompt + instead of a notebook flow. + + For more details, see [`login`]. + + Args: + skip_if_logged_in (`bool`, defaults to `True`): + If `True`, do not prompt for token if user is already logged in. + Set to `False` to force re-login. In CLI, use `--force` instead. + """ + if skip_if_logged_in and get_token() is not None: + logger.info("User is already logged in. Use `hf auth login --force` to force re-login.") + return + + if get_token() is not None: + logger.info("Note: a token is already saved on this machine. Logging in again will replace the active token.") + + if _prompt_login_method() == "token": + _paste_token_login() + else: + _device_code_login() + + +def _prompt_login_method() -> str: + """Ask the user how to log in: "browser" (default) or "token". Never prompts without a TTY.""" + if sys.stdin is None or not sys.stdin.isatty(): + return "browser" + choice = select_choice("How would you like to log in?", ["Log in with your browser", "Paste an access token"]) + return "browser" if choice == 0 else "token" + + +def _paste_token_login() -> None: + logger.info( + " To log in, `huggingface_hub` requires a token generated from https://huggingface.co/settings/tokens ." + ) + if os.name == "nt": + logger.info("Token can be pasted using 'Right-Click'.") + token = getpass("Enter your token (input will not be visible): ") + _validate_and_save_token(token=token, add_to_git_credential=False) + + +### +# Notebook-based login +### + + +def notebook_login(*, skip_if_logged_in: bool = True) -> None: + """ + Displays a prompt to log in to the HF website and store the token. + + This is equivalent to [`login`] without passing a token when run in a notebook. + [`notebook_login`] is useful if you want to force the use of the notebook flow + instead of a prompt in the terminal. + + For more details, see [`login`]. + + Args: + skip_if_logged_in (`bool`, defaults to `True`): + If `True`, do not prompt for token if user is already logged in. + Set to `False` to force re-login. In CLI, use `--force` instead. + """ + if skip_if_logged_in and get_token() is not None: + logger.info("User is already logged in. Use `hf auth login --force` to force re-login.") + return + + try: + from IPython.display import HTML, display # type: ignore + except ImportError: + # Not in a notebook environment: fall back to the terminal flow + interpreter_login(skip_if_logged_in=False) + return + + device_info = request_device_code() + # Escape server-provided values: they end up in raw notebook HTML. + verification_uri = html.escape(device_info["verification_uri"]) + verification_uri_complete = html.escape(device_info["verification_uri_complete"]) + + display( + HTML( + '
Hugging Face

' + "

To log in, open this URL and enter the code:

" + f'

{verification_uri}

' + '

' + f"{html.escape(device_info['user_code'])}

" + ) + ) + display(HTML("
Waiting for authorization...
")) + try: + response = poll_device_token(device_info) + except DeviceCodeError as e: + display(HTML(f"
Login failed: {html.escape(str(e))}
")) + return + + try: + token_name, username = _save_oauth_token(response) + except Exception as error: + display(HTML(f"
{html.escape(str(error))}
")) + return + + message = f"Login successful. Logged in as {html.escape(username)} (token: {html.escape(token_name)})." + if note := _expiration_note(response): + message += f"
{html.escape(note)}" + display(HTML(f"
{message}
")) + + +### +# Login private helpers +### + + +def _validate_and_save_token( + token: str, + add_to_git_credential: bool, + refresh_token: str | None = None, + expires_at: int | None = None, +) -> tuple[str, str]: + """Validate a token against the Hub, save it to the stored tokens file and set it as active. + + The token is stored under its `displayName` from the whoami response, or `oauth-{username}` + for OAuth tokens (which have no display name). + + Args: + token (`str`): + The access token. + add_to_git_credential (`bool`): + Whether to save the token to the git credential helpers. + refresh_token (`str`, *optional*): + OAuth refresh token to persist alongside the access token. + expires_at (`int`, *optional*): + Unix timestamp at which the access token expires. + + Returns: + `tuple[str, str]`: The token name and the username. + """ + from .hf_api import whoami # avoid circular import + + if token.startswith("api_org"): + raise ValueError("You must use your personal account token, not an organization token.") + + token_info = whoami(token) + username = token_info["name"] + + access_token_info = (token_info.get("auth") or {}).get("accessToken") or {} + if role := access_token_info.get("role"): + logger.info(f"Token is valid (permission: {role}).") + else: + logger.info("Token is valid.") + + token_name = access_token_info.get("displayName") or f"oauth-{username}" + + # Store token locally + _save_token(token=token, token_name=token_name, refresh_token=refresh_token, expires_at=expires_at) + # Set active token + _set_active_token(token_name=token_name, add_to_git_credential=add_to_git_credential) + logger.info("Login successful.") + if _get_token_from_environment(): + logger.warning( + "Note: Environment variable`HF_TOKEN` is set and is the current active token independently from the token you've just configured." + ) + else: + logger.info(f"The current active token is: `{token_name}`") + return token_name, username + + +def _logout_from_token(token_name: str) -> None: + """Logout from a specific access token. + + Args: + token_name (`str`): + The name of the access token to logout from. + """ + stored_tokens = _read_stored_tokens_full() + # If there is no access tokens saved or the access token name is not found, do nothing + if token_name not in stored_tokens: + return + + fields = stored_tokens.pop(token_name) + _save_stored_tokens_full(stored_tokens) + + if fields.get("hf_token") == _get_token_from_file(): + logger.warning(f"Active token '{token_name}' has been deleted.") + Path(constants.HF_TOKEN_PATH).unlink(missing_ok=True) + + +def _format_expiration(expires_at: str | None) -> str: + """Format an `expires_at` unix timestamp for display in `auth list`.""" + if not expires_at: + return "" + try: + timestamp = int(expires_at) + except ValueError: + return "" + date_str = datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d") + return f"{date_str} (expired)" if timestamp < time.time() else date_str + + +def _set_active_token( + token_name: str, + add_to_git_credential: bool, +) -> None: + """Set the active access token. + + Args: + token_name (`str`): + The name of the token to set as active. + """ + token = _get_token_by_name(token_name) + if not token: + raise ValueError(f"Token {token_name} not found in {constants.HF_STORED_TOKENS_PATH}") + if add_to_git_credential: + if _is_git_credential_helper_configured(): + set_git_credential(token) + logger.info( + "Your token has been saved in your configured git credential helpers" + + f" ({','.join(list_credential_helpers())})." + ) + else: + logger.warning("Token has not been saved to git credential helper.") + # Write token to HF_TOKEN_PATH + _write_secret(Path(constants.HF_TOKEN_PATH), token) + logger.info(f"Your token has been saved to {constants.HF_TOKEN_PATH}") + + +def _is_git_credential_helper_configured() -> bool: + """Check if a git credential helper is configured. + + Warns user if not the case (except for Google Colab where "store" is set by default + by `huggingface_hub`). + """ + helpers = list_credential_helpers() + if len(helpers) > 0: + return True # Do not warn: at least 1 helper is set + + # Only in Google Colab to avoid the warning message + # See https://github.com/huggingface/huggingface_hub/issues/1043#issuecomment-1247010710 + if is_google_colab(): + _set_store_as_git_credential_helper_globally() + return True # Do not warn: "store" is used by default in Google Colab + + # Otherwise, warn user + print( + ANSI.red( + "Cannot authenticate through git-credential as no helper is defined on your" + " machine.\nYou might have to re-authenticate when pushing to the Hugging" + " Face Hub.\nRun the following command in your terminal in case you want to" + " set the 'store' credential helper as default.\n\ngit config --global" + " credential.helper store\n\nRead" + " https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage for more" + " details." + ) + ) + return False + + +def _set_store_as_git_credential_helper_globally() -> None: + """Set globally the credential.helper to `store`. + + To be used only in Google Colab as we assume the user doesn't care about the git + credential config. It is the only particular case where we don't want to display the + warning message in [`notebook_login()`]. + + Related: + - https://github.com/huggingface/huggingface_hub/issues/1043 + - https://github.com/huggingface/huggingface_hub/issues/1051 + - https://git-scm.com/docs/git-credential-store + """ + try: + run_subprocess("git config --global credential.helper store") + except subprocess.CalledProcessError as exc: + raise OSError(exc.stderr) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_oauth.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_oauth.py new file mode 100644 index 0000000000000000000000000000000000000000..cac82ada87262370031740ea6d7c9234aec44de0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_oauth.py @@ -0,0 +1,460 @@ +import datetime +import hashlib +import logging +import os +import time +import urllib.parse +import warnings +from dataclasses import dataclass +from typing import TYPE_CHECKING, Literal + +from . import constants +from .hf_api import whoami +from .utils import experimental, get_token + + +logger = logging.getLogger(__name__) + +if TYPE_CHECKING: + import fastapi + + +@dataclass +class OAuthOrgInfo: + """ + Information about an organization linked to a user logged in with OAuth. + + Attributes: + sub (`str`): + Unique identifier for the org. OpenID Connect field. + name (`str`): + The org's full name. OpenID Connect field. + preferred_username (`str`): + The org's username. OpenID Connect field. + picture (`str`): + The org's profile picture URL. OpenID Connect field. + plan (`str`, *optional*): + The org's plan (e.g., "enterprise", "team"). Hugging Face field. + can_pay (`Optional[bool]`, *optional*): + Whether the org has a payment method set up. Hugging Face field. + role_in_org (`Optional[str]`, *optional*): + The user's role in the org. Hugging Face field. + security_restrictions (`Optional[list[Literal["ip", "token-policy", "mfa", "sso"]]]`, *optional*): + Array of security restrictions that the user hasn't completed for this org. Possible values: "ip", "token-policy", "mfa", "sso". Hugging Face field. + """ + + sub: str + name: str + preferred_username: str + picture: str + plan: str | None = None + can_pay: bool | None = None + role_in_org: str | None = None + security_restrictions: list[Literal["ip", "token-policy", "mfa", "sso"]] | None = None + + +@dataclass +class OAuthUserInfo: + """ + Information about a user logged in with OAuth. + + Attributes: + sub (`str`): + Unique identifier for the user, even in case of rename. OpenID Connect field. + name (`str`): + The user's full name. OpenID Connect field. + preferred_username (`str`): + The user's username. OpenID Connect field. + email_verified (`Optional[bool]`, *optional*): + Indicates if the user's email is verified. OpenID Connect field. + email (`Optional[str]`, *optional*): + The user's email address. OpenID Connect field. + picture (`str`): + The user's profile picture URL. OpenID Connect field. + profile (`str`): + The user's profile URL. OpenID Connect field. + website (`Optional[str]`, *optional*): + The user's website URL. OpenID Connect field. + is_pro (`bool`): + Whether the user is a pro user. Hugging Face field. + can_pay (`Optional[bool]`, *optional*): + Whether the user has a payment method set up. Hugging Face field. + orgs (`Optional[list[OrgInfo]]`, *optional*): + List of organizations the user is part of. Hugging Face field. + """ + + sub: str + name: str + preferred_username: str + email_verified: bool | None + email: str | None + picture: str + profile: str + website: str | None + is_pro: bool + can_pay: bool | None + orgs: list[OAuthOrgInfo] | None + + +@dataclass +class OAuthInfo: + """ + Information about the OAuth login. + + Attributes: + access_token (`str`): + The access token. + access_token_expires_at (`datetime.datetime`): + The expiration date of the access token. + user_info ([`OAuthUserInfo`]): + The user information. + state (`str`, *optional*): + State passed to the OAuth provider in the original request to the OAuth provider. + scope (`str`): + Granted scope. + """ + + access_token: str + access_token_expires_at: datetime.datetime + user_info: OAuthUserInfo + state: str | None + scope: str + + +@experimental +def attach_huggingface_oauth(app: "fastapi.FastAPI", route_prefix: str = "/"): + """ + Add OAuth endpoints to a FastAPI app to enable OAuth login with Hugging Face. + + How to use: + - Call this method on your FastAPI app to add the OAuth endpoints. + - Inside your route handlers, call `parse_huggingface_oauth(request)` to retrieve the OAuth info. + - If user is logged in, an [`OAuthInfo`] object is returned with the user's info. If not, `None` is returned. + - In your app, make sure to add links to `/oauth/huggingface/login` and `/oauth/huggingface/logout` for the user to log in and out. + + Example: + ```py + from huggingface_hub import attach_huggingface_oauth, parse_huggingface_oauth + + # Create a FastAPI app + app = FastAPI() + + # Add OAuth endpoints to the FastAPI app + attach_huggingface_oauth(app) + + # Add a route that greets the user if they are logged in + @app.get("/") + def greet_json(request: Request): + # Retrieve the OAuth info from the request + oauth_info = parse_huggingface_oauth(request) # e.g. OAuthInfo dataclass + if oauth_info is None: + return {"msg": "Not logged in!"} + return {"msg": f"Hello, {oauth_info.user_info.preferred_username}!"} + ``` + """ + # TODO: handle generic case (handling OAuth in a non-Space environment with custom dev values) (low priority) + + # Add SessionMiddleware to the FastAPI app to store the OAuth info in the session. + # Session Middleware requires a secret key to sign the cookies. Let's use a hash + # of the OAuth secret key to make it unique to the Space + updated in case OAuth + # config gets updated. When ran locally, we use an empty string as a secret key. + try: + from starlette.middleware.sessions import SessionMiddleware + except ImportError as e: + raise ImportError( + "Cannot initialize OAuth to due a missing library. Please run `pip install huggingface_hub[oauth]` or add " + "`huggingface_hub[oauth]` to your requirements.txt file in order to install the required dependencies." + ) from e + session_secret = (constants.OAUTH_CLIENT_SECRET or "") + "-v1" + app.add_middleware( + SessionMiddleware, # type: ignore + secret_key=hashlib.sha256(session_secret.encode()).hexdigest(), + same_site="none", + https_only=True, + ) # type: ignore + + # Add OAuth endpoints to the FastAPI app: + # - {route_prefix}/oauth/huggingface/login + # - {route_prefix}/oauth/huggingface/callback + # - {route_prefix}/oauth/huggingface/logout + # If the app is running in a Space, OAuth is enabled normally. + # Otherwise, we mock the endpoints to make the user log in with a fake user profile - without any calls to hf.co. + route_prefix = route_prefix.strip("/") + if os.getenv("SPACE_ID") is not None: + logger.info("OAuth is enabled in the Space. Adding OAuth routes.") + _add_oauth_routes(app, route_prefix=route_prefix) + else: + logger.info("App is not running in a Space. Adding mocked OAuth routes.") + _add_mocked_oauth_routes(app, route_prefix=route_prefix) + + +def parse_huggingface_oauth(request: "fastapi.Request") -> OAuthInfo | None: + """ + Returns the information from a logged-in user as a [`OAuthInfo`] object. + + For flexibility and future-proofing, this method is very lax in its parsing and does not raise errors. + Missing fields are set to `None` without a warning. + + Return `None`, if the user is not logged in (no info in session cookie). + + See [`attach_huggingface_oauth`] for an example on how to use this method. + """ + if "oauth_info" not in request.session: + logger.debug("No OAuth info in session.") + return None + + logger.debug("Parsing OAuth info from session.") + oauth_data = request.session["oauth_info"] + user_data = oauth_data.get("userinfo", {}) + orgs_data = user_data.get("orgs", []) + + orgs = ( + [ + OAuthOrgInfo( + sub=org.get("sub"), + name=org.get("name"), + preferred_username=org.get("preferred_username"), + picture=org.get("picture"), + plan=org.get("plan"), + can_pay=org.get("canPay"), + role_in_org=org.get("roleInOrg"), + security_restrictions=org.get("securityRestrictions"), + ) + for org in orgs_data + ] + if orgs_data + else None + ) + + user_info = OAuthUserInfo( + sub=user_data.get("sub"), + name=user_data.get("name"), + preferred_username=user_data.get("preferred_username"), + email_verified=user_data.get("email_verified"), + email=user_data.get("email"), + picture=user_data.get("picture"), + profile=user_data.get("profile"), + website=user_data.get("website"), + is_pro=user_data.get("isPro"), + can_pay=user_data.get("canPay"), + orgs=orgs, + ) + + return OAuthInfo( + access_token=oauth_data.get("access_token"), + access_token_expires_at=datetime.datetime.fromtimestamp(oauth_data.get("expires_at")), + user_info=user_info, + state=oauth_data.get("state"), + scope=oauth_data.get("scope"), + ) + + +def _add_oauth_routes(app: "fastapi.FastAPI", route_prefix: str) -> None: + """Add OAuth routes to the FastAPI app (login, callback handler and logout).""" + try: + import fastapi + from authlib.integrations.base_client.errors import MismatchingStateError + from authlib.integrations.starlette_client import OAuth + from fastapi.responses import RedirectResponse + except ImportError as e: + raise ImportError( + "Cannot initialize OAuth to due a missing library. Please run `pip install huggingface_hub[oauth]` or add " + "`huggingface_hub[oauth]` to your requirements.txt file." + ) from e + + # Check environment variables + msg = ( + "OAuth is required but '{}' environment variable is not set. Make sure you've enabled OAuth in your Space by" + " setting `hf_oauth: true` in the Space metadata." + ) + if constants.OAUTH_CLIENT_ID is None: + raise ValueError(msg.format("OAUTH_CLIENT_ID")) + if constants.OAUTH_CLIENT_SECRET is None: + raise ValueError(msg.format("OAUTH_CLIENT_SECRET")) + if constants.OAUTH_SCOPES is None: + raise ValueError(msg.format("OAUTH_SCOPES")) + if constants.OPENID_PROVIDER_URL is None: + raise ValueError(msg.format("OPENID_PROVIDER_URL")) + + # Register OAuth server + oauth = OAuth() + oauth.register( + name="huggingface", + client_id=constants.OAUTH_CLIENT_ID, + client_secret=constants.OAUTH_CLIENT_SECRET, + client_kwargs={"scope": constants.OAUTH_SCOPES}, + server_metadata_url=constants.OPENID_PROVIDER_URL + "/.well-known/openid-configuration", + ) + + login_uri, callback_uri, logout_uri = _get_oauth_uris(route_prefix) + + # Register OAuth endpoints + @app.get(login_uri) + async def oauth_login(request: fastapi.Request) -> RedirectResponse: + """Endpoint that redirects to HF OAuth page.""" + redirect_uri = _generate_redirect_uri(request) + return await oauth.huggingface.authorize_redirect(request, redirect_uri) # type: ignore + + @app.get(callback_uri) + async def oauth_redirect_callback(request: fastapi.Request) -> RedirectResponse: + """Endpoint that handles the OAuth callback.""" + try: + oauth_info = await oauth.huggingface.authorize_access_token(request) # type: ignore + except MismatchingStateError: + # Parse query params + nb_redirects = int(request.query_params.get("_nb_redirects", 0)) + target_url = request.query_params.get("_target_url") + + # Build redirect URI with the same query params as before and bump nb_redirects count + query_params: dict[str, int | str] = {"_nb_redirects": nb_redirects + 1} + if target_url: + query_params["_target_url"] = target_url + + redirect_uri = f"{login_uri}?{urllib.parse.urlencode(query_params)}" + + # If the user is redirected more than 3 times, it is very likely that the cookie is not working properly. + # (e.g. browser is blocking third-party cookies in iframe). In this case, redirect the user in the + # non-iframe view. + if nb_redirects > constants.OAUTH_MAX_REDIRECTS: + host = os.environ.get("SPACE_HOST") + if host is None: # cannot happen in a Space + raise RuntimeError( + "App is not running in a Space (SPACE_HOST environment variable is not set). Cannot redirect to non-iframe view." + ) from None + host_url = "https://" + host.rstrip("/") + return RedirectResponse(host_url + redirect_uri) + + # Redirect the user to the login page again + return RedirectResponse(redirect_uri) + + # OAuth login worked => store the user info in the session and redirect + logger.debug("Successfully logged in with OAuth. Storing user info in session.") + request.session["oauth_info"] = oauth_info + return RedirectResponse(_get_redirect_target(request)) + + @app.get(logout_uri) + async def oauth_logout(request: fastapi.Request) -> RedirectResponse: + """Endpoint that logs out the user (e.g. delete info from cookie session).""" + logger.debug("Logged out with OAuth. Removing user info from session.") + request.session.pop("oauth_info", None) + return RedirectResponse(_get_redirect_target(request)) + + +def _add_mocked_oauth_routes(app: "fastapi.FastAPI", route_prefix: str = "/") -> None: + """Add fake oauth routes if app is run locally and OAuth is enabled. + + Using OAuth will have the same behavior as in a Space but instead of authenticating with HF, a mocked user profile + is added to the session. + """ + try: + import fastapi + from fastapi.responses import RedirectResponse + from starlette.datastructures import URL + except ImportError as e: + raise ImportError( + "Cannot initialize OAuth to due a missing library. Please run `pip install huggingface_hub[oauth]` or add " + "`huggingface_hub[oauth]` to your requirements.txt file." + ) from e + + warnings.warn( + "OAuth is not supported outside of a Space environment. To help you debug your app locally, the oauth endpoints" + " are mocked to return your profile and token. To make it work, your machine must be logged in to Huggingface." + ) + mocked_oauth_info = _get_mocked_oauth_info() + + login_uri, callback_uri, logout_uri = _get_oauth_uris(route_prefix) + + # Define OAuth routes + @app.get(login_uri) + async def oauth_login(request: fastapi.Request) -> RedirectResponse: + """Fake endpoint that redirects to HF OAuth page.""" + # Define target (where to redirect after login) + redirect_uri = _generate_redirect_uri(request) + return RedirectResponse(callback_uri + "?" + urllib.parse.urlencode({"_target_url": redirect_uri})) + + @app.get(callback_uri) + async def oauth_redirect_callback(request: fastapi.Request) -> RedirectResponse: + """Endpoint that handles the OAuth callback.""" + request.session["oauth_info"] = mocked_oauth_info + return RedirectResponse(_get_redirect_target(request)) + + @app.get(logout_uri) + async def oauth_logout(request: fastapi.Request) -> RedirectResponse: + """Endpoint that logs out the user (e.g. delete cookie session).""" + request.session.pop("oauth_info", None) + logout_url = URL("/").include_query_params(**request.query_params) + return RedirectResponse(url=logout_url, status_code=302) # see https://github.com/gradio-app/gradio/pull/9659 + + +def _generate_redirect_uri(request: "fastapi.Request") -> str: + if "_target_url" in request.query_params: + # if `_target_url` already in query params => respect it + target = request.query_params["_target_url"] + else: + # otherwise => keep query params + target = "/?" + urllib.parse.urlencode(request.query_params) + + redirect_uri = request.url_for("oauth_redirect_callback").include_query_params(_target_url=target) + redirect_uri_as_str = str(redirect_uri) + if redirect_uri.netloc.endswith(".hf.space"): + # In Space, FastAPI redirect as http but we want https + redirect_uri_as_str = redirect_uri_as_str.replace("http://", "https://") + return redirect_uri_as_str + + +def _get_redirect_target(request: "fastapi.Request", default_target: str = "/") -> str: + return request.query_params.get("_target_url", default_target) + + +def _get_mocked_oauth_info() -> dict: + token = get_token() + if token is None: + raise ValueError( + "Your machine must be logged in to HF to debug an OAuth app locally. Please" + " run `hf auth login` or set `HF_TOKEN` as environment variable " + "with one of your access token. You can generate a new token in your " + "settings page (https://huggingface.co/settings/tokens)." + ) + + user = whoami() + if user["type"] != "user": + raise ValueError( + "Your machine is not logged in with a personal account. Please use a " + "personal access token. You can generate a new token in your settings page" + " (https://huggingface.co/settings/tokens)." + ) + + return { + "access_token": token, + "token_type": "bearer", + "expires_in": 8 * 60 * 60, # 8 hours + "id_token": "FOOBAR", + "scope": "openid profile", + "refresh_token": "hf_oauth__refresh_token", + "expires_at": int(time.time()) + 8 * 60 * 60, # 8 hours + "userinfo": { + "sub": "0123456789", + "name": user["fullname"], + "preferred_username": user["name"], + "profile": f"https://huggingface.co/{user['name']}", + "picture": user["avatarUrl"], + "website": "", + "aud": "00000000-0000-0000-0000-000000000000", + "auth_time": 1691672844, + "nonce": "aaaaaaaaaaaaaaaaaaa", + "iat": 1691672844, + "exp": 1691676444, + "iss": "https://huggingface.co", + }, + } + + +def _get_oauth_uris(route_prefix: str = "/") -> tuple[str, str, str]: + route_prefix = route_prefix.strip("/") + if route_prefix: + route_prefix = f"/{route_prefix}" + return ( + f"{route_prefix}/oauth/huggingface/login", + f"{route_prefix}/oauth/huggingface/callback", + f"{route_prefix}/oauth/huggingface/logout", + ) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_oidc.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_oidc.py new file mode 100644 index 0000000000000000000000000000000000000000..3a7dba20418a2ece15afa5b5c1cbc127eb8f32cd --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_oidc.py @@ -0,0 +1,163 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""Keyless CI/CD authentication via OIDC token exchange ("Trusted Publishers"). + +A CI job proves its identity to the Hub with a short-lived OIDC id token minted by its CI +provider (e.g. GitHub Actions), then exchanges it at ``POST {ENDPOINT}/oauth/token`` (RFC 8693) +for a short-lived Hugging Face token — no long-lived ``HF_TOKEN`` secret to store. + +This module is self-contained: it only handles minting the provider id token and the exchange. +It deliberately does not register a public API or a CLI verb; the integration point is the token +resolution in ``utils/_auth.py`` (see ``_get_token_from_oidc``). + +Docs: https://huggingface.co/docs/hub/trusted-publishers +""" + +import os +from enum import Enum + +from . import constants +from .errors import OIDCError +from .utils import get_session, hf_raise_for_status + + +# RFC 8693 token-exchange grant + id-token subject type (see trusted-publishers docs). +_TOKEN_EXCHANGE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:token-exchange" +_ID_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:id_token" + + +class Provider(str, Enum): + """CI providers that can mint an OIDC id token natively. GitHub Actions only for now.""" + + GITHUB = "github" + + +def detect_provider() -> Provider | None: + """Detect the CI provider able to mint an OIDC id token, or `None` if not in a supported CI.""" + if os.environ.get("GITHUB_ACTIONS") == "true": + return Provider.GITHUB + return None + + +def _get_github_oidc_token(audience: str) -> str: + """Mint an OIDC id token from the GitHub Actions runtime. + + Relies on the `ACTIONS_ID_TOKEN_REQUEST_URL` / `ACTIONS_ID_TOKEN_REQUEST_TOKEN` env vars, + which GitHub only injects when the job declares `permissions: id-token: write`. + """ + request_url = os.environ.get("ACTIONS_ID_TOKEN_REQUEST_URL") + request_token = os.environ.get("ACTIONS_ID_TOKEN_REQUEST_TOKEN") + if not request_url or not request_token: + raise OIDCError( + "Cannot request an OIDC id token from GitHub Actions. Make sure the workflow job sets " + "`permissions: id-token: write`. See " + "https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect" + ) + response = get_session().get( + request_url, + params={"audience": audience}, + headers={"Authorization": f"Bearer {request_token}"}, + ) + hf_raise_for_status(response) + return response.json()["value"] + + +def get_oidc_token(*, provider: Provider | str | None = None, audience: str | None = None) -> str: + """Mint a raw OIDC id token (JWT) from the current CI provider. + + Args: + provider (`str`, *optional*): + CI provider to use. Auto-detected from the environment when omitted. + audience (`str`, *optional*): + The `aud` claim to request. Defaults to `constants.ENDPOINT` so it matches the endpoint + that validates it (respects `HF_ENDPOINT`/staging). + + Returns: + `str`: The raw id token (JWT) to pass to [`exchange_oidc_token`]. + """ + audience = audience or constants.ENDPOINT + provider = provider or detect_provider() + supported = ", ".join(p.value for p in Provider) + if provider is None: + raise OIDCError(f"No supported CI OIDC provider detected. Trusted Publishers currently supports: {supported}.") + if provider == Provider.GITHUB: + return _get_github_oidc_token(audience) + raise NotImplementedError(f"OIDC provider '{provider}' is not supported yet. Supported: {supported}.") + + +def exchange_oidc_token(*, subject_token: str, resource: str, endpoint: str | None = None) -> dict: + """Exchange a CI OIDC id token for a short-lived Hugging Face token (RFC 8693). + + Args: + subject_token (`str`): + The raw OIDC id token (JWT) from the CI provider. Its `aud` claim must be the Hub URL. + resource (`str`): + What to scope the token to: a Hub repo (`namespace/name`, `datasets/namespace/name`, + `spaces/namespace/name`, `kernels/namespace/name`) for a write token, or a bare Hub + username for a read-only `gated-repos` token. + endpoint (`str`, *optional*): + Hub endpoint. Defaults to `constants.ENDPOINT` (respects `HF_ENDPOINT`/staging). + + Returns: + `dict`: The token-exchange response, e.g. + `{"access_token": "hf_jwt_…", "token_type": "bearer", "expires_in": 3600, ...}`. + """ + response = get_session().post( + f"{endpoint or constants.ENDPOINT}/oauth/token", + json={ + "grant_type": _TOKEN_EXCHANGE_GRANT_TYPE, + "subject_token_type": _ID_TOKEN_TYPE, + "subject_token": subject_token, + "resource": resource, + }, + ) + hf_raise_for_status(response) + return response.json() + + +def oidc_login( + *, + resource: str, + subject_token: str | None = None, + provider: Provider | str | None = None, + audience: str | None = None, + endpoint: str | None = None, +) -> dict: + """Mint a CI OIDC id token and exchange it for a Hugging Face token. + + Convenience wrapper around [`get_oidc_token`] + [`exchange_oidc_token`]. Returns the raw + exchange response (it does not persist anything — the caller decides what to do with the token). + + Args: + resource (`str`): + Repo or username to scope the token to. See [`exchange_oidc_token`]. + subject_token (`str`, *optional*): + A pre-minted OIDC id token to exchange directly. Use this for CI providers not yet + supported natively (e.g. GitLab): mint the id token in your job and pass it here. When + omitted, the token is minted from the detected `provider`. + provider (`str`, *optional*): + CI provider. Auto-detected when omitted. Ignored when `subject_token` is provided. + audience (`str`, *optional*): + The `aud` claim to request. Defaults to the resolved `endpoint`, so it matches the + endpoint that validates it. + endpoint (`str`, *optional*): + Hub endpoint. Defaults to `constants.ENDPOINT`. + + Returns: + `dict`: The token-exchange response (`access_token`, `token_type`, `expires_in`, ...). + """ + endpoint = endpoint or constants.ENDPOINT + if subject_token is None: + subject_token = get_oidc_token(provider=provider, audience=audience or endpoint) + return exchange_oidc_token(subject_token=subject_token, resource=resource, endpoint=endpoint) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_sandbox.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_sandbox.py new file mode 100644 index 0000000000000000000000000000000000000000..55b7f4adb66c70a191ac3e21e8c261cf07a902f2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_sandbox.py @@ -0,0 +1,1764 @@ +# coding=utf-8 +# Copyright 2026-present, the HuggingFace Inc. team. +# +# 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. +import hashlib +import hmac +import json +import threading +import time +from concurrent.futures import ThreadPoolExecutor +from contextlib import contextmanager +from dataclasses import dataclass, field +from pathlib import Path +from secrets import token_hex +from typing import Any, BinaryIO, Callable, Iterator, List, Literal, overload + +import httpx + +from . import constants +from ._sandbox_cache import ( + CachedHost, + delete_pool_cache, + read_pool_cache, + save_pool_cache, +) +from ._space_api import Volume +from .errors import HfHubHTTPError, SandboxCommandError, SandboxError +from .hf_api import HfApi, JobInfo +from .utils import get_token, logging +from .utils._parsing import parse_duration + + +logger = logging.get_logger(__name__) + +# Port the sandbox server listens on inside the job. Deliberately uncommon so that typical user ports stay free. +SANDBOX_SERVER_PORT = 49983 + +# Stable marker present on every sandbox job to ease filtering +SANDBOX_LABEL = "hf-sandbox" +# Sandbox mode: "dedicated" or "pool" to ease filtering +MODE_LABEL = "hf-sandbox-mode" +MODE_DEDICATED = "dedicated" +MODE_POOL = "pool" +# Pool name, to scope host reuse to a named group (see SandboxPool(name=...)). Present on pool +# host jobs only. Pool config (capacity, idle timeout) lives in the host's env vars, read via +# inspect_job — labels are kept for filtering/grouping only. +POOL_LABEL = "hf-sandbox-pool" +# Per-job public nonce the sandbox token is derived from (see _derive_sandbox_token), so +# `Sandbox.connect(id)` can recompute the token from any machine with no local state. +NONCE_LABEL = "hf-sandbox-nonce" + +DEFAULT_IMAGE = "python:3.12" + +DEFAULT_IDLE_TIMEOUT = 10 * 60 # 10 minutes +SANDBOX_MAX_LIFETIME = "24h" + +DEFAULT_SANDBOXES_PER_HOST = 50 + +SHARED_ID_SEP = "." + +# Job stages in which a sandbox/host is finished and needs no teardown. +_TERMINAL_STAGES = ("COMPLETED", "ERROR", "DELETED", "CANCELED") + +# Safety bound on create()'s pack-retry loop +_MAX_PACK_ROUNDS = 8 + +# hf-mount path where the server bucket is mounted on every sandbox job +_SERVER_MOUNT_PATH = "/.hf-sbx-server" + +# Job startup script (needs only /bin/sh) +_BOOTSTRAP_DOWNLOAD = """\ +set -e +d=/tmp/.sbx-server +if command -v wget >/dev/null 2>&1; then wget -q --header "Authorization: Bearer $SBX_DL_TOKEN" -O "$d" "$SBX_SERVER_URL" +elif command -v curl >/dev/null 2>&1; then curl -fsSL -H "Authorization: Bearer $SBX_DL_TOKEN" -o "$d" "$SBX_SERVER_URL" +else cp "$SBX_SERVER_MOUNT/sbx-server" "$d"; fi +chmod +x "$d" +unset SBX_DL_TOKEN SBX_SERVER_URL SBX_SERVER_MOUNT +exec "$d" +""" + + +def _derive_sandbox_token(hf_token: str, nonce: str) -> str: + """Derive the per-sandbox auth token from the user's HF token and the sandbox nonce. + + Stateless: any machine holding the same HF token can recompute it from the + nonce stored in the job's labels, so `Sandbox.connect(job_id)` needs no local state. + The HF token itself is never sent to the sandbox. + """ + return hmac.new(hf_token.encode(), f"hf-sandbox:{nonce}".encode(), hashlib.sha256).hexdigest() + + +def _duration_to_secs(duration: int | float | str) -> int: + """Parse a duration like 300, "300s", "10m", "2h", "1d" into seconds.""" + if isinstance(duration, (int, float)): + return int(duration) + return parse_duration(duration) + + +@dataclass +class SandboxCommandResult: + """Result of a command executed in a sandbox with [`Sandbox.run`].""" + + exit_code: int | None + stdout: str + stderr: str + signal: int | None = None + timed_out: bool = False + duration_ms: int = 0 + + @property + def ok(self) -> bool: + return self.exit_code == 0 + + def __repr__(self) -> str: + out = self.stdout if len(self.stdout) <= 80 else self.stdout[:77] + "..." + return f"SandboxCommandResult(exit_code={self.exit_code}, stdout={out!r}, duration_ms={self.duration_ms})" + + +@dataclass +class SandboxProcess: + """A background process started in a sandbox with [`Sandbox.run`]`(..., background=True)`. + + List a sandbox's processes with [`Sandbox.processes`] and stop one with [`SandboxProcess.kill`]. + Completed processes stay in the listing until the sandbox is deleted, so `running` and + `exit_code` tell whether a process is still alive or already exited (as of when it was listed). + """ + + pid: int + cmd: str | List[str] + # Back-reference to the sandbox, used by `kill()`. Excluded from repr/eq so a process + # stays a plain data object (and two with the same pid compare equal). + _sandbox: "Sandbox" = field(repr=False, compare=False) + tag: str | None = None + started_at_ms: int | None = None + running: bool = True + exit_code: int | None = None + + def kill(self) -> None: + """Terminate the background process (idempotent server-side).""" + self._sandbox._request("DELETE", f"/processes/{self.pid}") + + +@dataclass +class FileEntry: + """A file or directory inside a sandbox.""" + + name: str + path: str + type: Literal["file", "dir", "symlink"] + size: int + mtime_ms: int | None = None + mode: str = "" + + +class SandboxFiles: + """Filesystem operations inside a sandbox, available as [`Sandbox.files`]. + + In shared (pool) mode, paths are rooted at the sandbox's private home — the + only place its code can write — so a leading `/` is taken relative to that + home. In dedicated mode, paths are absolute on the container filesystem. + """ + + # Above this size, transfers are split into ranged requests over parallel + # connections: a single TCP stream through the jobs proxy is limited by the + # bandwidth-delay product (~2 MiB/s at ~100ms RTT); parallel streams scale it. + PARALLEL_THRESHOLD = 2 * 1024 * 1024 + PARALLEL_CHUNK_SIZE = 1 * 1024 * 1024 + PARALLEL_MAX_WORKERS = 16 + + def __init__(self, sandbox: "Sandbox") -> None: + self._sandbox = sandbox + + def read(self, path: str) -> bytes: + """Read a file from the sandbox and return its content as bytes.""" + size = self.stat(path).size + if size > self.PARALLEL_THRESHOLD: + return b"".join(self._read_ranges(path, size)) + response = self._sandbox._request("GET", "/files/read", params={"path": path}) + return response.content + + def read_text(self, path: str, encoding: str = "utf-8") -> str: + """Read a file from the sandbox and return its content as a string.""" + return self.read(path).decode(encoding) + + def write(self, path: str, data: str | bytes | BinaryIO, mode: str | None = None) -> None: + """Write content to a file in the sandbox (parent directories are created).""" + if isinstance(data, str): + data = data.encode() + elif not isinstance(data, bytes): + data = data.read() # binary file object + if len(data) > self.PARALLEL_THRESHOLD: + self._write_ranges(path, data, mode) + return + params = {"path": path} + if mode is not None: + params["mode"] = mode + self._sandbox._request("PUT", "/files/write", params=params, content=data) + + def upload(self, local_path: str | Path, path: str, mode: str | None = None) -> None: + """Upload a local file to the sandbox.""" + size = Path(local_path).stat().st_size + if size > self.PARALLEL_THRESHOLD: + self._write_ranges(path, Path(local_path).read_bytes(), mode) + return + with open(local_path, "rb") as f: + self.write(path, f, mode=mode) + + def download(self, path: str, local_path: str | Path) -> None: + """Download a file from the sandbox.""" + size = self.stat(path).size + if size > self.PARALLEL_THRESHOLD: + with open(local_path, "wb") as f: + for part in self._read_ranges(path, size): + f.write(part) + return + with self._sandbox._stream("GET", "/files/read", params={"path": path}) as response: + with open(local_path, "wb") as f: + for chunk in response.iter_bytes(chunk_size=1024 * 1024): + f.write(chunk) + + def _ranges(self, size: int) -> List[tuple[int, int]]: + chunk = self.PARALLEL_CHUNK_SIZE + return [(offset, min(chunk, size - offset)) for offset in range(0, size, chunk)] + + def _parallel(self, items: List[Any], fn: Callable[[Any], Any]) -> List[Any]: + """Run `fn(item)` over items concurrently. + + All workers share the sandbox's `httpx.Client`, which is thread-safe and pools + connections, so parallel transfers fan out over several streams at once. + """ + workers = min(self.PARALLEL_MAX_WORKERS, len(items)) + with ThreadPoolExecutor(workers) as executor: + return list(executor.map(fn, items)) + + def _read_ranges(self, path: str, size: int) -> List[bytes]: + def fetch(rng: tuple[int, int]) -> bytes: + offset, length = rng + response = self._sandbox._request( + "GET", "/files/read", params={"path": path, "offset": offset, "length": length} + ) + return response.content + + return self._parallel(self._ranges(size), fetch) + + def _write_ranges(self, path: str, data: bytes, mode: str | None) -> None: + def push(rng: tuple[int, int]) -> None: + offset, length = rng + params: dict[str, Any] = {"path": path, "offset": offset} + if mode is not None: + params["mode"] = mode + self._sandbox._request("PUT", "/files/write", params=params, content=data[offset : offset + length]) + + self._parallel(self._ranges(len(data)), push) + + def list(self, path: str) -> List[FileEntry]: + """List a directory in the sandbox.""" + response = self._sandbox._request("GET", "/files/list", params={"path": path}) + return [FileEntry(**entry) for entry in response.json()["entries"]] + + def stat(self, path: str) -> FileEntry: + """Get metadata of a file or directory in the sandbox.""" + response = self._sandbox._request("GET", "/files/stat", params={"path": path}) + return FileEntry(**response.json()) + + def exists(self, path: str) -> bool: + """Check whether a path exists in the sandbox.""" + try: + self.stat(path) + return True + except SandboxError as e: + if e.status_code == 404: + return False + raise # network/auth/server errors must not be silently reported as "missing" + + def delete(self, path: str, recursive: bool = False) -> None: + """Delete a file or directory in the sandbox.""" + params = {"path": path} + if recursive: + params["recursive"] = "1" + self._sandbox._request("DELETE", "/files/delete", params=params) + + def mkdir(self, path: str) -> None: + """Create a directory (and parents) in the sandbox.""" + self._sandbox._request("POST", "/files/mkdir", params={"path": path}) + + +def _exec_payload(cmd: str | List[str], shell: bool | None) -> dict[str, Any]: + """Build the `cmd`/`shell` part of an `/exec` payload, validating their consistency.""" + if shell is True and not isinstance(cmd, str): + raise ValueError("shell=True requires `cmd` to be a shell command string, not a list.") + if shell is False and isinstance(cmd, str): + raise ValueError("shell=False requires `cmd` to be an argv list (e.g. ['echo', 'hi']), not a string.") + payload: dict[str, Any] = {"cmd": cmd} + if shell is not None: + payload["shell"] = shell + return payload + + +def _iter_events(response: httpx.Response) -> Iterator[dict]: + """Iterate NDJSON events from a streaming response, skipping keepalive pings.""" + for line in response.iter_lines(): + if not line: + continue + event = json.loads(line) + if event.get("event") != "ping": + yield event + + +def _raise_for_status(response: httpx.Response) -> None: + """Read the error body and raise a SandboxError (works for streaming responses too).""" + response.read() # no-op for buffered responses, reads the body for streaming ones + try: + message = response.json()["error"] + except Exception: + message = response.text[:500] + raise SandboxError(f"Sandbox API error ({response.status_code}): {message}", status_code=response.status_code) + + +class _SandboxServer: + """HTTP transport to one `sbx-server` instance — a dedicated job or a shared host. + + Owns the `httpx.Client`, the base URL and the auth headers. + In dedicated mode a server is paired 1:1 with its [`Sandbox` + In pool mode one server (one host job) is shared by many sandboxes, and `live`/`capacity` track packing. + """ + + def __init__( + self, + *, + job_id: str, + owner: str, + image: str | None, + base_url: str, + nonce: str, + sandbox_token: str, + api: HfApi, + max_connections: int = 10, + capacity: int = 0, + ) -> None: + self.job_id = job_id + self.owner = owner + self._image = image + self.base_url = base_url + # Public nonce the sandbox token is derived from; kept so a host can be persisted + # to (and rebuilt from) the pool cache without re-reading the job labels. + self.nonce = nonce + self._api = api + self._auth_token = _effective_token(api) + self._sandbox_token = sandbox_token + # Packing bookkeeping (shared mode only). + self.capacity = capacity + self.live = 0 + # False only for hosts rebuilt from the (best-effort) pool cache: their job may + # be gone, so the first failed request drops them instead of failing the create. + self.verified = True + # httpx.Client is thread-safe, so a single client serves both sequential requests + # and the concurrent workers used for parallel file transfers / many sandboxes. + self._client = httpx.Client( + headers={ + "Authorization": f"Bearer {self._auth_token}", + "X-Sandbox-Token": sandbox_token, + }, + limits=httpx.Limits(max_connections=max_connections, max_keepalive_connections=max_connections), + follow_redirects=True, + ) + + @classmethod + def from_job( + cls, + *, + job: JobInfo, + nonce: str, + sandbox_token: str, + api: HfApi, + max_connections: int = 10, + capacity: int = 0, + ) -> "_SandboxServer": + """Build a server from a freshly fetched job (reads its exposed server URL).""" + return cls( + job_id=job.id, + owner=job.owner.name, + image=job.docker_image or job.space_id, + base_url=_find_server_url(job), + nonce=nonce, + sandbox_token=sandbox_token, + api=api, + max_connections=max_connections, + capacity=capacity, + ) + + @property + def image(self) -> str | None: + return self._image + + def request(self, method: str, path: str, **kwargs) -> httpx.Response: + """Request to the in-job server. Raises SandboxError on API errors.""" + timeout = kwargs.pop("timeout", httpx.Timeout(60.0, connect=10.0)) + response = self._client.request(method, self.base_url + path, timeout=timeout, **kwargs) + if response.status_code >= 400: + _raise_for_status(response) + return response + + @contextmanager + def stream(self, method: str, path: str, **kwargs) -> Iterator[httpx.Response]: + """Streaming request to the in-job server. Raises SandboxError on API errors.""" + timeout = kwargs.pop("timeout", httpx.Timeout(70.0, connect=10.0)) # server pings every 15s + with self._client.stream(method, self.base_url + path, timeout=timeout, **kwargs) as response: + if response.status_code >= 400: + _raise_for_status(response) + yield response + + def close(self) -> None: + self._client.close() + + def cancel_job(self) -> None: + self._api.cancel_job(job_id=self.job_id, namespace=self.owner) + + def wait_ready(self, start_timeout: float) -> None: + """Poll /health until the server answers; fail fast (with logs) if the job dies.""" + deadline = time.time() + start_timeout + last_job_check = 0.0 + while time.time() < deadline: + try: + response = self._client.get(self.base_url + "/health", timeout=httpx.Timeout(5.0)) + if response.status_code == 200: + return + except httpx.RequestError: + pass + if time.time() - last_job_check > 2.0: + last_job_check = time.time() + job = self._api.inspect_job(job_id=self.job_id, namespace=self.owner) + if job.status.stage in _TERMINAL_STAGES: + logs = _tail_job_logs(self._api, self.job_id, namespace=self.owner) + raise SandboxError( + f"Sandbox job {self.job_id} terminated during startup " + f"(status: {job.status.stage}, message: {job.status.message}).{logs}" + ) + time.sleep(0.15) + raise SandboxError(f"Sandbox job {self.job_id} did not become ready within {start_timeout:.0f}s.") + + +class _KillMethod: + """Lets `kill` work both as a classmethod and an instance method.""" + + @overload + def __get__(self, instance: None, owner: type) -> Callable[..., None]: ... + @overload + def __get__(self, instance: "Sandbox", owner: type) -> Callable[[], None]: ... + def __get__(self, instance: "Sandbox | None", owner: type) -> Callable[..., None]: + if instance is not None: + return instance._kill + + def kill(sandbox_id: str, *, namespace: str | None = None, token: str | None = None) -> None: + owner.connect(sandbox_id, namespace=namespace, token=token).kill() # type: ignore[attr-defined] + + return kill + + +class Sandbox: + """An isolated cloud machine running on Hugging Face Jobs. + + Create a dedicated one with [`Sandbox.create`] (one job per sandbox), or get many cheap shared ones from a [`SandboxPool`]. + Reattach to a running sandbox from anywhere with [`Sandbox.connect`]. Use as a context manager to terminate it on exit: + + ```python + >>> from huggingface_hub import Sandbox + >>> with Sandbox.create(image="python:3.12") as sbx: + ... print(sbx.run("python --version").stdout) + ``` + """ + + def __init__( + self, + *, + id: str, + server: _SandboxServer, + local_id: str | None, + owns_sandbox: bool, + owns_server: bool, + ) -> None: + self.id = id + self._server = server + # None in dedicated mode; the host-local sandbox id in shared mode. + self._local_id = local_id + # Path prefix for all in-server operations: dedicated routes live under + # /v1/*, shared ones under /v1/sandboxes//*. + self._base_path = "/v1" if local_id is None else f"/v1/sandboxes/{local_id}" + # Whether exiting a `with` block terminates the sandbox (True for sandboxes + # we created, False for ones reattached via connect()). + self._owns_sandbox = owns_sandbox + # Whether closing/killing this sandbox also closes the HTTP client. False + # for pool sandboxes, whose client (the host) is owned by the pool. + self._owns_server = owns_server + # Set by SandboxPool to free a packing slot when a shared sandbox is killed. + self._on_kill: Callable[["Sandbox"], None] | None = None + self._killed = False + self.files = SandboxFiles(self) + + # ------------------------------------------------------------------ lifecycle + + @classmethod + def create( + cls, + image: str = DEFAULT_IMAGE, + *, + flavor: str = "cpu-basic", + idle_timeout: int | float | str | None = DEFAULT_IDLE_TIMEOUT, + env: dict[str, Any] | None = None, + secrets: dict[str, Any] | None = None, + volumes: List[Volume] | None = None, + namespace: str | None = None, + forward_hf_token: bool = False, + start_timeout: float = 120.0, + token: str | None = None, + ) -> "Sandbox": + """Create a dedicated sandbox (one HF Job) and block until it is ready (~7s on cpu-basic). + + Each sandbox is a full isolated VM, so this is the right choice for GPU + workloads or untrusted code. To fan out many cheap CPU sandboxes instead, use + [`SandboxPool`]. + + The job runs with a fixed 24h maximum lifetime; `idle_timeout` is the real + keeper — an idle sandbox shuts itself down well before that. + + Args: + image (`str`, *optional*, defaults to `"python:3.12"`): + Any Docker image with `/bin/sh` (Docker Hub or `hf.co/spaces/...`). + flavor (`str`, *optional*, defaults to `"cpu-basic"`): + Hardware flavor, e.g. `"cpu-basic"`, `"a10g-small"`. See `hf jobs hardware`. + idle_timeout (`int` or `float` or `str`, *optional*, defaults to `600`): + Auto-shutdown after this much inactivity (no API calls, no running + processes). Defaults to 10 minutes; pass `None` to disable. + env (`dict[str, Any]`, *optional*): + Environment variables available in the sandbox. + secrets (`dict[str, Any]`, *optional*): + Secret environment variables (encrypted server-side). + volumes (`List[Volume]`, *optional*): + HF repos/buckets to mount, see [`Volume`]. + namespace (`str`, *optional*): + User or org namespace to run under (defaults to current user). + forward_hf_token (`bool`, *optional*, defaults to `False`): + If True, your HF token is injected as `HF_TOKEN` (opt-in). + start_timeout (`float`, *optional*, defaults to `120.0`): + Max seconds to wait for the sandbox to become ready. + token (`str`, *optional*): + HF token override. + + The image only needs `/bin/sh`. The sandbox server is downloaded at startup with + `wget`/`curl` if available, otherwise read off an always-mounted server bucket (which + adds ~2-3s to cold start, so shipping `wget`/`curl` keeps it fast). + """ + api = HfApi(token=token) + hf_token = _effective_token(api) + nonce = token_hex(16) + sandbox_token = _derive_sandbox_token(hf_token, nonce) + + command, job_env, job_secrets, job_volumes = _bootstrap_job_spec( + api, + hf_token, + env=env, + secrets=secrets, + volumes=volumes, + idle_timeout=idle_timeout, + forward_hf_token=forward_hf_token, + sandbox_token=sandbox_token, + ) + + job = api.run_job( + image=image, + command=command, + env=job_env, + secrets=job_secrets, + flavor=flavor, + timeout=SANDBOX_MAX_LIFETIME, + labels={SANDBOX_LABEL: "1", MODE_LABEL: MODE_DEDICATED, NONCE_LABEL: nonce}, + volumes=job_volumes or None, + expose=[SANDBOX_SERVER_PORT], + namespace=namespace, + ) + server: "_SandboxServer | None" = None + try: + server = _SandboxServer.from_job( + job=job, + nonce=nonce, + sandbox_token=sandbox_token, + api=api, + max_connections=SandboxFiles.PARALLEL_MAX_WORKERS + 2, + ) + server.wait_ready(start_timeout) + except Exception: + # run_job already started a billable job; cancel it before re-raising so it + # doesn't linger as an orphan (e.g. if the server port isn't exposed or startup fails). + try: + api.cancel_job(job_id=job.id, namespace=job.owner.name) + except Exception as e: + logger.warning(f"Failed to cancel sandbox job {job.id} after startup failure: {e}") + if server is not None: + server.close() + raise + return cls(id=job.id, server=server, local_id=None, owns_sandbox=True, owns_server=True) + + @classmethod + def connect(cls, sandbox_id: str, *, namespace: str | None = None, token: str | None = None) -> "Sandbox": + """Reattach to a running sandbox from anywhere, using only its id.""" + api = HfApi(token=token) + sandbox_id, namespace = _split_sandbox_id(sandbox_id, namespace) + if SHARED_ID_SEP in sandbox_id: + host_job_id, local_id = sandbox_id.split(SHARED_ID_SEP, 1) + server = _connect_host(api, host_job_id, namespace=namespace) + try: + existing = {item["id"] for item in server.request("GET", "/v1/sandboxes").json()} + if local_id not in existing: + raise SandboxError(f"Sandbox {sandbox_id} no longer exists on host {host_job_id}.") + except Exception: + server.close() # don't leak the HTTP client when the host is gone/unreachable + raise + return cls(id=sandbox_id, server=server, local_id=local_id, owns_sandbox=False, owns_server=True) + + job = api.inspect_job(job_id=sandbox_id, namespace=namespace) + labels = job.labels or {} + nonce = labels.get(NONCE_LABEL) + if labels.get(SANDBOX_LABEL) != "1" or nonce is None: + raise SandboxError(f"Job {sandbox_id} is not a sandbox (missing '{SANDBOX_LABEL}' label).") + if labels.get(MODE_LABEL) == MODE_POOL: + raise SandboxError( + f"Job {sandbox_id} is a sandbox host, not a single sandbox. Connect to one of its " + f"sandboxes with id '{SHARED_ID_SEP}'." + ) + if job.status.stage != "RUNNING": + raise SandboxError(f"Sandbox {sandbox_id} is not running (status: {job.status.stage}).") + sandbox_token = _derive_sandbox_token(_effective_token(api), nonce) + server = _SandboxServer.from_job( + job=job, + nonce=nonce, + sandbox_token=sandbox_token, + api=api, + max_connections=SandboxFiles.PARALLEL_MAX_WORKERS + 2, + ) + return cls(id=job.id, server=server, local_id=None, owns_sandbox=False, owns_server=True) + + # `kill` is both a classmethod (`Sandbox.kill(id)`) and an instance method (`sbx.kill()`), + # dispatched by the `_KillMethod` descriptor; `_kill` holds the instance behaviour. + kill = _KillMethod() + + def _kill(self) -> None: + """Terminate the sandbox. Idempotent. + + Dedicated sandboxes cancel their underlying job; shared sandboxes are + removed from their host (freeing a slot) while the host keeps running. + """ + if self._killed: + return + try: + if self._local_id is None: + self._server.cancel_job() + else: + self._server.request("DELETE", f"/v1/sandboxes/{self._local_id}") + except Exception as e: + # Don't mark as killed: a later kill() call should retry so nothing leaks. + logger.warning(f"Failed to kill sandbox {self.id}: {e}") + return + self._killed = True + if self._on_kill is not None: + self._on_kill(self) + if self._owns_server: + self._server.close() + + def close(self) -> None: + """Release the local HTTP client without terminating the sandbox. Idempotent. + + No-op for pool sandboxes (the client belongs to the pool's host). + """ + if self._owns_server: + self._server.close() + + def __enter__(self) -> "Sandbox": + return self + + def __exit__(self, *exc_info) -> None: + if self._owns_sandbox: + self.kill() + else: + self.close() + + # ------------------------------------------------------------------ exec + + @overload + def run( + self, + cmd: str | List[str], + *, + shell: bool | None = ..., + env: dict[str, Any] | None = ..., + cwd: str | None = ..., + timeout: float | None = ..., + stdin: str | None = ..., + on_stdout: Callable[[str], None] | None = ..., + on_stderr: Callable[[str], None] | None = ..., + check: bool = ..., + background: Literal[False] = ..., + ) -> SandboxCommandResult: ... + + @overload + def run( + self, + cmd: str | List[str], + *, + shell: bool | None = ..., + env: dict[str, Any] | None = ..., + cwd: str | None = ..., + background: Literal[True], + ) -> SandboxProcess: ... + + def run( + self, + cmd: str | List[str], + *, + shell: bool | None = None, + env: dict[str, Any] | None = None, + cwd: str | None = None, + timeout: float | None = None, + stdin: str | None = None, + on_stdout: Callable[[str], None] | None = None, + on_stderr: Callable[[str], None] | None = None, + check: bool = True, + background: bool = False, + ) -> SandboxCommandResult | SandboxProcess: + """Run a command in the sandbox and wait for it, streaming output live. + + With `background=True` the command is started detached and `run` returns a + [`SandboxProcess`] immediately, without waiting for it to finish — handy for + servers and other long-running processes. List them later with [`Sandbox.processes`] + and stop one with [`SandboxProcess.kill`]. The streaming/wait-only options + (`timeout`, `stdin`, `on_stdout`, `on_stderr`, `check`) don't apply in that mode. + + Args: + cmd (`str` or `List[str]`): + A shell command string (run with `/bin/sh -c`) or an argv list (exec'd directly). + shell (`bool`, *optional*): + Force the execution mode instead of inferring it from the type of `cmd`. + `True` runs through `/bin/sh -c` and requires `cmd` to be a string; `False` + exec's `cmd` directly and requires it to be an argv list. `None` (default) + infers from the type. Set it explicitly to avoid the type-driven footgun (e.g. + `["echo hi"]` being exec'd as a single program named `"echo hi"`). + env (`dict[str, Any]`, *optional*): + Extra environment variables for this command. + cwd (`str`, *optional*): + Working directory. + timeout (`float`, *optional*): + Kill the command (whole process group) after this many seconds. + stdin (`str`, *optional*): + Data to write to the command's stdin. + on_stdout (`Callable[[str], None]`, *optional*): + Callback invoked with stdout chunks as they arrive. + on_stderr (`Callable[[str], None]`, *optional*): + Callback invoked with stderr chunks as they arrive. + check (`bool`, *optional*, defaults to `True`): + If True, raise [`SandboxCommandError`] on non-zero exit. + background (`bool`, *optional*, defaults to `False`): + If True, start the command detached and return a [`SandboxProcess`] right + away instead of waiting for it and returning a [`SandboxCommandResult`]. + + Returns: a [`SandboxCommandResult`] (with `exit_code`, `stdout`, `stderr`, + `duration_ms`), or a [`SandboxProcess`] when `background=True`. + """ + payload = _exec_payload(cmd, shell) + if env: + payload["env"] = env + if cwd: + payload["cwd"] = cwd + if background: + data = self._request("POST", "/processes", json=payload).json() + return SandboxProcess(pid=data["pid"], cmd=cmd, tag=data.get("tag"), _sandbox=self) + if timeout is not None: + payload["timeout"] = timeout + if stdin is not None: + payload["stdin"] = stdin + + stdout_parts: list[str] = [] + stderr_parts: list[str] = [] + result: SandboxCommandResult | None = None + with self._stream("POST", "/exec", json=payload) as response: + for event in _iter_events(response): + if event["event"] == "stdout": + stdout_parts.append(event["data"]) + if on_stdout is not None: + on_stdout(event["data"]) + elif event["event"] == "stderr": + stderr_parts.append(event["data"]) + if on_stderr is not None: + on_stderr(event["data"]) + elif event["event"] == "exit": + result = SandboxCommandResult( + exit_code=event["exit_code"], + stdout="".join(stdout_parts), + stderr="".join(stderr_parts), + signal=event.get("signal"), + timed_out=event.get("timed_out", False), + duration_ms=event.get("duration_ms", 0), + ) + if result is None: + raise SandboxError("connection lost while running command") + if check and (result.exit_code != 0 or result.timed_out): + raise SandboxCommandError(cmd=cmd, result=result) + return result + + def processes(self) -> List[SandboxProcess]: + """List the background processes of this sandbox. + + Returns the processes started with [`Sandbox.run`]`(..., background=True)`; stop one + with [`SandboxProcess.kill`]. Completed processes stay listed (with `running=False` and + their `exit_code`) until the sandbox is deleted. + """ + data = self._request("GET", "/processes").json() + return [ + SandboxProcess( + pid=p["pid"], + cmd=p["cmd"], + tag=p.get("tag"), + started_at_ms=p.get("started_at_ms"), + running=p["running"], + exit_code=p.get("exit_code"), + _sandbox=self, + ) + for p in data + ] + + # ------------------------------------------------------------------ misc + + @property + def image(self) -> str | None: + return self._server.image + + @property + def host_id(self) -> str | None: + """For a shared/pool sandbox, the job id of the host running it (else None).""" + return self._server.job_id if self._local_id is not None else None + + # ------------------------------------------------------------------ port proxy + + def proxy_url_for(self, port: int | str, path: str = "/", *, scheme: str = "https://") -> str: + """Public URL that proxies through to a server running *inside* this sandbox. + + Requests to the returned URL are forwarded by the in-job sandbox server to a + server you started in the sandbox on `port`, including WebSocket (`ws(s)://`) + upgrades and streamed responses. Pair it with [`proxy_headers`] for auth. + + How the sandbox must listen on `port`: + + - **Pool / shared sandbox**: it cannot bind a TCP port (Landlock), so bind a + **unix socket** at `$SBX_PROXY_DIR/.sock` (the `SBX_PROXY_DIR` env var + is set in every sandbox). E.g. `uvicorn app:app --uds $SBX_PROXY_DIR/8000.sock`. + - **Dedicated sandbox**: bind a normal TCP port on `127.0.0.1:`. (You can + also expose the port directly via the job proxy without going through here.) + + Args: + port (`int` or `str`): + The port (pool: the `` of the unix socket) the inner server listens on. + path (`str`, *optional*, defaults to `"/"`): + Path on the inner server to point at, e.g. `"/ws"`. + scheme (`str`, *optional*, defaults to `"https://"`): + URL scheme to build the link with. Defaults to `"https://"`; pass + `"wss://"` for a WebSocket client (the proxy is protocol-agnostic, so only + the client-side scheme changes). + + Returns: + `str`: a URL like `https://--49983.hf.jobs/v1/.../proxy/8000/ws` (or + `wss://...` with `scheme="wss://"`). + + Example: + ```python + >>> url = sandbox.proxy_url_for(8000, "/ws", scheme="wss://") + >>> import websockets + >>> async with websockets.connect(url, additional_headers=sandbox.proxy_headers) as ws: + ... await ws.send("hello") + ``` + """ + # base_url is always https://...; swap in the requested scheme (e.g. wss://) for the client. + host_and_rest = self._server.base_url.split("://", 1)[-1] + path = path if path.startswith("/") else "/" + path + return f"{scheme}{host_and_rest}{self._base_path}/proxy/{port}{path}" + + @property + def proxy_headers(self) -> dict[str, str]: + """Auth headers to send with [`proxy_url_for`] requests (HF token + sandbox token).""" + return { + "Authorization": f"Bearer {self._server._auth_token}", + "X-Sandbox-Token": self._server._sandbox_token, + } + + def __repr__(self) -> str: + return f"Sandbox(id={self.id!r}, image={self.image!r})" + + # ------------------------------------------------------------------ internals + + def _request(self, method: str, resource: str, **kwargs) -> httpx.Response: + return self._server.request(method, self._base_path + resource, **kwargs) + + @contextmanager + def _stream(self, method: str, resource: str, **kwargs) -> Iterator[httpx.Response]: + with self._server.stream(method, self._base_path + resource, **kwargs) as response: + yield response + + +class SandboxPool: + """A fleet of shared "host" jobs, each packing many landlock-isolated sandboxes. + + One host is one billed HF Job (a VM); it runs the sandbox server and multiplexes + up to `sandboxes_per_host` lightweight sandboxes, isolated from each other by + uid + the Landlock LSM. This makes large fan-outs cheap (the VM cost is shared + across all its sandboxes) and fast (creating a sandbox is ~one proxy round-trip + once a host is warm). Best for many parallel CPU sandboxes such as RL rollouts; + for GPU or strong VM-level isolation between mutually-distrusting workloads, use + [`Sandbox.create`] instead. + + The constructor pre-provisions `warm_up` hosts (default 1) and blocks until they are + ready; further hosts are then provisioned on demand as sandboxes are requested, and all + are torn down on `close()` (or when idle, via `idle_timeout`). The user never manages jobs: + + ```python + >>> from huggingface_hub import SandboxPool + >>> with SandboxPool(image="python:3.12", flavor="cpu-basic", warm_up=2) as pool: + ... boxes = [pool.create() for _ in range(100)] # packed across the warm hosts + ... print(boxes[0].run("echo hi").stdout) + hi + ``` + + `create()` makes **one** sandbox at a time: it reuses a host that still has free + capacity before booting a new one, so you grow on demand as work arrives. To avoid + a cold start on the first few calls, pre-provision hosts with `warm_up` (or + [`warm`]). Warm hosts are discovered via job labels, so reuse works **across + processes** too (a fresh pool with the same `image`/`flavor`/`name` attaches to + hosts an earlier run left behind): + + ```python + >>> pool = SandboxPool(image="python:3.12") + >>> sbx = pool.create() # finds a warm host (here or in another process), else boots one + ``` + """ + + def __init__( + self, + image: str = DEFAULT_IMAGE, + *, + flavor: str = "cpu-basic", + sandboxes_per_host: int = DEFAULT_SANDBOXES_PER_HOST, + warm_up: int = 1, + max_hosts: int | None = None, + name: str | None = None, + idle_timeout: int | float | str | None = DEFAULT_IDLE_TIMEOUT, + namespace: str | None = None, + start_timeout: float = 120.0, + token: str | None = None, + _connect_mode: bool = False, + ) -> None: + """Configure a pool and pre-provision `warm_up` hosts (blocks until they are ready). + + Env/secrets are *not* set here: they belong to each sandbox and are passed to + `create(env=...)`, so sandboxes in the same pool can have different environments. + + Args: + image (`str`, *optional*, defaults to `"python:3.12"`): + Docker image for the hosts (needs `/bin/sh`). All sandboxes in the + pool share this image. + flavor (`str`, *optional*, defaults to `"cpu-basic"`): + Hardware flavor for the host jobs (e.g. `"cpu-basic"`). + sandboxes_per_host (`int`, *optional*, defaults to `50`): + How many sandboxes to pack per host (per VM density). + warm_up (`int`, *optional*, defaults to `1`): + How many hosts to pre-provision in the constructor (which blocks + until they are ready), so an initial burst of `create()` calls doesn't pay + a host cold start each. Existing warm hosts (from the cache / other processes) + count towards it, so only the shortfall is booted; capped by `max_hosts`. + Defaults to 1 (a single host). + max_hosts (`int`, *optional*): + Optional cap on the number of host jobs (a cost ceiling). When + reached and all hosts are full, `create()` raises. + name (`str`, *optional*): + Pool name, used as the `hf-sandbox-pool` job label so the pool is + discoverable (e.g. `hf sandbox pool ls`, `connect()`). `create()` reuses + running hosts carrying this label (including from other processes) before + booting new ones, so distinct names keep separate pools from sharing hosts. + A random name is generated when omitted. + idle_timeout (`int` or `float` or `str`, *optional*, defaults to `600`): + Host idle timeout — a host shuts down once it has had no + sandboxes for this long (a billing backstop). Each sandbox also has its + own idle timeout, set at `create()`. Pass `None` to disable. + namespace (`str`, *optional*): + User or org namespace to run hosts under. + start_timeout (`float`, *optional*, defaults to `120.0`): + Max seconds to wait for a host to become ready. + token (`str`, *optional*): + HF token override. + """ + if sandboxes_per_host < 1: + raise ValueError("sandboxes_per_host must be >= 1.") + if warm_up < 1: + raise ValueError("warm_up must be >= 1.") + self._api = HfApi(token=token) + self.image = image + self.flavor = flavor + self.sandboxes_per_host = sandboxes_per_host + self._warm_up = warm_up + self.max_hosts = max_hosts + self.name = name if name is not None else f"pool-{token_hex(6)}" + self._idle_timeout = idle_timeout + self._namespace = namespace + self._start_timeout = start_timeout + self._hosts: List[_SandboxServer] = [] + self._lock = threading.Lock() + # Held across the whole one-time warm-up so concurrent first create() calls block until + # it finishes (and see the warm hosts) instead of racing past a half-set flag. + self._warmup_lock = threading.Lock() + # Serializes on-demand host creation within the process: a burst of create() calls that + # all find every host full boots one host at a time (each new host frees + # `sandboxes_per_host` slots for the threads still queued behind the lock) instead of + # one host per thread. The CLI is a single process per command, so this is a no-op there. + self._boot_lock = threading.Lock() + self._closed = False + # Whether the one-time warm-up (seed cache + pre-provision `warm_up` hosts) ran. + self._warmed_up = False + # Set for connect()'d handles: the pool must already exist, so create() refuses to + # silently resurrect it by booting a fresh host if discovery confirms every host is gone. + # Such a handle also never boots during construction — it attaches lazily on create(). + self._require_live_host = _connect_mode + # Whether close()/`__exit__` cancels the host jobs. True for a pool we created; False + # for a connect()'d handle, which only releases its HTTP clients on exit — the shared + # hosts (possibly serving other clients) are left running, like Sandbox.connect(). + self._owns_hosts = not _connect_mode + # Job ids of cached hosts we found dead this session; pruned from the cache on save. + self._dead_host_ids: set[str] = set() + + # Pre-provision `warm_up` hosts now so the constructor returns only once the pool is + # warm. A connect()'d handle skips this: it must never boot during construction (it can + # only attach to existing hosts, lazily on the first create()). + if not _connect_mode: + self._ensure_warmed_up() + + # ------------------------------------------------------------------ public API + + @classmethod + def connect(cls, pool_id: str, *, namespace: str | None = None, token: str | None = None) -> "SandboxPool": + """Reattach to a running pool by id, from any machine — no local state needed. + + Finds a running host labelled with `pool_id` and rebuilds the pool's config + (image/flavor/density/host-idle) from that host job's spec and env vars, returning + a [`SandboxPool`] ready to `create()` more sandboxes — packing onto the running + hosts, or booting a duplicate (same config) when they are full. + + Raises [`SandboxError`] if no running host is found (a pool stops existing once + all of its hosts are gone — idle-timed-out or killed). + + Args: + pool_id (`str`): + The id returned when the pool was first created. + namespace (`str`, *optional*): + Namespace to search for the pool's hosts (defaults to yours). + token (`str`, *optional*): + HF token override. + """ + # Fast path: rebuild the pool from the local best-effort cache, with no HTTP at all. + # The cached hosts are seeded (and verified) lazily on the next create(); if they are + # all stale, create() falls back to label discovery exactly like a cold connect would. + cache = read_pool_cache(pool_id) + if cache is not None: + return cls( + image=cache.image, + flavor=cache.flavor, + sandboxes_per_host=cache.sandboxes_per_host, + max_hosts=cache.max_hosts, + name=pool_id, + idle_timeout=cache.idle_timeout, + namespace=cache.namespace if namespace is None else namespace, + token=token, + _connect_mode=True, # attach to existing hosts; never boot during construction + ) + + # Cold path: find a running host via labels and rebuild the config from its job spec. + api = HfApi(token=token) + job = _find_pool_host_job(api, pool_id, namespace=namespace) + env = _host_env(api, job, namespace=namespace) + idle_raw = env.get("SBX_IDLE_TIMEOUT") + max_hosts_raw = env.get("SBX_MAX_HOSTS") + return cls( + image=job.docker_image or job.space_id or DEFAULT_IMAGE, + flavor=str(job.flavor) if job.flavor is not None else "cpu-basic", + sandboxes_per_host=int(env.get("SBX_CAPACITY", DEFAULT_SANDBOXES_PER_HOST)), + max_hosts=int(max_hosts_raw) if max_hosts_raw is not None else None, + name=pool_id, + idle_timeout=int(idle_raw) if idle_raw is not None else None, + namespace=namespace, + token=token, + _connect_mode=True, # attach to existing hosts; never boot during construction + ) + + def warm(self, num_hosts: int = 1) -> List[str]: + """Ensure `num_hosts` empty host(s) are running and leave them running. Returns the + pool's host job ids. + + Used to "create" a pool up front: the hosts carry the pool label and config (in + their env vars), so a later `SandboxPool.connect(pool_id)` (even from another + machine) finds them and spawns sandboxes without a cold start. The hosts keep + billing until killed or idle. + + Adopts hosts already running for this pool (found via job labels) before booting, + so a `warm()` after `connect()` — or a repeated `warm()` — tops up to `num_hosts` + instead of duplicating live hosts and blowing past `max_hosts`. + """ + if self._closed: + raise SandboxError("This SandboxPool is closed.") + self._discover_hosts() + with self._lock: + shortfall = num_hosts - len(self._hosts) + if shortfall > 0: + booted = self._provision_hosts(shortfall) + with self._lock: + self._hosts.extend(booted) + with self._warmup_lock: + self._warmed_up = True # explicit warm-up satisfies create()'s one-time warm-up + self._save_cache() + return self.host_ids + + def create( + self, + *, + env: dict[str, Any] | None = None, + idle_timeout: int | float | str | None = DEFAULT_IDLE_TIMEOUT, + forward_hf_token: bool = False, + ) -> "Sandbox": + """Create one sandbox, provisioning a host if needed. + + Reuses a host with free capacity (this pool's, or a warm host found via job labels + / the local cache) before booting a new one, so a `create()` against a warm host + costs ~one round-trip. Call it repeatedly to fan out; use `warm_up` (or [`warm`]) + to pre-provision hosts and avoid a cold start on the first calls. If a host fills + up under us (another process packed it) or a cached host is gone, the sandbox is + re-placed on another host (or a fresh one). + + Args: + env (`dict[str, Any]`, *optional*): + Environment variables for this sandbox (each sandbox gets its own). + idle_timeout (`int` or `float` or `str`, *optional*, defaults to `600`): + Per-sandbox idle timeout — a sandbox is evicted from its host + after this much inactivity (no API calls, no running process). Distinct + from the host idle timeout. Pass `None` to disable. + forward_hf_token (`bool`, *optional*, defaults to `False`): + If True, inject your HF token as `HF_TOKEN` in the sandbox + (opt-in). Unlike a dedicated sandbox's `secrets`, a pooled sandbox's env is + delivered to the host server at creation (never stored in the host job), so + it doesn't appear in any job's metadata. + """ + if self._closed: + raise SandboxError("This SandboxPool is closed.") + sandbox_env = dict(env or {}) + if forward_hf_token: + sandbox_env["HF_TOKEN"] = _effective_token(self._api) + # None disables per-sandbox idle eviction (mirrors Sandbox.create): leave it out of + # the create body entirely rather than sending 0, which the server reads as "evict now". + idle_secs = _duration_to_secs(idle_timeout) if idle_timeout is not None else None + + new_hosts: List[_SandboxServer] = [] + discovered = False + rounds = 0 + try: + # One-time warm-up: seed from cache (no HTTP) and pre-provision `warm_up` hosts. + # Warm-up hosts are pool-level (like `warm()`), so they survive a failed create(). + self._ensure_warmed_up() + while True: + # 1. Reserve a slot on a host we already track. + host = self._reserve_one() + # 2. If none free, attach (once) to warm hosts discovered via labels. + if host is None and not discovered: + discovered = True + self._discover_hosts() + host = self._reserve_one() + # 3. Still none? Boot one host (unless we must not resurrect a dead pool). + if host is None: + if self._require_live_host and discovered and not self._hosts: + # connect()'d to a pool whose hosts are all gone (stale cache + nothing + # found via labels): don't resurrect it under the same id, just report it. + delete_pool_cache(self.name) + raise SandboxError( + f"No running host found for pool '{self.name}'. The pool has stopped " + "(all its hosts were killed or idle-timed-out); create a new one." + ) + host = self._boot_one_host(new_hosts) + # 4. Create the sandbox on the reserved host. `None` means the host filled up + # (another process packed it) or a stale cached host is gone — retry. + if host is not None: + try: + sandbox = self._create_one(host, sandbox_env, idle_secs) + except Exception: + # The create POST failed on a live host: release the slot we optimistically + # reserved so the host isn't left permanently one sandbox short. + with self._lock: + host.live = max(0, host.live - 1) + raise + if sandbox is not None: + self._save_cache() + return sandbox + # sandbox is None: the host is full (packed by another process) or gone. + # Either way it's no longer a host we exclusively own, so stop tracking it + # for teardown — cancelling it on a later round's failure would kill another + # tenant's sandboxes (full host) or hit an already-dead job (gone host). + if host in new_hosts: + new_hosts.remove(host) + discovered = False # re-scan for room / boot a host next round + rounds += 1 + if rounds > _MAX_PACK_ROUNDS: + raise SandboxError( + "Could not place sandbox: hosts kept reporting full. Raise max_hosts or sandboxes_per_host." + ) + except Exception: + # All-or-nothing: tear down hosts we booted in this call. + with self._lock: + self._hosts = [h for h in self._hosts if h not in new_hosts] + for host in new_hosts: + try: + host.cancel_job() + except Exception: + pass + finally: + host.close() + raise + + @property + def num_hosts(self) -> int: + """Number of host jobs currently provisioned.""" + with self._lock: + return len(self._hosts) + + @property + def num_sandboxes(self) -> int: + """Number of sandboxes currently handed out (across all hosts).""" + with self._lock: + return sum(host.live for host in self._hosts) + + @property + def host_ids(self) -> List[str]: + """Job ids of the provisioned hosts.""" + with self._lock: + return [host.job_id for host in self._hosts] + + def close(self) -> None: + """Release the pool. Idempotent. + + For a pool we created, this terminates all host jobs (and therefore all their + sandboxes). For a `connect()`'d handle it only releases the local HTTP clients: the + shared hosts may be serving other clients, so — like [`Sandbox.connect`] — leaving a + `with` block must not tear them down. Terminate a connected pool's hosts explicitly + with `hf sandbox pool delete `. + """ + with self._lock: + hosts = self._hosts + self._hosts = [] + self._closed = True + for host in hosts: + try: + if self._owns_hosts: + host.cancel_job() + except Exception as e: + logger.warning(f"Failed to cancel sandbox host {host.job_id}: {e}") + finally: + host.close() + if self._owns_hosts: + delete_pool_cache(self.name) # the pool's hosts are gone; don't leave a stale entry + + def __enter__(self) -> "SandboxPool": + return self + + def __exit__(self, *exc_info) -> None: + self.close() + + # ------------------------------------------------------------------ internals + + def _ensure_warmed_up(self) -> None: + """One-time: seed from the cache and pre-provision up to `warm_up` hosts. + + Cheap by default: seeding is local (no HTTP), and if the cache already gives at + least `warm_up` hosts we trust them and skip discovery/booting (dead ones are + pruned lazily by `create()`). Only when short do we list_jobs and boot the + shortfall in parallel, capped by `max_hosts`. + + Runs at most once per pool, under `_warmup_lock`: concurrent first `create()` calls + block here until the warm-up completes — and see its hosts — rather than racing past + a half-set flag and each booting their own. `_warmed_up` is only set once the work + succeeds, so a failed warm-up is retried (seeding/discovery dedupe by job id). + + Warm-up hosts are pool-level (like [`warm`]): they are not torn down if the + triggering `create()` later fails — `close()` (or the `with` block) reclaims them. + """ + with self._warmup_lock: + if self._warmed_up: + return + self._seed_hosts_from_cache() + target = self._warm_up if self.max_hosts is None else min(self._warm_up, self.max_hosts) + with self._lock: + shortfall = target - len(self._hosts) + if shortfall > 0: + self._discover_hosts() + # A connect()'d pool must never boot during warm-up: it may only attach to + # existing hosts. Booting is left to create()'s loop, guarded by + # `_require_live_host`, so a stopped pool is reported instead of resurrected. + if not self._require_live_host: + with self._lock: + shortfall = target - len(self._hosts) + if shortfall > 0: + booted = self._provision_hosts(shortfall) + with self._lock: + self._hosts.extend(booted) + self._warmed_up = True + # Persist the warmed hosts so the next process (e.g. `hf sandbox create --pool` after a + # bare `hf sandbox pool create`) hits the cache fast path instead of re-discovering. + if self._hosts: + self._save_cache() + + def _reserve_one(self) -> "_SandboxServer | None": + """Reserve one slot on the first host with free capacity (under lock), else None.""" + with self._lock: + for host in self._hosts: + if host.capacity - host.live > 0: + host.live += 1 + return host + return None + + def _boot_one_host(self, new_hosts: List["_SandboxServer"]) -> "_SandboxServer | None": + """Provision (or adopt) one host and reserve a slot on it. Returns None to retry. + + Held under `_boot_lock` so that, within a process, only one host is booted at a time: + a burst of create() calls that all found every host full queue here, and each new host + frees `sandboxes_per_host` slots for the threads still waiting — so they reuse it instead + of each booting their own. Before booting, we reuse a slot freed by a concurrent boot and, + failing that, adopt a host already SCHEDULING for this pool (here or in another process) + rather than piling on a duplicate. + """ + with self._boot_lock: + # A concurrent boot (this process) may have added a host with free slots while we + # waited for the lock — reuse it instead of booting another. + host = self._reserve_one() + if host is not None: + return host + # A host already coming up for this pool (ours, or another process'): wait for it + # to start and adopt it instead of booting a duplicate. + if self._adopt_pending_host(): + host = self._reserve_one() + if host is not None: + return host + booted = self._provision_hosts(1) + new_hosts.extend(booted) + with self._lock: + self._hosts.extend(booted) + return self._reserve_one() + + def _adopt_pending_host(self) -> bool: + """Wait for and adopt a host already SCHEDULING for this pool, if any. + + Avoids over-provisioning when a host is already on its way up for this pool (started by + another process, or an earlier create() in this one): rather than booting a duplicate, + wait for it to reach RUNNING and adopt it via discovery. Returns True if a pending host + was found (whether or not it eventually came up), False if none is scheduling. + """ + known = {host.job_id for host in self._hosts} + pending = next( + ( + job + for job in self._api.list_jobs( + status="SCHEDULING", + labels={MODE_LABEL: MODE_POOL, POOL_LABEL: self.name}, + namespace=self._namespace, + ) + if job.id not in known + ), + None, + ) + if pending is None: + return False + logger.debug(f"Pool '{self.name}' host {pending.id} is already SCHEDULING; waiting for it instead of booting.") + deadline = time.time() + self._start_timeout + while time.time() < deadline: + stage = self._api.inspect_job(job_id=pending.id, namespace=self._namespace).status.stage + if stage not in ("SCHEDULING", "RUNNING"): + return False # it died before starting up; let the caller boot a fresh one + if stage == "RUNNING": + # RUNNING precedes "server ready" (the host still has to fetch + exec sbx-server), + # so discovery only adopts it once its server answers — keep polling until it does. + self._discover_hosts() + if any(host.job_id == pending.id for host in self._hosts): + return True + time.sleep(1.0) + return False + + def _discover_hosts(self) -> None: + """Attach to running host jobs that match this pool (image/flavor/name). + + Lets `create()` reuse a host warmed by an earlier call or another process + instead of booting a new one. Hosts are found via job labels; each adopted + host's free capacity is read from the server, so packing stays accurate. + """ + known = {host.job_id for host in self._hosts} + matches = [ + job + for job in self._api.list_jobs( + status="RUNNING", + labels={MODE_LABEL: MODE_POOL, POOL_LABEL: self.name}, + namespace=self._namespace, + ) + if job.id not in known + ] + + for job in matches: + server = None + try: + server = _connect_host(self._api, job.id, namespace=self._namespace) + # Capacity comes from the host's SBX_CAPACITY env; otherwise an adopted host + # would silently pack at the pool default and mis-pack. + env = _host_env(self._api, job, namespace=self._namespace) + server.capacity = int(env.get("SBX_CAPACITY", self.sandboxes_per_host)) + server.live = len(server.request("GET", "/v1/sandboxes").json()) + except (SandboxError, httpx.HTTPError, HfHubHTTPError) as e: + # Host died (e.g. deleted between list_jobs and inspect_job), is still starting + # up, or is unreachable: skip it, closing the client if one was opened. + logger.debug(f"Skipping host {job.id} during discovery: {e}") + if server is not None: + server.close() + continue + with self._lock: + if any(host.job_id == job.id for host in self._hosts): + server.close() # adopted concurrently by another thread + else: + self._hosts.append(server) + + def _provision_hosts(self, num_new: int) -> List[_SandboxServer]: + """Boot `num_new` host jobs in parallel, respecting `max_hosts`.""" + with self._lock: + current = len(self._hosts) + if self.max_hosts is not None and current + num_new > self.max_hosts: + allowed = self.max_hosts - current + raise SandboxError( + f"Pool needs {num_new} more host(s) but max_hosts={self.max_hosts} " + f"allows only {max(0, allowed)} more. Raise max_hosts or kill some sandboxes." + ) + # Boot in parallel, but collect every result before re-raising: if one boot fails, + # the others may have already started billable host jobs, so cancel those instead of + # leaking them (executor.map would surface the first error and drop the rest). + with ThreadPoolExecutor(max_workers=min(num_new, 32)) as executor: + futures = [executor.submit(self._boot_host) for _ in range(num_new)] + booted: List[_SandboxServer] = [] + error: Exception | None = None + for future in futures: + try: + booted.append(future.result()) + except Exception as e: + error = e + if error is not None: + for server in booted: + try: + server.cancel_job() + except Exception: + pass + finally: + server.close() + raise error + return booted + + def _boot_host(self) -> _SandboxServer: + """Start one host job and wait until its server is ready.""" + hf_token = _effective_token(self._api) + nonce = token_hex(16) + sandbox_token = _derive_sandbox_token(hf_token, nonce) + command, job_env, job_secrets, job_volumes = _bootstrap_job_spec( + self._api, + hf_token, + env=None, # host job carries no user env; sandboxes get env per create request + secrets=None, + volumes=None, + idle_timeout=self._idle_timeout, + forward_hf_token=False, + sandbox_token=sandbox_token, + ) + # Host mode: per-sandbox idle eviction + empty-host shutdown (vs the dedicated + # whole-job watchdog). + job_env["SBX_HOST_MODE"] = "1" + # Server-authoritative packing cap: the host refuses creates past this (the client + # then packs onto / boots another host). Avoids cross-process over-commit. Read + # back (with SBX_IDLE_TIMEOUT) by `connect()` to rebuild the pool — labels stay for + # filtering only. + job_env["SBX_CAPACITY"] = str(self.sandboxes_per_host) + # Persist the optional cost ceiling on the host too, so a later connect() (e.g. the CLI + # `pool create --max-hosts N` then `create --pool ` flow) rebuilds the cap instead of + # defaulting to unlimited and provisioning past it. + if self.max_hosts is not None: + job_env["SBX_MAX_HOSTS"] = str(self.max_hosts) + labels = {SANDBOX_LABEL: "1", MODE_LABEL: MODE_POOL, POOL_LABEL: self.name, NONCE_LABEL: nonce} + job = self._api.run_job( + image=self.image, + command=command, + env=job_env, + secrets=job_secrets, + flavor=self.flavor, + timeout=SANDBOX_MAX_LIFETIME, + labels=labels, + volumes=job_volumes or None, + expose=[SANDBOX_SERVER_PORT], + namespace=self._namespace, + ) + server: "_SandboxServer | None" = None + try: + # from_job is inside the try: if it raises (e.g. the server port isn't exposed), + # the already-started host job must still be cancelled so it doesn't linger billing. + server = _SandboxServer.from_job( + job=job, + nonce=nonce, + sandbox_token=sandbox_token, + api=self._api, + max_connections=min(self.sandboxes_per_host + 8, 256), + capacity=self.sandboxes_per_host, + ) + server.wait_ready(self._start_timeout) + except Exception: + try: + self._api.cancel_job(job_id=job.id, namespace=job.owner.name) + except Exception as e: + logger.warning(f"Failed to cancel sandbox host {job.id} after startup failure: {e}") + if server is not None: + server.close() + raise + return server + + def _create_one(self, host: "_SandboxServer", env: dict[str, Any], idle_secs: int | None) -> "Sandbox | None": + """Create one sandbox on a reserved `host`. Returns the sandbox, or None to retry. + + None means either the host filled up between our reservation and the create + (server-authoritative capacity — another client packed it, so we mark it full and + place the sandbox elsewhere) or a host rebuilt from the cache is gone/unreachable + (dropped and re-placed via discovery / a fresh boot). + """ + body: dict[str, Any] = {"count": 1} + if idle_secs is not None: + body["idle_timeout_secs"] = idle_secs + if env: + body["env"] = env + try: + data = host.request("POST", "/v1/sandboxes", json=body).json() + except (SandboxError, httpx.HTTPError) as e: + if host.verified: + raise # a host we booted/discovered this session failing is a real error + logger.debug(f"Dropping unreachable cached host {host.job_id}: {e}") + self._drop_host(host) + return None + host.verified = True # it answered, so it's a real live host now + sandboxes = data.get("sandboxes") or [] + if int(data.get("rejected", 0)) or not sandboxes: + with self._lock: + host.live = host.capacity # the host is full; stop reserving it + return None + item = sandboxes[0] + sandbox = Sandbox( + id=f"{host.job_id}{SHARED_ID_SEP}{item['id']}", + server=host, + local_id=item["id"], + owns_sandbox=True, + owns_server=False, + ) + sandbox._on_kill = self._on_sandbox_killed + return sandbox + + def _on_sandbox_killed(self, sandbox: Sandbox) -> None: + """Free the packing slot of a shared sandbox that was killed.""" + with self._lock: + sandbox._server.live = max(0, sandbox._server.live - 1) + + def _drop_host(self, host: _SandboxServer) -> None: + """Forget a host found dead this session (and mark it for cache pruning).""" + with self._lock: + self._hosts = [h for h in self._hosts if h is not host] + self._dead_host_ids.add(host.job_id) + host.close() + + # ------------------------------------------------------------------ cache (best effort) + + def _seed_hosts_from_cache(self) -> None: + """Adopt the pool's cached hosts without any HTTP (rebuilt from cached URL + nonce). + + Best-effort and unverified: each adopted host is confirmed on the first successful + request (and dropped on the first failure, see `_create_one`). Hosts the cache + believes are full are skipped — label discovery re-checks them with fresh counts if + the seeded ones don't satisfy the request, so a stale-full entry never blocks a create. + """ + cache = read_pool_cache(self.name) + if cache is None: + return + hf_token = _effective_token(self._api) + with self._lock: + known = {host.job_id for host in self._hosts} + for ch in cache.hosts: + if ch.job_id in known or ch.live >= ch.capacity: + continue + server = _SandboxServer( + job_id=ch.job_id, + owner=ch.owner, + image=self.image, + base_url=ch.base_url, + nonce=ch.nonce, + sandbox_token=_derive_sandbox_token(hf_token, ch.nonce), + api=self._api, + max_connections=min(self.sandboxes_per_host + 8, 256), + capacity=ch.capacity, + ) + server.live = ch.live + server.verified = False + self._hosts.append(server) + + def _save_cache(self) -> None: + """Persist the pool config + current hosts (with their live counts) for next time.""" + with self._lock: + hosts = [ + CachedHost( + job_id=host.job_id, + owner=host.owner, + base_url=host.base_url, + nonce=host.nonce, + capacity=host.capacity, + live=host.live, + updated_at=time.time(), + ) + for host in self._hosts + ] + dead = set(self._dead_host_ids) + save_pool_cache( + self.name, + image=self.image, + flavor=self.flavor, + sandboxes_per_host=self.sandboxes_per_host, + max_hosts=self.max_hosts, + idle_timeout=_duration_to_secs(self._idle_timeout) if self._idle_timeout is not None else None, + namespace=self._namespace, + hosts=hosts, + dead_host_ids=dead, + ) + + +def _effective_token(api: HfApi) -> str: + token = api.token if isinstance(api.token, str) else get_token() + if not token: + raise SandboxError("A Hugging Face token is required to use sandboxes. Run `hf auth login` first.") + return token + + +def _bootstrap_job_spec( + api: HfApi, + hf_token: str, + *, + env: dict[str, Any] | None, + secrets: dict[str, Any] | None, + volumes: List[Volume] | None, + idle_timeout: int | float | str | None, + forward_hf_token: bool, + sandbox_token: str, +) -> tuple[list[str], dict[str, Any], dict[str, Any], List[Volume]]: + """Build the (command, env, secrets, volumes) to launch a job running sbx-server. + + Shared by dedicated sandboxes and shared hosts: both fetch and exec the same unified + `sbx-server` binary at startup (via `/bin/sh`), downloading it with wget/curl, or + reading it off the always-mounted server bucket when the image ships neither. + """ + # Reserved SBX_* keys go last so user-provided env/secrets can't override them + # (e.g. clobbering SBX_PORT would break the proxy, SBX_TOKEN would break auth). + job_env: dict[str, Any] = {**(env or {}), "SBX_PORT": str(SANDBOX_SERVER_PORT)} + job_secrets: dict[str, Any] = {**(secrets or {}), "SBX_TOKEN": sandbox_token} + job_volumes = list(volumes or []) + if idle_timeout is not None: + job_env["SBX_IDLE_TIMEOUT"] = str(_duration_to_secs(idle_timeout)) + if forward_hf_token: + job_secrets["HF_TOKEN"] = hf_token + + job_env["SBX_SERVER_URL"] = f"{api.endpoint}/buckets/{constants.SANDBOX_SERVER_BUCKET}/resolve/sbx-server" + job_secrets["SBX_DL_TOKEN"] = hf_token + # Always mount the server bucket as a transparent fallback for images without wget/curl. + # It's only read (paying the ~2-3s FUSE cost) when the bootstrap script can't download. + job_env["SBX_SERVER_MOUNT"] = _SERVER_MOUNT_PATH + job_volumes.append( + Volume(type="bucket", source=constants.SANDBOX_SERVER_BUCKET, mount_path=_SERVER_MOUNT_PATH, read_only=True) + ) + command = ["/bin/sh", "-c", _BOOTSTRAP_DOWNLOAD] + return command, job_env, job_secrets, job_volumes + + +def _host_env(api: HfApi, job: JobInfo, *, namespace: str | None) -> dict[str, Any]: + """Return a host job's env vars (where pool config lives)""" + env = job.environment if isinstance(job.environment, dict) else {} + if "SBX_CAPACITY" not in env: + env = api.inspect_job(job_id=job.id, namespace=namespace).environment or {} + env = env if isinstance(env, dict) else {} + return env + + +def _find_pool_host_job(api: HfApi, pool_id: str, *, namespace: str | None = None) -> JobInfo: + """Return any running host job belonging to `pool_id` (found via the pool label).""" + for job in api.list_jobs( + status="RUNNING", labels={MODE_LABEL: MODE_POOL, POOL_LABEL: pool_id}, namespace=namespace + ): + return job + raise SandboxError( + f"No running host found for pool '{pool_id}'. The pool has stopped " + "(all its hosts were killed or idle-timed-out); create a new one." + ) + + +def _connect_host(api: HfApi, host_job_id: str, *, namespace: str | None = None) -> _SandboxServer: + """Reattach to a running host job and return its server transport.""" + job = api.inspect_job(job_id=host_job_id, namespace=namespace) + labels = job.labels or {} + nonce = labels.get(NONCE_LABEL) + if nonce is None or labels.get(MODE_LABEL) != MODE_POOL: + raise SandboxError(f"Job {host_job_id} is not a sandbox host.") + if job.status.stage != "RUNNING": + raise SandboxError(f"Sandbox host {host_job_id} is not running (status: {job.status.stage}).") + return _SandboxServer.from_job( + job=job, + nonce=nonce, + sandbox_token=_derive_sandbox_token(_effective_token(api), nonce), + api=api, + max_connections=SandboxFiles.PARALLEL_MAX_WORKERS + 2, + ) + + +def _split_sandbox_id(sandbox_id: str, namespace: str | None) -> tuple[str, str | None]: + """Accept `namespace/sandbox_id` ids (as shown in the Hub UI), like `hf jobs` does.""" + if "/" not in sandbox_id: + return sandbox_id, namespace + extracted_namespace, parsed_id = sandbox_id.split("/", 1) + if not extracted_namespace or not parsed_id or "/" in parsed_id: + raise SandboxError(f"Sandbox id must be 'sandbox_id' or 'namespace/sandbox_id', got {sandbox_id!r}.") + if namespace is not None and namespace != extracted_namespace: + raise SandboxError( + f"Conflicting namespace: got namespace={namespace!r} but sandbox id implies namespace={extracted_namespace!r}." + ) + return parsed_id, extracted_namespace + + +def _find_server_url(job: JobInfo) -> str: + for url in job.status.expose_urls or []: + if f"--{SANDBOX_SERVER_PORT}." in url: + return url + raise SandboxError(f"Job {job.id} does not expose the sandbox server port {SANDBOX_SERVER_PORT}.") + + +def _tail_job_logs(api: HfApi, job_id: str, *, namespace: str | None = None, limit: int = 20) -> str: + try: + lines = list(api.fetch_job_logs(job_id=job_id, namespace=namespace))[-limit:] + except Exception: + return "" + return " Last logs:\n" + "\n".join(f" {line}" for line in lines) if lines else "" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_sandbox_cache.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_sandbox_cache.py new file mode 100644 index 0000000000000000000000000000000000000000..25ddca75be16347006d4946f80cbda12311820f6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_sandbox_cache.py @@ -0,0 +1,159 @@ +# coding=utf-8 +# Copyright 2026-present, the HuggingFace Inc. team. +# +# 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. +"""Best-effort local cache for SandboxPool hosts (host/pool mode).""" + +import json +import os +import time +from dataclasses import asdict, dataclass, field +from pathlib import Path +from typing import List + +from . import constants +from .utils import WeakFileLock, logging + + +logger = logging.get_logger(__name__) + +# Bump if the on-disk layout changes incompatibly; older/newer files are ignored on read. +_CACHE_VERSION = 1 + +# A write should never block a sandbox creation for long: the cache is best-effort, so we +# rather skip persisting than wait on a stuck lock. +_LOCK_TIMEOUT = 5.0 + + +@dataclass +class CachedHost: + """A single host Job of a pool, as last seen by some process. + + `base_url` + `nonce` are everything needed to rebuild the in-job server transport + (`_SandboxServer`) without an `inspect_job` round-trip: the per-sandbox auth token is + re-derived from the user's HF token and `nonce` (see `_derive_sandbox_token`). + """ + + job_id: str + owner: str # namespace the host job runs under (for cancel/inspect) + base_url: str # exposed sbx-server URL (does not change while the job lives) + nonce: str # public nonce from the job label; derives the sandbox auth token + capacity: int # SBX_CAPACITY: max sandboxes the host packs + live: int # sandboxes last observed on the host (best-effort, may be stale) + updated_at: float = 0.0 + + +@dataclass +class PoolCache: + """Cached view of one pool: its config (to boot new hosts) + its known hosts.""" + + pool_id: str + image: str + flavor: str + sandboxes_per_host: int + max_hosts: int | None + idle_timeout: int | None + namespace: str | None + hosts: List[CachedHost] = field(default_factory=list) + version: int = _CACHE_VERSION + updated_at: float = 0.0 + + +def _pools_dir() -> Path: + return Path(constants.HF_HOME) / "sandbox" / "pools" + + +def pool_cache_path(pool_id: str) -> Path: + """Path of the cache file for `pool_id` (no I/O).""" + if any(c in pool_id for c in ("/", "\\", "\x00")) or pool_id in (".", ".."): + raise ValueError(f"Invalid pool id: {pool_id!r}") + return _pools_dir() / f"{pool_id}.json" + + +def read_pool_cache(pool_id: str) -> PoolCache | None: + """Return the cached view of `pool_id`, or `None` if missing/corrupt/incompatible.""" + try: + path = pool_cache_path(pool_id) + with path.open("r", encoding="utf-8") as f: + data = json.load(f) + if data.get("version") != _CACHE_VERSION: + return None + hosts = [CachedHost(**h) for h in data.pop("hosts", [])] + return PoolCache(**data, hosts=hosts) + except FileNotFoundError: + return None + except Exception as e: + logger.debug(f"Ignoring unreadable sandbox pool cache for {pool_id!r}: {e}") + return None + + +def save_pool_cache( + pool_id: str, + *, + image: str, + flavor: str, + sandboxes_per_host: int, + max_hosts: int | None, + idle_timeout: int | None, + namespace: str | None, + hosts: List[CachedHost], + dead_host_ids: set[str] | None = None, +) -> None: + """Merge `hosts` into the cache for `pool_id` (best-effort, never raises). + + Concurrency-safe: under a file lock, the on-disk hosts are read, then `hosts` are + upserted by `job_id` and `dead_host_ids` removed, so a process only adds/updates what + it learned and never drops hosts another process discovered. The result is written + atomically. The pool config is refreshed from the arguments. + """ + dead = dead_host_ids or set() + try: + path = pool_cache_path(pool_id) + path.parent.mkdir(parents=True, exist_ok=True) + with WeakFileLock(str(path) + ".lock", timeout=_LOCK_TIMEOUT): + existing = read_pool_cache(pool_id) + merged = {h.job_id: h for h in (existing.hosts if existing else [])} + for host in hosts: + merged[host.job_id] = host + for job_id in dead: + merged.pop(job_id, None) + cache = PoolCache( + pool_id=pool_id, + image=image, + flavor=flavor, + sandboxes_per_host=sandboxes_per_host, + max_hosts=max_hosts, + idle_timeout=idle_timeout, + namespace=namespace, + hosts=list(merged.values()), + updated_at=time.time(), + ) + _atomic_write(path, cache) + except Exception as e: + logger.debug(f"Could not write sandbox pool cache for {pool_id!r}: {e}") + + +def delete_pool_cache(pool_id: str) -> None: + """Remove the cache file for `pool_id` (best-effort, never raises).""" + try: + pool_cache_path(pool_id).unlink(missing_ok=True) + except Exception as e: + logger.debug(f"Could not delete sandbox pool cache for {pool_id}: {e}") + + +def _atomic_write(path: Path, cache: PoolCache) -> None: + """Write the cache via a temp file + `os.replace` so readers never see a partial file.""" + tmp = path.parent / f"{path.name}.{os.getpid()}.tmp" + with tmp.open("w", encoding="utf-8") as f: + json.dump(asdict(cache), f, indent=2) + os.replace(tmp, path) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_snapshot_download.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_snapshot_download.py new file mode 100644 index 0000000000000000000000000000000000000000..b5515bd196b6ef22a0ffa69cdd336ed11baca673 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_snapshot_download.py @@ -0,0 +1,681 @@ +import os +from pathlib import Path +from typing import Literal, overload + +import httpx +from tqdm.auto import tqdm as base_tqdm +from tqdm.contrib.concurrent import thread_map + +from . import constants +from ._tree_cache import TreeCacheEntry, read_tree_cache, tree_cache_folder_for_local_dir, write_tree_cache +from .errors import ( + CachedRepoTreeNotFoundError, + DryRunError, + GatedRepoError, + HfHubHTTPError, + IncompleteSnapshotError, + LocalEntryNotFoundError, + RepositoryNotFoundError, + RevisionNotFoundError, +) +from .file_download import REGEX_COMMIT_HASH, DryRunFileInfo, hf_hub_download, repo_folder_name +from .hf_api import DatasetInfo, HfApi, KernelInfo, ModelInfo, RepoFile, SpaceInfo +from .utils import OfflineModeIsEnabled, filter_repo_objects, logging, validate_hf_hub_args +from .utils._xet_progress_reporting import ( + XET_BYTES_BAR_FORMAT, + XET_TRANSFER_BAR_FORMAT, + _finish_transfer_bar, + _update_transfer_bar, +) +from .utils.tqdm import _create_progress_bar +from .utils.tqdm import tqdm as hf_tqdm + + +logger = logging.get_logger(__name__) + + +@overload +def snapshot_download( + repo_id: str, + *, + repo_type: str | None = None, + revision: str | None = None, + cache_dir: str | Path | None = None, + local_dir: str | Path | None = None, + library_name: str | None = None, + library_version: str | None = None, + user_agent: dict | str | None = None, + etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT, + force_download: bool = False, + token: bool | str | None = None, + local_files_only: bool = False, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + max_workers: int = 8, + tqdm_class: type[base_tqdm] | None = None, + headers: dict[str, str] | None = None, + endpoint: str | None = None, + dry_run: Literal[False] = False, +) -> str: ... + + +@overload +def snapshot_download( + repo_id: str, + *, + repo_type: str | None = None, + revision: str | None = None, + cache_dir: str | Path | None = None, + local_dir: str | Path | None = None, + library_name: str | None = None, + library_version: str | None = None, + user_agent: dict | str | None = None, + etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT, + force_download: bool = False, + token: bool | str | None = None, + local_files_only: bool = False, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + max_workers: int = 8, + tqdm_class: type[base_tqdm] | None = None, + headers: dict[str, str] | None = None, + endpoint: str | None = None, + dry_run: Literal[True] = True, +) -> list[DryRunFileInfo]: ... + + +@overload +def snapshot_download( + repo_id: str, + *, + repo_type: str | None = None, + revision: str | None = None, + cache_dir: str | Path | None = None, + local_dir: str | Path | None = None, + library_name: str | None = None, + library_version: str | None = None, + user_agent: dict | str | None = None, + etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT, + force_download: bool = False, + token: bool | str | None = None, + local_files_only: bool = False, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + max_workers: int = 8, + tqdm_class: type[base_tqdm] | None = None, + headers: dict[str, str] | None = None, + endpoint: str | None = None, + dry_run: bool = False, +) -> str | list[DryRunFileInfo]: ... + + +@validate_hf_hub_args +def snapshot_download( + repo_id: str, + *, + repo_type: str | None = None, + revision: str | None = None, + cache_dir: str | Path | None = None, + local_dir: str | Path | None = None, + library_name: str | None = None, + library_version: str | None = None, + user_agent: dict | str | None = None, + etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT, + force_download: bool = False, + token: bool | str | None = None, + local_files_only: bool = False, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + max_workers: int = 8, + tqdm_class: type[base_tqdm] | None = None, + headers: dict[str, str] | None = None, + endpoint: str | None = None, + dry_run: bool = False, +) -> str | list[DryRunFileInfo]: + """Download repo files. + + Download a whole snapshot of a repo's files at the specified revision. This is useful when you want all files from + a repo because you don't know which ones you will need _a priori_. All files are nested in a folder to keep their + path and filename relative to that folder. You can also filter which files to download by using `allow_patterns` + and `ignore_patterns`. + + If `local_dir` is provided, the file structure from the repo will be replicated in this location. When using this + option, the `cache_dir` will not be used, and a `.cache/huggingface/` folder will be created at the root of `local_dir` + to store some metadata related to the downloaded files. While this mechanism is not as robust as the main + cache system, it's optimized for regularly pulling the latest version of a repository. + + An alternative would be to clone the repo, but this requires git and git-lfs to be installed and properly + configured. It is also not possible to filter which files to download when cloning a repository using git. + + Args: + repo_id (`str`): + A user or an organization name and a repo name separated by a `/`. + repo_type (`str`, *optional*): + Set to `"dataset"`, `"space"` or `"kernel"` if downloading from a dataset, space or kernel repo, + `None` or `"model"` if downloading from a model. Default is `None`. + revision (`str`, *optional*): + An optional Git revision id, which can be a branch name, a tag, or a + commit hash. + cache_dir (`str`, `Path`, *optional*): + Path to the folder where cached files are stored. + local_dir (`str` or `Path`, *optional*): + If provided, the downloaded files will be placed under this directory. + library_name (`str`, *optional*): + The name of the library to which the object corresponds. + library_version (`str`, *optional*): + The version of the library. + user_agent (`str`, `dict`, *optional*): + The user-agent info in the form of a dictionary or a string. + etag_timeout (`float`, *optional*, defaults to `10`): + When fetching ETag, how many seconds to wait for the server to send + data before giving up, which is passed to `httpx.request`. + force_download (`bool`, *optional*, defaults to `False`): + Whether the file should be downloaded even if it already exists in the local cache. + token (`str`, `bool`, *optional*): + A token to be used for the download. + - If `True`, the token is read from the HuggingFace config + folder. + - If a string, it's used as the authentication token. + headers (`dict`, *optional*): + Additional headers to include in the request. Those headers take precedence over the others. + endpoint (`str`, *optional*): + The Hub endpoint to send the request to. Defaults to the value of `HF_ENDPOINT`. + local_files_only (`bool`, *optional*, defaults to `False`): + If `True`, do not download any files even if they are not in `cache_dir` or `local_dir`. + allow_patterns (`list[str]` or `str`, *optional*): + If provided, only files matching at least one pattern are downloaded. + ignore_patterns (`list[str]` or `str`, *optional*): + If provided, files matching any of the patterns are not downloaded. + max_workers (`int`, *optional*): + Number of concurrent threads to download files (1 thread = 1 file download). + Defaults to 8. + tqdm_class (`tqdm`, *optional*): + If provided, overwrites the default behavior for the progress bar. Passed + argument must inherit from `tqdm.auto.tqdm` or at least mimic its behavior. + Note that the `tqdm_class` is not passed to each individual download. + Defaults to the custom HF progress bar that can be disabled by setting + `HF_HUB_DISABLE_PROGRESS_BARS` environment variable. + dry_run (`bool`, *optional*, defaults to `False`): + If `True`, perform a dry run without actually downloading the files. Returns a list of + [`DryRunFileInfo`] objects containing information about what would be downloaded. + + Returns: + `str` or list of [`DryRunFileInfo`]: + - If `dry_run=False`: Local snapshot path. + - If `dry_run=True`: A list of [`DryRunFileInfo`] objects containing download information. + + Raises: + [`~utils.RepositoryNotFoundError`] + If the repository to download from cannot be found. This may be because it doesn't exist + or because it is set to `private` and you do not have access. + [`~utils.RevisionNotFoundError`] + If the revision to download from cannot be found. + [`~errors.IncompleteSnapshotError`] + If the Hub cannot be reached (offline, connection issue, or `local_files_only=True`) and the + cached snapshot is missing some of the requested files. + [`EnvironmentError`](https://docs.python.org/3/library/exceptions.html#EnvironmentError) + If `token=True` and the token cannot be found. + [`OSError`](https://docs.python.org/3/library/exceptions.html#OSError) if + ETag cannot be determined. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If some parameter value is invalid. + """ + if cache_dir is None: + cache_dir = constants.HF_HUB_CACHE + cache_dir = str(Path(cache_dir).expanduser().resolve()) + if local_dir is not None: + local_dir = str(Path(local_dir).expanduser().resolve()) + if revision is None: + revision = constants.DEFAULT_REVISION + + if repo_type is None: + repo_type = "model" + if repo_type not in constants.REPO_TYPES_WITH_KERNEL: + raise ValueError( + f"Invalid repo type: {repo_type}. Accepted repo types are: {str(constants.REPO_TYPES_WITH_KERNEL)}" + ) + + storage_folder = os.path.join(cache_dir, repo_folder_name(repo_id=repo_id, repo_type=repo_type)) + + # Folder under which the per-commit tree listing (`trees/.json`) is cached on disk. + tree_cache_folder = tree_cache_folder_for_local_dir(local_dir) if local_dir is not None else storage_folder + + api = HfApi( + library_name=library_name, + library_version=library_version, + user_agent=user_agent, + endpoint=endpoint, + headers=headers, + token=token, + ) + + repo_info: ModelInfo | DatasetInfo | SpaceInfo | KernelInfo | None = None + api_call_error: Exception | None = None + if not local_files_only: + # try/except logic to handle different errors => taken from `hf_hub_download` + try: + # if we have internet connection we want to list files to download + repo_info = api.repo_info(repo_id=repo_id, repo_type=repo_type, revision=revision) + except httpx.ProxyError: + # Actually raise on proxy error + raise + except (httpx.ConnectError, httpx.TimeoutException, OfflineModeIsEnabled) as error: + # Internet connection is down + # => will try to use local files only + api_call_error = error + pass + except RevisionNotFoundError: + # The repo was found but the revision doesn't exist on the Hub (never existed or got deleted) + raise + except HfHubHTTPError as error: + # Multiple reasons for an http error: + # - Repository is private and invalid/missing token sent + # - Repository is gated and invalid/missing token sent + # - Hub is down (error 500 or 504) + # => let's switch to 'local_files_only=True' to check if the files are already cached. + # (if it's not the case, the error will be re-raised) + api_call_error = error + pass + + # At this stage, if `repo_info` is None it means either: + # - internet connection is down + # - internet connection is deactivated (local_files_only=True or HF_HUB_OFFLINE=True) + # - repo is private/gated and invalid/missing token sent + # - Hub is down + # => let's look if we can find the appropriate folder in the cache: + # - if the specified revision is a commit hash, look inside "snapshots". + # - f the specified revision is a branch or tag, look inside "refs". + # => if local_dir is not None, we will return the path to the local folder if it exists. + if repo_info is None: + if dry_run: + raise DryRunError( + "Dry run cannot be performed as the repository cannot be accessed. Please check your internet connection or authentication token." + ) from api_call_error + + # Try to get which commit hash corresponds to the specified revision + commit_hash = None + if REGEX_COMMIT_HASH.match(revision): + commit_hash = revision + else: + ref_path = os.path.join(storage_folder, "refs", revision) + if os.path.exists(ref_path): + # retrieve commit_hash from refs file + with open(ref_path) as f: + commit_hash = f.read() + + # Try to locate snapshot folder for this commit hash + if commit_hash is not None and local_dir is None: + snapshot_folder = os.path.join(storage_folder, "snapshots", commit_hash) + if os.path.exists(snapshot_folder): + # The folder exists, but may be partial (e.g. after an interrupted download): only return it + # if the cached tree listing confirms it is complete. + _raise_if_incomplete_snapshot( + tree_cache_folder=tree_cache_folder, + commit_hash=commit_hash, + base_dir=snapshot_folder, + allow_patterns=allow_patterns, + ignore_patterns=ignore_patterns, + repo_id=repo_id, + revision=revision, + api_call_error=api_call_error, + ) + return snapshot_folder + + # If local_dir is not None, return it if it exists and is complete + if local_dir is not None: + local_dir = Path(local_dir) + if local_dir.is_dir() and any(local_dir.iterdir()): + if commit_hash is not None: + _raise_if_incomplete_snapshot( + tree_cache_folder=tree_cache_folder, + commit_hash=commit_hash, + base_dir=str(local_dir), + allow_patterns=allow_patterns, + ignore_patterns=ignore_patterns, + repo_id=repo_id, + revision=revision, + api_call_error=api_call_error, + ) + logger.warning( + f"Returning existing local_dir `{local_dir}` as remote repo cannot be accessed in `snapshot_download` ({api_call_error})." + ) + return str(local_dir.resolve()) + # If we couldn't find the appropriate folder on disk, raise an error. + if local_files_only: + raise LocalEntryNotFoundError( + "Cannot find an appropriate cached snapshot folder for the specified revision on the local disk and " + "outgoing traffic has been disabled. To enable repo look-ups and downloads online, pass " + "'local_files_only=False' as input." + ) + elif isinstance(api_call_error, OfflineModeIsEnabled): + raise LocalEntryNotFoundError( + "Cannot find an appropriate cached snapshot folder for the specified revision on the local disk and " + "outgoing traffic has been disabled. To enable repo look-ups and downloads online, set " + "'HF_HUB_OFFLINE=0' as environment variable." + ) from api_call_error + elif isinstance(api_call_error, (RepositoryNotFoundError, GatedRepoError)) or ( + isinstance(api_call_error, HfHubHTTPError) and api_call_error.response.status_code == 401 + ): + # Repo not found, gated, or specific authentication error => let's raise the actual error + raise api_call_error + else: + # Otherwise: most likely a connection issue or Hub downtime => let's warn the user + raise LocalEntryNotFoundError( + f"Got: {api_call_error.__class__.__name__}: {api_call_error}" + "\nAn error happened while trying to locate the files on the Hub, and we cannot find the appropriate" + " snapshot folder for the specified revision on the local disk. Please check your internet connection" + " and try again." + ) from api_call_error + + # At this stage, internet connection is up and running + # => let's download the files! + assert repo_info.sha is not None, "Repo info returned from server must have a revision sha." + commit_hash = repo_info.sha + + # Retrieve /tree listing from cache or fetch it + tree_entries = read_tree_cache(tree_cache_folder, commit_hash) + if tree_entries is None: + tree_entries = { + f.path: TreeCacheEntry( + size=f.size, + blob_id=f.blob_id, + lfs_sha256=f.lfs.sha256 if f.lfs is not None else None, + lfs_size=f.lfs.size if f.lfs is not None else None, + xet_hash=f.xet_hash, + ) + for f in api.list_repo_tree(repo_id=repo_id, recursive=True, revision=commit_hash, repo_type=repo_type) + if isinstance(f, RepoFile) + } + if not dry_run: + write_tree_cache(tree_cache_folder, commit_hash, tree_entries) + + filtered_repo_files = list( + filter_repo_objects( + items=tree_entries.keys(), + allow_patterns=allow_patterns, + ignore_patterns=ignore_patterns, + ) + ) + tqdm_desc = f"Fetching {len(filtered_repo_files)} files" + if dry_run: + tqdm_desc = "[dry-run] " + tqdm_desc + + snapshot_folder = os.path.join(storage_folder, "snapshots", commit_hash) + # if passed revision is not identical to commit_hash + # then revision has to be a branch name or tag name. + # In that case store a ref. + if revision != commit_hash: + ref_path = os.path.join(storage_folder, "refs", revision) + try: + os.makedirs(os.path.dirname(ref_path), exist_ok=True) + with open(ref_path, "w") as f: + f.write(commit_hash) + except OSError as e: + logger.warning(f"Ignored error while writing commit hash to {ref_path}: {e}.") + + results: list[str | DryRunFileInfo] = [] + + # User can use its own tqdm class or the default one from `huggingface_hub.utils` + tqdm_class = tqdm_class or hf_tqdm + + # Create progress bars for the bytes downloaded. + # Transfer bytes are received from the network; reconstruction bytes are written to disk. + transfer_progress = _create_progress_bar( + cls=tqdm_class, + log_level=logger.getEffectiveLevel(), + name="huggingface_hub.snapshot_download.transfer", + desc="Downloading bytes", + total=0, + initial=0, + unit="B", + unit_scale=True, + bar_format=XET_TRANSFER_BAR_FORMAT, + ) + + reconstruct_progress = _create_progress_bar( + cls=tqdm_class, + log_level=logger.getEffectiveLevel(), + name="huggingface_hub.snapshot_download", + desc="Reconstructing (incomplete total...)", + total=0, + initial=0, + unit="B", + unit_scale=True, + bar_format=XET_BYTES_BAR_FORMAT, + ) + + class _AggregatedTqdm: + """Fake tqdm object to aggregate progress into the parent snapshot progress bars. + + In practice, the `_AggregatedTqdm` object won't be displayed; it's just used to update + the `reconstruct_progress` and `transfer_progress` bars from each thread/file download. + """ + + def __init__(self, *args, **kwargs): + # Adjust the total of the parent progress bar + total = kwargs.pop("total", None) + if total is not None: + reconstruct_progress.total = (reconstruct_progress.total or 0) + total + transfer_progress.total = (transfer_progress.total or 0) + total + reconstruct_progress.refresh() + + # Adjust initial of the parent progress bar + initial = kwargs.pop("initial", 0) + if initial: + reconstruct_progress.update(initial) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + pass + + def close(self) -> None: + pass + + def update(self, n: int | float | None = 1) -> None: + reconstruct_progress.update(n) + + def update_transfer(self, n: int | float | None = 1) -> None: + _update_transfer_bar(transfer_progress, int(n or 0)) + + def set_postfix_str(self, postfix: str, refresh: bool = False) -> None: + reconstruct_progress.set_postfix_str(postfix, refresh=refresh) + + def set_transfer_postfix_str(self, postfix: str, refresh: bool = False) -> None: + transfer_progress.set_postfix_str(postfix, refresh=refresh) + + # Pass the commit_hash as revision to hf_hub_download to skip network call if: + # - file is cached + # - or xet file with metadata cached in /tree cache + def _inner_hf_hub_download(repo_file: str) -> None: + results.append( + hf_hub_download( # type: ignore + repo_id, + filename=repo_file, + repo_type=repo_type, + revision=commit_hash, + endpoint=endpoint, + cache_dir=cache_dir, + local_dir=local_dir, + library_name=library_name, + library_version=library_version, + user_agent=user_agent, + etag_timeout=etag_timeout, + force_download=force_download, + token=token, + headers=headers, + tqdm_class=_AggregatedTqdm, # type: ignore + dry_run=dry_run, + ) + ) + + thread_map( + _inner_hf_hub_download, + filtered_repo_files, + desc=tqdm_desc, + max_workers=max_workers, + tqdm_class=tqdm_class, + ) + + _finish_transfer_bar(transfer_progress) + transfer_progress.set_description("Download complete") + reconstruct_progress.set_description("Reconstruction complete") + + if dry_run: + assert all(isinstance(r, DryRunFileInfo) for r in results) + return results # type: ignore + + if local_dir is not None: + return str(os.path.realpath(local_dir)) + return snapshot_folder + + +def _raise_if_incomplete_snapshot( + *, + tree_cache_folder: str, + commit_hash: str, + base_dir: str, + allow_patterns: list[str] | str | None, + ignore_patterns: list[str] | str | None, + repo_id: str, + revision: str, + api_call_error: Exception | None, +) -> None: + """Raise [`IncompleteSnapshotError`] if the cached tree listing shows `base_dir` misses requested files. + + If the tree listing is not cached we cannot tell, so we do nothing and the caller keeps returning the + folder as-is. Otherwise every expected file (after pattern filtering) must exist under `base_dir`. + """ + tree_entries = read_tree_cache(tree_cache_folder, commit_hash) + if tree_entries is None: + return + expected = filter_repo_objects( + items=tree_entries.keys(), allow_patterns=allow_patterns, ignore_patterns=ignore_patterns + ) + missing = [path for path in expected if not _local_file_exists(base_dir, path)] + if not missing: + return + + sample = ", ".join(missing[:3]) + if len(missing) > 3: + sample += f", ... ({len(missing) - 3} more)" + if api_call_error is not None: + reason = f"The Hub could not be reached ({api_call_error.__class__.__name__}: {api_call_error})." + else: + reason = "Outgoing traffic is disabled ('local_files_only=True')." + raise IncompleteSnapshotError( + f"The cached snapshot for '{repo_id}' (revision '{revision}', commit {commit_hash}) is incomplete: " + f"{len(missing)} file(s) are missing ({sample}). {reason} Re-run the download with network access " + "to complete the snapshot.", + snapshot_path=base_dir, + ) from api_call_error + + +@validate_hf_hub_args +def get_cached_repo_tree( + repo_id: str, + *, + repo_type: str | None = None, + revision: str | None = None, + cache_dir: str | Path | None = None, + local_dir: str | Path | None = None, +) -> list[RepoFile]: + """Return the cached tree listing of a repo at a given revision, without any network call. + + The tree listing is the set of files (with their download metadata) of a repo at a commit. It is populated + on disk as a side effect of [`snapshot_download`] (see the `trees/.json` cache files) and is + used to skip network calls on subsequent downloads. This function exposes that cache directly. + + If you need the current tree listing of a repo on the Hub, use [`list_repo_tree`] instead. + + Args: + repo_id (`str`): + A user or an organization name and a repo name separated by a `/`. + repo_type (`str`, *optional*): + Set to `"dataset"`, `"space"` or `"kernel"` if listing from a dataset, space or kernel repo, + `None` or `"model"` if listing from a model. Default is `None`. + revision (`str`, *optional*): + An optional Git revision id, which can be a branch name, a tag, or a commit hash. Defaults to the + default branch. Branch/tag names are resolved to a commit hash using the local cache (`refs/`). + cache_dir (`str`, `Path`, *optional*): + Path to the folder where cached files are stored. Defaults to the value of `HF_HUB_CACHE`. + local_dir (`str` or `Path`, *optional*): + If provided, read the tree listing cached by a `local_dir` download (from + `local_dir/.cache/huggingface/`) instead of the main cache. Branch/tag revisions are still resolved + to a commit hash using the main cache (`cache_dir`). + + Returns: + `list[RepoFile]`: The list of [`RepoFile`] objects cached for this revision. + + Raises: + [`~errors.CachedRepoTreeNotFoundError`] + If no tree listing is cached for the requested revision (e.g. the repo was never downloaded at this revision). + + Example: + ```py + >>> from huggingface_hub import get_cached_repo_tree + >>> files = get_cached_repo_tree("openai-community/gpt2") + >>> [f.path for f in files] + ['.gitattributes', 'config.json', 'model.safetensors', ...] + ``` + """ + if cache_dir is None: + cache_dir = constants.HF_HUB_CACHE + cache_dir = str(Path(cache_dir).expanduser().resolve()) + if local_dir is not None: + local_dir = str(Path(local_dir).expanduser().resolve()) + if revision is None: + revision = constants.DEFAULT_REVISION + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + if repo_type not in constants.REPO_TYPES_WITH_KERNEL: + raise ValueError( + f"Invalid repo type: {repo_type}. Accepted repo types are: {str(constants.REPO_TYPES_WITH_KERNEL)}" + ) + + storage_folder = os.path.join(cache_dir, repo_folder_name(repo_id=repo_id, repo_type=repo_type)) + + # For `local_dir` downloads the tree listing lives under `local_dir/.cache/huggingface/`; otherwise it lives + # in the per-repo `storage_folder`. Refs are always recorded in the main cache, so we resolve them there. + tree_cache_folder = tree_cache_folder_for_local_dir(local_dir) if local_dir is not None else storage_folder + + # The tree cache is keyed by commit hash. Resolve the revision to a commit hash: either it already is one, + # or it's a branch/tag name recorded in `refs/` by a previous download. + if REGEX_COMMIT_HASH.match(revision): + commit_hash = revision + else: + ref_path = os.path.join(storage_folder, "refs", revision) + if not os.path.isfile(ref_path): + raise CachedRepoTreeNotFoundError( + f"No cached tree listing found for '{repo_id}' (revision '{revision}', repo_type '{repo_type}'): " + f"the revision is not a commit hash and no matching ref is cached in '{storage_folder}'. " + "Download the repo (e.g. with `snapshot_download`) to populate the cache first." + ) + with open(ref_path) as f: + commit_hash = f.read() + + tree_entries = read_tree_cache(tree_cache_folder, commit_hash) + if tree_entries is None: + raise CachedRepoTreeNotFoundError( + f"No cached tree listing found for '{repo_id}' (revision '{revision}', commit '{commit_hash}', " + f"repo_type '{repo_type}') in '{tree_cache_folder}'. Download the repo (e.g. with `snapshot_download`) " + "to populate the cache first." + ) + + return [ + RepoFile(path=path, size=entry.size, oid=entry.blob_id, xetHash=entry.xet_hash) + for path, entry in tree_entries.items() + ] + + +def _local_file_exists(base_dir: str, path: str) -> bool: + """Check whether a repo file (path relative to `base_dir`, '/'-separated) exists on disk. + + On Windows, paths longer than 255 characters must be prefixed with `\\\\?\\`, otherwise `os.path.isfile` reports an + existing file as missing. + """ + full_path = os.path.join(base_dir, *path.split("/")) + if os.name == "nt" and len(os.path.abspath(full_path)) > 255 and not full_path.startswith("\\\\?\\"): + full_path = "\\\\?\\" + os.path.abspath(full_path) + return os.path.isfile(full_path) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_space_api.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_space_api.py new file mode 100644 index 0000000000000000000000000000000000000000..7d00fd56a78a6d17b82d81dc4e8816da9a45518c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_space_api.py @@ -0,0 +1,395 @@ +# Copyright 2019-present, the HuggingFace Inc. team. +# +# 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. +from dataclasses import dataclass +from datetime import datetime +from enum import Enum +from typing import Literal + +from huggingface_hub.utils import HfMount, HfUri, parse_datetime + + +class SpaceStage(str, Enum): + """ + Enumeration of possible stage of a Space on the Hub. + + Value can be compared to a string: + ```py + assert SpaceStage.BUILDING == "BUILDING" + ``` + + Taken from https://github.com/huggingface/moon-landing/blob/main/server/repo_types/SpaceInfo.ts#L61 (private url). + """ + + # Copied from moon-landing > server > repo_types > SpaceInfo.ts (private repo) + NO_APP_FILE = "NO_APP_FILE" + CONFIG_ERROR = "CONFIG_ERROR" + BUILDING = "BUILDING" + BUILD_ERROR = "BUILD_ERROR" + RUNNING = "RUNNING" + RUNNING_BUILDING = "RUNNING_BUILDING" + RUNTIME_ERROR = "RUNTIME_ERROR" + DELETING = "DELETING" + STOPPED = "STOPPED" + PAUSED = "PAUSED" + APP_STARTING = "APP_STARTING" + RUNNING_APP_STARTING = "RUNNING_APP_STARTING" + + +INTERMEDIATE_SPACE_STAGES = ( + SpaceStage.BUILDING, + SpaceStage.RUNNING_BUILDING, + SpaceStage.APP_STARTING, + SpaceStage.RUNNING_APP_STARTING, +) + +TERMINAL_SPACE_STAGES = ( + SpaceStage.RUNNING, + SpaceStage.BUILD_ERROR, + SpaceStage.RUNTIME_ERROR, + SpaceStage.CONFIG_ERROR, + SpaceStage.NO_APP_FILE, + SpaceStage.STOPPED, + SpaceStage.PAUSED, + SpaceStage.DELETING, +) + + +class SpaceHardware(str, Enum): + """ + Enumeration of hardwares available to run your Space on the Hub. + + Value can be compared to a string: + ```py + assert SpaceHardware.CPU_BASIC == "cpu-basic" + ``` + + Taken from https://github.com/huggingface-internal/moon-landing/blob/main/server/repo_types/SpaceHardwareFlavor.ts (private url). + """ + + # CPU + CPU_BASIC = "cpu-basic" + CPU_UPGRADE = "cpu-upgrade" + + # ZeroGPU + ZERO_A10G = "zero-a10g" + + # GPU + T4_SMALL = "t4-small" + T4_MEDIUM = "t4-medium" + L4X1 = "l4x1" + L4X4 = "l4x4" + L40SX1 = "l40sx1" + L40SX4 = "l40sx4" + L40SX8 = "l40sx8" + A10G_SMALL = "a10g-small" + A10G_LARGE = "a10g-large" + A10G_LARGEX2 = "a10g-largex2" + A10G_LARGEX4 = "a10g-largex4" + A100_LARGE = "a100-large" + A100X4 = "a100x4" + A100X8 = "a100x8" + + +class SpaceStorage(str, Enum): + """ + Enumeration of persistent storage available for your Space on the Hub. + + Value can be compared to a string: + ```py + assert SpaceStorage.SMALL == "small" + ``` + + Taken from https://github.com/huggingface/moon-landing/blob/main/server/repo_types/SpaceHardwareFlavor.ts#L24 (private url). + """ + + SMALL = "small" + MEDIUM = "medium" + LARGE = "large" + + +@dataclass +class Volume: + """ + Describes a volume to mount in a Space or Job container. + + Args: + type (`str`): + Type of volume: `"bucket"`, `"model"`, `"dataset"`, or `"space"`. + source (`str`): + Source identifier, e.g. `"username/my-bucket"` or `"username/my-model"`. + mount_path (`str`): + Mount path inside the container, e.g. `"/data"`. Must start with `/`. + revision (`str` or `None`): + Git revision (only for repos, defaults to `"main"`). + read_only (`bool` or `None`): + Read-only mount. Forced `True` for repos, defaults to `False` for buckets. + path (`str` or `None`): + Subfolder prefix inside the bucket/repo to mount, e.g. `"path/to/dir"`. + """ + + type: Literal["bucket", "model", "dataset", "space"] + source: str + mount_path: str + revision: str | None = None + read_only: bool | None = None + path: str | None = None + + def __init__(self, **kwargs) -> None: + self.type = kwargs.get("type", "model") + self.source = kwargs["source"] + mount_path = kwargs.get("mountPath") + self.mount_path = mount_path if mount_path is not None else kwargs["mount_path"] + self.revision = kwargs.get("revision") + read_only = kwargs.get("readOnly") + self.read_only = read_only if read_only is not None else kwargs.get("read_only") + self.path = kwargs.get("path") + + def to_dict(self) -> dict: + """Serialize to the JSON payload expected by the Hub API.""" + data: dict = { + "type": self.type, + "source": self.source, + "mountPath": self.mount_path, + } + if self.revision is not None: + data["revision"] = self.revision + if self.read_only is not None: + data["readOnly"] = self.read_only + if self.path is not None: + data["path"] = self.path + return data + + def to_uri(self) -> str: + """Return the volume as an HF mount URI in the format expected by the CLI.""" + return HfMount( + source=HfUri(type=self.type, id=self.source, revision=self.revision, path_in_repo=self.path or ""), + mount_path=self.mount_path, + read_only=self.read_only, + ).to_uri() + + +@dataclass +class SpaceHotReloading: + status: Literal["created", "canceled"] + replica_statuses: list[tuple[str, str | None]] # See _hot_reloading_types.ApiCreateReloadResponse.res.status + raw: dict + + def __init__(self, data: dict) -> None: + self.status = data["status"] + self.replica_statuses = data["replicaStatuses"] + self.raw = data + + +@dataclass +class SpaceRuntime: + """ + Contains information about the current runtime of a Space. + + Args: + stage (`str`): + Current stage of the space. Example: RUNNING. + hardware (`str` or `None`): + Current hardware of the space. Example: "cpu-basic". Can be `None` if Space + is `BUILDING` for the first time. + requested_hardware (`str` or `None`): + Requested hardware. Can be different from `hardware` especially if the request + has just been made. Example: "t4-medium". Can be `None` if no hardware has + been requested yet. + sleep_time (`int` or `None`): + Number of seconds the Space will be kept alive after the last request. By default (if value is `None`), the + Space will never go to sleep if it's running on an upgraded hardware, while it will go to sleep after 48 + hours on a free 'cpu-basic' hardware. For more details, see https://huggingface.co/docs/hub/spaces-gpus#sleep-time. + volumes (`list[Volume]` or `None`): + List of volumes mounted in the Space. Each volume is a [`Volume`] object describing its type, source, + mount path, and optional settings. `None` if no volumes are attached. + raw (`dict`): + Raw response from the server. Contains more information about the Space + runtime like number of replicas, number of cpu, memory size,... + """ + + stage: SpaceStage + hardware: SpaceHardware | None + requested_hardware: SpaceHardware | None + sleep_time: int | None + storage: SpaceStorage | None + dev_mode: bool + hot_reloading: SpaceHotReloading | None + volumes: list[Volume] | None + raw: dict + + def __init__(self, data: dict) -> None: + self.stage = data["stage"] + self.hardware = data.get("hardware", {}).get("current") + self.requested_hardware = data.get("hardware", {}).get("requested") + self.sleep_time = data.get("gcTimeout") + self.storage = data.get("storage") + self.dev_mode = data.get("devMode", False) + self.hot_reloading = SpaceHotReloading(raw_hr) if (raw_hr := data.get("hotReloading")) is not None else None + raw_volumes = data.get("volumes") + self.volumes = [Volume(**v) for v in raw_volumes] if raw_volumes is not None else None + self.raw = data + + +@dataclass +class SpaceSecret: + """ + Contains information about a secret of a Space. + + Secret values are write-only and cannot be read back. Only the key, description, + and last update time are returned by the API. + + Args: + key (`str`): + Secret key. Example: `"GITHUB_API_KEY"` + description (`str` or None): + Description of the secret. Example: `"Github API key to access the Github API"`. + updated_at (`datetime` or None): + datetime of the last update of the secret (if the secret has been updated at least once). + """ + + key: str + description: str | None + updated_at: datetime | None + + def __init__(self, key: str, values: dict) -> None: + self.key = key + self.description = values.get("description") + updated_at = values.get("updatedAt") + self.updated_at = parse_datetime(updated_at) if updated_at is not None else None + + +@dataclass +class SpaceVariable: + """ + Contains information about the current variables of a Space. + + Args: + key (`str`): + Variable key. Example: `"MODEL_REPO_ID"` + value (`str`): + Variable value. Example: `"the_model_repo_id"`. + description (`str` or None): + Description of the variable. Example: `"Model Repo ID of the implemented model"`. + updatedAt (`datetime` or None): + datetime of the last update of the variable (if the variable has been updated at least once). + """ + + key: str + value: str + description: str | None + updated_at: datetime | None + + def __init__(self, key: str, values: dict) -> None: + self.key = key + self.value = values["value"] + self.description = values.get("description") + updated_at = values.get("updatedAt") + self.updated_at = parse_datetime(updated_at) if updated_at is not None else None + + +@dataclass +class SpaceSearchResult: + """A single result from the Spaces semantic search API. + + Returned by [`HfApi.search_spaces`]. + + Attributes: + id (`str`): + ID of the Space (e.g. `"username/repo-name"`). + author (`str`): + Author of the Space. + title (`str`): + Display title of the Space. + emoji (`str` or `None`): + Emoji icon of the Space. + sdk (`str` or `None`): + SDK used by the Space (e.g. `"gradio"`, `"docker"`, `"static"`). + likes (`int`): + Number of likes. + private (`bool`): + Whether the Space is private. + tags (`list[str]` or `None`): + List of tags. + runtime ([`SpaceRuntime`] or `None`): + Runtime information (stage, hardware, etc.). + ai_short_description (`str` or `None`): + AI-generated short description. + ai_category (`str` or `None`): + AI-generated category (e.g. `"Image Generation"`). + semantic_relevancy_score (`float` or `None`): + Semantic relevancy score (0-1) relative to the search query. + trending_score (`int` or `None`): + Trending score. + """ + + id: str + author: str + title: str + emoji: str | None + sdk: str | None + likes: int + private: bool + tags: list[str] | None + runtime: SpaceRuntime | None + ai_short_description: str | None + ai_category: str | None + semantic_relevancy_score: float | None + trending_score: int | None + + def __init__(self, data: dict) -> None: + runtime = data.get("runtime") + self.id = data["id"] + self.author = data.get("author", "") + self.title = data.get("title", "") + self.emoji = data.get("emoji") + self.sdk = data.get("sdk") + self.likes = data.get("likes", 0) + self.private = data.get("private", False) + self.tags = data.get("tags") + self.runtime = SpaceRuntime(runtime) if runtime else None + self.ai_short_description = data.get("ai_short_description") + self.ai_category = data.get("ai_category") + self.semantic_relevancy_score = data.get("semanticRelevancyScore") + self.trending_score = data.get("trendingScore") + + +@dataclass +class SpaceTemplate: + """ + Contains information about a Space template available on the Hub. + + Returned by [`HfApi.list_space_templates`]. The `repo_id` can be passed as `space_template` + to [`HfApi.create_repo`] to seed a new Space from that template. + + Args: + name (`str`): + Human-friendly name of the template (e.g. `"JupyterLab"`, `"chatbot"`). + repo_id (`str`): + Repo id of the template Space (e.g. `"SpacesExamples/jupyterlab"`). + sdk (`str`): + SDK the template is built with (e.g. `"gradio"`, `"docker"`, `"static"`). + preferred_private (`bool`): + Whether Spaces created from this template are recommended to be private. + """ + + name: str + repo_id: str + sdk: str + preferred_private: bool + + def __init__(self, data: dict) -> None: + self.name = data["name"] + self.repo_id = data["repoId"] + self.sdk = data["sdk"] + self.preferred_private = data["preferredPrivate"] diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_tensorboard_logger.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_tensorboard_logger.py new file mode 100644 index 0000000000000000000000000000000000000000..c6a0d222990e25297feaa72c846b94212e0ebcfc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_tensorboard_logger.py @@ -0,0 +1,189 @@ +# Copyright 2023 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains a logger to push training logs to the Hub, using Tensorboard.""" + +from pathlib import Path + +from ._commit_scheduler import CommitScheduler +from .errors import EntryNotFoundError +from .repocard import ModelCard +from .utils import experimental + + +# Depending on user's setup, SummaryWriter can come either from 'tensorboardX' +# or from 'torch.utils.tensorboard'. Both are compatible so let's try to load +# from either of them. +try: + from tensorboardX import SummaryWriter as _RuntimeSummaryWriter + + is_summary_writer_available = True +except ImportError: + try: + from torch.utils.tensorboard import SummaryWriter as _RuntimeSummaryWriter + + is_summary_writer_available = True + except ImportError: + # Dummy class to avoid failing at import. Will raise on instance creation. + class _DummySummaryWriter: + pass + + _RuntimeSummaryWriter = _DummySummaryWriter # type: ignore[assignment] # ty: ignore[conflicting-declarations] + is_summary_writer_available = False + + +class HFSummaryWriter(_RuntimeSummaryWriter): + """ + Wrapper around the tensorboard's `SummaryWriter` to push training logs to the Hub. + + Data is logged locally and then pushed to the Hub asynchronously. Pushing data to the Hub is done in a separate + thread to avoid blocking the training script. In particular, if the upload fails for any reason (e.g. a connection + issue), the main script will not be interrupted. Data is automatically pushed to the Hub every `commit_every` + minutes (default to every 5 minutes). + + > [!WARNING] + > `HFSummaryWriter` is experimental. Its API is subject to change in the future without prior notice. + + Args: + repo_id (`str`): + The id of the repo to which the logs will be pushed. + logdir (`str`, *optional*): + The directory where the logs will be written. If not specified, a local directory will be created by the + underlying `SummaryWriter` object. + commit_every (`int` or `float`, *optional*): + The frequency (in minutes) at which the logs will be pushed to the Hub. Defaults to 5 minutes. + squash_history (`bool`, *optional*): + Whether to squash the history of the repo after each commit. Defaults to `False`. Squashing commits is + useful to avoid degraded performances on the repo when it grows too large. + repo_type (`str`, *optional*): + The type of the repo to which the logs will be pushed. Defaults to "model". + repo_revision (`str`, *optional*): + The revision of the repo to which the logs will be pushed. Defaults to "main". + repo_private (`bool`, *optional*): + Whether to make the repo private. If `None` (default), the repo will be public unless the organization's default is private. This value is ignored if the repo already exists. + path_in_repo (`str`, *optional*): + The path to the folder in the repo where the logs will be pushed. Defaults to "tensorboard/". + repo_allow_patterns (`list[str]` or `str`, *optional*): + A list of patterns to include in the upload. Defaults to `"*.tfevents.*"`. Check out the + [upload guide](https://huggingface.co/docs/huggingface_hub/guides/upload#upload-a-folder) for more details. + repo_ignore_patterns (`list[str]` or `str`, *optional*): + A list of patterns to exclude in the upload. Check out the + [upload guide](https://huggingface.co/docs/huggingface_hub/guides/upload#upload-a-folder) for more details. + token (`str`, *optional*): + Authentication token. Will default to the stored token. See https://huggingface.co/settings/token for more + details + kwargs: + Additional keyword arguments passed to `SummaryWriter`. + + Examples: + ```diff + # Taken from https://pytorch.org/docs/stable/tensorboard.html + - from torch.utils.tensorboard import SummaryWriter + + from huggingface_hub import HFSummaryWriter + + import numpy as np + + - writer = SummaryWriter() + + writer = HFSummaryWriter(repo_id="username/my-trained-model") + + for n_iter in range(100): + writer.add_scalar('Loss/train', np.random.random(), n_iter) + writer.add_scalar('Loss/test', np.random.random(), n_iter) + writer.add_scalar('Accuracy/train', np.random.random(), n_iter) + writer.add_scalar('Accuracy/test', np.random.random(), n_iter) + ``` + + ```py + >>> from huggingface_hub import HFSummaryWriter + + # Logs are automatically pushed every 15 minutes (5 by default) + when exiting the context manager + >>> with HFSummaryWriter(repo_id="test_hf_logger", commit_every=15) as logger: + ... logger.add_scalar("a", 1) + ... logger.add_scalar("b", 2) + ``` + """ + + @experimental + def __new__(cls, *args, **kwargs) -> "HFSummaryWriter": + if not is_summary_writer_available: + raise ImportError( + "You must have `tensorboard` installed to use `HFSummaryWriter`. Please run `pip install --upgrade" + " tensorboardX` first." + ) + return super().__new__(cls) + + def __init__( + self, + repo_id: str, + *, + logdir: str | None = None, + commit_every: int | float = 5, + squash_history: bool = False, + repo_type: str | None = None, + repo_revision: str | None = None, + repo_private: bool | None = None, + path_in_repo: str | None = "tensorboard", + repo_allow_patterns: list[str] | str | None = "*.tfevents.*", + repo_ignore_patterns: list[str] | str | None = None, + token: str | None = None, + **kwargs, + ): + # Initialize SummaryWriter + super().__init__(logdir=logdir, **kwargs) + + # Check logdir has been correctly initialized and fail early otherwise. In practice, SummaryWriter takes care of it. + if not isinstance(self.logdir, str): + raise ValueError(f"`self.logdir` must be a string. Got '{self.logdir}' of type {type(self.logdir)}.") + + # Append logdir name to `path_in_repo` + if path_in_repo is None or path_in_repo == "": + path_in_repo = Path(self.logdir).name + else: + path_in_repo = path_in_repo.strip("/") + "/" + Path(self.logdir).name + + # Initialize scheduler + self.scheduler = CommitScheduler( + folder_path=self.logdir, + path_in_repo=path_in_repo, + repo_id=repo_id, + repo_type=repo_type, + revision=repo_revision, + private=repo_private, + token=token, + allow_patterns=repo_allow_patterns, + ignore_patterns=repo_ignore_patterns, + every=commit_every, + squash_history=squash_history, + ) + + # Exposing some high-level info at root level + self.repo_id = self.scheduler.repo_id + self.repo_type = self.scheduler.repo_type + self.repo_revision = self.scheduler.revision + + # Add `hf-summary-writer` tag to the model card metadata + try: + card = ModelCard.load(repo_id_or_path=self.repo_id, repo_type=self.repo_type) + except EntryNotFoundError: + card = ModelCard("") + tags = card.data.get("tags", []) + if "hf-summary-writer" not in tags: + tags.append("hf-summary-writer") + card.data["tags"] = tags + card.push_to_hub(repo_id=self.repo_id, repo_type=self.repo_type) + + def __exit__(self, exc_type, exc_val, exc_tb): + """Push to hub in a non-blocking way when exiting the logger's context manager.""" + super().__exit__(exc_type, exc_val, exc_tb) + future = self.scheduler.trigger() + future.result() diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_tree_cache.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_tree_cache.py new file mode 100644 index 0000000000000000000000000000000000000000..09fe01f8e9d2fb1d7264647e3456e261bed95f50 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_tree_cache.py @@ -0,0 +1,138 @@ +# Copyright 2026-present, the HuggingFace Inc. team. +# +# 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. +"""On-disk cache for repository tree listings. + +A tree listing is the set of files (with their download metadata) contained in a repo at a given commit. Because a +commit hash is immutable, its tree listing never changes and can be cached forever without any invalidation logic. + +The listing is stored as a human-readable JSON file under `/trees/.json`. The +folder depends on the download target: the per-repo `storage_folder` for `cache_dir` downloads, or +`local_dir/.cache/huggingface/` for `local_dir` downloads (see `tree_cache_folder_for_local_dir`). + +```json +{ + "format_version": 1, + "files": { + "config.json": {"size": 519, "blob_id": ""}, + "model.safetensors": {"size": 1234, "blob_id": "...", "lfs_sha256": "", "lfs_size": 1234, "xet_hash": "..."} + } +} +``` +""" + +import json +import os +import tempfile +import threading +from dataclasses import dataclass + +from .utils import logging + + +logger = logging.get_logger(__name__) + +TREE_CACHE_FORMAT_VERSION = 1 + +# In-memory cache of parsed tree listings, keyed by absolute file path. +_IN_MEMORY_TREE_CACHE: dict[str, "dict[str, TreeCacheEntry]"] = {} +_IN_MEMORY_TREE_CACHE_LOCK = threading.Lock() + + +@dataclass(frozen=True) +class TreeCacheEntry: + """Raw metadata of a single file in a cached tree listing, mirroring the `/tree` endpoint fields.""" + + size: int + blob_id: str + lfs_sha256: str | None = None + lfs_size: int | None = None + xet_hash: str | None = None + + def to_json(self) -> dict: + info: dict = {"size": self.size, "blob_id": self.blob_id} + if self.lfs_sha256 is not None: + info["lfs_sha256"] = self.lfs_sha256 + info["lfs_size"] = self.lfs_size + if self.xet_hash is not None: + info["xet_hash"] = self.xet_hash + return info + + @classmethod + def from_json(cls, info: dict) -> "TreeCacheEntry": + return cls( + size=info["size"], + blob_id=info["blob_id"], + lfs_sha256=info.get("lfs_sha256"), + lfs_size=info.get("lfs_size"), + xet_hash=info.get("xet_hash"), + ) + + +def _tree_cache_path(tree_cache_folder: str, commit_hash: str) -> str: + return os.path.join(tree_cache_folder, "trees", f"{commit_hash}.json") + + +def tree_cache_folder_for_local_dir(local_dir: str) -> str: + """Folder under which the `trees/` cache lives for a `local_dir` download.""" + return os.path.join(local_dir, ".cache", "huggingface") + + +def read_tree_cache(tree_cache_folder: str, commit_hash: str) -> dict[str, TreeCacheEntry] | None: + """Return the cached tree listing for a commit hash, or `None` if not cached (or unreadable).""" + path = _tree_cache_path(tree_cache_folder, commit_hash) + with _IN_MEMORY_TREE_CACHE_LOCK: + if path in _IN_MEMORY_TREE_CACHE: + return _IN_MEMORY_TREE_CACHE[path] + entries = _read_tree_cache_from_disk(path) + if entries is not None: + with _IN_MEMORY_TREE_CACHE_LOCK: + _IN_MEMORY_TREE_CACHE[path] = entries + return entries + + +def _read_tree_cache_from_disk(path: str) -> dict[str, TreeCacheEntry] | None: + try: + with open(path, encoding="utf-8") as f: + data = json.load(f) + if data.get("format_version") != TREE_CACHE_FORMAT_VERSION: + # Unknown format (e.g. written by a newer version) => ignore and re-fetch. + return None + return {file_path: TreeCacheEntry.from_json(info) for file_path, info in data["files"].items()} + except FileNotFoundError: + return None + except (OSError, ValueError, KeyError, TypeError) as e: + logger.warning(f"Ignoring corrupted tree cache file {path}: {e}") + return None + + +def write_tree_cache(tree_cache_folder: str, commit_hash: str, entries: dict[str, TreeCacheEntry]) -> None: + """Write the tree listing of a commit hash to the cache (ignoring any failures).""" + path = _tree_cache_path(tree_cache_folder, commit_hash) + data = { + "format_version": TREE_CACHE_FORMAT_VERSION, + "files": {file_path: entries[file_path].to_json() for file_path in sorted(entries)}, + } + try: + os.makedirs(os.path.dirname(path), exist_ok=True) + tmp_fd, tmp_path = tempfile.mkstemp(dir=os.path.dirname(path), suffix=".tmp") + with os.fdopen(tmp_fd, "w", encoding="utf-8") as f: + json.dump(data, f, indent=1) + os.replace(tmp_path, path) + except OSError as e: + logger.warning(f"Ignored error while writing tree cache file {path}: {e}") + return + + # Seed the in-memory cache so later readers of this commit skip re-reading and re-parsing the file. + with _IN_MEMORY_TREE_CACHE_LOCK: + _IN_MEMORY_TREE_CACHE[path] = dict(entries) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_upload_large_folder.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_upload_large_folder.py new file mode 100644 index 0000000000000000000000000000000000000000..2fd0045e6776d2170c5ef31548916ba0fd0470a1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_upload_large_folder.py @@ -0,0 +1,769 @@ +# Copyright 2024-present, the HuggingFace Inc. team. +# +# 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. +import enum +import logging +import os +import queue +import shutil +import sys +import threading +import time +import traceback +from datetime import datetime +from pathlib import Path +from threading import Lock +from typing import TYPE_CHECKING, Any +from urllib.parse import quote + +from ._commit_api import CommitOperationAdd, UploadInfo, _fetch_upload_modes +from ._local_folder import LocalUploadFileMetadata, LocalUploadFilePaths, get_local_upload_paths, read_upload_metadata +from .constants import DEFAULT_REVISION, REPO_TYPES +from .utils import DEFAULT_IGNORE_PATTERNS, _format_size, filter_repo_objects, tqdm +from .utils._runtime import is_xet_available +from .utils.sha import sha_fileobj + + +if TYPE_CHECKING: + from .hf_api import HfApi + +logger = logging.getLogger(__name__) + +WAITING_TIME_IF_NO_TASKS = 10 # seconds +MAX_NB_FILES_FETCH_UPLOAD_MODE = 100 +COMMIT_SIZE_SCALE: list[int] = [20, 50, 75, 100, 125, 200, 250, 400, 600, 1000] + +UPLOAD_BATCH_SIZE_XET = 256 # Max 256 files per upload batch for XET-enabled repos +UPLOAD_BATCH_SIZE_LFS = 1 # Otherwise, batches of 1 for regular LFS upload + +# Repository limits (from https://huggingface.co/docs/hub/repositories-recommendations) +MAX_FILES_PER_REPO = 100_000 # Recommended maximum number of files per repository +MAX_FILES_PER_FOLDER = 10_000 # Recommended maximum number of files per folder +MAX_FILE_SIZE_GB = 200 # Recommended maximum for individual file size (split larger files) +RECOMMENDED_FILE_SIZE_GB = 20 # Recommended maximum for individual file size + + +def _validate_upload_limits(paths_list: list[LocalUploadFilePaths]) -> None: + """ + Validate upload against repository limits and warn about potential issues. + + Args: + paths_list: List of file paths to be uploaded + + Warns about: + - Too many files in the repository (>100k) + - Too many entries (files or subdirectories) in a single folder (>10k) + - Files exceeding size limits (>20GB recommended, >200GB maximum) + """ + logger.info("Running validation checks on files to upload...") + + # Check 1: Total file count + if len(paths_list) > MAX_FILES_PER_REPO: + logger.warning( + f"You are about to upload {len(paths_list):,} files. " + f"This exceeds the recommended limit of {MAX_FILES_PER_REPO:,} files per repository.\n" + f"Consider:\n" + f" - Splitting your data into multiple repositories\n" + f" - Using fewer, larger files (e.g., parquet files)\n" + f" - See: https://huggingface.co/docs/hub/repositories-recommendations" + ) + + # Check 2: Files and subdirectories per folder + # Track immediate children (files and subdirs) for each folder + from collections import defaultdict + + entries_per_folder: dict[str, Any] = defaultdict(lambda: {"files": 0, "subdirs": set()}) + + for paths in paths_list: + path = Path(paths.path_in_repo) + parts = path.parts + + # Count this file in its immediate parent directory + parent = str(path.parent) if str(path.parent) != "." else "." + entries_per_folder[parent]["files"] += 1 + + # Track immediate subdirectories for each parent folder + # Walk through the path components to track parent-child relationships + for i, child in enumerate(parts[:-1]): + parent = "." if i == 0 else "/".join(parts[:i]) + entries_per_folder[parent]["subdirs"].add(child) + + # Check limits for each folder + for folder, data in entries_per_folder.items(): + file_count = data["files"] + subdir_count = len(data["subdirs"]) + total_entries = file_count + subdir_count + + if total_entries > MAX_FILES_PER_FOLDER: + folder_display = "root" if folder == "." else folder + logger.warning( + f"Folder '{folder_display}' contains {total_entries:,} entries " + f"({file_count:,} files and {subdir_count:,} subdirectories). " + f"This exceeds the recommended {MAX_FILES_PER_FOLDER:,} entries per folder.\n" + "Consider reorganising into sub-folders." + ) + + # Check 3: File sizes + large_files = [] + very_large_files = [] + + for paths in paths_list: + size = paths.file_path.stat().st_size + size_gb = size / 1_000_000_000 # Use decimal GB as per Hub limits + + if size_gb > MAX_FILE_SIZE_GB: + very_large_files.append((paths.path_in_repo, size_gb)) + elif size_gb > RECOMMENDED_FILE_SIZE_GB: + large_files.append((paths.path_in_repo, size_gb)) + + # Warn about very large files (>200GB) + if very_large_files: + files_str = "\n - ".join(f"{path}: {size:.1f}GB" for path, size in very_large_files[:5]) + more_str = f"\n ... and {len(very_large_files) - 5} more files" if len(very_large_files) > 5 else "" + logger.warning( + f"Found {len(very_large_files)} files exceeding the {MAX_FILE_SIZE_GB}GB recommended maximum:\n" + f" - {files_str}{more_str}\n" + f"Consider splitting these files into smaller chunks." + ) + + # Warn about large files (>20GB) + if large_files: + files_str = "\n - ".join(f"{path}: {size:.1f}GB" for path, size in large_files[:5]) + more_str = f"\n ... and {len(large_files) - 5} more files" if len(large_files) > 5 else "" + logger.warning( + f"Found {len(large_files)} files larger than {RECOMMENDED_FILE_SIZE_GB}GB (recommended limit):\n" + f" - {files_str}{more_str}\n" + f"Large files may slow down loading and processing." + ) + + logger.info("Validation checks complete.") + + +def upload_large_folder_internal( + api: "HfApi", + repo_id: str, + folder_path: str | Path, + *, + repo_type: str, # Repo type is required! + revision: str | None = None, + private: bool | None = None, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + num_workers: int | None = None, + print_report: bool = True, + print_report_every: int = 60, +): + """Upload a large folder to the Hub in the most resilient way possible. + + See [`HfApi.upload_large_folder`] for the full documentation. + """ + # 1. Check args and setup + if repo_type is None: + raise ValueError( + "For large uploads, `repo_type` is explicitly required. Please set it to `model`, `dataset` or `space`." + " If you are using the CLI, pass it as `--repo-type=model`." + ) + if repo_type not in REPO_TYPES: + raise ValueError(f"Invalid repo type, must be one of {REPO_TYPES}") + if revision is None: + revision = DEFAULT_REVISION + + folder_path = Path(folder_path).expanduser().resolve() + if not folder_path.is_dir(): + raise ValueError(f"Provided path: '{folder_path}' is not a directory") + + if ignore_patterns is None: + ignore_patterns = [] + elif isinstance(ignore_patterns, str): + ignore_patterns = [ignore_patterns] + ignore_patterns += DEFAULT_IGNORE_PATTERNS + + if num_workers is None: + nb_cores = os.cpu_count() or 1 + num_workers = max(nb_cores // 2, 1) # Use at most half of cpu cores + + # 2. Create repo if missing + repo_url = api.create_repo(repo_id=repo_id, repo_type=repo_type, private=private, exist_ok=True) + logger.info(f"Repo created: {repo_url}") + repo_id = repo_url.repo_id + + # Warn on too many commits + try: + commits = api.list_repo_commits(repo_id=repo_id, repo_type=repo_type, revision=revision) + commit_count = len(commits) + if commit_count > 500: + logger.warning( + f"\n{'=' * 80}\n" + f"WARNING: This repository has {commit_count} commits.\n" + f"Repositories with a large number of commits can experience performance issues.\n" + f"\n" + f"Consider squashing your commit history using `super_squash_history()`.\n" + "To do so, you need to stop this process, run the snippet below and restart the upload command." + f" from huggingface_hub import super_squash_history\n" + f" super_squash_history(repo_id='{repo_id}', repo_type='{repo_type}')\n" + f"\n" + f"Note: This is a non-revertible operation. See the documentation for more details:\n" + f"https://huggingface.co/docs/huggingface_hub/main/en/package_reference/hf_api#huggingface_hub.HfApi.super_squash_history\n" + f"{'=' * 80}\n" + ) + except Exception as e: + # Don't fail the upload if we can't check commit count + logger.debug(f"Could not check commit count: {e}") + + # 2.1 Check if xet is enabled to set batch file upload size + upload_batch_size = UPLOAD_BATCH_SIZE_XET if is_xet_available() else UPLOAD_BATCH_SIZE_LFS + + # 3. List files to upload + filtered_paths_list = filter_repo_objects( + (path.relative_to(folder_path).as_posix() for path in folder_path.glob("**/*") if path.is_file()), + allow_patterns=allow_patterns, + ignore_patterns=ignore_patterns, + ) + paths_list = [get_local_upload_paths(folder_path, relpath) for relpath in filtered_paths_list] + logger.info(f"Found {len(paths_list)} candidate files to upload") + + # Validate upload against repository limits + _validate_upload_limits(paths_list) + + logger.info("Starting upload...") + + # Read metadata for each file + items = [ + (paths, read_upload_metadata(folder_path, paths.path_in_repo)) + for paths in tqdm(paths_list, desc="Recovering from metadata files") + ] + + # 4. Start workers + status = LargeUploadStatus(items, upload_batch_size) + threads = [ + threading.Thread( + target=_worker_job, + kwargs={ + "status": status, + "api": api, + "repo_id": repo_id, + "repo_type": repo_type, + "revision": revision, + }, + ) + for _ in range(num_workers) + ] + + for thread in threads: + thread.start() + + # 5. Print regular reports + if print_report: + print("\n\n" + status.current_report()) + last_report_ts = time.time() + while True: + time.sleep(1) + if time.time() - last_report_ts >= print_report_every: + if print_report: + _print_overwrite(status.current_report()) + last_report_ts = time.time() + if status.is_done(): + logger.info("Is done: exiting main loop") + break + + for thread in threads: + thread.join() + + logger.info(status.current_report()) + logger.info("Upload is complete!") + + +#################### +# Logic to manage workers and synchronize tasks +#################### + + +class WorkerJob(enum.Enum): + SHA256 = enum.auto() + GET_UPLOAD_MODE = enum.auto() + PREUPLOAD_LFS = enum.auto() + COMMIT = enum.auto() + WAIT = enum.auto() # if no tasks are available but we don't want to exit + + +JOB_ITEM_T = tuple[LocalUploadFilePaths, LocalUploadFileMetadata] + + +class LargeUploadStatus: + """Contains information, queues and tasks for a large upload process.""" + + def __init__(self, items: list[JOB_ITEM_T], upload_batch_size: int = 1): + self.items = items + self.queue_sha256: "queue.Queue[JOB_ITEM_T]" = queue.Queue() + self.queue_get_upload_mode: "queue.Queue[JOB_ITEM_T]" = queue.Queue() + self.queue_preupload_lfs: "queue.Queue[JOB_ITEM_T]" = queue.Queue() + self.queue_commit: "queue.Queue[JOB_ITEM_T]" = queue.Queue() + self.lock = Lock() + + self.nb_workers_sha256: int = 0 + self.nb_workers_get_upload_mode: int = 0 + self.nb_workers_preupload_lfs: int = 0 + self.upload_batch_size: int = upload_batch_size + self.nb_workers_commit: int = 0 + self.nb_workers_waiting: int = 0 + self.last_commit_attempt: float | None = None + + self._started_at = datetime.now() + self._chunk_idx: int = 1 + self._chunk_lock: Lock = Lock() + + # Setup queues + for item in self.items: + paths, metadata = item + if metadata.sha256 is None: + self.queue_sha256.put(item) + elif metadata.upload_mode is None: + self.queue_get_upload_mode.put(item) + elif metadata.upload_mode == "lfs" and not metadata.is_uploaded: + self.queue_preupload_lfs.put(item) + elif not metadata.is_committed: + self.queue_commit.put(item) + else: + logger.debug(f"Skipping file {paths.path_in_repo} (already uploaded and committed)") + + def target_chunk(self) -> int: + with self._chunk_lock: + return COMMIT_SIZE_SCALE[self._chunk_idx] + + def update_chunk(self, success: bool, nb_items: int, duration: float) -> None: + with self._chunk_lock: + if not success: + logger.warning(f"Failed to commit {nb_items} files at once. Will retry with less files in next batch.") + self._chunk_idx -= 1 + elif nb_items >= COMMIT_SIZE_SCALE[self._chunk_idx] and duration < 40: + logger.info(f"Successfully committed {nb_items} at once. Increasing the limit for next batch.") + self._chunk_idx += 1 + + self._chunk_idx = max(0, min(self._chunk_idx, len(COMMIT_SIZE_SCALE) - 1)) + + def current_report(self) -> str: + """Generate a report of the current status of the large upload.""" + nb_hashed = 0 + size_hashed = 0 + nb_preuploaded = 0 + nb_lfs = 0 + nb_lfs_unsure = 0 + size_preuploaded = 0 + nb_committed = 0 + size_committed = 0 + total_size = 0 + ignored_files = 0 + total_files = 0 + + with self.lock: + for _, metadata in self.items: + if metadata.should_ignore: + ignored_files += 1 + continue + total_size += metadata.size + total_files += 1 + if metadata.sha256 is not None: + nb_hashed += 1 + size_hashed += metadata.size + if metadata.upload_mode == "lfs": + nb_lfs += 1 + if metadata.upload_mode is None: + nb_lfs_unsure += 1 + if metadata.is_uploaded: + nb_preuploaded += 1 + size_preuploaded += metadata.size + if metadata.is_committed: + nb_committed += 1 + size_committed += metadata.size + total_size_str = _format_size(total_size) + + now = datetime.now() + now_str = now.strftime("%Y-%m-%d %H:%M:%S") + elapsed = now - self._started_at + elapsed_str = str(elapsed).split(".")[0] # remove milliseconds + + message = "\n" + "-" * 10 + message += f" {now_str} ({elapsed_str}) " + message += "-" * 10 + "\n" + + message += "Files: " + message += f"hashed {nb_hashed}/{total_files} ({_format_size(size_hashed)}/{total_size_str}) | " + message += f"pre-uploaded: {nb_preuploaded}/{nb_lfs} ({_format_size(size_preuploaded)}/{total_size_str})" + if nb_lfs_unsure > 0: + message += f" (+{nb_lfs_unsure} unsure)" + message += f" | committed: {nb_committed}/{total_files} ({_format_size(size_committed)}/{total_size_str})" + message += f" | ignored: {ignored_files}\n" + + message += "Workers: " + message += f"hashing: {self.nb_workers_sha256} | " + message += f"get upload mode: {self.nb_workers_get_upload_mode} | " + message += f"pre-uploading: {self.nb_workers_preupload_lfs} | " + message += f"committing: {self.nb_workers_commit} | " + message += f"waiting: {self.nb_workers_waiting}\n" + message += "-" * 51 + + return message + + def is_done(self) -> bool: + with self.lock: + return all(metadata.is_committed or metadata.should_ignore for _, metadata in self.items) + + +def _worker_job( + status: LargeUploadStatus, + api: "HfApi", + repo_id: str, + repo_type: str, + revision: str, +): + """ + Main process for a worker. The worker will perform tasks based on the priority list until all files are uploaded + and committed. If no tasks are available, the worker will wait for 10 seconds before checking again. + + If a task fails for any reason, the item(s) are put back in the queue for another worker to pick up. + + Read `upload_large_folder` docstring for more information on how tasks are prioritized. + """ + while True: + next_job: tuple[WorkerJob, list[JOB_ITEM_T]] | None = None + + # Determine next task + next_job = _determine_next_job(status) + if next_job is None: + return + job, items = next_job + + # Perform task + match job: + case WorkerJob.SHA256: + item = items[0] # single item + try: + _compute_sha256(item) + status.queue_get_upload_mode.put(item) + except KeyboardInterrupt: + raise + except Exception as e: + logger.error(f"Failed to compute sha256: {e}") + traceback.format_exc() + status.queue_sha256.put(item) + + with status.lock: + status.nb_workers_sha256 -= 1 + + case WorkerJob.GET_UPLOAD_MODE: + try: + _get_upload_mode(items, api=api, repo_id=repo_id, repo_type=repo_type, revision=revision) + except KeyboardInterrupt: + raise + except Exception as e: + logger.error(f"Failed to get upload mode: {e}") + traceback.format_exc() + + # Items are either: + # - dropped (if should_ignore) + # - put in LFS queue (if LFS) + # - put in commit queue (if regular) + # - or put back (if error occurred). + for item in items: + _, metadata = item + if metadata.should_ignore: + continue + match metadata.upload_mode: + case "lfs": + status.queue_preupload_lfs.put(item) + case "regular": + status.queue_commit.put(item) + case _: + status.queue_get_upload_mode.put(item) + + with status.lock: + status.nb_workers_get_upload_mode -= 1 + + case WorkerJob.PREUPLOAD_LFS: + try: + _preupload_lfs(items, api=api, repo_id=repo_id, repo_type=repo_type, revision=revision) + for item in items: + status.queue_commit.put(item) + except KeyboardInterrupt: + raise + except Exception as e: + logger.error(f"Failed to preupload LFS: {e}") + traceback.format_exc() + for item in items: + status.queue_preupload_lfs.put(item) + + with status.lock: + status.nb_workers_preupload_lfs -= 1 + + case WorkerJob.COMMIT: + start_ts = time.time() + success = True + try: + _commit(items, api=api, repo_id=repo_id, repo_type=repo_type, revision=revision) + except KeyboardInterrupt: + raise + except Exception as e: + logger.error(f"Failed to commit: {e}") + traceback.format_exc() + for item in items: + status.queue_commit.put(item) + success = False + duration = time.time() - start_ts + status.update_chunk(success, len(items), duration) + with status.lock: + status.last_commit_attempt = time.time() + status.nb_workers_commit -= 1 + + case WorkerJob.WAIT: + time.sleep(WAITING_TIME_IF_NO_TASKS) + with status.lock: + status.nb_workers_waiting -= 1 + + +def _determine_next_job(status: LargeUploadStatus) -> tuple[WorkerJob, list[JOB_ITEM_T]] | None: + with status.lock: + # 1. Commit if more than 5 minutes since last commit attempt (and at least 1 file) + if ( + status.nb_workers_commit == 0 + and status.queue_commit.qsize() > 0 + and status.last_commit_attempt is not None + and time.time() - status.last_commit_attempt > 5 * 60 + ): + status.nb_workers_commit += 1 + logger.debug("Job: commit (more than 5 minutes since last commit attempt)") + return (WorkerJob.COMMIT, _get_n(status.queue_commit, status.target_chunk())) + + # 2. Commit if at least 100 files are ready to commit + elif status.nb_workers_commit == 0 and status.queue_commit.qsize() >= 150: + status.nb_workers_commit += 1 + logger.debug("Job: commit (>100 files ready)") + return (WorkerJob.COMMIT, _get_n(status.queue_commit, status.target_chunk())) + + # 3. Get upload mode if at least 100 files + elif status.queue_get_upload_mode.qsize() >= MAX_NB_FILES_FETCH_UPLOAD_MODE: + status.nb_workers_get_upload_mode += 1 + logger.debug(f"Job: get upload mode (>{MAX_NB_FILES_FETCH_UPLOAD_MODE} files ready)") + return (WorkerJob.GET_UPLOAD_MODE, _get_n(status.queue_get_upload_mode, MAX_NB_FILES_FETCH_UPLOAD_MODE)) + + # 4. Preupload LFS file if at least `status.upload_batch_size` files and no worker is preuploading LFS + elif status.queue_preupload_lfs.qsize() >= status.upload_batch_size and status.nb_workers_preupload_lfs == 0: + status.nb_workers_preupload_lfs += 1 + logger.debug("Job: preupload LFS (no other worker preuploading LFS)") + return (WorkerJob.PREUPLOAD_LFS, _get_n(status.queue_preupload_lfs, status.upload_batch_size)) + + # 5. Compute sha256 if at least 1 file and no worker is computing sha256 + elif status.queue_sha256.qsize() > 0 and status.nb_workers_sha256 == 0: + status.nb_workers_sha256 += 1 + logger.debug("Job: sha256 (no other worker computing sha256)") + return (WorkerJob.SHA256, _get_one(status.queue_sha256)) + + # 6. Get upload mode if at least 1 file and no worker is getting upload mode + elif status.queue_get_upload_mode.qsize() > 0 and status.nb_workers_get_upload_mode == 0: + status.nb_workers_get_upload_mode += 1 + logger.debug("Job: get upload mode (no other worker getting upload mode)") + return (WorkerJob.GET_UPLOAD_MODE, _get_n(status.queue_get_upload_mode, MAX_NB_FILES_FETCH_UPLOAD_MODE)) + + # 7. Preupload LFS file if at least `status.upload_batch_size` files + elif status.queue_preupload_lfs.qsize() >= status.upload_batch_size: + status.nb_workers_preupload_lfs += 1 + logger.debug("Job: preupload LFS") + return (WorkerJob.PREUPLOAD_LFS, _get_n(status.queue_preupload_lfs, status.upload_batch_size)) + + # 8. Compute sha256 if at least 1 file + elif status.queue_sha256.qsize() > 0: + status.nb_workers_sha256 += 1 + logger.debug("Job: sha256") + return (WorkerJob.SHA256, _get_one(status.queue_sha256)) + + # 9. Get upload mode if at least 1 file + elif status.queue_get_upload_mode.qsize() > 0: + status.nb_workers_get_upload_mode += 1 + logger.debug("Job: get upload mode") + return (WorkerJob.GET_UPLOAD_MODE, _get_n(status.queue_get_upload_mode, MAX_NB_FILES_FETCH_UPLOAD_MODE)) + + # 10. Preupload LFS file if at least 1 file + elif status.queue_preupload_lfs.qsize() > 0: + status.nb_workers_preupload_lfs += 1 + logger.debug("Job: preupload LFS") + return (WorkerJob.PREUPLOAD_LFS, _get_n(status.queue_preupload_lfs, status.upload_batch_size)) + + # 11. Commit if at least 1 file and 1 min since last commit attempt + elif ( + status.nb_workers_commit == 0 + and status.queue_commit.qsize() > 0 + and status.last_commit_attempt is not None + and time.time() - status.last_commit_attempt > 1 * 60 + ): + status.nb_workers_commit += 1 + logger.debug("Job: commit (1 min since last commit attempt)") + return (WorkerJob.COMMIT, _get_n(status.queue_commit, status.target_chunk())) + + # 12. Commit if at least 1 file all other queues are empty and all workers are waiting + # e.g. when it's the last commit + elif ( + status.nb_workers_commit == 0 + and status.queue_commit.qsize() > 0 + and status.queue_sha256.qsize() == 0 + and status.queue_get_upload_mode.qsize() == 0 + and status.queue_preupload_lfs.qsize() == 0 + and status.nb_workers_sha256 == 0 + and status.nb_workers_get_upload_mode == 0 + and status.nb_workers_preupload_lfs == 0 + ): + status.nb_workers_commit += 1 + logger.debug("Job: commit") + return (WorkerJob.COMMIT, _get_n(status.queue_commit, status.target_chunk())) + + # 13. If all queues are empty, exit + elif all(metadata.is_committed or metadata.should_ignore for _, metadata in status.items): + logger.info("All files have been processed! Exiting worker.") + return None + + # 14. If no task is available, wait + else: + status.nb_workers_waiting += 1 + logger.debug(f"No task available, waiting... ({WAITING_TIME_IF_NO_TASKS}s)") + return (WorkerJob.WAIT, []) + + +#################### +# Atomic jobs (sha256, get_upload_mode, preupload_lfs, commit) +#################### + + +def _compute_sha256(item: JOB_ITEM_T) -> None: + """Compute sha256 of a file and save it in metadata.""" + paths, metadata = item + if metadata.sha256 is None: + with paths.file_path.open("rb") as f: + metadata.sha256 = sha_fileobj(f).hex() + metadata.save(paths) + + +def _get_upload_mode(items: list[JOB_ITEM_T], api: "HfApi", repo_id: str, repo_type: str, revision: str) -> None: + """Get upload mode for each file and update metadata. + + Also receive info if the file should be ignored. + """ + additions = [_build_hacky_operation(item) for item in items] + _fetch_upload_modes( + additions=additions, + repo_type=repo_type, + repo_id=repo_id, + headers=api._build_hf_headers(), + revision=quote(revision, safe=""), + endpoint=api.endpoint, + ) + for item, addition in zip(items, additions): + paths, metadata = item + metadata.upload_mode = addition._upload_mode + metadata.should_ignore = addition._should_ignore + metadata.remote_oid = addition._remote_oid + metadata.save(paths) + + +def _preupload_lfs(items: list[JOB_ITEM_T], api: "HfApi", repo_id: str, repo_type: str, revision: str) -> None: + """Preupload LFS files and update metadata.""" + additions = [_build_hacky_operation(item) for item in items] + api.preupload_lfs_files( + repo_id=repo_id, + repo_type=repo_type, + revision=revision, + additions=additions, + ) + + for paths, metadata in items: + metadata.is_uploaded = True + metadata.save(paths) + + +def _commit(items: list[JOB_ITEM_T], api: "HfApi", repo_id: str, repo_type: str, revision: str) -> None: + """Commit files to the repo.""" + additions = [_build_hacky_operation(item) for item in items] + api.create_commit( + repo_id=repo_id, + repo_type=repo_type, + revision=revision, + operations=additions, + commit_message="Add files using upload-large-folder tool", + ) + for paths, metadata in items: + metadata.is_committed = True + metadata.save(paths) + + +#################### +# Hacks with CommitOperationAdd to bypass checks/sha256 calculation +#################### + + +class HackyCommitOperationAdd(CommitOperationAdd): + def __post_init__(self) -> None: + if isinstance(self.path_or_fileobj, Path): + self.path_or_fileobj = str(self.path_or_fileobj) + + +def _build_hacky_operation(item: JOB_ITEM_T) -> HackyCommitOperationAdd: + paths, metadata = item + operation = HackyCommitOperationAdd(path_in_repo=paths.path_in_repo, path_or_fileobj=paths.file_path) + with paths.file_path.open("rb") as file: + sample = file.peek(512)[:512] + if metadata.sha256 is None: + raise ValueError("sha256 must have been computed by now!") + operation.upload_info = UploadInfo(sha256=bytes.fromhex(metadata.sha256), size=metadata.size, sample=sample) + operation._upload_mode = metadata.upload_mode # type: ignore + operation._should_ignore = metadata.should_ignore + operation._remote_oid = metadata.remote_oid + operation._is_uploaded = metadata.is_uploaded + if metadata.is_uploaded and metadata.upload_mode == "lfs": + operation.path_or_fileobj = b"" + return operation + + +#################### +# Misc helpers +#################### + + +def _get_one(queue: "queue.Queue[JOB_ITEM_T]") -> list[JOB_ITEM_T]: + return [queue.get()] + + +def _get_n(queue: "queue.Queue[JOB_ITEM_T]", n: int) -> list[JOB_ITEM_T]: + return [queue.get() for _ in range(min(queue.qsize(), n))] + + +def _print_overwrite(report: str) -> None: + """Print a report, overwriting the previous lines. + + Since tqdm in using `sys.stderr` to (re-)write progress bars, we need to use `sys.stdout` + to print the report. + + Note: works well only if no other process is writing to `sys.stdout`! + """ + report += "\n" + # Get terminal width + terminal_width = shutil.get_terminal_size().columns + + # Count number of lines that should be cleared + nb_lines = sum(len(line) // terminal_width + 1 for line in report.splitlines()) + + # Clear previous lines based on the number of lines in the report + for _ in range(nb_lines): + sys.stdout.write("\r\033[K") # Clear line + sys.stdout.write("\033[F") # Move cursor up one line + + # Print the new report, filling remaining space with whitespace + sys.stdout.write(report) + sys.stdout.write(" " * (terminal_width - len(report.splitlines()[-1]))) + sys.stdout.flush() diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_upload_pipeline.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_upload_pipeline.py new file mode 100644 index 0000000000000000000000000000000000000000..89def61799ec73cd7b629f6916765371127a20eb --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_upload_pipeline.py @@ -0,0 +1,682 @@ +# coding=utf-8 +# Copyright 2026-present, the HuggingFace Inc. team. +# +# 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. +"""Streamed, multi-commit upload of a folder on top of the Xet upload protocol. + +How it works: + +- The **coordinator** (caller's thread) walks the list of files and asks the Hub, 256 files at a + time, what each file is (regular git blob, xet file, ignored). Regular files are accumulated + directly; xet files are registered into a `XetSession` upload-commit, which chunks, deduplicates, + retries and uploads them in the background while the coordinator keeps going. No Python-side + sha256 computation: `hf_xet` computes it during chunking (single read pass over each file). +- Whenever enough files have accumulated (adaptive batch size), the batch is handed over to the + **committer** thread which joins the xet uploads, drops unchanged files, and creates a git + commit for the batch. While a batch is being committed, the coordinator is already uploading + the next one. +- Interrupted uploads are resumable by simply re-running the same call: already-committed files + are dropped (no-op detection against the remote oid) and already-uploaded chunks are + deduplicated by the xet storage backend, transferring ~0 bytes. +""" + +import queue +import shutil +import sys +import threading +import time +from typing import TYPE_CHECKING, Any, Callable +from urllib.parse import quote + +from . import constants +from ._commit_api import ( + CommitOperationAdd, + CommitOperationDelete, + _fetch_upload_modes, + _send_commit, + _warn_on_overwriting_operations, +) +from .errors import RepositoryNotFoundError +from .utils import are_progress_bars_disabled, logging +from .utils._xet import ( + XetTokenType, + abort_xet_session, + get_xet_session, + xet_connection_info_refresh_url, + xet_headers_without_auth, +) + + +if TYPE_CHECKING: + from .hf_api import CommitInfo, HfApi + +logger = logging.get_logger(__name__) + +# Number of files sent to the "preupload" endpoint per call (server-side limit). +PREUPLOAD_BATCH_SIZE = 256 + +# Files per git commit: adaptive, scaled up after fast commits and down after failures. +COMMIT_SIZE_SCALE = [20, 50, 75, 100, 125, 200, 250, 400, 600, 1000] +INITIAL_COMMIT_SIZE_INDEX = 6 # start at 256 files per commit +TARGET_COMMIT_DURATION = 40.0 # seconds; scale up batch size if commits are faster than this +MAX_COMMIT_INTERVAL = 5 * 60.0 # seconds; force a commit if the current batch is older than this + +# Budget of regular-file content per commit (regular files are base64-encoded in the payload). +REGULAR_CONTENT_BYTES_BUDGET = 100 * 1024 * 1024 + +_SENTINEL = object() # Sentinel value for the batch queue to indicate the end of the upload + +# Live display tuning +_BAR_WIDTH = 20 +_REFRESH_INTERVAL = 0.5 # seconds between redraws on a TTY +_NON_TTY_LOG_INTERVAL = 30.0 # seconds between summary logs when stderr is not a TTY + + +def _bar(current: float, total: float, width: int = _BAR_WIDTH) -> str: + if total <= 0: + return "░" * width + filled = int(min(current / total, 1.0) * width) + return "█" * filled + "░" * (width - filled) + + +def _format_bytes(n: float) -> str: + for unit in ("B", "kB", "MB", "GB", "TB"): + if abs(n) < 1000: + if n < 10: + return f"{n:.2f}{unit}" + elif n < 100: + return f"{n:.1f}{unit}" + return f"{n:.0f}{unit}" + n /= 1000 + return f"{n:.1f}PB" + + +class _LiveDisplay: + """Three-line live progress display on stderr:: + + Preparing ████████████████████ 11,100 / 11,100 ✓ + Uploading ██████████████░░░░░░ 580 / 603 files 3.8GB · 19.7MB/s + Committing ██████████████████░░ 10,800 / 11,100 14 commits + + A small renderer thread redraws the three lines in-place every ~0.5 s on a TTY + (worker threads only update counters under a lock). When stderr is not a TTY, + it falls back to a periodic ``logger.info`` summary instead. + + Disabling progress bars (e.g. agent output mode) only turns off the TTY renderer: + the non-TTY log summaries are gated by the logger verbosity alone, so consumers + tailing stderr during a long upload still see periodic progress. + """ + + _N_LINES = 3 + + def __init__(self, total_files: int, enabled: bool = True) -> None: + self._total = total_files + self._tty = enabled and sys.stderr.isatty() + self._active = self._tty or logger.isEnabledFor(logging.INFO) + self._lock = threading.Lock() + self._drawn = False + self._stop_event = threading.Event() + self._thread: threading.Thread | None = None + + # Counters (written by coordinator/committer threads, read by the renderer) + self._prepared = 0 + self._ignored = 0 + self._xet_total = 0 + self._xet_done: set[str] = set() # item names; unique across batches + self._committed = 0 # committed or skipped-as-unchanged + self._nb_commits = 0 + + # Xet transfer bytes, summed across (possibly concurrent) upload-commits + self._xet_bytes = 0 + self._speed_ema = 0.0 + self._prev_bytes = 0 + self._prev_time: float | None = None + + # -- lifecycle (main thread) ------------------------------------------------ + + def start(self) -> None: + if not self._active: + return + if self._tty: + sys.stderr.write(f"Found {self._total:,} files to upload\n") + sys.stderr.flush() + else: + logger.info(f"Found {self._total:,} files to upload") + self._thread = threading.Thread(target=self._render_loop, name="hf-upload-display", daemon=True) + self._thread.start() + + def close(self) -> None: + if self._thread is not None: + self._stop_event.set() + self._thread.join() + if self._tty: + with self._lock: + self._redraw() # final state + + # -- counter updates (coordinator / committer / xet callback threads) -------- + + def notify_prepared(self, n: int) -> None: + with self._lock: + self._prepared += n + + def notify_ignored(self, n: int) -> None: + with self._lock: + self._ignored += n + + def notify_xet_registered(self, n: int) -> None: + with self._lock: + self._xet_total += n + + def notify_xet_uploaded(self, names: list[str]) -> None: + with self._lock: + self._xet_done.update(names) + + def notify_skipped(self, n: int) -> None: + with self._lock: + self._committed += n + + def notify_commit(self, n_files: int) -> None: + with self._lock: + self._committed += n_files + self._nb_commits += 1 + + def new_xet_callback(self) -> "Callable | None": + """Progress callback for one ``new_upload_commit``. + + The byte counters in ``group_report`` are cumulative *per upload-commit* and several + upload-commits can be in flight at once (one finalizing, one filling), so each commit + gets its own closure tracking its own previous value; increments are summed globally. + """ + if not self._active: + return None + prev = 0 + + def callback(group_report: Any, item_reports: Any) -> None: + nonlocal prev + with self._lock: + completed = group_report.total_transfer_bytes_completed + self._xet_bytes += max(0, completed - prev) + prev = completed + for item in item_reports.values(): + if item.total_bytes > 0 and item.bytes_completed == item.total_bytes: + self._xet_done.add(item.item_name) + + return callback + + # -- rendering (display thread) ---------------------------------------------- + + def _render_loop(self) -> None: + last_log = 0.0 + while not self._stop_event.wait(_REFRESH_INTERVAL): + with self._lock: + self._update_speed() + if self._tty: + self._redraw() + elif time.monotonic() - last_log >= _NON_TTY_LOG_INTERVAL: + logger.info(self._summary()) + last_log = time.monotonic() + + def _update_speed(self) -> None: + now = time.monotonic() + if self._prev_time is not None and now > self._prev_time: + rate = (self._xet_bytes - self._prev_bytes) / (now - self._prev_time) + self._speed_ema = rate if self._speed_ema == 0 else 0.3 * rate + 0.7 * self._speed_ema + self._prev_time = now + self._prev_bytes = self._xet_bytes + + def _redraw(self) -> None: + if self._drawn: + sys.stderr.write(f"\033[{self._N_LINES}A") + width = shutil.get_terminal_size().columns + for line in (self._line_preparing(), self._line_uploading(), self._line_committing()): + truncated = line[: width - 4] + "..." if len(line) > width - 1 else line + sys.stderr.write(f"\r\033[K{truncated}\n") + sys.stderr.flush() + self._drawn = True + + def _line_preparing(self) -> str: + done = " ✓" if self._prepared >= self._total else "" + return f" Preparing {_bar(self._prepared, self._total)} {self._prepared:,} / {self._total:,}{done}" + + def _line_uploading(self) -> str: + if self._xet_total == 0: + bar = _bar(1, 1) if self._prepared >= self._total else _bar(0, 1) + return f" Uploading {bar} -" + n_done = len(self._xet_done) + parts = [] + if self._xet_bytes > 0: + parts.append(_format_bytes(self._xet_bytes)) + if self._speed_ema > 0: + parts.append(f"{_format_bytes(self._speed_ema)}/s") + extra = f" {' · '.join(parts)}" if parts else "" + done = " ✓" if self._prepared >= self._total and n_done >= self._xet_total else "" + return f" Uploading {_bar(n_done, self._xet_total)} {n_done:,} / {self._xet_total:,} files{extra}{done}" + + def _line_committing(self) -> str: + effective = self._total - self._ignored + commits_str = f" {self._nb_commits} commits" if self._nb_commits > 1 else "" + done = " ✓" if self._committed >= effective > 0 else "" + return ( + f" Committing {_bar(self._committed, effective)} {self._committed:,} / {effective:,}{commits_str}{done}" + ) + + def _summary(self) -> str: + return ( + f"Uploading... {self._prepared:,}/{self._total:,} files checked, " + f"{len(self._xet_done):,}/{self._xet_total:,} uploaded ({_format_bytes(self._xet_bytes)} transferred), " + f"{self._committed:,} committed in {self._nb_commits} commit(s)" + ) + + +class _CommitPacer: + """Adaptive number of files per commit, to stay below server-side commit timeouts.""" + + def __init__(self) -> None: + self._index = INITIAL_COMMIT_SIZE_INDEX + + @property + def target(self) -> int: + return COMMIT_SIZE_SCALE[self._index] + + def record_success(self, duration: float, nb_files: int) -> None: + if duration < TARGET_COMMIT_DURATION and nb_files >= self.target: + self._index = min(self._index + 1, len(COMMIT_SIZE_SCALE) - 1) + elif duration > TARGET_COMMIT_DURATION: + self._index = max(self._index - 1, 0) + + def record_failure(self) -> None: + self._index = max(self._index - 1, 0) + + +class _Batch: + """A group of files destined to a single git commit, with their in-flight xet uploads.""" + + def __init__(self) -> None: + self.ops: list[CommitOperationAdd] = [] + self.regular_bytes: int = 0 + self.xet_commit: Any = None # XetUploadCommit, opened lazily + self.handles: list[tuple[CommitOperationAdd, Any]] = [] # (op, XetFileUpload) + self.created_at: float = time.monotonic() + + +class _UploadPipeline: + def __init__( + self, + api: "HfApi", + *, + repo_id: str, + repo_type: str, + add_operations: list[CommitOperationAdd], + delete_operations: list[CommitOperationDelete], + commit_message: str, + commit_description: str | None, + token: str | bool | None, + revision: str | None, + create_pr: bool, + parent_commit: str | None, + ) -> None: + self.api = api + self.repo_id = repo_id + self.repo_type = repo_type + self.add_operations = add_operations + self.delete_operations = delete_operations + self.commit_message = commit_message + self.commit_description = commit_description + self.token = token + self.headers = api._build_hf_headers(token=token) + self.revision = revision or constants.DEFAULT_REVISION + self.create_pr = create_pr + self.parent_commit = parent_commit + + # The base revision is used by the coordinator for ALL preupload calls and the xet token + # refresh URL, with the `create_pr` flag — exactly like `create_commit` does. It never + # changes during the run, even after a PR has been created. + self.base_revision_quoted = quote(self.revision, safe="") + + # Committer state (mutated by the committer thread only) + self.commit_revision_quoted = self.base_revision_quoted # switched to the PR ref once created + self.pr_url: str | None = None + self.pr_revision: str | None = None + self.nb_commits = 0 + self.last_commit_info: "CommitInfo | None" = None + self.pacer = _CommitPacer() + + # Pipeline plumbing + self.batch_queue: queue.Queue = queue.Queue(maxsize=1) + self.errors: list[BaseException] = [] + self.abort_event = threading.Event() + self.display = _LiveDisplay(total_files=len(add_operations), enabled=not are_progress_bars_disabled()) + + # All xet uploads share the same token refresh URL. With `create_pr`, the final ref is not + # known in advance: `?create_pr=1` makes the server grant a token valid for PR refs. + refresh_url = xet_connection_info_refresh_url( + token_type=XetTokenType.WRITE, + repo_id=repo_id, + repo_type=repo_type, + revision=self.base_revision_quoted, + endpoint=api.endpoint, + ) + if create_pr: + refresh_url += "?create_pr=1" + self.xet_session = get_xet_session() + self.xet_commit_kwargs = { + "token_refresh_url": refresh_url, + "token_refresh_headers": self.headers, + "custom_headers": xet_headers_without_auth(self.headers), + } + + # `.gitignore` rules are enforced server-side: forward the local one if it's being uploaded. + self.gitignore_content: str | None = None + for op in add_operations: + if op.path_in_repo == ".gitignore": + with op.as_file() as f: + self.gitignore_content = f.read().decode() + break + + def run(self) -> "CommitInfo": + _warn_on_overwriting_operations([*self.delete_operations, *self.add_operations]) + committer = threading.Thread(target=self._committer_loop, name="hf-upload-committer", daemon=True) + committer.start() + self.display.start() + try: + self._coordinator_loop() + except BaseException: + self.abort_event.set() + abort_xet_session() + raise + finally: + if self.abort_event.is_set(): + # The committer exits on its own once the queue is drained (see `_committer_loop`). + # Bound the wait so a xet call blocked on the (aborted) session can never hang the + # shutdown — the committer is a daemon thread. + committer.join(timeout=10) + else: + self.batch_queue.put(_SENTINEL) + committer.join() + self.display.close() + if self.abort_event.is_set() and self.pr_revision is not None: + logger.warning( + f"Upload to pull request {self.pr_url} did not complete. To resume into the" + f' same PR, re-run with `revision="{self.pr_revision}"` (without `create_pr=True`). Re-running' + " with `create_pr=True` would open a new pull request." + ) + if self.errors: + raise self.errors[0] + return self._final_commit_info() + + # ---------------------------------------------------------------- coordinator + + def _coordinator_loop(self) -> None: + import hf_xet + + batch = _Batch() + for start in range(0, len(self.add_operations), PREUPLOAD_BATCH_SIZE): + if self.abort_event.is_set(): + self._abort_batch(batch) + return + chunk = self.add_operations[start : start + PREUPLOAD_BATCH_SIZE] + try: + _fetch_upload_modes( + additions=chunk, + repo_type=self.repo_type, + repo_id=self.repo_id, + headers=self.headers, + revision=self.base_revision_quoted, + endpoint=self.api.endpoint, + create_pr=self.create_pr, + gitignore_content=self.gitignore_content, + ) + except RepositoryNotFoundError as e: + from .hf_api import _CREATE_COMMIT_NO_REPO_ERROR_MESSAGE + + e.append_to_message(_CREATE_COMMIT_NO_REPO_ERROR_MESSAGE) + raise + self.display.notify_prepared(len(chunk)) + for op in chunk: + if op._should_ignore: + logger.debug(f"Skipping upload for '{op.path_in_repo}' (ignored by gitignore rules).") + self.display.notify_ignored(1) + continue + if op._upload_mode == "regular": + batch.regular_bytes += op.upload_info.size + else: + if batch.xet_commit is None: + batch.xet_commit = self.xet_session.new_upload_commit( + progress_callback=self.display.new_xet_callback(), **self.xet_commit_kwargs + ) + # Upload starts immediately in the background. sha256 is computed by hf_xet + # while chunking, unless already known (e.g. resumed operations). + sha_arg = op.upload_info.sha256.hex() if op.upload_info.is_hashed else hf_xet.COMPUTE_SHA256 + if isinstance(op.path_or_fileobj, bytes): + handle = batch.xet_commit.start_upload_bytes( + op.path_or_fileobj, sha256=sha_arg, name=op.path_in_repo + ) + else: + handle = batch.xet_commit.start_upload_file(str(op.path_or_fileobj), sha256=sha_arg) + batch.handles.append((op, handle)) + self.display.notify_xet_registered(1) + batch.ops.append(op) + + if ( + len(batch.ops) >= self.pacer.target + or batch.regular_bytes >= REGULAR_CONTENT_BYTES_BUDGET + or (time.monotonic() - batch.created_at > MAX_COMMIT_INTERVAL and len(batch.ops) > 0) + ): + self._enqueue(batch) + batch = _Batch() + self._enqueue(batch) + + def _enqueue(self, batch: _Batch) -> None: + if len(batch.ops) == 0 and not (self.nb_commits == 0 and len(self.delete_operations) > 0): + return + # Blocks if a batch is already waiting: natural backpressure on scanning/uploading. + while not self.abort_event.is_set(): + try: + self.batch_queue.put(batch, timeout=1.0) + return + except queue.Full: + continue + self._abort_batch(batch) + + def _abort_batch(self, batch: _Batch) -> None: + if batch.xet_commit is not None: + try: + batch.xet_commit.abort() + except Exception: + pass + + # ---------------------------------------------------------------- committer + + def _committer_loop(self) -> None: + while True: + try: + batch = self.batch_queue.get(timeout=0.5) + except queue.Empty: + if self.abort_event.is_set(): + return # aborted: exit once the queue is drained, no sentinel needed + continue + if batch is _SENTINEL: + return + try: + if not self.abort_event.is_set(): + self._process_batch(batch) + else: + self._abort_batch(batch) + except BaseException as e: + self._abort_batch(batch) + self.errors.append(e) + self.abort_event.set() + + def _process_batch(self, batch: _Batch) -> None: + # 1. Wait for all xet uploads of this batch and finalize them (atomic xet commit). Files + # can only be referenced by a git commit once their xet upload-commit is finalized. + if batch.xet_commit is not None: + batch.xet_commit.wait_to_finish() + for op, handle in batch.handles: + if not op.upload_info.is_hashed: + op.upload_info.sha256 = bytes.fromhex(handle.result().xet_info.sha256) + op._is_uploaded = True + # Files whose last progress tick was missed are still done at this point. + self.display.notify_xet_uploaded( + [ + str(op.path_or_fileobj) if not isinstance(op.path_or_fileobj, bytes) else op.path_in_repo + for op, _ in batch.handles + ] + ) + + # 2. Drop files that have not changed compared to the remote (prevents empty commits). + # Their chunks were deduplicated anyway (~0 bytes transferred). + ops_to_commit = [] + for op in batch.ops: + if op._remote_oid is not None and op._remote_oid == op._local_oid: + logger.debug(f"Skipping commit for '{op.path_in_repo}' (file unchanged).") + self.display.notify_skipped(1) + continue + ops_to_commit.append(op) + + # 3. Create the git commit(s). On failure, scale down and split the batch. + if len(ops_to_commit) > 0 or (self.nb_commits == 0 and len(self.delete_operations) > 0): + self._commit_with_split(ops_to_commit) + + def _commit_with_split(self, ops: list[CommitOperationAdd]) -> None: + try: + self._do_commit(ops) + except Exception as e: + self.pacer.record_failure() + if len(ops) <= COMMIT_SIZE_SCALE[0]: + raise + logger.warning(f"Commit of {len(ops)} files failed ({e!r}). Retrying in smaller chunks.") + target = self.pacer.target + for start in range(0, len(ops), target): + self._commit_with_split(ops[start : start + target]) + + def _do_commit(self, ops: list[CommitOperationAdd]) -> None: + if self.create_pr and self.pr_revision is None: + # Create the (draft) pull request explicitly and push every commit to its ref. Committing + # with `?create_pr=1` instead would risk opening a second PR if the commit POST is retried + # after a lost response. Created lazily so that a fully-unchanged upload opens no PR. + # Note: PRs created this way are always opened against the default branch, hence the + # `create_pr` + `revision` combination being rejected in `upload_folder`. + pr = self.api.create_pull_request( + repo_id=self.repo_id, + title=self.commit_message, + token=self.token, + description=self.commit_description, + repo_type=self.repo_type, + ) + if pr.git_reference is None: + raise ValueError("Server did not return a git reference for the created pull request.") + self.pr_url = pr.url + self.pr_revision = pr.git_reference + self.commit_revision_quoted = quote(pr.git_reference, safe="") + + operations: list[Any] = list(ops) + if self.nb_commits == 0: + # Deletions and `parent_commit` ride the first commit. + operations = list(self.delete_operations) + operations + + commit_message = ( + self.commit_message if self.nb_commits == 0 else f"{self.commit_message} (part {self.nb_commits + 1})" + ) + t0 = time.monotonic() + # Retried with backoff on transient errors: safe because the commit targets an explicit + # ref (`?create_pr=1` is never used, see above). + self.last_commit_info = _send_commit( + operations=operations, + files_to_copy={}, + commit_message=commit_message, + commit_description=self.commit_description or "", + repo_type=self.repo_type, + repo_id=self.repo_id, + headers=self.headers, + revision=self.commit_revision_quoted, + endpoint=self.api.endpoint, + parent_commit=self.parent_commit if self.nb_commits == 0 else None, + retry_on_error=True, + ) + duration = time.monotonic() - t0 + self.pacer.record_success(duration, len(ops)) + self.nb_commits += 1 + + for op in ops: + op._is_committed = True + self.display.notify_commit(len(ops)) + logger.debug(f"Committed {len(ops)} file(s) in {duration:.1f}s: {self.last_commit_info.commit_url}") + + # ---------------------------------------------------------------- result + + def _final_commit_info(self) -> "CommitInfo": + from .hf_api import CommitInfo + + if self.last_commit_info is None: + # Nothing was committed (everything unchanged/ignored): mimic `create_commit` and + # return info about the latest commit on the target revision. + logger.warning("No files have been modified since last commit. Skipping to prevent empty commit.") + info = self.api.repo_info(repo_id=self.repo_id, repo_type=self.repo_type, revision=self.revision) + url_prefix = self.api.endpoint + if self.repo_type != constants.REPO_TYPE_MODEL: + url_prefix = f"{url_prefix}/{self.repo_type}s" + return CommitInfo( + commit_url=f"{url_prefix}/{self.repo_id}/commit/{info.sha}", + commit_message=self.commit_message, + commit_description=self.commit_description or "", + oid=info.sha, # type: ignore + _endpoint=self.api.endpoint, + ) + if self.nb_commits > 1: + logger.info(f"Upload completed in {self.nb_commits} commits.") + if self.pr_url is not None: + # PR upload: attach the PR info (commit responses don't carry it; the PR is created separately). + return CommitInfo( + commit_url=self.last_commit_info.commit_url, + commit_message=self.last_commit_info.commit_message, + commit_description=self.last_commit_info.commit_description, + oid=self.last_commit_info.oid, + pr_url=self.pr_url, + _endpoint=self.api.endpoint, + ) + return self.last_commit_info + + +def pipelined_upload( + api: "HfApi", + *, + repo_id: str, + repo_type: str, + add_operations: list[CommitOperationAdd], + delete_operations: list[CommitOperationDelete], + commit_message: str, + commit_description: str | None = None, + token: str | bool | None = None, + revision: str | None = None, + create_pr: bool = False, + parent_commit: str | None = None, +) -> "CommitInfo": + """Upload a prepared list of operations through the streamed multi-commit pipeline. + + Requires `hf_xet` to be installed. See module docstring for the architecture. + """ + + return _UploadPipeline( + api, + repo_id=repo_id, + repo_type=repo_type, + add_operations=add_operations, + delete_operations=delete_operations, + commit_message=commit_message, + commit_description=commit_description, + token=token, + revision=revision, + create_pr=create_pr, + parent_commit=parent_commit, + ).run() diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_webhooks_payload.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_webhooks_payload.py new file mode 100644 index 0000000000000000000000000000000000000000..976a97a1d30a5105d26f4cb3746be2c9d10d1e4b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_webhooks_payload.py @@ -0,0 +1,136 @@ +# Copyright 2023-present, the HuggingFace Inc. team. +# +# 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. +"""Contains data structures to parse the webhooks payload.""" + +from typing import Literal + +from .utils import is_pydantic_available + + +if is_pydantic_available(): + from pydantic import BaseModel +else: + # Define a dummy BaseModel to avoid import errors when pydantic is not installed + # Import error will be raised when trying to use the class + + class BaseModel: # type: ignore [no-redef] + def __init__(self, *args, **kwargs) -> None: + raise ImportError( + "You must have `pydantic` installed to use `WebhookPayload`. This is an optional dependency that" + " should be installed separately. Please run `pip install --upgrade pydantic` and retry." + ) + + +# This is an adaptation of the ReportV3 interface implemented in moon-landing. V0, V1 and V2 have been ignored as they +# are not in used anymore. To keep in sync when format is updated in +# https://github.com/huggingface/moon-landing/blob/main/server/lib/HFWebhooks.ts (internal link). + + +WebhookEvent_T = Literal[ + "create", + "delete", + "move", + "update", +] +RepoChangeEvent_T = Literal[ + "add", + "move", + "remove", + "update", +] +RepoType_T = Literal[ + "dataset", + "model", + "space", +] +DiscussionStatus_T = Literal[ + "closed", + "draft", + "open", + "merged", +] +SupportedWebhookVersion = Literal[3] + + +class ObjectId(BaseModel): + id: str + + +class WebhookPayloadUrl(BaseModel): + web: str + api: str | None = None + + +class WebhookPayloadMovedTo(BaseModel): + name: str + owner: ObjectId + + +class WebhookPayloadWebhook(ObjectId): + version: SupportedWebhookVersion + + +class WebhookPayloadEvent(BaseModel): + action: WebhookEvent_T + scope: str + + +class WebhookPayloadDiscussionChanges(BaseModel): + base: str + mergeCommitId: str | None = None + + +class WebhookPayloadComment(ObjectId): + author: ObjectId + hidden: bool + content: str | None = None + url: WebhookPayloadUrl + + +class WebhookPayloadDiscussion(ObjectId): + num: int + author: ObjectId + url: WebhookPayloadUrl + title: str + isPullRequest: bool + status: DiscussionStatus_T + changes: WebhookPayloadDiscussionChanges | None = None + pinned: bool | None = None + + +class WebhookPayloadRepo(ObjectId): + owner: ObjectId + head_sha: str | None = None + name: str + private: bool + subdomain: str | None = None + tags: list[str] | None = None + type: Literal["dataset", "model", "space"] + url: WebhookPayloadUrl + + +class WebhookPayloadUpdatedRef(BaseModel): + ref: str + oldSha: str | None = None + newSha: str | None = None + + +class WebhookPayload(BaseModel): + event: WebhookPayloadEvent + repo: WebhookPayloadRepo + discussion: WebhookPayloadDiscussion | None = None + comment: WebhookPayloadComment | None = None + webhook: WebhookPayloadWebhook + movedTo: WebhookPayloadMovedTo | None = None + updatedRefs: list[WebhookPayloadUpdatedRef] | None = None diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/_webhooks_server.py b/.venv/lib/python3.13/site-packages/huggingface_hub/_webhooks_server.py new file mode 100644 index 0000000000000000000000000000000000000000..8e327d5ee882c503baf3e3a34a8dad4ec3bf6ef2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/_webhooks_server.py @@ -0,0 +1,376 @@ +# Copyright 2023-present, the HuggingFace Inc. team. +# +# 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. +"""Contains `WebhooksServer` and `webhook_endpoint` to create a webhook server easily.""" + +import atexit +import inspect +import os +from collections.abc import Callable +from functools import wraps +from typing import TYPE_CHECKING, Any, Optional + +from .utils import experimental, is_fastapi_available, is_gradio_available + + +if TYPE_CHECKING: + import gradio as gr + from fastapi import Request + +if is_fastapi_available(): + from fastapi import FastAPI, Request + from fastapi.responses import JSONResponse +else: + # Will fail at runtime if FastAPI is not available + FastAPI = Request = JSONResponse = None # type: ignore + + +_global_app: Optional["WebhooksServer"] = None # ty: ignore[invalid-type-form] +_is_local = os.environ.get("SPACE_ID") is None + + +@experimental +class WebhooksServer: + """ + The [`WebhooksServer`] class lets you create an instance of a Gradio app that can receive Huggingface webhooks. + These webhooks can be registered using the [`~WebhooksServer.add_webhook`] decorator. Webhook endpoints are added to + the app as a POST endpoint to the FastAPI router. Once all the webhooks are registered, the `launch` method has to be + called to start the app. + + It is recommended to accept [`WebhookPayload`] as the first argument of the webhook function. It is a Pydantic + model that contains all the information about the webhook event. The data will be parsed automatically for you. + + Check out the [webhooks guide](../guides/webhooks_server) for a step-by-step tutorial on how to set up your + WebhooksServer and deploy it on a Space. + + > [!WARNING] + > `WebhooksServer` is experimental. Its API is subject to change in the future. + + > [!WARNING] + > You must have `gradio` installed to use `WebhooksServer` (`pip install --upgrade gradio`). + + Args: + ui (`gradio.Blocks`, optional): + A Gradio UI instance to be used as the Space landing page. If `None`, a UI displaying instructions + about the configured webhooks is created. + webhook_secret (`str`, optional): + A secret key to verify incoming webhook requests. You can set this value to any secret you want as long as + you also configure it in your [webhooks settings panel](https://huggingface.co/settings/webhooks). You + can also set this value as the `WEBHOOK_SECRET` environment variable. If no secret is provided, the + webhook endpoints are opened without any security. + + Example: + + ```python + import gradio as gr + from huggingface_hub import WebhooksServer, WebhookPayload + + with gr.Blocks() as ui: + ... + + app = WebhooksServer(ui=ui, webhook_secret="my_secret_key") + + @app.add_webhook("/say_hello") + async def hello(payload: WebhookPayload): + return {"message": "hello"} + + app.launch() + ``` + """ + + def __new__(cls, *args, **kwargs) -> "WebhooksServer": # ty: ignore[invalid-type-form] + if not is_gradio_available(): + raise ImportError( + "You must have `gradio` installed to use `WebhooksServer`. Please run `pip install --upgrade gradio`" + " first." + ) + if not is_fastapi_available(): + raise ImportError( + "You must have `fastapi` installed to use `WebhooksServer`. Please run `pip install --upgrade fastapi`" + " first." + ) + return super().__new__(cls) + + def __init__( + self, + ui: Optional["gr.Blocks"] = None, + webhook_secret: str | None = None, + ) -> None: + self._ui = ui + + self.webhook_secret = webhook_secret or os.getenv("WEBHOOK_SECRET") + self.registered_webhooks: dict[str, Callable] = {} + _warn_on_empty_secret(self.webhook_secret) + + def add_webhook(self, path: str | None = None) -> Callable: + """ + Decorator to add a webhook to the [`WebhooksServer`] server. + + Args: + path (`str`, optional): + The URL path to register the webhook function. If not provided, the function name will be used as the + path. In any case, all webhooks are registered under `/webhooks`. + + Raises: + ValueError: If the provided path is already registered as a webhook. + + Example: + ```python + from huggingface_hub import WebhooksServer, WebhookPayload + + app = WebhooksServer() + + @app.add_webhook + async def trigger_training(payload: WebhookPayload): + if payload.repo.type == "dataset" and payload.event.action == "update": + # Trigger a training job if a dataset is updated + ... + + app.launch() + ``` + """ + # Usage: directly as decorator. Example: `@app.add_webhook` + if callable(path): + # If path is a function, it means it was used as a decorator without arguments + return self.add_webhook()(path) + + # Usage: provide a path. Example: `@app.add_webhook(...)` + @wraps(FastAPI.post) + def _inner_post(*args, **kwargs): + func = args[0] + abs_path = f"/webhooks/{(path or func.__name__).strip('/')}" + if abs_path in self.registered_webhooks: + raise ValueError(f"Webhook {abs_path} already exists.") + self.registered_webhooks[abs_path] = func + + return _inner_post + + def launch(self, prevent_thread_lock: bool = False, **launch_kwargs: Any) -> None: + """Launch the Gradio app and register webhooks to the underlying FastAPI server. + + Input parameters are forwarded to Gradio when launching the app. + """ + ui = self._ui or self._get_default_ui() + + # Start Gradio App + # - as non-blocking so that webhooks can be added afterwards + # - as shared if launch locally (to debug webhooks) + launch_kwargs.setdefault("share", _is_local) + self.fastapi_app, _, _ = ui.launch(prevent_thread_lock=True, **launch_kwargs) + + # Register webhooks to FastAPI app + for path, func in self.registered_webhooks.items(): + # Add secret check if required + if self.webhook_secret is not None: + func = _wrap_webhook_to_check_secret(func, webhook_secret=self.webhook_secret) + + # Add route to FastAPI app + self.fastapi_app.post(path)(func) + + # Print instructions and block main thread + space_host = os.environ.get("SPACE_HOST") + url = "https://" + space_host if space_host is not None else (ui.share_url or ui.local_url) + if url is None: + raise ValueError("Cannot find the URL of the app. Please provide a valid `ui` or update `gradio` version.") + url = url.strip("/") + message = "\nWebhooks are correctly setup and ready to use:" + message += "\n" + "\n".join(f" - POST {url}{webhook}" for webhook in self.registered_webhooks) + message += "\nGo to https://huggingface.co/settings/webhooks to setup your webhooks." + print(message) + + if not prevent_thread_lock: + ui.block_thread() + + def _get_default_ui(self) -> "gr.Blocks": + """Default UI if not provided (lists webhooks and provides basic instructions).""" + import gradio as gr + + with gr.Blocks() as ui: + gr.Markdown("# This is an app to process 🤗 Webhooks") + gr.Markdown( + "Webhooks are a foundation for MLOps-related features. They allow you to listen for new changes on" + " specific repos or to all repos belonging to particular set of users/organizations (not just your" + " repos, but any repo). Check out this [guide](https://huggingface.co/docs/hub/webhooks) to get to" + " know more about webhooks on the Huggingface Hub." + ) + gr.Markdown( + f"{len(self.registered_webhooks)} webhook(s) are registered:" + + "\n\n" + + "\n ".join( + f"- [{webhook_path}]({_get_webhook_doc_url(webhook.__name__, webhook_path)})" + for webhook_path, webhook in self.registered_webhooks.items() + ) + ) + gr.Markdown( + "Go to https://huggingface.co/settings/webhooks to setup your webhooks." + + "\nYou app is running locally. Please look at the logs to check the full URL you need to set." + if _is_local + else ( + "\nThis app is running on a Space. You can find the corresponding URL in the options menu" + " (top-right) > 'Embed the Space'. The URL looks like 'https://{username}-{repo_name}.hf.space'." + ) + ) + return ui + + +@experimental +def webhook_endpoint(path: str | None = None) -> Callable: + """Decorator to start a [`WebhooksServer`] and register the decorated function as a webhook endpoint. + + This is a helper to get started quickly. If you need more flexibility (custom landing page or webhook secret), + you can use [`WebhooksServer`] directly. You can register multiple webhook endpoints (to the same server) by using + this decorator multiple times. + + Check out the [webhooks guide](../guides/webhooks_server) for a step-by-step tutorial on how to set up your + server and deploy it on a Space. + + > [!WARNING] + > `webhook_endpoint` is experimental. Its API is subject to change in the future. + + > [!WARNING] + > You must have `gradio` installed to use `webhook_endpoint` (`pip install --upgrade gradio`). + + Args: + path (`str`, optional): + The URL path to register the webhook function. If not provided, the function name will be used as the path. + In any case, all webhooks are registered under `/webhooks`. + + Examples: + The default usage is to register a function as a webhook endpoint. The function name will be used as the path. + The server will be started automatically at exit (i.e. at the end of the script). + + ```python + from huggingface_hub import webhook_endpoint, WebhookPayload + + @webhook_endpoint + async def trigger_training(payload: WebhookPayload): + if payload.repo.type == "dataset" and payload.event.action == "update": + # Trigger a training job if a dataset is updated + ... + + # Server is automatically started at the end of the script. + ``` + + Advanced usage: register a function as a webhook endpoint and start the server manually. This is useful if you + are running it in a notebook. + + ```python + from huggingface_hub import webhook_endpoint, WebhookPayload + + @webhook_endpoint + async def trigger_training(payload: WebhookPayload): + if payload.repo.type == "dataset" and payload.event.action == "update": + # Trigger a training job if a dataset is updated + ... + + # Start the server manually + trigger_training.launch() + ``` + """ + if callable(path): + # If path is a function, it means it was used as a decorator without arguments + return webhook_endpoint()(path) + + @wraps(WebhooksServer.add_webhook) + def _inner(func: Callable) -> Callable: + app = _get_global_app() + app.add_webhook(path)(func) + if len(app.registered_webhooks) == 1: + # Register `app.launch` to run at exit (only once) + atexit.register(app.launch) + + @wraps(app.launch) + def _launch_now(): + # Run the app directly (without waiting atexit) + atexit.unregister(app.launch) + app.launch() + + func.launch = _launch_now # type: ignore + return func + + return _inner + + +def _get_global_app() -> WebhooksServer: # ty: ignore[invalid-type-form] + global _global_app + if _global_app is None: + _global_app = WebhooksServer() + return _global_app + + +def _warn_on_empty_secret(webhook_secret: str | None) -> None: + if webhook_secret is None: + print("Webhook secret is not defined. This means your webhook endpoints will be open to everyone.") + print( + "To add a secret, set `WEBHOOK_SECRET` as environment variable or pass it at initialization: " + "\n\t`app = WebhooksServer(webhook_secret='my_secret', ...)`" + ) + print( + "For more details about webhook secrets, please refer to" + " https://huggingface.co/docs/hub/webhooks#webhook-secret." + ) + else: + print("Webhook secret is correctly defined.") + + +def _get_webhook_doc_url(webhook_name: str, webhook_path: str) -> str: + """Returns the anchor to a given webhook in the docs (experimental)""" + return "/docs#/default/" + webhook_name + webhook_path.replace("/", "_") + "_post" + + +def _wrap_webhook_to_check_secret(func: Callable, webhook_secret: str) -> Callable: + """Wraps a webhook function to check the webhook secret before calling the function. + + This is a hacky way to add the `request` parameter to the function signature. Since FastAPI based itself on route + parameters to inject the values to the function, we need to hack the function signature to retrieve the `Request` + object (and hence the headers). A far cleaner solution would be to use a middleware. However, since + `fastapi==0.90.1`, a middleware cannot be added once the app has started. And since the FastAPI app is started by + Gradio internals (and not by us), we cannot add a middleware. + + This method is called only when a secret has been defined by the user. If a request is sent without the + "x-webhook-secret", the function will return a 401 error (unauthorized). If the header is sent but is incorrect, + the function will return a 403 error (forbidden). + + Inspired by https://stackoverflow.com/a/33112180. + """ + initial_sig = inspect.signature(func) + + @wraps(func) + async def _protected_func(request: Request, **kwargs): + request_secret = request.headers.get("x-webhook-secret") + if request_secret is None: + return JSONResponse({"error": "x-webhook-secret header not set."}, status_code=401) + if request_secret != webhook_secret: + return JSONResponse({"error": "Invalid webhook secret."}, status_code=403) + + # Inject `request` in kwargs if required + if "request" in initial_sig.parameters: + kwargs["request"] = request + + # Handle both sync and async routes + if inspect.iscoroutinefunction(func): + return await func(**kwargs) + else: + return func(**kwargs) + + # Update signature to include request + if "request" not in initial_sig.parameters: + _protected_func.__signature__ = initial_sig.replace( # type: ignore + parameters=( + inspect.Parameter(name="request", kind=inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=Request), + ) + + tuple(initial_sig.parameters.values()) + ) + + # Return protected route + return _protected_func diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/__init__.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..15c9257674e1f57ed2437e5725dc11e082e13e7f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/__init__.py @@ -0,0 +1,14 @@ +# Copyright 2025 The HuggingFace Team. All rights reserved. +# +# 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. +from huggingface_hub.cli._output import out # noqa: F401 diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_city_game.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_city_game.py new file mode 100644 index 0000000000000000000000000000000000000000..85c84ddb7c01efe3e11f08c1c499104a72ab262f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_city_game.py @@ -0,0 +1,661 @@ +"""Interactive isometric city explorer — easter egg for `hf repos ls --explore`.""" + +import dataclasses +import math +import os +import random +import re +import select +import shutil +import sys +import time + +from huggingface_hub.hf_api import RepoStorageInfo + +from ._file_listing import format_size + + +Color = tuple[int, int, int] + +# (top_face, left_face, right_face) — lighter to darker for 3D effect +_TYPE_COLORS: dict[str, tuple[Color, Color, Color]] = { + "model": ((175, 148, 240), (138, 112, 208), (105, 80, 180)), + "dataset": ((245, 128, 128), (222, 92, 92), (190, 60, 60)), + "space": ((245, 175, 85), (218, 140, 55), (185, 110, 30)), + "bucket": ((112, 185, 242), (70, 150, 220), (40, 118, 192)), +} +_EXTRA_COLORS: tuple[Color, Color, Color] = ((168, 176, 188), (128, 136, 148), (90, 98, 110)) +_GRID_COLOR: Color = (178, 182, 190) + +_DX = 4 # isometric half-width (pixels) +_DY = 2 # isometric half-height (pixels) +_MAX_H = 16 # tallest tile (pixels) +_MIN_H = 1 +_COLS = 6 +_EXT = 1 # grid extension beyond tiles +_MAX_TILES = 30 + +# Cursor sprite — pixel art arrow pointer +_OUTLINE: Color = (30, 30, 30) +_FILL: Color = (255, 255, 255) + +_CURSOR_GRID = [ + " X ", + " XWX ", + "XWWWX", + " XWX ", + " X ", +] +_CURSOR_PALETTE: dict[str, Color] = { + "X": _OUTLINE, + "W": _FILL, +} +_CURSOR_H = len(_CURSOR_GRID) + +_MOVE_FRAMES = 8 +_MOVE_DELAY = 0.03 +_CURSOR_PAD = _CURSOR_H + 16 +_GAP = 3 +_MIN_TERM_W = 100 +_MIN_TERM_H = 24 +_SUMMARY_W = 24 + + +# --------------------------------------------------------------------------- +# Data structures +# --------------------------------------------------------------------------- + + +@dataclasses.dataclass +class TileInfo: + grid_row: int + grid_col: int + height: int + top: Color + left: Color + right: Color + repo: RepoStorageInfo | None + + +@dataclasses.dataclass +class CityData: + tiles: list[TileInfo] + rows: int + cols: int + x_off: int + y_off: int + buf_w: int + buf_h: int + total_storage: int + extra_count: int + extra_storage: int + all_repos: list[RepoStorageInfo] + + +# --------------------------------------------------------------------------- +# City layout +# --------------------------------------------------------------------------- + + +def _prepare_city_data(repos: list[RepoStorageInfo]) -> CityData: + sorted_repos = sorted(repos, key=lambda r: r.storage, reverse=True) + display = sorted_repos[:_MAX_TILES] + extra_count = max(0, len(sorted_repos) - _MAX_TILES) + extra_storage = sum(r.storage for r in sorted_repos[_MAX_TILES:]) + total_storage = sum(r.storage for r in repos) + max_storage = max(1, display[0].storage) + + n = len(display) + (1 if extra_count > 0 else 0) + cols = min(n, _COLS) + rows = math.ceil(n / cols) if cols > 0 else 1 + + tiles: list[TileInfo] = [] + for i, repo in enumerate(display): + r, c = divmod(i, cols) + h = max(_MIN_H, round(math.sqrt(repo.storage / max_storage) * _MAX_H)) + top, left, right = _TYPE_COLORS.get(repo.type, _EXTRA_COLORS) + tiles.append(TileInfo(r, c, h, top, left, right, repo)) + if extra_count > 0: + r, c = divmod(len(display), cols) + h = max(_MIN_H, round(math.sqrt(extra_storage / max_storage) * _MAX_H)) + tiles.append(TileInfo(r, c, h, *_EXTRA_COLORS, None)) + + r_lo, r_hi = -_EXT, rows - 1 + _EXT + c_lo, c_hi = -_EXT, cols - 1 + _EXT + + xs: list[int] = [] + ys: list[int] = [] + for rr in range(r_lo, r_hi + 1): + for cc in range(c_lo, c_hi + 1): + cx, cy = (cc - rr) * _DX, (cc + rr) * _DY + xs.extend([cx - _DX, cx + _DX]) + ys.extend([cy, cy + 2 * _DY]) + for tile in tiles: + ys.append((tile.grid_col + tile.grid_row) * _DY - tile.height) + + x_off = -min(xs) + y_off = -min(ys) + buf_w = max(xs) - min(xs) + 1 + buf_h = max(ys) - min(ys) + 1 + if buf_h % 2: + buf_h += 1 + + return CityData( + tiles=tiles, + rows=rows, + cols=cols, + x_off=x_off, + y_off=y_off, + buf_w=buf_w, + buf_h=buf_h, + total_storage=total_storage, + extra_count=extra_count, + extra_storage=extra_storage, + all_repos=repos, + ) + + +# --------------------------------------------------------------------------- +# Drawing primitives +# --------------------------------------------------------------------------- + + +def _draw_diamond_outline(buf: list[list[Color | None]], cx: int, cy: int) -> None: + t = (cx, cy) + r = (cx + _DX, cy + _DY) + b = (cx, cy + 2 * _DY) + ll = (cx - _DX, cy + _DY) + _draw_line(buf, *t, *r, _GRID_COLOR) + _draw_line(buf, *r, *b, _GRID_COLOR) + _draw_line(buf, *b, *ll, _GRID_COLOR) + _draw_line(buf, *ll, *t, _GRID_COLOR) + + +def _draw_block( + buf: list[list[Color | None]], + cx: int, + cy: int, + h: int, + top: Color, + left: Color, + right: Color, +) -> None: + _fill_poly( + buf, + [(cx - _DX, cy + _DY - h), (cx, cy + 2 * _DY - h), (cx, cy + 2 * _DY), (cx - _DX, cy + _DY)], + left, + ) + _fill_poly( + buf, + [(cx, cy + 2 * _DY - h), (cx + _DX, cy + _DY - h), (cx + _DX, cy + _DY), (cx, cy + 2 * _DY)], + right, + ) + _fill_poly( + buf, + [(cx, cy - h), (cx + _DX, cy + _DY - h), (cx, cy + 2 * _DY - h), (cx - _DX, cy + _DY - h)], + top, + ) + + +def _fill_poly(buf: list[list[Color | None]], verts: list[tuple[int, int]], color: Color) -> None: + bh = len(buf) + bw = len(buf[0]) if buf else 0 + all_y = [v[1] for v in verts] + y0 = max(0, min(all_y)) + y1 = min(bh - 1, max(all_y)) + n = len(verts) + for y in range(y0, y1 + 1): + xl: float = float("inf") + xr: float = float("-inf") + for i in range(n): + ax, ay = verts[i] + bx, by = verts[(i + 1) % n] + if ay == by: + if y == ay: + xl = min(xl, float(min(ax, bx))) + xr = max(xr, float(max(ax, bx))) + continue + if not (min(ay, by) <= y <= max(ay, by)): + continue + t = (y - ay) / (by - ay) + ix = ax + t * (bx - ax) + xl = min(xl, ix) + xr = max(xr, ix) + if xl <= xr: + for x in range(max(0, round(xl)), min(bw, round(xr) + 1)): + buf[y][x] = color + + +def _draw_line(buf: list[list[Color | None]], x0: int, y0: int, x1: int, y1: int, color: Color) -> None: + bh = len(buf) + bw = len(buf[0]) if buf else 0 + dx = abs(x1 - x0) + dy = abs(y1 - y0) + steps = max(dx, dy) + if steps == 0: + if 0 <= y0 < bh and 0 <= x0 < bw: + buf[y0][x0] = color + return + xi = (x1 - x0) / steps + yi = (y1 - y0) / steps + fx, fy = float(x0), float(y0) + for _ in range(steps + 1): + px, py = round(fx), round(fy) + if 0 <= py < bh and 0 <= px < bw: + buf[py][px] = color + fx += xi + fy += yi + + +# --------------------------------------------------------------------------- +# Pixel buffer → terminal +# --------------------------------------------------------------------------- + +_ANSI_RE = re.compile(r"\033\[[0-9;]*m") + + +def _strip_ansi(s: str) -> str: + return _ANSI_RE.sub("", s) + + +def _visible_len(s: str) -> int: + return len(_strip_ansi(s)) + + +def _pixels_to_lines(buf: list[list[Color | None]]) -> list[str]: + height = len(buf) + width = len(buf[0]) if buf else 0 + lines: list[str] = [] + for row in range(0, height, 2): + last = -1 + for col in range(width - 1, -1, -1): + top = buf[row][col] + bot = buf[row + 1][col] if row + 1 < height else None + if top or bot: + last = col + break + if last < 0: + lines.append("") + continue + + parts: list[str] = [] + cfg: Color | None = None + cbg: Color | None = None + + for col in range(last + 1): + top = buf[row][col] + bot = buf[row + 1][col] if row + 1 < height else None + + if not top and not bot: + if cfg is not None or cbg is not None: + parts.append("\033[0m") + cfg = cbg = None + parts.append(" ") + continue + + if top and bot and top == bot: + nfg, nbg, ch = top, None, "█" + elif top and bot: + nfg, nbg, ch = bot, top, "▄" + elif top: + nfg, nbg, ch = top, None, "▀" + else: + nfg, nbg, ch = bot, None, "▄" # type: ignore[assignment] + + esc = "" + if nfg != cfg: + esc += f"\033[38;2;{nfg[0]};{nfg[1]};{nfg[2]}m" + cfg = nfg + if nbg != cbg: + esc += "\033[49m" if nbg is None else f"\033[48;2;{nbg[0]};{nbg[1]};{nbg[2]}m" + cbg = nbg + parts.append(esc + ch) + + if cfg is not None or cbg is not None: + parts.append("\033[0m") + lines.append("".join(parts)) + return lines + + +# --------------------------------------------------------------------------- +# Rendering +# --------------------------------------------------------------------------- + + +def _render_base_buffer(city: CityData) -> list[list[Color | None]]: + buf: list[list[Color | None]] = [[None] * city.buf_w for _ in range(city.buf_h)] + + for tile in city.tiles: + cx = city.x_off + (tile.grid_col - tile.grid_row) * _DX + cy = city.y_off + (tile.grid_col + tile.grid_row) * _DY + _draw_diamond_outline(buf, cx, cy) + + sorted_tiles = sorted(city.tiles, key=lambda t: (t.grid_row + t.grid_col, t.grid_col)) + for tile in sorted_tiles: + cx = city.x_off + (tile.grid_col - tile.grid_row) * _DX + cy = city.y_off + (tile.grid_col + tile.grid_row) * _DY + _draw_block(buf, cx, cy, tile.height, tile.top, tile.left, tile.right) + + return buf + + +# --------------------------------------------------------------------------- +# Summary panel +# --------------------------------------------------------------------------- + + +def _colored_square(color: Color) -> str: + return f"\033[38;2;{color[0]};{color[1]};{color[2]}m■\033[0m" + + +def _build_summary( + repos: list[RepoStorageInfo], + total_storage: int, + extra_count: int, +) -> list[str]: + lines: list[str] = [""] + lines.append(" Storage Overview") + lines.append(" " + "─" * 16) + lines.append(f" {format_size(total_storage, human_readable=True)} total") + lines.append("") + + order = ["model", "dataset", "space", "bucket"] + labels = {"model": "Models", "dataset": "Datasets", "space": "Spaces", "bucket": "Buckets"} + for rtype in order: + group = [r for r in repos if r.type == rtype] + if not group: + continue + storage = sum(r.storage for r in group) + sq = _colored_square(_TYPE_COLORS[rtype][0]) + lines.append(f" {sq} {labels[rtype]}") + lines.append(f" {len(group)} repos · {format_size(storage, human_readable=True)}") + lines.append("") + + if extra_count > 0: + sq = _colored_square(_EXTRA_COLORS[0]) + lines.append(f" {sq} +{extra_count} more repos") + + return lines + + +# --------------------------------------------------------------------------- +# Cursor +# --------------------------------------------------------------------------- + + +def _build_cursor() -> list[tuple[int, int, Color]]: + pixels: list[tuple[int, int, Color]] = [] + for ri, row in enumerate(_CURSOR_GRID): + for ci, ch in enumerate(row): + if ch in _CURSOR_PALETTE: + pixels.append((ci - len(row) // 2, ri - _CURSOR_H + 1, _CURSOR_PALETTE[ch])) + return pixels + + +_CURSOR_PIXELS = _build_cursor() + + +# --------------------------------------------------------------------------- +# Interactive game +# --------------------------------------------------------------------------- + + +def run_city_game(repos: list[RepoStorageInfo]) -> None: + """Launch the interactive city explorer.""" + if not repos: + print("No repositories found.") + return + + try: + import termios + import tty + except ImportError: + print("Interactive mode requires a Unix-like terminal (Linux/macOS).") + return + + if not sys.stdin.isatty() or not sys.stdout.isatty(): + print("Interactive mode requires a terminal.") + return + + term = shutil.get_terminal_size() + if term.columns < _MIN_TERM_W or term.lines < _MIN_TERM_H: + print(f"Your terminal is {term.columns}×{term.lines} characters.") + print(f"Please resize to at least {_MIN_TERM_W}×{_MIN_TERM_H} to explore the city!") + return + + city = _prepare_city_data(repos) + + tiles_with_repos = [t for t in city.tiles if t.repo is not None] + start_tile = random.choice(tiles_with_repos) if tiles_with_repos else city.tiles[0] + + fd = sys.stdin.fileno() + old_settings = termios.tcgetattr(fd) + try: + tty.setraw(fd) + sys.stdout.write("\033[?1049h\033[?25l\033[2J") + sys.stdout.flush() + _game_loop(city, start_tile.grid_row, start_tile.grid_col) + finally: + sys.stdout.write("\033[?25h\033[?1049l") + sys.stdout.flush() + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + + +def _game_loop(city: CityData, cur_row: int, cur_col: int) -> None: + tile_map: dict[tuple[int, int], TileInfo] = {(t.grid_row, t.grid_col): t for t in city.tiles} + city = dataclasses.replace(city, buf_h=city.buf_h + _CURSOR_PAD, y_off=city.y_off + _CURSOR_PAD) + base_buf = _render_base_buffer(city) + + summary = _build_summary(city.all_repos, city.total_storage, city.extra_count) + + # Intro: cursor drops onto starting tile + tx, ty = _tile_top_center(city, cur_row, cur_col, tile_map) + for i in range(1, _MOVE_FRAMES + 1): + t = i / _MOVE_FRAMES + t = t * t * (3 - 2 * t) + drop_y = ty - 16 * (1 - t) + frame = _copy_buf(base_buf) + _highlight_tile(frame, city, tile_map[(cur_row, cur_col)]) + _draw_cursor(frame, tx, round(drop_y)) + _present(city, frame, tile_map.get((cur_row, cur_col)), summary) + time.sleep(_MOVE_DELAY) + + while True: + cx, cy = _tile_top_center(city, cur_row, cur_col, tile_map) + frame = _copy_buf(base_buf) + _highlight_tile(frame, city, tile_map[(cur_row, cur_col)]) + _draw_cursor(frame, cx, cy) + _present(city, frame, tile_map.get((cur_row, cur_col)), summary) + + key = _read_key() + if key in ("q", "Q", "esc", "\x03"): + return + + dr, dc = _key_to_direction(key) + if dr == 0 and dc == 0: + continue + + nr, nc = cur_row + dr, cur_col + dc + if (nr, nc) not in tile_map: + continue + + ex, ey = _tile_top_center(city, nr, nc, tile_map) + for i in range(1, _MOVE_FRAMES + 1): + t = i / _MOVE_FRAMES + t = t * t * (3 - 2 * t) + bx = cx + (ex - cx) * t + by = cy + (ey - cy) * t + frame = _copy_buf(base_buf) + _highlight_tile(frame, city, tile_map[(nr, nc)]) + _draw_cursor(frame, round(bx), round(by)) + _present(city, frame, tile_map.get((nr, nc)), summary) + time.sleep(_MOVE_DELAY) + + cur_row, cur_col = nr, nc + + +def _tile_top_center(city: CityData, row: int, col: int, tile_map: dict[tuple[int, int], TileInfo]) -> tuple[int, int]: + tile = tile_map.get((row, col)) + h = tile.height if tile else 1 + cx = city.x_off + (col - row) * _DX + cy = city.y_off + (col + row) * _DY + return cx, cy + _DY - h + + +def _key_to_direction(key: str) -> tuple[int, int]: + match key: + case "w" | "W" | "\x1b[A": + return -1, 0 + case "s" | "S" | "\x1b[B": + return 1, 0 + case "a" | "A" | "\x1b[D": + return 0, -1 + case "d" | "D" | "\x1b[C": + return 0, 1 + case _: + return 0, 0 + + +def _draw_cursor(buf: list[list[Color | None]], cx: int, cy: int) -> None: + bh = len(buf) + bw = len(buf[0]) if buf else 0 + for dx, dy, color in _CURSOR_PIXELS: + px, py = cx + dx, cy + dy + if 0 <= py < bh and 0 <= px < bw: + buf[py][px] = color + + +def _highlight_tile(buf: list[list[Color | None]], city: CityData, tile: TileInfo) -> None: + cx = city.x_off + (tile.grid_col - tile.grid_row) * _DX + cy = city.y_off + (tile.grid_col + tile.grid_row) * _DY + h = tile.height + _fill_poly( + buf, + [(cx, cy - h), (cx + _DX, cy + _DY - h), (cx, cy + 2 * _DY - h), (cx - _DX, cy + _DY - h)], + _brighten(tile.top, 35), + ) + + +def _brighten(color: Color, amount: int) -> Color: + return (min(255, color[0] + amount), min(255, color[1] + amount), min(255, color[2] + amount)) + + +def _present( + city: CityData, + buf: list[list[Color | None]], + tile: TileInfo | None, + summary: list[str], +) -> None: + city_lines = _pixels_to_lines(buf) + while city_lines and not _strip_ansi(city_lines[0]).strip(): + city_lines.pop(0) + while city_lines and not _strip_ansi(city_lines[-1]).strip(): + city_lines.pop() + + city_w = max((_visible_len(line) for line in city_lines), default=0) + term = shutil.get_terminal_size() + panel_max_w = max(20, term.columns - city_w - _SUMMARY_W - 2 * _GAP) + + info = _build_info_panel(tile, city, panel_max_w) + + n = max(len(summary), len(city_lines), len(info)) + summary_lo = max(0, (n - len(summary)) // 2) + info_lo = max(0, (n - len(info)) // 2) + + lines: list[str] = [] + for i in range(n): + si = i - summary_lo + lt = summary[si] if 0 <= si < len(summary) else "" + lpad = max(0, _SUMMARY_W - _visible_len(lt)) + + ct = city_lines[i] if i < len(city_lines) else "" + cpad = max(0, city_w - _visible_len(ct)) + + ri = i - info_lo + rt = info[ri] if 0 <= ri < len(info) else "" + + lines.append(lt + " " * lpad + " " * _GAP + ct + " " * cpad + " " * _GAP + rt) + + lines.append("") + lines.append(" \033[90mWASD/Arrows: move · Q/ESC: quit\033[0m") + + while len(lines) < term.lines - 1: + lines.append("") + + output = "\033[H" + for line in lines[: term.lines - 1]: + output += line + "\033[K\r\n" + sys.stdout.write(output) + sys.stdout.flush() + + +def _build_info_panel(tile: TileInfo | None, city: CityData, max_w: int) -> list[str]: + reset = "\033[0m" + gray = "\033[90m" + bold = "\033[1m" + indent = " " + content_w = max_w - len(indent) + + lines: list[str] = [""] + lines.append(f"{indent}{bold}City Explorer{reset}") + lines.append(indent + "─" * min(22, content_w)) + lines.append("") + + if tile is None: + lines.append(f"{indent}{gray}Move to a tile") + lines.append(f"{indent}to see details.{reset}") + return lines + + if tile.repo is None: + lines.append(f"{indent}{gray}+{city.extra_count} more repos{reset}") + lines.append(f"{indent}{gray}{format_size(city.extra_storage, human_readable=True)} combined{reset}") + return lines + + repo = tile.repo + name = repo.id + if len(name) > content_w: + name = name[: content_w - 3] + "..." + lines.append(f"{indent}{bold}{name}{reset}") + lines.append("") + + type_ansi = { + "model": "\033[38;2;175;148;240m", + "dataset": "\033[38;2;245;128;128m", + "space": "\033[38;2;245;175;85m", + "bucket": "\033[38;2;112;185;242m", + } + tc = type_ansi.get(repo.type, "") + + lines.append(f"{indent}Type {tc}{repo.type}{reset}") + lines.append(f"{indent}Visibility {repo.visibility}") + lines.append(f"{indent}Storage {format_size(repo.storage, human_readable=True)}") + lines.append(f"{indent}Usage {repo.storage_percent:.1f}%") + lines.append("") + + bar_w = min(18, content_w) + filled = max(0, min(bar_w, round(repo.storage_percent / 100 * bar_w))) + lines.append(f"{indent}{tc}{'█' * filled}{gray}{'░' * (bar_w - filled)}{reset}") + + return lines + + +def _copy_buf(buf: list[list[Color | None]]) -> list[list[Color | None]]: + return [row[:] for row in buf] + + +def _read_key() -> str: + fd = sys.stdin.fileno() + ch = os.read(fd, 1) + if ch == b"\x1b": + if _has_input(fd, 0.05): + ch2 = os.read(fd, 1) + if ch2 == b"[" and _has_input(fd, 0.05): + ch3 = os.read(fd, 1) + return f"\x1b[{ch3.decode()}" + return "esc" + return ch.decode("utf-8", errors="replace") + + +def _has_input(fd: int, timeout: float) -> bool: + r, _, _ = select.select([fd], [], [], timeout) + return bool(r) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_cli_utils.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_cli_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..0bb0e25aabb394328d930a9458d126f110d19950 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_cli_utils.py @@ -0,0 +1,1069 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains CLI utilities (styling, helpers).""" + +import difflib +import importlib.metadata +import os +import re +import shlex +import subprocess +import sys +import time +from collections.abc import Callable, Sequence +from enum import Enum +from pathlib import Path +from typing import TYPE_CHECKING, Annotated, Any, Literal, TypeVar, cast + +import click + +from huggingface_hub import Volume, __version__, constants +from huggingface_hub.errors import CLIError +from huggingface_hub.utils import ( + get_session, + hf_raise_for_status, + installation_method, + logging, + parse_hf_mount, +) +from huggingface_hub.utils._dotenv import load_dotenv + +from ._framework import Argument, HfCommand, HfGroup, Option +from ._help_formatter import StyledContext +from ._output import OutputFormat, out + + +logger = logging.get_logger() + +# Arbitrary default limit for models/datasets/spaces list commands. +REPO_LIST_DEFAULT_LIMIT = 30 + +if TYPE_CHECKING: + from huggingface_hub.hf_api import HfApi + + +def get_hf_api(token: str | None = None) -> "HfApi": + # Import here to avoid circular import + from huggingface_hub.hf_api import HfApi + + return HfApi(token=token, library_name="huggingface-cli", library_version=__version__) + + +#### TYPER UTILS + +CLI_REFERENCE_URL = "https://huggingface.co/docs/huggingface_hub/en/guides/cli" + + +def generate_epilog(examples: list[str], docs_anchor: str | None = None) -> str: + """Generate an epilog with examples and a Learn More section. + + Args: + examples: List of example commands (without the `$ ` prefix). + docs_anchor: Optional anchor for the docs URL (e.g., "#hf-download"). + + Returns: + Formatted epilog string. + """ + docs_url = f"{CLI_REFERENCE_URL}{docs_anchor}" if docs_anchor else CLI_REFERENCE_URL + examples_str = "\n".join(f" $ {ex}" for ex in examples) + return f"""\ +Examples +{examples_str} + +Learn more + Use `hf --help` for more information about a command. + Read the documentation at {docs_url} +""" + + +TOPIC_T = Literal["main", "help"] | str +FallbackHandlerT = Callable[[list[str], set[str]], int | None] +ExpandPropertyT = TypeVar("ExpandPropertyT", bound=str) + + +def _format_epilog_no_indent(epilog: str | None, ctx: click.Context, formatter: click.HelpFormatter) -> None: + """Write the epilog without indentation.""" + if epilog: + formatter.write_paragraph() + for line in epilog.split("\n"): + formatter.write_text(line) + + +_ALIAS_SPLIT = re.compile(r"\s*\|\s*") + + +class HFCliTyperGroup(HfGroup): + """ + CLI Group that: + - lists commands alphabetically within sections. + - separates commands by topic (main, help, etc.). + - formats epilog without extra indentation. + - supports aliases via pipe-separated names (e.g. ``name="list | ls"``). + - consumes the global formatting flags (``--format``, ``--json``, ``-q`` / ``--quiet``, ``--no-truncate``) + anywhere in the args of a leaf command and applies them to ``out``, so leaf + commands don't need to declare these options themselves. + - rewrites ``spaces/user/repo`` to ``user/repo --type space`` for commands that accept ``--type``. + - enriches "No such option" / "No such command" errors with available options or commands. + """ + + context_class = StyledContext + + def invoke(self, ctx: click.Context) -> None: + """Enrich unknown-option errors with available options or subcommands. + + Catches `NoSuchOption` raised during subcommand `make_context()` + (option parsing). For leaf commands (e.g. `hf repos create --test`) + we list the command's options; for groups (e.g. `hf cache --test`) + we list subcommands since groups have no user-facing options. + """ + try: + return super().invoke(ctx) + except click.NoSuchOption as e: + if e.ctx is not None and e.ctx.command is not None: + cmd = e.ctx.command + if isinstance(cmd, click.Group): + # Group has no user-facing options -> show subcommands instead + items = [ + (name, sub.get_short_help_str(limit=80)) + for name in cmd.list_commands(e.ctx) + if (sub := cmd.get_command(e.ctx, name)) is not None and not sub.hidden + ] + _enrich_usage_error(e, "commands", items) + else: + # Leaf command -> show its options using Click's rich formatting + items = [ + record + for p in cmd.get_params(e.ctx) + if isinstance(p, click.Option) and not p.hidden and (record := p.get_help_record(e.ctx)) + ] + _enrich_usage_error(e, "options", items) + raise + + def resolve_command(self, ctx: click.Context, args: list[str]) -> tuple: + cmd_name = args[0] if args and not args[0].startswith("-") else None + cmd = self.get_command(ctx, cmd_name) if cmd_name else None + + if cmd is not None: + self._rewrite_repo_type_prefix(cmd, args) + + try: + name, resolved_cmd, sub_args = super().resolve_command(ctx, args) + except click.UsageError as e: + # Unknown subcommand -> add fuzzy suggestions and list available commands. + if cmd is None and cmd_name is not None: + # Expand aliases ("list | ls" → ["list", "ls"]) for accurate fuzzy matching. + visible_names = [ + alias + for key, registered in self.commands.items() + if not registered.hidden + for alias in _ALIAS_SPLIT.split(key) + ] + matches = difflib.get_close_matches(cmd_name, visible_names) + if matches: + suggestions = ", ".join(f"'{m}'" for m in matches) + setattr(e, "message", f"{e.message.rstrip('.')}. Did you mean {suggestions}?") + items = [ + (name, sub.get_short_help_str(limit=80)) + for name in self.list_commands(ctx) + if (sub := self.get_command(ctx, name)) is not None and not sub.hidden + ] + _enrich_usage_error(e, "commands", items) + raise + + # If we just resolved a leaf command, eagerly consume any global formatting + # flags (--format / --json / -q / --quiet / --no-truncate) from its args before click parses + # them. Group resolution is recursive — leaves (and only leaves) need this. + if resolved_cmd is not None and not isinstance(resolved_cmd, click.Group): + _consume_format_flags_for_leaf(resolved_cmd, sub_args) + + return name, resolved_cmd, sub_args + + @staticmethod + def _rewrite_repo_type_prefix(cmd: click.Command, args: list[str]) -> None: + """Rewrite prefixed repo IDs (e.g. ``spaces/user/repo``) to ``user/repo --type space``. + + Only applies to commands that have a ``--type`` / ``--repo-type`` option and + at least one repo-ID positional argument (any ``click.Argument`` whose name + ends with ``_id``, e.g. ``repo_id``, ``from_id``, ``to_id``). When the + token that maps to such an argument matches ``{prefix}/org/repo`` (where + *prefix* is one of ``spaces``, ``datasets``, or ``models``), the prefix is + stripped and an implicit ``--type {type}`` is appended. An error is raised + if ``--type`` is also provided explicitly or if multiple prefixed arguments + disagree on the repo type. + + Only repo-ID positional slots are inspected so that other positional + arguments (filenames, local paths, patterns …) are never misinterpreted as + prefixed repo IDs. + """ + has_type_option = any(isinstance(param, click.Option) and "--type" in param.opts for param in cmd.params) + if not has_type_option: + return + + # Locate all repo-ID positional arguments and their indices among Arguments. + repo_id_positions: set[int] = set() + arg_idx = 0 + for param in cmd.params: + if isinstance(param, click.Argument): + if param.name in ("repo_id", "from_id", "to_id"): + repo_id_positions.add(arg_idx) + arg_idx += 1 + + if not repo_id_positions: + return + + # Build a set of option names that consume a following value token. + value_options: set[str] = set() + for param in cmd.params: + if isinstance(param, click.Option) and not param.is_flag: + for opt in (*param.opts, *param.secondary_opts): + value_options.add(opt) + + # Walk through args (skipping args[0] = command name) to map positional + # slots to their indices in `args`. + positional_count = 0 + repo_id_arg_indices: list[int] = [] + i = 1 + while i < len(args): + arg = args[i] + if arg == "--": + break # everything after -- is positional literal; stop rewriting + if arg.startswith("-"): + if "=" in arg or arg not in value_options: + i += 1 # flag or --opt=val — single token + else: + i += 2 # value-taking option — skip the value too + else: + if positional_count in repo_id_positions: + repo_id_arg_indices.append(i) + positional_count += 1 + i += 1 + + if not repo_id_arg_indices: + return + + # Check each repo-ID arg for a type prefix and collect rewrites. + inferred_type: str | None = None + first_prefix: str | None = None + rewrites: list[tuple[int, str]] = [] # (args index, new value without prefix) + + for arg_index in repo_id_arg_indices: + parts = args[arg_index].split("/", 2) + if len(parts) != 3 or parts[0] not in constants.REPO_TYPES_MAPPING: + continue + prefix = parts[0] + mapped_type = constants.REPO_TYPES_MAPPING[prefix] + if inferred_type is not None and mapped_type != inferred_type: + raise click.UsageError(f"Conflicting repo type prefixes: '{first_prefix}/' and '{prefix}/'.") + inferred_type = mapped_type + first_prefix = prefix + rewrites.append((arg_index, f"{parts[1]}/{parts[2]}")) + + if not rewrites: + return + + # Error if --type / --repo-type was also provided explicitly. + if any( + arg == "--type" or arg.startswith("--type=") or arg == "--repo-type" or arg.startswith("--repo-type=") + for arg in args + ): + raise click.UsageError( + f"Ambiguous repo type: got prefix '{first_prefix}/' in repo ID and explicit --type. Use one or the other." + ) + + # Apply all rewrites and append --type once. + for arg_index, new_value in rewrites: + args[arg_index] = new_value + args.extend(["--type", inferred_type]) # type: ignore + + def get_command(self, ctx: click.Context, cmd_name: str) -> click.Command | None: + # Try exact match first + cmd = super().get_command(ctx, cmd_name) + if cmd is not None: + return cmd + # Fall back to alias lookup: check if cmd_name matches any alias + # taken from https://github.com/fastapi/typer/issues/132#issuecomment-2417492805 + for registered_name, registered_cmd in self.commands.items(): + aliases = _ALIAS_SPLIT.split(registered_name) + if cmd_name in aliases: + return registered_cmd + return None + + def _alias_map(self) -> dict[str, list[str]]: + """Build a mapping from primary command name to its aliases (if any).""" + result: dict[str, list[str]] = {} + for registered_name in self.commands: + parts = _ALIAS_SPLIT.split(registered_name) + primary = parts[0] + result[primary] = parts[1:] + return result + + def format_commands(self, ctx: click.Context, formatter: click.HelpFormatter) -> None: + topics: dict[str, list] = {} + alias_map = self._alias_map() + + for name in self.list_commands(ctx): + cmd = self.get_command(ctx, name) + if cmd is None or cmd.hidden: + continue + help_text = cmd.get_short_help_str(limit=formatter.width) + aliases = alias_map.get(name, []) + if aliases: + help_text = f"{help_text} [alias: {', '.join(aliases)}]" + topic = getattr(cmd, "topic", "main") + topics.setdefault(topic, []).append((name, help_text)) + + with formatter.section("Main commands"): + formatter.write_dl(topics["main"]) + for topic in sorted(topics.keys()): + if topic == "main": + continue + with formatter.section(f"{topic.capitalize()} commands"): + formatter.write_dl(topics[topic]) + + def format_epilog(self, ctx: click.Context, formatter: click.HelpFormatter) -> None: + # Collect only the first example from each command (to keep group help concise) + # Full examples are shown in individual subcommand help (e.g. `hf buckets sync --help`) + all_examples: list[str] = [] + for name in self.list_commands(ctx): + cmd = self.get_command(ctx, name) + if cmd is None or cmd.hidden: + continue + cmd_examples = getattr(cmd, "examples", []) + if cmd_examples: + all_examples.append(cmd_examples[0]) + + if all_examples: + epilog = generate_epilog(all_examples) + _format_epilog_no_indent(epilog, ctx, formatter) + elif self.epilog: + _format_epilog_no_indent(self.epilog, ctx, formatter) + + def list_commands(self, ctx: click.Context) -> list[str]: # type: ignore[name-defined] + # For aliased commands ("list | ls"), use the primary name (first entry). + primary_names: list[str] = [] + for name in self.commands: + primary = _ALIAS_SPLIT.split(name)[0] + primary_names.append(primary) + return sorted(primary_names) + + def command( # type: ignore # adds topic/examples on top of HfGroup.command + self, + name: str | None = None, + *, + topic: TOPIC_T = "main", + examples: list[str] | None = None, + epilog: str | None = None, + **kwargs: Any, + ) -> Callable[[Callable[..., Any]], Callable[..., Any]]: + # Generate the epilog from examples when not provided explicitly, then build the + # command with a topic/examples-aware command class. + if epilog is None and examples: + epilog = generate_epilog(examples) + return super().command(name, cls=HFCliCommand(topic, examples), epilog=epilog, **kwargs) + + +_FORMATTING_OPTIONS_HELP_RECORDS: list[tuple[str, str]] = [ + ( + "--format [auto|human|agent|json|quiet]", + "Output format. Defaults to 'auto' which picks 'agent' or 'human' based on the terminal.", + ), + ("--json", "JSON output. Equivalent to '--format json'."), + ("-q, --quiet", "Quiet output (one ID per line). Equivalent to '--format quiet'."), + ("--no-truncate", "Do not truncate scalar values in human tables (list/dict columns stay shortened)."), +] + + +def _format_formatting_options_section(formatter: click.HelpFormatter) -> None: + with formatter.section("Formatting options"): + formatter.write_dl(_FORMATTING_OPTIONS_HELP_RECORDS) + + +def _has_local_formatting_option(cmd: click.Command) -> bool: + """Return True if the command defines its own --format, --json or --quiet / -q. + + Used to skip the global formatting flag pre-processor and the duplicated "Formatting options" help section for + legacy commands like 'hf jobs ls' that have their own format/quiet options. + """ + for param in cmd.params: + if not isinstance(param, click.Option): + continue + opts = (*param.opts, *param.secondary_opts) + if "--format" in opts or "--json" in opts or "--quiet" in opts or "-q" in opts: + return True + return False + + +def _consume_format_flags_for_leaf(cmd: click.Command, args: list[str]) -> None: + """Apply global formatting flags from 'args' to a leaf command. + + Two modes, depending on the command: + + * **Pass-through commands** (ignore_unknown_options=True, e.g. 'hf extensions exec'): + args are forwarded verbatim to an external binary; we don't touch them. + + * **Legacy commands with a local --format option** (e.g. 'hf jobs ls' whose '--format' accepts Go templates): + the global flags are rewritten in-place to the legacy form ('--json' → '--format json', '--quiet'/'-q' → '--format quiet' + when the cmd has no own '--quiet') so click can parse them locally. This preserves backwards compatibility with the previous shorthand behavior. + + * **Modern commands** (no local format/quiet/json options): the flags '--format ' / '--json' / '--quiet' / '-q' are stripped from 'args' and applied to the singleton 'out'. + + '--no-truncate' is stripped for all non-pass-through commands; when present, human table cells are not truncated. + + Raises click.UsageError if multiple conflicting flags are supplied (e.g. '--json' together with '--format table'). + """ + if cmd.context_settings.get("ignore_unknown_options"): + return + + no_truncate = _consume_no_truncate_flags(args) + out.set_no_truncate(no_truncate) + + has_local_format = False + has_local_quiet = False + has_local_json = False + for param in cmd.params: + if not isinstance(param, click.Option): + continue + opts = (*param.opts, *param.secondary_opts) + if "--format" in opts: + has_local_format = True + if "--quiet" in opts or "-q" in opts: + has_local_quiet = True + if "--json" in opts: + has_local_json = True + + if has_local_format: + _rewrite_legacy_shorthands(args, rewrite_json=not has_local_json, rewrite_quiet=not has_local_quiet) + return + + # Strip --format/--json/-q/--quiet from 'args' and apply to 'out' + chosen_mode: OutputFormat = OutputFormat.auto + chosen_flag: str | None = None + + def _check_conflict(new_flag: str) -> None: + # Reject any second formatting flag before parsing values, so the user gets + # a "mutually exclusive" error rather than e.g. an "invalid value" error + # from the second flag's argument. + if chosen_flag is not None: + raise click.UsageError(f"'{chosen_flag}' and '{new_flag}' are mutually exclusive.") + + i = 0 + while i < len(args): + arg = args[i] + if arg == "--": + break # everything after '--' is a positional literal + if arg == "--format": + _check_conflict("--format") + if i + 1 >= len(args): + raise click.UsageError("Option '--format' requires a value.") + chosen_mode = _parse_format_value(args[i + 1]) + chosen_flag = "--format" + del args[i : i + 2] # --format value => 2 args removed + continue + if arg.startswith("--format="): + _check_conflict("--format") + chosen_mode = _parse_format_value(arg[len("--format=") :]) + chosen_flag = "--format" + del args[i : i + 1] + continue + if arg == "--json": + _check_conflict("--json") + chosen_mode = OutputFormat.json + chosen_flag = "--json" + del args[i : i + 1] + continue + if arg in ("-q", "--quiet"): + _check_conflict(arg) + chosen_mode = OutputFormat.quiet + chosen_flag = arg + del args[i : i + 1] + continue + i += 1 + + out.set_mode(chosen_mode) + + +def _consume_no_truncate_flags(args: list[str]) -> bool: + """Strip all global --no-truncate flags from args and return whether any was provided.""" + no_truncate = False + i = 0 + while i < len(args): + arg = args[i] + if arg == "--": + break # everything after '--' is a positional literal + if arg == "--no-truncate": + no_truncate = True + del args[i : i + 1] + continue + if arg.startswith("--no-truncate="): + raise click.UsageError("Option '--no-truncate' does not take a value.") + i += 1 + return no_truncate + + +def _rewrite_legacy_shorthands(args: list[str], *, rewrite_json: bool, rewrite_quiet: bool) -> None: + """Rewrite --json / -q / --quiet to --format ... for legacy commands. + + Used for commands like 'hf jobs ls' that still own their '--format' option. + The rewrite lets users keep using the global shorthand while click parses + '--format ' locally. + """ + has_format_in_args = any(arg == "--format" or arg.startswith("--format=") for arg in args) + + if rewrite_json and "--json" in args: + if has_format_in_args: + raise click.UsageError("'--json' and '--format' are mutually exclusive.") + idx = args.index("--json") + args[idx : idx + 1] = ["--format", "json"] + has_format_in_args = True + + if rewrite_quiet: + flag = "-q" if "-q" in args else ("--quiet" if "--quiet" in args else None) + if flag is not None: + if has_format_in_args: + raise click.UsageError(f"'{flag}' and '--format' are mutually exclusive.") + idx = args.index(flag) + args[idx : idx + 1] = ["--format", "quiet"] + + +def _parse_format_value(value: str) -> "OutputFormat": + try: + return OutputFormat(value) + except ValueError: + valid = ", ".join(m.value for m in OutputFormat) + raise click.UsageError(f"Invalid value for '--format': '{value}'. Valid values: {valid}.") from None + + +def _enrich_usage_error(error: click.UsageError, label: str, items: list[tuple[str, str]]) -> None: + """Append a list of available options or commands to a usage error message.""" + if not items or error.ctx is None or f"Available {label} for" in error.message: + return + cmd_path = error.ctx.command_path + lines = [f"\n\nAvailable {label} for '{cmd_path}':"] + for name, help_text in items: + lines.append(f" {name:30s} {help_text}") + lines.append(f"\nRun '{cmd_path} --help' for full details.") + if isinstance(error, click.NoSuchOption) and error.possibilities: + lines.append(f"\nDid you mean: {', '.join(sorted(error.possibilities))}?") + setattr(error, "possibilities", []) + setattr(error, "message", error.message + "\n".join(lines)) + + +def fallback_typer_group_factory( + fallback_handler: FallbackHandlerT, + extra_commands_provider: Callable[[], list[tuple[str, str]]] | None = None, +) -> type[HFCliTyperGroup]: + """Return a Typer group class that runs a fallback handler before command resolution.""" + + class FallbackTyperGroup(HFCliTyperGroup): + def resolve_command(self, ctx: click.Context, args: list[str]) -> tuple: + fallback_exit_code = fallback_handler(args, set(self.commands.keys())) + if fallback_exit_code is not None: + raise SystemExit(fallback_exit_code) + return super().resolve_command(ctx, args) + + def format_commands(self, ctx: click.Context, formatter: click.HelpFormatter) -> None: + super().format_commands(ctx, formatter) + if extra_commands_provider is not None: + entries = extra_commands_provider() + if entries: + with formatter.section("Extension commands"): + formatter.write_dl(entries) + + return FallbackTyperGroup + + +def HFCliCommand(topic: TOPIC_T, examples: list[str] | None = None) -> type[HfCommand]: + def format_epilog(self: click.Command, ctx: click.Context, formatter: click.HelpFormatter) -> None: + _format_epilog_no_indent(self.epilog, ctx, formatter) + + def format_options(self: HfCommand, ctx: click.Context, formatter: click.HelpFormatter) -> None: + HfCommand.format_options(self, ctx, formatter) + # Skip the section for commands that define their own --format / --quiet / --json, + # or for pass-through commands that forward args to an external binary. + if _has_local_formatting_option(self): + return + if self.context_settings.get("ignore_unknown_options"): + return + _format_formatting_options_section(formatter) + + def parse_args(self: click.Command, ctx: click.Context, args: list[str]) -> list[str]: + # Show help when a command with required arguments is invoked without any args + # (mirrors group behavior: `hf jobs` prints help, so `hf download` should too). + if not args and not ctx.resilient_parsing: + if any(isinstance(p, click.Argument) and p.required for p in self.params): + click.echo(ctx.get_help(), color=ctx.color) + ctx.exit() + return HfCommand.parse_args(self, ctx, args) + + return type( + f"HfCommand{topic.capitalize()}", + (HfCommand,), + { + "context_class": StyledContext, + "topic": topic, + "examples": examples or [], + "format_epilog": format_epilog, + "format_options": format_options, + "parse_args": parse_args, + }, + ) + + +def typer_factory(help: str, epilog: str | None = None, cls: type[HFCliTyperGroup] | None = None) -> "HFCliTyperGroup": + """Create a CLI command group with consistent settings. + + The returned group is the app: register commands with ``@group.command(...)``, + subgroups with ``group.add_group(sub, name=...)``, and a group-level callback + with ``@group.callback(...)``. + + Args: + help: Help text for the group. + epilog: Optional epilog text (use `generate_epilog` to create one). + cls: Optional group class to use (defaults to `HFCliTyperGroup`). + + Returns: + A configured `HFCliTyperGroup` instance. + """ + if cls is None: + cls = HFCliTyperGroup + return cls( + help=help, + epilog=epilog, + no_args_is_help=True, + # Increase max content width for better readability + context_settings={ + "max_content_width": 120, + "help_option_names": ["-h", "--help"], + }, + ) + + +class SoftChoice(click.Choice): + """A click Choice that suggests choices for autocompletion/docs but accepts any string. + + Unlike `click.Choice`, unknown values are passed through as-is instead of raising an error. + This makes CLI options future-compatible when new server-side values are added. + + Accepts either a sequence of strings or an Enum class: + ```python + SoftChoice(SpaceHardware) # from an enum + SoftChoice(["a", "b", "c"]) # from a list + ``` + """ + + def __init__(self, choices: Sequence[str] | type[Enum]) -> None: + values = ( + [m.value for m in choices] if isinstance(choices, type) and issubclass(choices, Enum) else list(choices) + ) + super().__init__(values, case_sensitive=True) + + def convert(self, value: Any, param: click.Parameter | None, ctx: click.Context | None) -> str: + try: + return super().convert(value, param, ctx) + except click.exceptions.BadParameter: + return str(value) + + +class RepoType(str, Enum): + model = "model" + dataset = "dataset" + space = "space" + + +RepoIdArg = Annotated[ + str, + Argument( + help="The ID of the repo (e.g. `username/repo-name` or `spaces/username/repo-name`).", + ), +] + + +RepoTypeOpt = Annotated[ + RepoType, + Option( + "--type", + "--repo-type", + help="The type of repository (model, dataset, or space).", + ), +] + +# Same as `RepoTypeOpt` but optional (defaults to `None` rather than `model`). Used by commands that +# accept an `hf://` URI as repo id: a `None` default lets us tell apart "user did not pass --repo-type" +# from "user explicitly passed --repo-type model", which is required to detect conflicts with the URI. +RepoTypeOptionalOpt = Annotated[ + RepoType | None, + Option( + "--type", + "--repo-type", + help="The type of repository (model, dataset, or space).", + show_default="model", + ), +] + +TokenOpt = Annotated[ + str | None, + Option( + help="A User Access Token generated from https://huggingface.co/settings/tokens.", + ), +] + +PrivateOpt = Annotated[ + bool | None, + Option( + help="Whether to create a private repo if repo doesn't exist on the Hub. Ignored if the repo already exists.", + ), +] + +RevisionOpt = Annotated[ + str | None, + Option( + help="Git revision id which can be a branch name, a tag, or a commit hash.", + ), +] + + +LimitOpt = Annotated[ + int, + Option(help="Limit the number of results."), +] + +AuthorOpt = Annotated[ + str | None, + Option(help="Filter by author or organization."), +] + +FilterOpt = Annotated[ + list[str] | None, + Option(help="Filter by tags (e.g. 'text-classification'). Can be used multiple times."), +] + +SearchOpt = Annotated[ + str | None, + Option(help="Search query."), +] + + +# --- Env / Secrets shared options and parsing helpers (used by jobs, repos, etc.) --- + +EnvOpt = Annotated[ + list[str] | None, + Option( + "-e", + "--env", + help="Set environment variables. E.g. --env ENV=value", + ), +] + +SecretsOpt = Annotated[ + list[str] | None, + Option( + "-s", + "--secrets", + help=( + "Set secret environment variables. E.g. --secrets SECRET=value" + " or `--secrets HF_TOKEN` to pass your Hugging Face token." + ), + ), +] + +EnvFileOpt = Annotated[ + str | None, + Option( + "--env-file", + help="Read in a file of environment variables.", + ), +] + +SecretsFileOpt = Annotated[ + str | None, + Option( + help="Read in a file of secret environment variables.", + ), +] + + +def _get_extended_environ() -> dict[str, str]: + """Return a copy of ``os.environ`` with the user's HF token injected (if available).""" + from huggingface_hub import get_token + + extended_environ = os.environ.copy() + if (token := get_token()) is not None: + extended_environ["HF_TOKEN"] = token + return extended_environ + + +def parse_env_map( + env: list[str] | None = None, + env_file: str | None = None, +) -> dict[str, str | None]: + """Parse ``-e``/``--env``/``-s``/``--secrets`` and ``--env-file``/``--secrets-file`` CLI args into a dict. + + Uses an extended environment that includes the user's HF token so that + bare ``--secrets HF_TOKEN`` resolves correctly. + """ + extended_environ = _get_extended_environ() + env_map: dict[str, str | None] = {} + if env_file: + env_map.update(load_dotenv(Path(env_file).read_text(), environ=extended_environ)) + for env_value in env or []: + env_map.update(load_dotenv(env_value, environ=extended_environ)) + return env_map + + +def env_map_to_key_value_list(env_map: dict[str, str | None]) -> list[dict[str, str]] | None: + """Convert an env/secrets dict to the ``[{"key": ..., "value": ...}]`` format used by the Hub API.""" + if not env_map: + return None + return [{"key": k, "value": v or ""} for k, v in env_map.items()] + + +VolumesOpt = Annotated[ + list[str] | None, + Option( + "-v", + "--volume", + help="Mount one or more volumes. Format: hf://[TYPE/]SOURCE:/MOUNT_PATH[:ro]. " + "TYPE is one of: models, datasets, spaces, buckets. " + "TYPE defaults to models if omitted. " + "models, datasets and spaces are always mounted read-only. buckets are read+write by default. " + "E.g. -v hf://org/m:/data or -v hf://datasets/org/ds:/data or -v hf://buckets/org/b:/mnt:ro", + ), +] + + +def parse_volumes(volumes: list[str] | None) -> "list[Volume] | None": + """Parse volume specs from CLI arguments. + + Format: hf://[TYPE/]SOURCE[/PATH]:/MOUNT_PATH[:ro|:rw] + Where TYPE is one of: models, datasets, spaces, buckets (defaults to models if omitted). + SOURCE is the repo/bucket identifier (e.g. 'username/my-model'). + PATH is an optional subfolder inside the repo/bucket. + MOUNT_PATH starts with '/'. + Optional ':ro' or ':rw' suffix for read-only or read-write. + + Examples: + hf://my-org/my-model:/data (model, implicit type) + hf://models/my-org/my-model:/data (model, explicit type) + hf://datasets/my-org/my-dataset:/data:ro + hf://buckets/my-org/my-bucket:/mnt + hf://spaces/my-org/my-space:/app + hf://datasets/org/ds/train:/data (with path inside repo) + hf://buckets/org/b/sub/dir:/mnt (with path inside bucket) + """ + if not volumes: + return None + + result: list[Volume] = [] + for raw_spec in volumes: + mount = parse_hf_mount(raw_spec) + result.append( + Volume( + type=mount.source.type, + source=mount.source.id, + mount_path=mount.mount_path, + read_only=mount.read_only, + path=mount.source.path_in_repo or None, + revision=mount.source.revision or None, + ) + ) + return result + + +def make_expand_properties_parser(valid_properties: Sequence[ExpandPropertyT]): + """Create a callback to parse and validate comma-separated expand properties.""" + + def _parse_expand_properties(value: str | None) -> list[ExpandPropertyT] | None: + if value is None: + return None + properties = [p.strip() for p in value.split(",")] + for prop in properties: + if prop not in valid_properties: + raise click.BadParameter( + f"Invalid expand property: '{prop}'. Valid values are: {', '.join(valid_properties)}" + ) + return [cast(ExpandPropertyT, prop) for prop in properties] + + return _parse_expand_properties + + +### SSH + + +SshIdentityFileOpt = Annotated[ + Path | None, + Option("-i", "--identity-file", help="Path to the SSH identity file (forwarded to `ssh -i`)."), +] + +SshDryRunOpt = Annotated[ + bool, + Option("--dry-run", help="Print the SSH command instead of running it."), +] + + +def exec_ssh( + destination: str, *, port: int | None = None, identity_file: Path | None = None, dry_run: bool = False +) -> None: + """Run an interactive `ssh` command to `destination` (`user@host`) and exit with its return code. + + With `dry_run`, print the command instead of running it. + """ + cmd = ["ssh"] + if identity_file is not None: + cmd += ["-i", str(identity_file)] + if port is not None: + cmd += ["-p", str(port)] + cmd.append(destination) + if dry_run: + out.text(shlex.join(cmd)) + return + out.text(f"Running `{shlex.join(cmd)}`") + result = subprocess.run(cmd) + raise click.exceptions.Exit(code=result.returncode) + + +### PyPI VERSION CHECKER + + +def check_cli_update(library: Literal["huggingface_hub", "transformers"]) -> None: + """ + Check whether a newer version of a library is available on PyPI. + + If a newer version is found, print a hint pointing at `hf update`. + + If current version is a pre-release (e.g. `1.0.0.rc1`), or a dev version (e.g. `1.0.0.dev1`), no check is performed. + If `HF_HUB_DISABLE_UPDATE_CHECK` is set, the check is skipped entirely. + + This function is called at the entry point of the CLI. It only performs the check once every 24 hours, and any error + during the check is caught and logged, to avoid breaking the CLI. + + Args: + library: The library to check for updates. Currently supports "huggingface_hub" and "transformers". + """ + try: + _check_cli_update(library) + except Exception: + # We don't want the CLI to fail on version checks, no matter the reason. + logger.debug("Error while checking for CLI update.", exc_info=True) + + +def _check_cli_update(library: Literal["huggingface_hub", "transformers"]) -> None: + if constants.HF_HUB_DISABLE_UPDATE_CHECK: + return + + current_version = importlib.metadata.version(library) + + # Skip if current version is a pre-release or dev version + if any(tag in current_version for tag in ["rc", "dev"]): + return + + # Skip if already checked in the last 24 hours + if os.path.exists(constants.CHECK_FOR_UPDATE_DONE_PATH): + mtime = os.path.getmtime(constants.CHECK_FOR_UPDATE_DONE_PATH) + if (time.time() - mtime) < 24 * 3600: + return + + # Touch the file to mark that we did the check now + Path(constants.CHECK_FOR_UPDATE_DONE_PATH).parent.mkdir(parents=True, exist_ok=True) + Path(constants.CHECK_FOR_UPDATE_DONE_PATH).touch() + + # Check latest version from the appropriate registry + if library == "huggingface_hub" and installation_method() == "brew": + latest_version = _fetch_latest_brew_version() + else: + latest_version = _fetch_latest_pypi_version(library) + if latest_version is None or current_version == latest_version: + return + + if library == "huggingface_hub": + update_command = _get_huggingface_hub_update_command() + else: + update_command = _get_transformers_update_command() + + message = f"A new version of {library} ({latest_version}) is available! You are using version {current_version}." + if update_command is not None: + match library: + case "huggingface_hub": + message += "\nTo update, run: hf update" + case _: + message += f"\nTo update, run: {' '.join(update_command)}" + out.hint(message) + + +def _fetch_latest_pypi_version(library: str) -> str | None: + """Fetch the latest version of a library from PyPI. Returns None if the request fails.""" + try: + response = get_session().get(f"https://pypi.org/pypi/{library}/json", timeout=2) + hf_raise_for_status(response) + return response.json()["info"]["version"] + except Exception: + logger.debug("Error while fetching latest version from PyPI.", exc_info=True) + return None + + +def _fetch_latest_brew_version() -> str | None: + """Fetch the latest version of the `hf` formula from the Homebrew registry. Returns None if the request fails.""" + try: + response = get_session().get("https://formulae.brew.sh/api/formula/hf.json", timeout=2) + hf_raise_for_status(response) + return response.json()["versions"]["stable"] + except Exception: + logger.debug("Error while fetching latest version from Homebrew.", exc_info=True) + return None + + +def run_update() -> int: + """Run the install-method-appropriate update command for the `hf` CLI. + + Raises CLIError if the installation method can't be determined. + Returns the subprocess exit code on success/failure of the update itself. + """ + cmd = _get_huggingface_hub_update_command() + if cmd is None: + raise CLIError( + "Cannot determine how to update huggingface_hub (unknown installation method). Please update manually." + ) + return subprocess.call(cmd) + + +def _get_huggingface_hub_update_command() -> list[str] | None: + """Return the command to update huggingface_hub as an argv list, or None if the installation method is unknown.""" + match installation_method(): + case "brew": + return ["brew", "upgrade", "hf"] + case "hf_installer" if os.name == "nt": + return ["powershell", "-NoProfile", "-Command", "iwr -useb https://hf.co/cli/install.ps1 | iex"] + case "hf_installer": + return ["bash", "-c", "curl -LsSf https://hf.co/cli/install.sh | bash -"] + case "pip": + return [sys.executable, "-m", "pip", "install", "-U", "huggingface_hub"] + case _: + return None + + +def _get_transformers_update_command() -> list[str] | None: + """Return the command to update transformers as an argv list, or None if the installation method is unknown.""" + match installation_method(): + case "hf_installer" if os.name == "nt": + return [ + "powershell", + "-NoProfile", + "-Command", + "iwr -useb https://hf.co/cli/install.ps1 | iex -WithTransformers", + ] + case "hf_installer": + return ["bash", "-c", "curl -LsSf https://hf.co/cli/install.sh | bash -s -- --with-transformers"] + case "pip": + return [sys.executable, "-m", "pip", "install", "-U", "transformers"] + case _: + return None diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_completion.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_completion.py new file mode 100644 index 0000000000000000000000000000000000000000..cbbb3d1c0ab2e0835eca7692f31644731094fe15 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_completion.py @@ -0,0 +1,105 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""Shell completion for the ``hf`` CLI, built on Click's native completion. + +Click generates completion scripts activated by the ``_HF_COMPLETE`` env var (this +works out of the box because ``hf`` is a Click command). This module exposes the two +conveniences Typer used to provide — ``--install-completion`` / ``--show-completion`` +— as thin eager options over that machinery. +""" + +import os +from pathlib import Path +from typing import Annotated + +import click +from click.shell_completion import get_completion_class + +from ._framework import Option + + +_COMPLETE_VAR = "_HF_COMPLETE" + +# Shells with a shared rc file: the line that activates completion (appended once). +_RC_ACTIVATION: dict[str, tuple[Path, str]] = { + "bash": (Path.home() / ".bashrc", f'eval "$({_COMPLETE_VAR}=bash_source hf)"'), + "zsh": (Path.home() / ".zshrc", f'eval "$({_COMPLETE_VAR}=zsh_source hf)"'), +} +# Fish auto-loads per-command files from its completions directory. The file is dedicated +# to `hf`, so the full script is written there directly (overwriting any stale version) +# instead of re-generating it via `hf` on every shell startup. +_FISH_COMPLETION_PATH = Path.home() / ".config" / "fish" / "completions" / "hf.fish" + + +def _detect_shell() -> str: + return Path(os.environ.get("SHELL", "")).name or "bash" + + +def _completion_script(shell: str) -> str: + # Imported lazily to avoid a circular import (hf.py imports the options below). + from .hf import app + + completion_cls = get_completion_class(shell) + if completion_cls is None: + raise click.ClickException(f"Shell '{shell}' is not supported for completion.") + return completion_cls(app, {}, "hf", _COMPLETE_VAR).source() + + +def _show_completion(value: bool) -> None: + if not value: + return + click.echo(_completion_script(_detect_shell())) + raise click.exceptions.Exit() + + +def _install_completion(value: bool) -> None: + if not value: + return + shell = _detect_shell() + if shell == "fish": + path = _FISH_COMPLETION_PATH + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(_completion_script("fish")) + elif shell in _RC_ACTIVATION: + path, activation = _RC_ACTIVATION[shell] + path.parent.mkdir(parents=True, exist_ok=True) + existing = path.read_text() if path.exists() else "" + if activation not in existing: + with path.open("a") as file: + file.write(f"\n{activation}\n") + else: + raise click.ClickException(f"Shell '{shell}' is not supported for completion.") + click.echo(f"{shell} completion installed in {path}. Restart your shell for it to take effect.") + raise click.exceptions.Exit() + + +InstallCompletionOpt = Annotated[ + bool, + Option( + "--install-completion", + callback=_install_completion, + is_eager=True, + help="Install completion for the current shell.", + ), +] + +ShowCompletionOpt = Annotated[ + bool, + Option( + "--show-completion", + callback=_show_completion, + is_eager=True, + help="Show completion for the current shell, to copy it or customize the installation.", + ), +] diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_cp.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_cp.py new file mode 100644 index 0000000000000000000000000000000000000000..e163cc6596188e052ae177bebaac1cf6786669fb --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_cp.py @@ -0,0 +1,253 @@ +# Copyright 2026-present, the HuggingFace Inc. team. +# +# 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. +"""Shared ``cp`` command to copy files between local paths, repositories and buckets. + +This single command backs three identical CLI entry points: ``hf cp`` (top-level), +``hf repos cp`` and ``hf buckets cp``. It supports any source/destination combination +of local file, repo/bucket ``hf://`` URI, and ``-`` (stdin/stdout), with two exceptions: +- bucket-to-repo copies are not supported (server limitation), and +- local-to-local copies (use a regular ``cp`` for that). +""" + +import os +import sys +from dataclasses import replace +from typing import Annotated, Literal + +import click + +from huggingface_hub import HfApi +from huggingface_hub.errors import CLIError +from huggingface_hub.utils import HfUri, SoftTemporaryDirectory, disable_progress_bars, is_hf_uri, parse_hf_uri + +from ._cli_utils import TokenOpt, get_hf_api +from ._framework import Argument +from ._output import out + + +CP_EXAMPLES = [ + # Download (repo or bucket -> local / stdout) + "hf cp hf://username/my-model/config.json", + "hf cp hf://username/my-model/config.json ./config.json", + "hf cp hf://datasets/username/my-dataset/data.csv ./data/", + "hf cp hf://buckets/username/my-bucket/config.json -", + # Upload (local / stdin -> repo or bucket) + "hf cp ./model.safetensors hf://username/my-model/model.safetensors", + "hf cp ./config.json hf://buckets/username/my-bucket/logs/", + "hf cp - hf://buckets/username/my-bucket/config.json", + # Remote to remote (repo/bucket -> repo/bucket, server-side when possible) + "hf cp hf://username/source-model/ hf://username/dest-model/", + "hf cp hf://datasets/username/my-dataset/processed/ hf://buckets/username/my-bucket/processed/", + "hf cp hf://buckets/username/my-bucket/logs/ hf://buckets/username/archive-bucket/ # copies contents only", +] + + +# Which alias registered the command, used to restrict the remote endpoint type (see `_enforce_context`). +CpContext = Literal["repos", "buckets"] + + +def make_cp(context: CpContext | None = None): + """Build the ``cp`` command function for a given alias. + + The three entry points (`hf cp`, `hf repos cp`, `hf buckets cp`) share the exact same logic; + 'context' only adds a guardrail on the remote endpoint type (see `_enforce_context`). + """ + + def cp( + src: Annotated[ + str, + Argument(help="Source: local file, hf:// URI (repo or bucket), or - for stdin."), + ], + dst: Annotated[ + str | None, + Argument(help="Destination: local path, hf:// URI (repo or bucket), or - for stdout."), + ] = None, + token: TokenOpt = None, + ) -> None: + """Copy files between local paths, repositories, and buckets. + + Handles uploads (local/stdin -> repo/bucket), downloads (repo/bucket -> local/stdout) and + remote-to-remote copies (repo/bucket -> repo/bucket). Bucket-to-repo and local-to-local + copies are not supported. For directories, use `hf upload`/`hf download` (repos) or + `hf buckets sync` (buckets). Remote-to-remote copies only work within the same storage + region (https://huggingface.co/docs/hub/storage-regions). + """ + _enforce_context(context, src, dst) + _run_cp(src, dst, token) + + return cp + + +def _enforce_context(context: CpContext | None, src: str, dst: str | None) -> None: + """Guardrail for the `hf repos cp` / `hf buckets cp` aliases. + + These aliases are exact duplicates of `hf cp`, so a bare `hf repos cp` could otherwise touch a + bucket (and vice versa). We validate the type of the remote side: the destination for uploads and + remote-to-remote copies, or the source when downloading to a local path / stdout. The top-level + `hf cp` (i.e. 'context' is None) accepts any combination. + """ + if context is None: + return + # The remote endpoint is the destination when it is an hf:// URI, otherwise the source (download). + remote = dst if (dst is not None and is_hf_uri(dst)) else src + if not is_hf_uri(remote): + return + if context == "repos" and parse_hf_uri(remote).is_bucket: + raise CLIError("`hf repos cp` only works with repositories. Use `hf cp` or `hf buckets cp` for buckets.") + if context == "buckets" and not parse_hf_uri(remote).is_bucket: + raise CLIError("`hf buckets cp` only works with buckets. Use `hf cp` or `hf repos cp` for repositories.") + + +def _run_cp(src: str, dst: str | None, token: str | None) -> None: + api = get_hf_api(token=token) + + src_is_stdin = src == "-" + dst_is_stdout = dst == "-" + src_is_hf = is_hf_uri(src) + dst_is_hf = dst is not None and is_hf_uri(dst) + + # --- Remote to remote: delegate to copy_files (repo/bucket -> repo/bucket) --- + if src_is_hf and dst_is_hf: + assert dst is not None # guaranteed by dst_is_hf + api.copy_files(src, dst) + out.result("Copied", src=src, dst=dst) + return + + # --- At least one side must be a remote hf:// URI (rules out local->local, stdin->local, etc.) --- + if not src_is_hf and not dst_is_hf: + if dst is None: + raise click.BadParameter("Missing destination. Provide a repo or bucket hf:// URI as DST.") + raise click.BadParameter( + "One of SRC or DST must be a repo (hf://username/...) or bucket (hf://buckets/...) URI." + ) + + # --- Download: repo/bucket -> local file or stdout --- + if src_is_hf: + if dst_is_stdout: + _download_file_to_stdout(api, src) + return + _download_file_to_local(api, src, dst) + return + + # --- Upload: local file or stdin -> repo/bucket --- + assert dst is not None # guaranteed: reaching here means dst_is_hf is True + _upload_file_to_remote(api, src, dst, src_is_stdin=src_is_stdin) + + +def _download_file_to_stdout(api: HfApi, src: str) -> None: + uri = parse_hf_uri(src) + filename = _source_filename(uri, src) + # Suppress progress bars to avoid polluting the piped output. + with disable_progress_bars(): + with SoftTemporaryDirectory() as tmp_dir: + tmp_path = os.path.join(tmp_dir, filename) + _download_single(api, uri, tmp_path) + with open(tmp_path, "rb") as f: + while chunk := f.read(32_000_000): # 32MB chunks + sys.stdout.buffer.write(chunk) + + +def _download_file_to_local(api: HfApi, src: str, dst: str | None) -> None: + uri = parse_hf_uri(src) + filename = _source_filename(uri, src) + + if dst is None: + local_path = filename + elif os.path.isdir(dst) or dst.endswith(os.sep) or dst.endswith("/"): + local_path = os.path.join(dst, filename) + else: + local_path = dst + + parent_dir = os.path.dirname(local_path) + if parent_dir: + os.makedirs(parent_dir, exist_ok=True) + + _download_single(api, uri, local_path) + out.result("Downloaded", src=src, dst=local_path) + + +def _download_single(api: HfApi, uri: HfUri, local_path: str) -> None: + """Download a single file (repo or bucket) to ``local_path``. + + Used by `_download_file_to_local` and `_download_file_to_stdout`. + """ + if uri.is_bucket: + api.download_bucket_files(uri.id, [(uri.path_in_repo, local_path)], raise_on_missing_files=True) + else: + # Download into a temporary folder next to the destination (rather than the shared cache) + # so the final move stays on the same filesystem and is instant. The temp folder is + # cleaned up automatically once the move is complete. + parent_dir = os.path.dirname(local_path) or "." + with SoftTemporaryDirectory(prefix=".tmp", dir=parent_dir) as tmp_dir: + downloaded_path = api.hf_hub_download( + repo_id=uri.id, + repo_type=uri.type, + filename=uri.path_in_repo, + revision=uri.revision, + local_dir=tmp_dir, + ) + os.replace(downloaded_path, local_path) + + +def _source_filename(uri: HfUri, src: str) -> str: + if uri.path_in_repo == "" or src.endswith("/"): + raise click.BadParameter( + "Source path must include a file name, not just a repo/bucket or directory path." + " Use `hf download` or `hf buckets sync` to copy directories." + ) + return uri.path_in_repo.rsplit("/", 1)[-1] + + +def _upload_file_to_remote(api: HfApi, src: str, dst: str, *, src_is_stdin: bool) -> None: + uri = parse_hf_uri(dst) + + if src_is_stdin: + if uri.path_in_repo == "" or dst.endswith("/"): + raise click.BadParameter("Stdin upload requires a full destination path including filename.") + data = sys.stdin.buffer.read() + _upload_single(api, uri, data, uri.path_in_repo) + out.result("Uploaded", src="stdin", dst=uri.to_uri()) + return + + if os.path.isdir(src): + raise click.BadParameter( + "Source must be a file, not a directory. Use `hf upload` or `hf buckets sync` for directories." + ) + if not os.path.isfile(src): + raise click.BadParameter(f"Source file not found: {src}") + + prefix = uri.path_in_repo + if prefix == "": + remote_path = os.path.basename(src) + elif dst.endswith("/"): + remote_path = prefix + "/" + os.path.basename(src) + else: + remote_path = prefix + + _upload_single(api, uri, src, remote_path) + out.result("Uploaded", src=src, dst=replace(uri, path_in_repo=remote_path).to_uri()) + + +def _upload_single(api: HfApi, uri: HfUri, source: str | bytes, remote_path: str) -> None: + """Upload a single file or bytes (to a repo or bucket).""" + if uri.is_bucket: + api.batch_bucket_files(uri.id, add=[(source, remote_path)]) + else: + api.upload_file( + path_or_fileobj=source, + path_in_repo=remote_path, + repo_id=uri.id, + repo_type=uri.type, + revision=uri.revision, + ) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_errors.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_errors.py new file mode 100644 index 0000000000000000000000000000000000000000..45e98da0907f2b4b559c48fedc41b652eb438499 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_errors.py @@ -0,0 +1,155 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""CLI error handling utilities.""" + +import traceback +from collections.abc import Callable + +from huggingface_hub.errors import ( + BucketNotFoundError, + CLIError, + CLIExtensionInstallError, + DeviceCodeError, + EntryNotFoundError, + GatedRepoError, + HfHubHTTPError, + HfUriError, + IncompleteSnapshotError, + LocalEntryNotFoundError, + LocalTokenNotFoundError, + OfflineModeIsEnabled, + OIDCError, + RemoteEntryNotFoundError, + RepositoryNotFoundError, + RevisionNotFoundError, +) + + +def _format_repo_not_found(error: RepositoryNotFoundError) -> str: + label = error.repo_type.capitalize() if error.repo_type else "Repository" + if error.repo_id: + msg = f"{label} '{error.repo_id}' not found." + else: + msg = f"{label} not found." + msg += "\nIf the repo is private, make sure you are authenticated and your token has the required permissions." + + msg += "\nIf the repo does not exist, create it with: " + if error.repo_id is not None: + type_flag = f" --type {error.repo_type}" if error.repo_type and error.repo_type != "model" else "" + msg += f"hf repos create {error.repo_id}{type_flag}" + else: + msg += "hf repos create " + + return msg + + +def _format_gated_repo(error: GatedRepoError) -> str: + label = error.repo_type if error.repo_type else "repository" + if error.repo_id: + return f"Access denied. {label.capitalize()} '{error.repo_id}' requires approval." + return f"Access denied. This {label} requires approval." + + +def _format_bucket_not_found(error: BucketNotFoundError) -> str: + if error.bucket_id: + msg = f"Bucket '{error.bucket_id}' not found." + cmd = f"hf buckets create {error.bucket_id}" + else: + msg = "Bucket not found." + cmd = "hf buckets create " + msg += "\nIf the bucket is private, make sure you are authenticated and your token has the required permissions." + msg += f"\nIf the bucket does not exist, create it with: {cmd}" + return msg + + +def _format_entry_not_found(error: RemoteEntryNotFoundError) -> str: + label = error.repo_type if error.repo_type else "repository" + url = str(error.response.url) if error.response else None + if error.repo_id: + msg = f"File not found in {label} '{error.repo_id}'." + else: + msg = f"File not found in {label}." + if url: + msg += f"\nURL: {url}" + return msg + + +def _format_local_entry_not_found(error: LocalEntryNotFoundError) -> str: + cause = error.__cause__ + if cause is not None: + return f"Local entry not found. {cause}" + return f"Local entry not found. {error}" + + +def _format_incomplete_snapshot(error: IncompleteSnapshotError) -> str: + msg = _format_local_entry_not_found(error) + msg += f"\nIncomplete snapshot available at: {error.snapshot_path}" + return msg + + +def _format_revision_not_found(error: RevisionNotFoundError) -> str: + label = error.repo_type if error.repo_type else "repository" + if error.repo_id: + return f"Revision not found in {label} '{error.repo_id}'." + return f"Revision not found in {label}. Check the revision parameter." + + +def _format_cli_error(error: CLIError) -> str: + """No traceback, just the error message.""" + return str(error) + + +def _format_cli_extension_install_error(error: CLIExtensionInstallError) -> str: + """Format a CLI extension installation error. + + The error is likely to be a tricky subprocess error to investigate. In this specific case we want to format the + traceback of the root cause while keeping the "nicely formatted" error message of the CLIExtensionInstallError + as a 1-line message. + """ + cause_tb = ( + "".join(traceback.format_exception(type(error.__cause__), error.__cause__, error.__cause__.__traceback__)) + if error.__cause__ is not None + else "" + ) + return f"{cause_tb}\n{error}" + + +CLI_ERROR_MAPPINGS: dict[type[Exception], Callable[..., str]] = { + OfflineModeIsEnabled: lambda error: str(error), + # GatedRepoError must come before RepositoryNotFoundError (it's a subclass). + GatedRepoError: _format_gated_repo, + BucketNotFoundError: _format_bucket_not_found, + RepositoryNotFoundError: _format_repo_not_found, + RevisionNotFoundError: _format_revision_not_found, + LocalTokenNotFoundError: lambda _: "Not logged in. Run 'hf auth login' first.", + OIDCError: lambda error: f"OIDC Exchange failed. {error}", + DeviceCodeError: lambda error: f"Login failed: {error}", + RemoteEntryNotFoundError: _format_entry_not_found, + # IncompleteSnapshotError must come before LocalEntryNotFoundError (it's a subclass). + IncompleteSnapshotError: _format_incomplete_snapshot, + LocalEntryNotFoundError: _format_local_entry_not_found, + EntryNotFoundError: lambda error: str(error), + HfHubHTTPError: lambda error: str(error), + HfUriError: lambda error: f"Invalid HF URI: {error.uri}. {error.msg}", + ValueError: lambda error: f"Invalid value. {error}", + CLIExtensionInstallError: _format_cli_extension_install_error, + CLIError: _format_cli_error, +} + + +def format_known_exception(error: Exception) -> str | None: + for exc_type, formatter in CLI_ERROR_MAPPINGS.items(): + if isinstance(error, exc_type): + return formatter(error) + return None diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_file_listing.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_file_listing.py new file mode 100644 index 0000000000000000000000000000000000000000..bfa0bbef2cdea3d17ced555c0c19ea103bdb5a99 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_file_listing.py @@ -0,0 +1,225 @@ +# Copyright 2026-present, the HuggingFace Inc. team. +# +# 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. +"""Shared helpers for listing files in buckets and repos (tree view, flat view, formatting).""" + +import json +from datetime import datetime +from typing import Sequence + +import click + +from huggingface_hub._buckets import BucketFile, BucketFolder +from huggingface_hub.hf_api import RepoFile, RepoFolder + +from ._cli_utils import get_hf_api +from ._output import OutputFormat, _dataclass_to_dict, out + + +BucketItem = BucketFile | BucketFolder +RepoItem = RepoFile | RepoFolder +ListingItem = BucketItem | RepoItem + + +def get_item_date(item: ListingItem) -> datetime | None: + """Extract date from an item, supporting both repo items (last_commit.date) and bucket items (mtime/uploaded_at).""" + match item: + case BucketFile(mtime=mtime) if mtime is not None: + return mtime + case BucketFile(uploaded_at=uploaded_at) | BucketFolder(uploaded_at=uploaded_at) if uploaded_at is not None: + return uploaded_at + case RepoFile(last_commit=last_commit) | RepoFolder(last_commit=last_commit) if last_commit is not None: + return last_commit.date + case _: + return None + + +def format_size(size: int | float, human_readable: bool = False) -> str: + """Format a size in bytes.""" + if not human_readable: + return str(size) + + for unit in ["B", "KB", "MB", "GB", "TB"]: + if size < 1000: + if unit == "B": + return f"{size} {unit}" + return f"{size:.1f} {unit}" + size /= 1000 + return f"{size:.1f} PB" + + +def format_date(dt: datetime | None, human_readable: bool = False) -> str: + """Format a datetime to a readable date string.""" + if dt is None: + return "" + if human_readable: + return dt.strftime("%b %d %H:%M") + return dt.strftime("%Y-%m-%d %H:%M:%S") + + +def build_tree( + items: Sequence[BucketItem] | Sequence[RepoItem], + human_readable: bool = False, + quiet: bool = False, +) -> list[str]: + """Build a tree representation of files and directories. + + Produces ASCII tree with size and date columns before the tree connector. + When quiet=True, only the tree structure is shown (no size/date). + """ + tree: dict = {} + + for item in items: + parts = item.path.split("/") + current = tree + for part in parts[:-1]: + if part not in current: + current[part] = {"__children__": {}} + current = current[part]["__children__"] + + final_part = parts[-1] + if isinstance(item, BucketFolder | RepoFolder): + if final_part not in current: + current[final_part] = {"__children__": {}} + else: + current[final_part] = {"__item__": item} + + prefix_width = 0 + max_size_width = 0 + max_date_width = 0 + if not quiet: + for item in items: + if isinstance(item, BucketFile | RepoFile): + size_str = format_size(item.size, human_readable) + max_size_width = max(max_size_width, len(size_str)) + date_str = format_date(get_item_date(item), human_readable) + max_date_width = max(max_date_width, len(date_str)) + if max_size_width > 0: + prefix_width = max_size_width + 2 + max_date_width + + lines: list[str] = [] + _render_tree( + tree, + lines, + "", + prefix_width=prefix_width, + max_size_width=max_size_width, + human_readable=human_readable, + ) + return lines + + +def _render_tree( + node: dict, + lines: list[str], + indent: str, + prefix_width: int = 0, + max_size_width: int = 0, + human_readable: bool = False, +) -> None: + """Recursively render a tree structure with size+date prefix.""" + sorted_items = sorted(node.items()) + for i, (name, value) in enumerate(sorted_items): + is_last = i == len(sorted_items) - 1 + connector = "└── " if is_last else "├── " + + is_dir = "__children__" in value + children = value.get("__children__", {}) + + if prefix_width > 0: + if is_dir: + prefix = " " * prefix_width + else: + item = value.get("__item__") + if item is not None: + size_str = format_size(item.size, human_readable) + date_str = format_date(get_item_date(item), human_readable) + prefix = f"{size_str:>{max_size_width}} {date_str}" + else: + prefix = " " * prefix_width + lines.append(f"{prefix} {indent}{connector}{name}{'/' if is_dir else ''}") + else: + lines.append(f"{indent}{connector}{name}{'/' if is_dir else ''}") + + if children: + child_indent = indent + (" " if is_last else "│ ") + _render_tree( + children, + lines, + child_indent, + prefix_width=prefix_width, + max_size_width=max_size_width, + human_readable=human_readable, + ) + + +def list_repo_files_cmd( + repo_id: str, + repo_type: str, + human_readable: bool, + as_tree: bool, + recursive: bool, + revision: str | None, + token: str | None, +) -> None: + """List files in a repo on the Hub. Used by models/datasets/spaces ls commands.""" + if as_tree and out.mode == OutputFormat.json: + raise click.BadParameter("Cannot use --tree with --format json.") + + api = get_hf_api(token=token) + items = list(api.list_repo_tree(repo_id, recursive=recursive, revision=revision, repo_type=repo_type, expand=True)) + print_file_listing(items, human_readable=human_readable, as_tree=as_tree, recursive=recursive) + + +def print_file_listing( + items: Sequence[BucketItem] | Sequence[RepoItem], + *, + human_readable: bool = False, + as_tree: bool = False, + recursive: bool = False, +) -> None: + """Print a file listing in the appropriate format based on the current output mode. + + Supports tree, json, quiet, and flat human-readable views. Works with both + BucketFile/BucketFolder and RepoFile/RepoFolder items. + """ + if not items: + out.text("(empty)") + return + + has_directories = any(isinstance(item, BucketFolder | RepoFolder) for item in items) + + if as_tree: + quiet = out.mode == OutputFormat.quiet + for line in build_tree(items, human_readable=human_readable, quiet=quiet): + print(line) + elif out.mode == OutputFormat.json: + print(json.dumps([_dataclass_to_dict(item) for item in items], indent=2)) + elif out.mode == OutputFormat.quiet: + for item in items: + if isinstance(item, BucketFolder | RepoFolder): + print(f"{item.path}/") + else: + print(item.path) + else: + for item in items: + if isinstance(item, BucketFolder | RepoFolder): + date_str = format_date(get_item_date(item), human_readable) + print(f"{'':>12} {date_str:>19} {item.path}/") + else: + size_str = format_size(item.size, human_readable) + date_str = format_date(get_item_date(item), human_readable) + print(f"{size_str:>12} {date_str:>19} {item.path}") + + if not recursive and has_directories: + out.hint("Use -R to list files recursively.") diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_framework.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_framework.py new file mode 100644 index 0000000000000000000000000000000000000000..26c8382fb94c1ced57f662b68e72c96e27a46cff --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_framework.py @@ -0,0 +1,645 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""Minimal declaration layer over Click 8.x for the ``hf`` CLI. + +This module vendors *only* the slice of Typer the CLI actually uses: turning +annotated function signatures (``Annotated[T, Option(...)]`` / ``Argument(...)``) +into Click parameters, and rendering argument/option help the way Typer did. +It exists so the CLI depends on Click's stable public API instead of Typer's +now-internal vendored Click (``typer._click``), which Typer reserves the right +to refactor at any release. + +Deliberately *not* implemented (add a case here only when a command needs it): +rich rendering, shell-completion install commands, prompts/confirmation options, +env-var options, ``File``/``UUID`` params, ``count`` options, ``default_factory``. +Click's own machinery already handles exceptions, aborts, exits, and native +``_HF_COMPLETE`` shell completion, so none of Typer's ``main()`` overrides are +reproduced here. + +The interesting logic mirrors four Typer functions, kept faithful so ``--help`` +output stays byte-identical: +- :func:`_get_click_type` <- ``typer.main.get_click_type`` +- :func:`_build_click_param` <- ``typer.main.get_click_param`` +- :func:`_make_handler` <- ``typer.main.get_callback`` +- :class:`HfArgument` / :class:`HfOption` help records <- ``typer.core.Typer*`` +""" + +import enum +import functools +import inspect +from collections.abc import Callable, Sequence +from datetime import datetime +from pathlib import Path +from types import UnionType +from typing import Annotated, Any, Literal, Union, get_args, get_origin + +import click + + +def get_command_name(name: str) -> str: + """Normalize a Python identifier to a CLI name (``force_download`` -> ``force-download``).""" + return name.lower().replace("_", "-") + + +# --------------------------------------------------------------------------- +# 1. Declaration markers — replace ``typer.Option`` / ``typer.Argument``. +# Attached in ``Annotated[T, Option(...)]``; the ``= value`` in the function +# signature carries the default (never the marker). +# --------------------------------------------------------------------------- + + +class ParameterInfo: + """Base marker holding the (tiny) set of Click knobs the CLI actually sets. + + ``callback`` is a Typer-style value parser ``fn(value) -> parsed`` — it does NOT + receive Click's ``(ctx, param, value)``. It consumes the enum/list convertors, so + ``value`` is already converted when it runs. + """ + + def __init__( + self, + *param_decls: str, + help: str | None = None, + show_default: bool | str = True, + hidden: bool = False, + is_eager: bool = False, + callback: Callable[..., Any] | None = None, + min: int | None = None, + click_type: click.ParamType | None = None, + ) -> None: + self.param_decls = list(param_decls) + self.help = help + self.show_default = show_default + self.hidden = hidden + self.is_eager = is_eager + self.callback = callback + self.min = min + self.click_type = click_type + + +class Option(ParameterInfo): + """Declare a CLI option, e.g. ``Annotated[str | None, Option("--revision")]``.""" + + +class Argument(ParameterInfo): + """Declare a positional CLI argument, e.g. ``Annotated[str, Argument()]``.""" + + +# --------------------------------------------------------------------------- +# 2. Annotation -> Click type + value convertors. +# --------------------------------------------------------------------------- + + +def _get_click_type(annotation: Any, info: ParameterInfo) -> click.ParamType: + """Map a (already unwrapped) annotation to a Click ``ParamType``.""" + if info.click_type is not None: + return info.click_type + if annotation is str: + return click.STRING + if annotation is bool: + return click.BOOL + if annotation is int: + return click.IntRange(min=info.min) if info.min is not None else click.INT + if annotation is float: + return click.FloatRange(min=info.min) if info.min is not None else click.FLOAT + if annotation is Path: + return click.Path(path_type=Path) + if annotation is datetime: + return click.DateTime() + if isinstance(annotation, type) and issubclass(annotation, enum.Enum): + values = [item.value for item in annotation] + if not all(isinstance(value, str) for value in values): + # A non-str member default would fail Choice validation at parse time with a + # cryptic error; fail at build time with a clear one instead. + raise TypeError(f"Unsupported enum {annotation.__name__!r}: only str-valued enums are supported.") + return click.Choice(values) + if get_origin(annotation) is Literal: + return click.Choice([str(value) for value in get_args(annotation)]) + raise TypeError(f"Unsupported CLI annotation {annotation!r}. Add a case in `_framework._get_click_type()`.") + + +def _enum_convertor(enum_type: type[enum.Enum]) -> Callable[[Any], Any]: + """Map a parsed choice string back to its ``Enum`` member (mirrors Typer).""" + value_map = {str(member.value): member for member in enum_type} + + def convertor(value: Any) -> Any: + if value is not None: + return value_map.get(str(value)) + return None + + return convertor + + +def _list_convertor( + inner: Callable[[Any], Any] | None, default_value: Any | None +) -> Callable[[Sequence[Any] | None], list[Any] | None]: + """Turn Click's tuple (from ``multiple=True``) into a list, applying ``inner`` per item.""" + + def convertor(value: Sequence[Any] | None) -> list[Any] | None: + if value is None or (default_value is None and len(value) == 0): + return None + return [inner(item) if inner else item for item in value] + + return convertor + + +def _make_convertor( + annotation: Any, is_list: bool, default_value: Any | None, info: ParameterInfo +) -> Callable[[Any], Any] | None: + """Build the value convertor for a param (``None`` when no coercion is needed). + + An explicit ``click_type`` (e.g. ``SoftChoice``) owns its own conversion, so no + enum convertor is added on top of it. + """ + inner = None + if info.click_type is None and isinstance(annotation, type) and issubclass(annotation, enum.Enum): + inner = _enum_convertor(annotation) + if is_list: + return _list_convertor(inner, default_value) + return inner + + +def _unwrap_optional_and_list(annotation: Any) -> tuple[Any, bool]: + """Strip ``T | None`` / ``Optional[T]`` and ``list[T]``; return ``(base_type, is_list)``.""" + origin = get_origin(annotation) + if origin in (Union, UnionType): + non_none = [arg for arg in get_args(annotation) if arg is not type(None)] + if len(non_none) != 1: + raise TypeError(f"Unsupported union annotation {annotation!r}; only ``T | None`` is supported.") + annotation = non_none[0] + origin = get_origin(annotation) + if origin in (list, Sequence): + return get_args(annotation)[0], True + return annotation, False + + +def _split_annotated(annotation: Any) -> tuple[Any, ParameterInfo | None]: + """Split ``Annotated[T, Option(...)]`` into ``(T, marker)``; ``(annotation, None)`` otherwise.""" + if get_origin(annotation) is Annotated: + args = get_args(annotation) + marker = next((meta for meta in args[1:] if isinstance(meta, ParameterInfo)), None) + if marker is None and (typer_marker := next((meta for meta in args[1:] if _is_typer_marker(meta)), None)): + marker = _from_typer_marker(typer_marker, from_annotated=True) + return args[0], marker + return annotation, None + + +# --------------------------------------------------------------------------- +# Typer-marker compatibility shim (transition helper). +# +# ``typer_factory`` is exposed publicly and downstream CLIs (e.g. `transformers`) +# still register commands whose parameters carry ``typer.Option`` / +# ``typer.Argument`` markers. Recognize those markers structurally (no typer +# import required) and translate the fields this framework supports, so such +# commands keep working while downstream migrates. +# TODO: remove once transformers pins huggingface_hub>=1.22.0. +# --------------------------------------------------------------------------- + + +def _is_typer_marker(obj: Any) -> bool: + return type(obj).__module__.partition(".")[0] == "typer" and type(obj).__name__ in ("OptionInfo", "ArgumentInfo") + + +def _from_typer_marker(meta: Any, *, from_annotated: bool) -> ParameterInfo: + """Translate a ``typer.models.OptionInfo`` / ``ArgumentInfo`` into our marker.""" + param_decls = list(getattr(meta, "param_decls", None) or ()) + if type(meta).__name__ == "OptionInfo": + # In ``Annotated[...]`` usage typer stores the first flag name in ``default`` + # (``Option("--flag", "-f")`` -> ``default="--flag"``, ``param_decls=("-f",)``). + default = getattr(meta, "default", ...) + if from_annotated and isinstance(default, str): + param_decls = [default, *param_decls] + cls: type[ParameterInfo] = Option + else: + cls = Argument + return cls( + *param_decls, + help=getattr(meta, "help", None), + show_default=getattr(meta, "show_default", True), + hidden=getattr(meta, "hidden", False), + is_eager=getattr(meta, "is_eager", False), + callback=getattr(meta, "callback", None), + min=getattr(meta, "min", None), + click_type=getattr(meta, "click_type", None), + ) + + +# --------------------------------------------------------------------------- +# 3. Signature -> Click parameters (mirrors ``typer.main.get_click_param``). +# --------------------------------------------------------------------------- + + +def _wrap_param_callback( + user_callback: Callable[[Any], Any], convertor: Callable[[Any], Any] | None +) -> Callable[[click.Context, click.Parameter, Any], Any]: + """Adapt a Typer-style value parser ``fn(value) -> parsed`` to a Click param callback.""" + + def click_callback(ctx: click.Context, param: click.Parameter, value: Any) -> Any: + return user_callback(convertor(value) if convertor else value) + + return click_callback + + +def _build_click_param( + name: str, annotation: Any, info: ParameterInfo | None, signature_default: Any +) -> tuple[click.Parameter, Callable[[Any], Any] | None]: + """Build a Click ``Parameter`` (and its post-parse value convertor) for one function param.""" + required = signature_default is inspect.Parameter.empty + default_value = None if required else signature_default + if isinstance(default_value, enum.Enum): + default_value = default_value.value + if info is None: + # A bare annotation with no marker: required positional -> Argument, else Option. + info = Argument() if required else Option() + + base_type, is_list = _unwrap_optional_and_list(annotation) + convertor = _make_convertor(base_type, is_list, default_value, info) + + # A user ``callback`` consumes the value itself (and the convertor with it); otherwise the + # convertor runs later in the command handler wrapper. This keeps conversion single-pass. + if info.callback is not None: + param_callback: Callable[..., Any] | None = _wrap_param_callback(info.callback, convertor) + handler_convertor: Callable[[Any], Any] | None = None + else: + param_callback = None + handler_convertor = convertor + + if isinstance(info, Argument): + argument = HfArgument( + [name], + type=_get_click_type(base_type, info), + required=required, + default=default_value, + nargs=-1 if is_list else 1, + is_eager=info.is_eager, + callback=param_callback, + help=info.help, + show_default=info.show_default, + hidden=info.hidden, + ) + return argument, handler_convertor + + # Option: prepend the Python name so ``click.Parameter.name`` matches the function kwarg, + # regardless of the user-facing flag names ("-v"/"--version", "--type"/"--repo-type", ...). + is_flag = base_type is bool + decls = [name] + if info.param_decls: + decls.extend(info.param_decls) + else: + kebab = get_command_name(name) + decls.append(f"--{kebab}/--no-{kebab}" if is_flag else f"--{kebab}") + option = HfOption( + decls, + # Click infers the flag type itself; passing a type alongside ``is_flag`` is rejected. + type=None if is_flag else _get_click_type(base_type, info), + required=required, + default=default_value, + is_flag=is_flag, + multiple=is_list, + is_eager=info.is_eager, + callback=param_callback, + help=info.help, + show_default=info.show_default, + hidden=info.hidden, + ) + return option, handler_convertor + + +def _build_params( + func: Callable[..., Any], +) -> tuple[list[click.Parameter], dict[str, Callable[[Any], Any]], str | None]: + """Introspect ``func`` and return ``(params, convertors, context_param_name)``.""" + params: list[click.Parameter] = [] + convertors: dict[str, Callable[[Any], Any]] = {} + context_param_name: str | None = None + for name, sig_param in inspect.signature(func).parameters.items(): + # Read raw signature annotations rather than ``typing.get_type_hints``: the CLI never uses + # ``from __future__ import annotations``, so annotations are already live objects, and + # get_type_hints mangles ``Annotated[X | None, ...]`` on Python 3.10 (drops the origin). + annotation = sig_param.annotation if sig_param.annotation is not inspect.Parameter.empty else str + base_type, info = _split_annotated(annotation) + if isinstance(base_type, type) and ( + issubclass(base_type, click.Context) + # typer.Context subclasses typer's *vendored* click since typer 0.26, so an + # issubclass check against real click misses it. Match it structurally. + or (base_type.__module__.partition(".")[0] == "typer" and base_type.__name__ == "Context") + ): + context_param_name = name + continue + signature_default = sig_param.default + if _is_typer_marker(signature_default): + # Old typer style: the marker *is* the signature default and carries the value. + if info is None: + info = _from_typer_marker(signature_default, from_annotated=False) + marker_default = getattr(signature_default, "default", ...) + signature_default = inspect.Parameter.empty if marker_default is ... else marker_default + click_param, convertor = _build_click_param(name, base_type, info, signature_default) + if convertor is not None and click_param.name is not None: + convertors[click_param.name] = convertor + params.append(click_param) + return params, convertors, context_param_name + + +def _make_handler( + func: Callable[..., Any], + convertors: dict[str, Callable[[Any], Any]], + context_param_name: str | None, +) -> Callable[..., Any]: + """Wrap ``func`` so Click's kwargs map back to it, applying convertors and injecting the ctx.""" + + def handler(**kwargs: Any) -> Any: + call_kwargs = {key: (convertors[key](value) if key in convertors else value) for key, value in kwargs.items()} + if context_param_name is not None: + call_kwargs[context_param_name] = click.get_current_context() + return func(**call_kwargs) + + functools.update_wrapper(handler, func) + return handler + + +# --------------------------------------------------------------------------- +# 4. Click parameter subclasses — port Typer's help records so arguments show up +# in ``--help`` (plain ``click.Argument`` renders none) and defaults/metavars +# read identically. Rich/env-var branches are dropped (never enabled here). +# --------------------------------------------------------------------------- + + +def _split_opt(opt: str) -> tuple[str, str]: + """Split an option string into ``(prefix, name)`` (Click's ``split_opt``, inlined).""" + first = opt[:1] + if first.isalnum(): + return "", opt + if opt[1:2] == first: + return opt[:2], opt[2:] + return first, opt[1:] + + +def _extract_default_help_str(param: click.Parameter, ctx: click.Context) -> Any: + # Resilient parsing avoids type casting failing while rendering the default. + resilient = ctx.resilient_parsing + ctx.resilient_parsing = True + try: + return param.get_default(ctx, call=False) + finally: + ctx.resilient_parsing = resilient + + +def _default_string( + param: "HfArgument | HfOption", ctx: click.Context, show_default_is_str: bool, default_value: Any +) -> str: + if show_default_is_str: + return f"({param.show_default})" + if isinstance(default_value, (list, tuple)): + return ", ".join(_default_string(param, ctx, show_default_is_str, item) for item in default_value) + if isinstance(default_value, enum.Enum): + return str(default_value.value) + if inspect.isfunction(default_value): + return "(dynamic)" + if isinstance(param, HfOption) and param.is_bool_flag and param.secondary_opts: + # Boolean toggle: show the opt name (without prefix) matching the current default. + if default_value: + return _split_opt(param.opts[0])[1] if param.opts else str(default_value) + return _split_opt(param.secondary_opts[0])[1] + if isinstance(param, HfOption) and param.is_bool_flag and not param.secondary_opts and not default_value: + return "" + return str(default_value) + + +def _describe_number_range(param_type: "click.IntRange | click.FloatRange") -> str: + """Human-readable range hint like ``x>=1`` or ``1<=x<10``. + + Reproduces click's private ``_NumberRangeBase._describe_range()`` using the public + ``IntRange``/``FloatRange`` attributes, so the framework stays on Click's public API. + """ + if param_type.min is None: + return f"x{'<' if param_type.max_open else '<='}{param_type.max}" + if param_type.max is None: + return f"x{'>' if param_type.min_open else '>='}{param_type.min}" + left = "<" if param_type.min_open else "<=" + right = "<" if param_type.max_open else "<=" + return f"{param_type.min}{left}x{right}{param_type.max}" + + +def _build_help_extra(param: "HfArgument | HfOption", ctx: click.Context, base_help: str) -> str: + """Append the ``[default: ...; required]`` suffix to a help string (shared by arg/option).""" + extra: list[str] = [] + default_value = _extract_default_help_str(param, ctx) + show_default_is_str = isinstance(param.show_default, str) + if show_default_is_str or (default_value is not None and (param.show_default or ctx.show_default)): + default_string = _default_string(param, ctx, show_default_is_str, default_value) + if default_string: + extra.append(f"default: {default_string}") + # Numeric range hints are shown for options only (matches Typer; arguments omit them). + if isinstance(param, HfOption) and isinstance(param.type, (click.IntRange, click.FloatRange)): + range_str = _describe_number_range(param.type) + if range_str: + extra.append(range_str) + if param.required: + extra.append("required") + if extra: + suffix = f"[{'; '.join(extra)}]" + return f"{base_help} {suffix}" if base_help else suffix + return base_help + + +class HfArgument(click.Argument): + """Positional argument that renders help text and a metavar (Click's does neither).""" + + def __init__( + self, + param_decls: Sequence[str], + *, + help: str | None = None, + show_default: bool | str = True, + hidden: bool = False, + **attrs: Any, + ) -> None: + self.help = help + self.show_default = show_default + self.hidden = hidden + super().__init__(param_decls, **attrs) + + def make_metavar(self, ctx: click.Context) -> str: + if self.metavar is not None: + var = self.metavar + if not self.required and not var.startswith("["): + var = f"[{var}]" + return var + var = (self.name or "").upper() + if not self.required: + var = f"[{var}]" + type_var = self.type.get_metavar(self, ctx=ctx) + if type_var: + var += f":{type_var}" + if self.nargs != 1: + var += "..." + return var + + def get_help_record(self, ctx: click.Context) -> tuple[str, str] | None: + if self.hidden: + return None + return self.make_metavar(ctx=ctx), _build_help_extra(self, ctx, self.help or "") + + +class HfOption(click.Option): + """Option whose help record ports Typer's default/metavar rendering verbatim.""" + + show_default: bool | str + + def get_help_record(self, ctx: click.Context) -> tuple[str, str] | None: + if self.hidden: + return None + + any_prefix_is_slash = False + + def _write_opts(opts: Sequence[str]) -> str: + nonlocal any_prefix_is_slash + rv, any_slashes = click.formatting.join_options(opts) + if any_slashes: + any_prefix_is_slash = True + if not self.is_flag and not self.count: + rv += f" {self.make_metavar(ctx=ctx)}" + return rv + + rv = [_write_opts(self.opts)] + if self.secondary_opts: + rv.append(_write_opts(self.secondary_opts)) + + help_text = _build_help_extra(self, ctx, self.help or "") + return ("; " if any_prefix_is_slash else " / ").join(rv), help_text + + +# --------------------------------------------------------------------------- +# 5. Command / group base classes and the decorator API (replace ``typer.Typer``). +# --------------------------------------------------------------------------- + + +def _format_params(command: click.Command, ctx: click.Context, formatter: click.HelpFormatter) -> None: + """Render params split into "Arguments" and "Options" sections (mirrors Typer).""" + args: list[tuple[str, str]] = [] + opts: list[tuple[str, str]] = [] + for param in command.get_params(ctx): + record = param.get_help_record(ctx) + if record is None: + continue + if param.param_type_name == "argument": + args.append(record) + elif param.param_type_name == "option": + opts.append(record) + if args: + with formatter.section("Arguments"): + formatter.write_dl(args) + if opts: + with formatter.section("Options"): + formatter.write_dl(opts) + + +class HfCommand(click.Command): + """Leaf command that renders arguments and options in separate help sections.""" + + def format_options(self, ctx: click.Context, formatter: click.HelpFormatter) -> None: + _format_params(self, ctx, formatter) + + +def build_command( + func: Callable[..., Any], + *, + name: str | None = None, + cls: type[click.Command] | None = None, + help: str | None = None, + epilog: str | None = None, + short_help: str | None = None, + options_metavar: str = "[OPTIONS]", + add_help_option: bool = True, + no_args_is_help: bool = False, + hidden: bool = False, + deprecated: bool = False, + context_settings: dict[str, Any] | None = None, +) -> click.Command: + """Build a Click ``Command`` from a function with ``Annotated`` params. + + Replaces ``typer.main.get_command_from_info``. + """ + params, convertors, context_param_name = _build_params(func) + handler = _make_handler(func, convertors, context_param_name) + command_help = inspect.cleandoc(help) if help else inspect.getdoc(func) + return (cls or HfCommand)( + name=name if name is not None else get_command_name(func.__name__), + callback=handler, + params=params, + help=command_help, + epilog=epilog, + short_help=short_help, + options_metavar=options_metavar, + add_help_option=add_help_option, + no_args_is_help=no_args_is_help, + hidden=hidden, + deprecated=deprecated, + context_settings=context_settings or {}, + ) + + +class HfGroup(click.Group): + """Command group with the decorator API the CLI relies on (``command``/``callback``/``add_group``). + + Subclasses (see ``HFCliTyperGroup``) layer on styling, aliases, topics and error + enrichment; this base only wires functions to Click via :func:`build_command`. + """ + + #: Command class used by ``@group.command()`` unless overridden per call. + command_class: type[click.Command] = HfCommand + + def format_options(self, ctx: click.Context, formatter: click.HelpFormatter) -> None: + _format_params(self, ctx, formatter) + self.format_commands(ctx, formatter) + + def list_commands(self, ctx: click.Context) -> list[str]: + # Preserve declaration order rather than Click's alphabetical default. + return list(self.commands) + + def command( # type: ignore # deliberately narrows click.Group.command (builds from annotated signatures) + self, name: str | None = None, *, cls: type[click.Command] | None = None, **kwargs: Any + ) -> Callable[[Callable[..., Any]], Callable[..., Any]]: + def decorator(func: Callable[..., Any]) -> Callable[..., Any]: + command = build_command(func, name=name, cls=cls or self.command_class, **kwargs) + self.add_command(command, command.name) + return func + + return decorator + + def add_group(self, group: click.Group, *, name: str, hidden: bool = False) -> None: + """Register a subgroup under ``name`` (which may carry pipe aliases, e.g. ``"repos | repo"``).""" + group.name = name + group.hidden = hidden + self.add_command(group, name) + + def group_callback( + self, *, invoke_without_command: bool = False + ) -> Callable[[Callable[..., Any]], Callable[..., Any]]: + """Register the function invoked for this group (named ``group_callback`` because Click + already uses the ``callback`` attribute for the group's own handler).""" + + def decorator(func: Callable[..., Any]) -> Callable[..., Any]: + params, convertors, context_param_name = _build_params(func) + self.callback = _make_handler(func, convertors, context_param_name) + self.params = [*self.params, *params] + self.invoke_without_command = invoke_without_command + if invoke_without_command: + # Match Typer: the subcommand is optional when the group runs without one. + self.subcommand_metavar = "[COMMAND] [ARGS]..." + if self.help is None and func.__doc__: + self.help = inspect.cleandoc(func.__doc__) + return func + + return decorator diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_help_formatter.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_help_formatter.py new file mode 100644 index 0000000000000000000000000000000000000000..19c2909b7be9a151d912db851e6493f2b6e46bd3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_help_formatter.py @@ -0,0 +1,34 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""Pretty ANSI help formatter for the `hf` CLI.""" + +from collections.abc import Iterable + +import click + +from huggingface_hub.utils import ANSI + + +class StyledHelpFormatter(click.HelpFormatter): + def write_heading(self, heading: str) -> None: + styled = ANSI.underline(heading + ":") + self.write(f"{'':>{self.current_indent}}{styled}\n") + + def write_dl(self, rows: Iterable[tuple[str, str]], col_max: int = 30, col_spacing: int = 2) -> None: + rows = [(ANSI.bold(first), second) for first, second in rows] + super().write_dl(rows, col_max=col_max, col_spacing=col_spacing) + + +class StyledContext(click.Context): + formatter_class = StyledHelpFormatter diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_output.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_output.py new file mode 100644 index 0000000000000000000000000000000000000000..9806476feee1285b8e91f1e773caea879862a76e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_output.py @@ -0,0 +1,360 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""Output framework for the `hf` CLI.""" + +import dataclasses +import datetime +import json +import re +import shutil +import sys +from collections.abc import Sequence +from enum import Enum +from typing import Any, cast + +import click + +from huggingface_hub.errors import ConfirmationError +from huggingface_hub.utils import ANSI, StatusLine, disable_progress_bars, is_agent, tabulate + + +class OutputFormat(str, Enum): + """Output format for CLI commands with auto detection of agent/human mode.""" + + agent = "agent" + auto = "auto" + human = "human" + json = "json" + quiet = "quiet" + + +def _print_flush(*values: Any, **kwargs: Any) -> None: + """Like `print`, but always flushed: some CLI flows block on user action right after + printing (e.g. the device-code login), so output must not stay buffered.""" + print(*values, **kwargs, flush=True) + + +class Output: + """Output sink for the `hf` CLI. + + Mode is resolved once at init time based on `is_agent()` auto-detection + and can be overridden per-command via `set_mode()`. + """ + + mode: OutputFormat + no_truncate: bool + + def __init__(self) -> None: + self.no_truncate = False + self.set_mode() + + def set_mode(self, mode: OutputFormat = OutputFormat.auto) -> None: + """Override the output mode (called once at startup and again per '--format' flag).""" + if mode == OutputFormat.auto: + mode = OutputFormat.agent if is_agent() else OutputFormat.human + self.mode = mode + if mode != OutputFormat.human: + disable_progress_bars() + + def set_no_truncate(self, no_truncate: bool) -> None: + """Toggle off cell truncation for human table output.""" + self.no_truncate = no_truncate + + def is_quiet(self) -> bool: + return self.mode == OutputFormat.quiet + + def text(self, msg: str | None = None, *, human: str | None = None, agent: str | None = None) -> None: + """Print a free-form text message to stdout.""" + if msg is not None: + if human is not None or agent is not None: + raise ValueError("Cannot mix 'msg' with 'human'/'agent'.") + human = msg + agent = _strip_ansi(msg) + + match self.mode: + case OutputFormat.human: + if human is not None: + _print_flush(human) + case OutputFormat.agent: + if agent is not None: + _print_flush(agent) + # json/quiet: no-op + + def table( + self, + items: Sequence[dict[str, Any]], + *, + headers: list[str] | None = None, + id_key: str | None = None, + alignments: dict[str, str] | None = None, + ) -> None: + """Print tabular data to stdout. + + Args: + items: List of dicts. Headers are auto-detected from keys if not provided. + headers: Explicit column names. If None, derived from dict keys (all-None columns filtered). + id_key: Key to print in quiet mode. If None, uses the first header. + alignments: Optional mapping of header name to "left" or "right". Defaults to "left". + """ + if not items: + match self.mode: + case OutputFormat.agent | OutputFormat.human: + _print_flush("No results found.") + case OutputFormat.json: + _print_flush("[]") + return + + if headers is None: + all_columns = list(items[0].keys()) + headers = [col for col in all_columns if any(item.get(col) is not None for item in items)] + rows = [[item.get(h) for h in headers] for item in items] + + match self.mode: + case OutputFormat.human: # padded table, adaptive truncation, SCREAMING_SNAKE headers + screaming_headers = [_to_header(h) for h in headers] + formatted_rows: list[list[str]] = [[_format_table_value_human(v) for v in row] for row in rows] + + is_truncated = _truncate_columns(screaming_headers, formatted_rows, no_truncate=self.no_truncate) + + inferred = {**_infer_alignments(headers, rows), **(alignments or {})} + screaming_alignments = {_to_header(k): v for k, v in inferred.items()} + _print_flush( + tabulate( + cast("list[list[str | int]]", formatted_rows), + headers=screaming_headers, + alignments=screaming_alignments, + ), + ) + if is_truncated: + self.hint("Use `--no-truncate` or `--format json` to display full values.") + case OutputFormat.agent: # TSV, no truncation, full timestamps + _print_flush("\t".join(headers)) + for row in rows: + _print_flush("\t".join(_format_table_cell_agent(v) for v in row)) + case OutputFormat.json: # compact JSON array + _print_flush(json.dumps(list(items), default=str)) + case OutputFormat.quiet: # id_key column (or first column), one per line + quiet_key = id_key or headers[0] + for item in items: + _print_flush(item.get(quiet_key, "")) + + def dict(self, data: Any, *, id_key: str | None = None) -> None: + """Print structured data as JSON in all modes (indented for human, compact otherwise). + + Accepts a dict or a dataclass. + """ + if dataclasses.is_dataclass(data) and not isinstance(data, type): + data = _dataclass_to_dict(data) + if self.mode == OutputFormat.quiet and id_key is not None: + _print_flush(data.get(id_key, "")) + return + indent = 2 if self.mode == OutputFormat.human else None + _print_flush(json.dumps(data, indent=indent, default=str)) + + def result(self, message: str, **data: Any) -> None: + """Print a success summary to stdout.""" + match self.mode: + case OutputFormat.human: # ✓ message + key: value lines + parts = [ANSI.green(f"✓ {message}")] + for k, v in data.items(): + if v is not None: + parts.append(f" {k}: {v}") + _print_flush("\n".join(parts)) + case OutputFormat.agent: # key=val pairs, space-separated + parts = [f"{k}={v}" for k, v in data.items() if v is not None] + _print_flush(" ".join(parts) if parts else message) + case OutputFormat.json: # json.dumps(data), message ignored + _print_flush(json.dumps(data, default=str) if data else "") + case OutputFormat.quiet: # first value only + values = list(data.values()) + if values: + _print_flush(values[0]) + + def confirm(self, message: str, *, default: bool = False, yes: bool = False, confirm_param: str = "--yes") -> None: + """ + Ask for confirmation. Raises `ConfirmationError` in non-human modes. + """ + if yes: + return + if self.mode != OutputFormat.human: + raise ConfirmationError(f"{message} Use {confirm_param} to skip confirmation.") + click.confirm(message, default=default, abort=True) + + def status(self, message: str | None = None) -> StatusLine: + """Return a status line that emits only in human mode (no-op otherwise).""" + status = StatusLine(enabled=self.mode == OutputFormat.human) + if message is not None: + status.update(message) + return status + + def warning(self, message: str) -> None: + """Print a non-fatal warning to stderr (all modes).""" + if self.mode == OutputFormat.human: + _print_flush(ANSI.yellow(f"Warning: {message}"), file=sys.stderr) + else: + _print_flush(f"Warning: {message}", file=sys.stderr) + + def error(self, message: str) -> None: + """Print an error to stderr (all modes).""" + if self.mode == OutputFormat.human: + _print_flush(ANSI.red(f"Error: {message}"), file=sys.stderr) + else: + _print_flush(f"Error: {message}", file=sys.stderr) + + def log(self, message: str) -> None: + """Print a text message to stderr (human: gray, json/agent: plain text). + + Suppressed in quiet mode. Kept in json mode (like agent) since agents + commonly run with ``--format json`` and the message goes to stderr so + it never pollutes the parsed stdout. + """ + if self.mode == OutputFormat.quiet: + return + if self.mode == OutputFormat.human: + _print_flush(ANSI.gray(message), file=sys.stderr) + else: + _print_flush(message, file=sys.stderr) + + def hint(self, message: str) -> None: + """Print a helpful hint to stderr (human: gray, json/agent: plain text). + + Suppressed in quiet mode. Kept in json mode (like agent) since agents + commonly run with ``--format json`` and the next-command hints are useful + there; hints go to stderr so they never pollute the parsed stdout. + """ + self.log(f"Hint: {message}") + + +# HELPERS + + +def _serialize_value(v: object) -> object: + """Recursively serialize a value to be JSON-compatible.""" + if isinstance(v, datetime.datetime): + return v.isoformat() + elif isinstance(v, dict): + return {key: _serialize_value(val) for key, val in v.items() if val is not None} + elif isinstance(v, list): + return [_serialize_value(item) for item in v] + return v + + +def _dataclass_to_dict(info: Any) -> dict[str, Any]: + """Convert a dataclass to a json-serializable dict.""" + return {k: _serialize_value(v) for k, v in dataclasses.asdict(info).items() if v is not None} + + +_ANSI_RE = re.compile(r"\033\[[0-9;]*m") + + +def _strip_ansi(text: str) -> str: + return _ANSI_RE.sub("", text) + + +def _single_line(text: str) -> str: + return " ".join(text.split()) + + +def _to_header(name: str) -> str: + """Convert a camelCase or PascalCase string to SCREAMING_SNAKE_CASE.""" + s = re.sub(r"([a-z])([A-Z])", r"\1_\2", name) + return s.upper() + + +def _infer_alignments(headers: list[str], rows: list[list[Any]]) -> dict[str, str]: + """Return ``{"col": "right"}`` for columns where every non-None value is numeric.""" + result: dict[str, str] = {} + for c, h in enumerate(headers): + if all(row[c] is None or (isinstance(row[c], (int, float)) and not isinstance(row[c], bool)) for row in rows): + result[h] = "right" + return result + + +def _format_table_value_human(value: Any) -> str: + """Convert a value to string for terminal display.""" + if value is None: + return "" + if isinstance(value, bool): + return "✔" if value else "" + if isinstance(value, datetime.datetime): + return value.strftime("%Y-%m-%d") + if isinstance(value, str) and re.match(r"^\d{4}-\d{2}-\d{2}T", value): + return value[:10] + if isinstance(value, str): + return _single_line(value) + if isinstance(value, list): + return ", ".join(_format_table_value_human(v) for v in value) + elif isinstance(value, dict): + if "name" in value: # Likely to be a user or org => print name + return _single_line(str(value["name"])) + return _single_line(json.dumps(value)) + return _single_line(str(value)) + + +def _truncate_columns( + headers: list[str], + rows: list[list[str]], + *, + no_truncate: bool, +) -> bool: + """Truncate cells in-place to fit the current terminal width. + + Returns `True` if any cell was truncated, so the caller can emit a hint. + `shutil.get_terminal_size` is cross-platform: it honors `$COLUMNS`, then + queries the OS-native API, then falls back to `(80, 24)`. + """ + if no_truncate or not rows: + return False + + n = len(headers) + # Per-column natural width: longest of header label and cell values. + natural = [max(len(headers[c]), *(len(rows[r][c]) for r in range(len(rows)))) for c in range(n)] + + # `max(0, n - 1)` accounts for the single-space separator between columns. + budget = shutil.get_terminal_size().columns - max(0, n - 1) + if sum(natural) <= budget: + return False + + # Shrink the widest column 1 char at a time. Floors keep the header label + # visible; the `4` is the smallest cap that still shows "x..." (one content + # char plus the "..." marker). + caps = natural.copy() + min_widths = [max(len(h), 4) for h in headers] + while sum(caps) > budget: + widest = max( + (i for i, w in enumerate(caps) if w > min_widths[i]), + key=lambda i: caps[i], + default=-1, + ) + if widest < 0: + break # everything at floor — table wraps slightly + caps[widest] -= 1 + + truncated = False + for row in rows: + for c, cell in enumerate(row): + if len(cell) > caps[c]: + truncated = True + row[c] = cell[: caps[c] - 3] + "..." + return truncated + + +def _format_table_cell_agent(value: Any) -> str: + """Format a cell value for agent TSV output (ISO timestamps, tabs escaped).""" + if isinstance(value, datetime.datetime): + return value.isoformat() + return _single_line(str(value)) + + +out = Output() diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_skills.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_skills.py new file mode 100644 index 0000000000000000000000000000000000000000..664dd4bcdfb06bd62aad6bfe76815b5507f53beb --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/_skills.py @@ -0,0 +1,311 @@ +"""Internal helpers for Hugging Face marketplace skill installation and upgrades.""" + +import json +import re +import shutil +import tempfile +from collections.abc import Callable +from dataclasses import dataclass, replace +from pathlib import Path, PurePosixPath +from typing import Any, Literal + +from huggingface_hub._buckets import BucketFile +from huggingface_hub.errors import CLIError + +from ..utils import disable_progress_bars +from ._cli_utils import get_hf_api + + +DEFAULT_SKILL_ID = "hf-cli" +DEFAULT_SKILLS_BUCKET_ID = "huggingface/skills" +MARKETPLACE_PATH = "marketplace.json" +# Empty marker file dropped into managed skill installs so `hf skills update` knows +# to touch them and leave user-placed skill dirs alone. Filename is historical (used +# to be a JSON manifest with a revision); we keep it for backward compat with installs +# made by previous versions. +MANAGED_MARKER_FILENAME = ".hf-skill-manifest.json" + +SkillUpdateStatus = Literal["up_to_date", "unmanaged", "source_unreachable"] + + +@dataclass(frozen=True) +class MarketplaceSkill: + name: str + repo_path: str + description: str | None = None + + +@dataclass(frozen=True) +class SkillUpdateInfo: + name: str + skill_dir: Path + status: SkillUpdateStatus + detail: str | None = None + + +def add_skill(skill_name: str, destination_root: Path, force: bool = False) -> Path: + """Resolve a marketplace skill by name and install it.""" + api = get_hf_api() + with disable_progress_bars(): + marketplace_skills = _load_marketplace_skills(api) + skill = _select_marketplace_skill(marketplace_skills, skill_name) + if skill is None: + raise CLIError( + f"Skill '{skill_name}' not found in {DEFAULT_SKILLS_BUCKET_ID}. " + "Try `hf skills add` to install `hf-cli` or use a known skill name." + ) + return _install_marketplace_skill(api, skill, destination_root, force=force) + + +def install_generated_skill(content: str, destination_root: Path, force: bool = False) -> Path: + """Install the `hf-cli` skill from locally generated SKILL.md content (no bucket download).""" + + def populate(install_dir: Path) -> None: + install_dir.mkdir(parents=True, exist_ok=True) + (install_dir / "SKILL.md").write_text(content, encoding="utf-8") + (install_dir / MANAGED_MARKER_FILENAME).touch() + + return _install_skill(DEFAULT_SKILL_ID, destination_root, populate=populate, force=force) + + +def update_skills(roots: list[Path], selector: str | None = None, *, hf_cli_content: str) -> list[SkillUpdateInfo]: + """Re-sync managed skill installs (`hf-cli` is rewritten from `hf_cli_content`, the rest from the bucket).""" + skill_dirs = _iter_unique_skill_dirs(roots) + if selector is not None: + selector_lower = selector.strip().lower() + skill_dirs = [d for d in skill_dirs if d.name.lower() == selector_lower] + if not skill_dirs: + raise CLIError(f"No installed skill matches '{selector}'. Install it with `hf skills add {selector}`.") + + # `hf-cli` is regenerated locally, so only hit the marketplace when another managed skill needs it. + needs_marketplace = any(d.name != DEFAULT_SKILL_ID and (d / MANAGED_MARKER_FILENAME).exists() for d in skill_dirs) + api = None + marketplace_skills: dict[str, MarketplaceSkill] = {} + if needs_marketplace: + api = get_hf_api() + with disable_progress_bars(): + marketplace_skills = {skill.name.lower(): skill for skill in _load_marketplace_skills(api)} + + return [_apply_single_update(api, skill_dir, marketplace_skills, hf_cli_content) for skill_dir in skill_dirs] + + +def _load_marketplace_skills(api) -> list[MarketplaceSkill]: + payload = _load_marketplace_payload(api) + plugins = payload.get("plugins") + if not isinstance(plugins, list): + raise CLIError("Invalid marketplace payload: expected a top-level 'plugins' list.") + + skills: list[MarketplaceSkill] = [] + for plugin in plugins: + if not isinstance(plugin, dict): + continue + name = plugin.get("name") + source = plugin.get("source") + if not isinstance(name, str) or not isinstance(source, str): + continue + description = plugin.get("description") + skills.append( + MarketplaceSkill( + name=name, + repo_path=_normalize_repo_path(source), + description=description if isinstance(description, str) else None, + ) + ) + return skills + + +def _install_marketplace_skill(api, skill: MarketplaceSkill, destination_root: Path, force: bool = False) -> Path: + """Install a marketplace skill into a local skills directory.""" + + def populate(install_dir: Path) -> None: + install_dir.mkdir(parents=True, exist_ok=True) + bucket_files = _list_skill_files(api, skill) + _download_skill_files(api, skill, bucket_files, install_dir) + _validate_installed_skill_dir(install_dir) + (install_dir / MANAGED_MARKER_FILENAME).touch() + + return _install_skill(skill.name, destination_root, populate=populate, force=force) + + +_VALID_SKILL_NAME = re.compile(r"[A-Za-z0-9][A-Za-z0-9._-]*") + + +def _install_skill( + name: str, + destination_root: Path, + populate: Callable[[Path], None], + force: bool = False, +) -> Path: + """Install a skill into ``destination_root`` by calling ``populate(install_dir)`` to fill it. + + Used by both the marketplace install (populate = download from bucket) and the + locally-generated install (populate = write content). When the install already + exists and ``force`` is set, the new content is staged in a sibling tempdir and + atomically swapped in, so the existing install stays intact if ``populate`` + fails halfway through. + """ + # `name` may come from the remote marketplace payload and the install dir is removed on + # reinstall: validate it as defense-in-depth against path traversal. + if not _VALID_SKILL_NAME.fullmatch(name): + raise CLIError(f"Invalid skill name '{name}'.") + destination_root = destination_root.expanduser().resolve() + destination_root.mkdir(parents=True, exist_ok=True) + install_dir = destination_root / name + already_exists = install_dir.exists() + + if already_exists and not force: + raise FileExistsError(f"Skill already exists: {install_dir}") + + if already_exists: + with tempfile.TemporaryDirectory(dir=destination_root, prefix=f".{install_dir.name}.install-") as tmp_dir_str: + staged_dir = Path(tmp_dir_str) / install_dir.name + populate(staged_dir) + _atomic_replace_directory(existing_dir=install_dir, staged_dir=staged_dir) + return install_dir + + try: + populate(install_dir) + except Exception: + if install_dir.exists(): + shutil.rmtree(install_dir) + raise + return install_dir + + +def _load_marketplace_payload(api) -> dict[str, Any]: + with tempfile.TemporaryDirectory() as tmp_dir: + local_path = Path(tmp_dir) / "marketplace.json" + api.download_bucket_files( + DEFAULT_SKILLS_BUCKET_ID, + [(MARKETPLACE_PATH, local_path)], + raise_on_missing_files=True, + ) + parsed = json.loads(local_path.read_text(encoding="utf-8")) + + if not isinstance(parsed, dict): + raise CLIError("Invalid marketplace payload: expected a JSON object.") + return parsed + + +def _select_marketplace_skill(skills: list[MarketplaceSkill], selector: str) -> MarketplaceSkill | None: + selector_lower = selector.strip().lower() + for skill in skills: + if skill.name.lower() == selector_lower: + return skill + return None + + +def _normalize_repo_path(path: str) -> str: + normalized = path.strip() + while normalized.startswith("./"): + normalized = normalized[2:] + normalized = normalized.strip("/") + if not normalized: + raise CLIError("Invalid marketplace entry: empty source path.") + return normalized + + +def _validate_installed_skill_dir(skill_dir: Path) -> None: + skill_file = skill_dir / "SKILL.md" + if not skill_file.is_file(): + raise RuntimeError(f"Installed skill is missing SKILL.md: {skill_file}") + + +def _list_skill_files(api, skill: MarketplaceSkill) -> list[BucketFile]: + """List all files under `skill.repo_path` in the marketplace bucket.""" + prefix = skill.repo_path.rstrip("/") + files: list[BucketFile] = [ + item + for item in api.list_bucket_tree(DEFAULT_SKILLS_BUCKET_ID, prefix=prefix, recursive=True) + if isinstance(item, BucketFile) + ] + if not files: + raise FileNotFoundError(f"Path '{prefix}' not found in bucket '{DEFAULT_SKILLS_BUCKET_ID}'.") + return files + + +def _download_skill_files(api, skill: MarketplaceSkill, files: list[BucketFile], install_dir: Path) -> None: + """Download bucket files into `install_dir`.""" + prefix = skill.repo_path.rstrip("/") + prefix_with_slash = f"{prefix}/" + + # `list_bucket_tree(prefix=...)` matches as a raw string prefix, so e.g. asking for + # "skills/gradio" can also return "skills/gradio-tools/...". Filter on the trailing + # slash to keep only files actually inside the directory, then strip it so files land + # directly under `install_dir` preserving any nested structure. + download_specs: list[tuple[str | BucketFile, str | Path]] = [] + for bucket_file in files: + if not bucket_file.path.startswith(prefix_with_slash): + continue + relative = bucket_file.path[len(prefix_with_slash) :] + local_file = install_dir.joinpath(*PurePosixPath(relative).parts) + local_file.parent.mkdir(parents=True, exist_ok=True) + download_specs.append((bucket_file, local_file)) + + if not download_specs: + raise FileNotFoundError(f"No files found under '{prefix}' in bucket '{DEFAULT_SKILLS_BUCKET_ID}'.") + + api.download_bucket_files(DEFAULT_SKILLS_BUCKET_ID, download_specs) + + +def _atomic_replace_directory(existing_dir: Path, staged_dir: Path) -> None: + backup_dir = staged_dir.parent / f"{existing_dir.name}.backup" + try: + existing_dir.rename(backup_dir) + staged_dir.rename(existing_dir) + shutil.rmtree(backup_dir) + except Exception: + if backup_dir.exists() and not existing_dir.exists(): + backup_dir.rename(existing_dir) + raise + + +def _iter_unique_skill_dirs(roots: list[Path]) -> list[Path]: + seen: set[Path] = set() + discovered: list[Path] = [] + for root in roots: + root = root.expanduser().resolve() + if not root.is_dir(): + continue + for child in sorted(root.iterdir()): + if child.name.startswith("."): + continue + if not child.is_dir() and not child.is_symlink(): + continue + resolved = child.resolve() + if resolved in seen or not resolved.is_dir(): + continue + seen.add(resolved) + discovered.append(resolved) + return discovered + + +def _apply_single_update( + api, skill_dir: Path, marketplace_skills: dict[str, MarketplaceSkill], hf_cli_content: str +) -> SkillUpdateInfo: + base = SkillUpdateInfo(name=skill_dir.name, skill_dir=skill_dir, status="unmanaged") + + if not (skill_dir / MANAGED_MARKER_FILENAME).exists(): + return base + + if skill_dir.name == DEFAULT_SKILL_ID: + try: + install_generated_skill(hf_cli_content, skill_dir.parent, force=True) + except Exception as exc: + return replace(base, status="source_unreachable", detail=str(exc)) + return replace(base, status="up_to_date") + + skill = marketplace_skills.get(skill_dir.name.lower()) + if skill is None: + return replace( + base, + status="source_unreachable", + detail=f"Skill '{skill_dir.name}' is no longer available in {DEFAULT_SKILLS_BUCKET_ID}.", + ) + + try: + _install_marketplace_skill(api, skill, skill_dir.parent, force=True) + except Exception as exc: + return replace(base, status="source_unreachable", detail=str(exc)) + + return replace(base, status="up_to_date") diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/auth.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/auth.py new file mode 100644 index 0000000000000000000000000000000000000000..e04bfa316eef8899045b3d53b62ad88809bb35ab --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/auth.py @@ -0,0 +1,174 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains commands to authenticate to the Hugging Face Hub and interact with your repositories.""" + +from typing import Annotated + +import click + +from huggingface_hub.constants import ENDPOINT +from huggingface_hub.hf_api import whoami + +from .._login import _save_oauth_token, auth_list, auth_switch, login, logout +from ..errors import CLIError +from ..utils import get_stored_tokens, get_token, logging, select_choice +from ..utils._oauth_device import poll_device_token, request_device_code +from ._cli_utils import TokenOpt, typer_factory +from ._framework import Option +from ._output import OutputFormat, out + + +logger = logging.get_logger(__name__) + + +auth_cli = typer_factory(help="Manage authentication (login, logout, etc.).") + + +@auth_cli.command( + "login", + examples=[ + "hf auth login", + "hf auth login --token $HF_TOKEN", + "hf auth login --token $HF_TOKEN --add-to-git-credential", + "hf auth login --force", + ], +) +def auth_login( + token: TokenOpt = None, + add_to_git_credential: Annotated[ + bool, + Option( + help="Save to git credential helper. Useful only if you plan to run git commands directly.", + ), + ] = False, + force: Annotated[ + bool, + Option( + help="Force re-login even if already logged in.", + ), + ] = False, +) -> None: + """Login from your browser, or using a token from huggingface.co/settings/tokens.""" + if token is not None or out.mode == OutputFormat.human: + # `--token` bypasses any prompt; in human mode the gh-style menu lives in `login()`. + login(token=token, add_to_git_credential=add_to_git_credential, skip_if_logged_in=not force) + return + + # Logging in is an interactive flow: besides human mode, only agent mode is supported. + if out.mode != OutputFormat.agent: + raise CLIError( + "`hf auth login` is interactive and does not support --format json/quiet. " + "Pass --token for a non-interactive login." + ) + + # agent mode: never prompt; print instructions the agent can relay to its user. + if not force and get_token() is not None: + out.text(agent="Already logged in. Use `hf auth login --force` to re-login.") + return + device_info = request_device_code() + out.text( + agent=( + f"Ask the user to open {device_info['verification_uri_complete']} in a browser and enter the code " + f"{device_info['user_code']}. The code expires in {device_info['expires_in']} seconds. " + "Waiting for authorization..." + ) + ) + response = poll_device_token(device_info) + token_name, username = _save_oauth_token(response) + out.text(agent=f"Login successful: logged in as {username} (token saved as '{token_name}').") + + +@auth_cli.command( + "logout", + examples=["hf auth logout", "hf auth logout --token-name my-token"], +) +def auth_logout( + token_name: Annotated[ + str | None, + Option(help="Name of token to logout"), + ] = None, +) -> None: + """Logout from a specific token.""" + logout(token_name=token_name) + + +def _select_token_name() -> str | None: + token_names = list(get_stored_tokens().keys()) + + if not token_names: + logger.error("No stored tokens found. Please login first.") + return None + + if out.mode != OutputFormat.human: + raise CLIError("Use --token-name to select a token in non-interactive mode.") + return token_names[select_choice("Select a token to switch to:", token_names)] + + +@auth_cli.command( + "switch", + examples=["hf auth switch", "hf auth switch --token-name my-token"], +) +def auth_switch_cmd( + token_name: Annotated[ + str | None, + Option( + help="Name of the token to switch to", + ), + ] = None, + add_to_git_credential: Annotated[ + bool, + Option( + help="Save to git credential helper. Useful only if you plan to run git commands directly.", + ), + ] = False, +) -> None: + """Switch between access tokens.""" + if token_name is None: + token_name = _select_token_name() + if token_name is None: + print("No token name provided. Aborting.") + raise click.exceptions.Exit() + auth_switch(token_name, add_to_git_credential=add_to_git_credential) + + +@auth_cli.command("list | ls", examples=["hf auth list"]) +def auth_list_cmd() -> None: + """List all stored access tokens.""" + auth_list() + + +@auth_cli.command("token", examples=["hf auth token", "hf auth token | xargs curl -H 'Authorization: Bearer {}'"]) +def auth_token() -> None: + """Print the current access token to stdout.""" + token = get_token() + if token is None: + out.error("Not logged in. Run `hf auth login` first.") + raise click.exceptions.Exit(code=1) + print(token) + out.hint("Run `hf auth whoami` to see which account this token belongs to.") + + +@auth_cli.command("whoami", examples=["hf auth whoami", "hf auth whoami --format json"]) +def auth_whoami() -> None: + """Find out which huggingface.co account you are logged in as.""" + + token = get_token() + if token is None: + out.error("Not logged in") + raise click.exceptions.Exit(code=1) + + info = whoami(token) + orgs = ",".join(org["name"] for org in info["orgs"]) or None + endpoint = ENDPOINT if ENDPOINT != "https://huggingface.co" else None + out.result("Logged in", user=info["name"], orgs=orgs, endpoint=endpoint) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/buckets.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/buckets.py new file mode 100644 index 0000000000000000000000000000000000000000..9b84e77014902c14da41466e461ea854d75f1595 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/buckets.py @@ -0,0 +1,679 @@ +# Copyright 2025-present, the HuggingFace Inc. team. +# +# 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. +"""Contains commands to interact with buckets via the CLI.""" + +from typing import Annotated + +import click + +from huggingface_hub import logging +from huggingface_hub._buckets import ( + BUCKET_PREFIX, + BucketFile, + FilterMatcher, + _parse_bucket_uri, +) + +from ..hf_api import REPO_REGIONS +from ._cli_utils import ( + SearchOpt, + TokenOpt, + get_hf_api, + typer_factory, +) +from ._cp import make_cp +from ._file_listing import format_size, print_file_listing +from ._framework import Argument, Option +from ._output import OutputFormat, out + + +logger = logging.get_logger(__name__) + + +buckets_cli = typer_factory(help="Commands to interact with buckets.") + + +@buckets_cli.command( + name="create", + examples=[ + "hf buckets create my-bucket", + "hf buckets create user/my-bucket", + "hf buckets create hf://buckets/user/my-bucket", + "hf buckets create user/my-bucket --private", + "hf buckets create user/my-bucket --exist-ok", + "hf buckets create user/my-bucket --region us", + ], +) +def create( + bucket_id: Annotated[ + str, + Argument( + help="Bucket ID: bucket_name, namespace/bucket_name, or hf://buckets/namespace/bucket_name", + ), + ], + private: Annotated[ + bool, + Option( + "--private", + help="Create a private bucket.", + ), + ] = False, + region: Annotated[ + REPO_REGIONS | None, + Option( + "--region", + help="Cloud region in which to create the bucket. Can be one of 'us' or 'eu'. Requires Team plan or above.", + ), + ] = None, + exist_ok: Annotated[ + bool, + Option( + "--exist-ok", + help="Do not raise an error if the bucket already exists.", + ), + ] = False, + token: TokenOpt = None, +) -> None: + """Create a new bucket.""" + api = get_hf_api(token=token) + + if bucket_id.startswith(BUCKET_PREFIX): + parsed = _parse_bucket_uri(bucket_id) + if parsed.path_in_repo: + raise click.BadParameter( + f"Cannot specify a prefix for bucket creation: {bucket_id}." + f" Use namespace/bucket_name or {BUCKET_PREFIX}namespace/bucket_name." + ) + bucket_id = parsed.id + + bucket_url = api.create_bucket( + bucket_id, + private=private if private else None, + region=region, + exist_ok=exist_ok, + ) + out.result("Bucket created", uri=bucket_url.uri.to_uri(), url=bucket_url.url) + + +def _is_bucket_id(argument: str) -> bool: + """Check if argument is a bucket ID (namespace/name) vs just a namespace.""" + if argument.startswith(BUCKET_PREFIX): + path = argument[len(BUCKET_PREFIX) :] + else: + path = argument + return "/" in path + + +@buckets_cli.command( + name="list | ls", + examples=[ + "hf buckets list", + "hf buckets list huggingface", + 'hf buckets list --search "my-prefix"', + "hf buckets list user/my-bucket", + "hf buckets list user/my-bucket -R", + "hf buckets list user/my-bucket -h", + "hf buckets list user/my-bucket --tree", + "hf buckets list user/my-bucket --tree -h", + "hf buckets list hf://buckets/user/my-bucket", + "hf buckets list user/my-bucket/sub -R", + ], +) +def list_cmd( + argument: Annotated[ + str | None, + Argument( + help=( + "Namespace (user or org) to list buckets, or bucket ID" + " (namespace/bucket_name(/prefix) or hf://buckets/...) to list files." + ), + ), + ] = None, + human_readable: Annotated[ + bool, + Option( + "--human-readable", + "-h", + help="Show sizes in human readable format.", + ), + ] = False, + as_tree: Annotated[ + bool, + Option( + "--tree", + help="List files in tree format (only for listing files).", + ), + ] = False, + recursive: Annotated[ + bool, + Option( + "--recursive", + "-R", + help="List files recursively (only for listing files).", + ), + ] = False, + search: SearchOpt = None, + token: TokenOpt = None, +) -> None: + """List buckets or files in a bucket. + + When called with no argument or a namespace, lists buckets. + When called with a bucket ID (namespace/bucket_name), lists files in the bucket. + """ + # Determine mode: listing buckets or listing files + is_file_mode = argument is not None and _is_bucket_id(argument) + + if is_file_mode: + if search is not None: + raise click.BadParameter("Cannot use --search when listing files.") + _list_files( + argument=argument, # type: ignore + human_readable=human_readable, + as_tree=as_tree, + recursive=recursive, + token=token, + ) + else: + _list_buckets( + namespace=argument, + search=search, + human_readable=human_readable, + as_tree=as_tree, + recursive=recursive, + token=token, + ) + + +def _list_buckets( + namespace: str | None, + search: str | None, + human_readable: bool, + as_tree: bool, + recursive: bool, + token: str | None, +) -> None: + """List buckets in a namespace.""" + # Validate incompatible flags + if as_tree: + raise click.BadParameter("Cannot use --tree when listing buckets.") + if recursive: + raise click.BadParameter("Cannot use --recursive when listing buckets.") + + # Handle hf://buckets/namespace format + if namespace is not None and namespace.startswith(BUCKET_PREFIX): + namespace = namespace[len(BUCKET_PREFIX) :] + # Strip trailing slash if any + namespace = namespace.rstrip("/") + + api = get_hf_api(token=token) + items = [ + { + "id": bucket.id, + "private": bucket.private, + "size": format_size(bucket.size, human_readable) if human_readable else bucket.size, + "total_files": bucket.total_files, + "created_at": bucket.created_at, + } + for bucket in api.list_buckets(namespace=namespace, search=search) + ] + out.table(items, alignments={"size": "right"}) + + +def _list_files( + argument: str, + human_readable: bool, + as_tree: bool, + recursive: bool, + token: str | None, +) -> None: + """List files in a bucket.""" + if as_tree and out.mode == OutputFormat.json: + raise click.BadParameter("Cannot use --tree with --format json.") + + api = get_hf_api(token=token) + parsed = _parse_bucket_uri(argument) + items = list( + api.list_bucket_tree( + parsed.id, + prefix=parsed.path_in_repo or None, + recursive=recursive, + ) + ) + + print_file_listing(items, human_readable=human_readable, as_tree=as_tree, recursive=recursive) + + +@buckets_cli.command( + name="info", + examples=[ + "hf buckets info user/my-bucket", + "hf buckets info hf://buckets/user/my-bucket", + ], +) +def info( + bucket_id: Annotated[ + str, + Argument( + help="Bucket ID: namespace/bucket_name or hf://buckets/namespace/bucket_name", + ), + ], + token: TokenOpt = None, +) -> None: + """Get info about a bucket.""" + api = get_hf_api(token=token) + parsed = _parse_bucket_uri(bucket_id) + bucket = api.bucket_info(parsed.id) + out.dict(bucket, id_key="id") + + +@buckets_cli.command( + name="delete", + examples=[ + "hf buckets delete user/my-bucket", + "hf buckets delete hf://buckets/user/my-bucket", + "hf buckets delete user/my-bucket --yes", + "hf buckets delete user/my-bucket --missing-ok", + ], +) +def delete( + bucket_id: Annotated[ + str, + Argument( + help="Bucket ID: namespace/bucket_name or hf://buckets/namespace/bucket_name", + ), + ], + yes: Annotated[ + bool, + Option( + "--yes", + "-y", + help="Skip confirmation prompt.", + ), + ] = False, + missing_ok: Annotated[ + bool, + Option( + "--missing-ok", + help="Do not raise an error if the bucket does not exist.", + ), + ] = False, + token: TokenOpt = None, +) -> None: + """Delete a bucket. + + This deletes the entire bucket and all its contents. Use `hf buckets rm` to remove individual files. + """ + if bucket_id.startswith(BUCKET_PREFIX): + parsed = _parse_bucket_uri(bucket_id) + if parsed.path_in_repo: + raise click.BadParameter( + f"Cannot specify a prefix for bucket deletion: {bucket_id}." + f" Use namespace/bucket_name or {BUCKET_PREFIX}namespace/bucket_name." + ) + bucket_id = parsed.id + elif "/" not in bucket_id: + raise click.BadParameter( + f"Invalid bucket ID: {bucket_id}." + f" Must be in format namespace/bucket_name or {BUCKET_PREFIX}namespace/bucket_name." + ) + + out.confirm(f"Are you sure you want to delete bucket '{bucket_id}'?", yes=yes) + + api = get_hf_api(token=token) + api.delete_bucket(bucket_id, missing_ok=missing_ok) + out.result("Bucket deleted", bucket_id=bucket_id) + + +@buckets_cli.command( + name="remove | rm", + examples=[ + "hf buckets remove user/my-bucket/file.txt", + "hf buckets rm hf://buckets/user/my-bucket/file.txt", + "hf buckets rm user/my-bucket/logs/ --recursive", + 'hf buckets rm user/my-bucket --recursive --include "*.tmp"', + "hf buckets rm user/my-bucket/data/ --recursive --dry-run", + ], +) +def remove( + argument: Annotated[ + str, + Argument( + help=( + "Bucket path: namespace/bucket_name/path or hf://buckets/namespace/bucket_name/path." + " With --recursive, namespace/bucket_name is also accepted to target all files." + ), + ), + ], + recursive: Annotated[ + bool, + Option( + "--recursive", + "-R", + help="Remove files recursively under the given prefix.", + ), + ] = False, + yes: Annotated[ + bool, + Option( + "--yes", + "-y", + help="Skip confirmation prompt.", + ), + ] = False, + dry_run: Annotated[ + bool, + Option( + "--dry-run", + help="Preview what would be deleted without actually deleting.", + ), + ] = False, + include: Annotated[ + list[str] | None, + Option( + help="Include only files matching pattern (can specify multiple). Requires --recursive.", + ), + ] = None, + exclude: Annotated[ + list[str] | None, + Option( + help="Exclude files matching pattern (can specify multiple). Requires --recursive.", + ), + ] = None, + token: TokenOpt = None, +) -> None: + """Remove files from a bucket. + + To delete an entire bucket, use `hf buckets delete` instead. + """ + parsed = _parse_bucket_uri(argument) + bucket_id = parsed.id + prefix = parsed.path_in_repo + + if prefix == "" and not recursive: + raise click.BadParameter( + f"No file path specified. To remove files, provide a path" + f" (e.g. '{bucket_id}/FILE') or use --recursive to remove all files." + f" To delete the entire bucket, use `hf buckets delete {bucket_id}`." + ) + + if (include or exclude) and not recursive: + raise click.BadParameter("--include and --exclude require --recursive.") + + api = get_hf_api(token=token) + + if recursive: + status = out.status("Listing files from remote") + + all_files: list[BucketFile] = [] + for item in api.list_bucket_tree( + bucket_id, + prefix=prefix or None, + recursive=True, + ): + if isinstance(item, BucketFile): + all_files.append(item) + status.update(f"Listing files from remote ({len(all_files)} files)") + status.done(f"Listing files from remote ({len(all_files)} files)") + + if include or exclude: + matcher = FilterMatcher(include_patterns=include, exclude_patterns=exclude) + matched_files = [f for f in all_files if matcher.matches(f.path)] + else: + matched_files = all_files + + file_paths = [f.path for f in matched_files] + total_size = sum(f.size for f in matched_files) + size_str = format_size(total_size, human_readable=True) + + if not file_paths: + out.text("No files to remove.") + return + + count_label = f"{len(file_paths)} file(s) totaling {size_str}" + + if not yes and not dry_run: + out.text("\n".join(f" {path}" for path in file_paths)) + out.confirm(f"Remove {count_label} from '{bucket_id}'?", yes=False) + + if dry_run: + out.text("\n".join(f"delete: {BUCKET_PREFIX}{bucket_id}/{path}" for path in file_paths)) + out.text(f"(dry run) {count_label} would be removed.") + return + + api.batch_bucket_files(bucket_id, delete=file_paths) + out.result( + f"Removed {count_label} from '{bucket_id}'", + bucket_id=bucket_id, + files_deleted=len(file_paths), + size=size_str, + ) + + else: + file_path = prefix + if not file_path: + raise click.BadParameter("File path cannot be empty.") + + if dry_run: + out.text(f"delete: {BUCKET_PREFIX}{bucket_id}/{file_path}") + out.text("(dry run) 1 file would be removed.") + return + + out.confirm(f"Remove '{file_path}' from '{bucket_id}'?", yes=yes) + + api.batch_bucket_files(bucket_id, delete=[file_path]) + out.result("File removed", path=file_path, bucket_id=bucket_id) + + +@buckets_cli.command( + name="move", + examples=[ + "hf buckets move user/old-bucket user/new-bucket", + "hf buckets move user/my-bucket my-org/my-bucket", + "hf buckets move hf://buckets/user/old-bucket hf://buckets/user/new-bucket", + ], +) +def move( + from_id: Annotated[ + str, + Argument( + help="Source bucket ID: namespace/bucket_name or hf://buckets/namespace/bucket_name", + ), + ], + to_id: Annotated[ + str, + Argument( + help="Destination bucket ID: namespace/bucket_name or hf://buckets/namespace/bucket_name", + ), + ], + token: TokenOpt = None, +) -> None: + """Move (rename) a bucket to a new name or namespace.""" + # Parse from_id + parsed_from = _parse_bucket_uri(from_id) + if parsed_from.path_in_repo: + raise click.BadParameter( + f"Cannot specify a prefix for bucket move: {from_id}." + f" Use namespace/bucket_name or {BUCKET_PREFIX}namespace/bucket_name." + ) + + # Parse to_id + parsed_to = _parse_bucket_uri(to_id) + if parsed_to.path_in_repo: + raise click.BadParameter( + f"Cannot specify a prefix for bucket move: {to_id}." + f" Use namespace/bucket_name or {BUCKET_PREFIX}namespace/bucket_name." + ) + + api = get_hf_api(token=token) + api.move_bucket(from_id=parsed_from.id, to_id=parsed_to.id) + out.result("Bucket moved", from_id=parsed_from.id, to_id=parsed_to.id) + + +# ============================================================================= +# Sync command +# ============================================================================= + + +@buckets_cli.command( + name="sync", + examples=[ + "hf buckets sync ./data hf://buckets/user/my-bucket", + "hf buckets sync hf://buckets/user/my-bucket ./data", + "hf buckets sync ./data hf://buckets/user/my-bucket --delete", + 'hf buckets sync hf://buckets/user/my-bucket ./data --include "*.safetensors" --exclude "*.tmp"', + "hf buckets sync ./data hf://buckets/user/my-bucket --plan sync-plan.jsonl", + "hf buckets sync --apply sync-plan.jsonl", + "hf buckets sync ./data hf://buckets/user/my-bucket --dry-run", + "hf buckets sync ./data hf://buckets/user/my-bucket --dry-run | jq .", + ], +) +def sync( + source: Annotated[ + str | None, + Argument( + help="Source path: local directory or hf://buckets/namespace/bucket_name(/prefix)", + ), + ] = None, + dest: Annotated[ + str | None, + Argument( + help="Destination path: local directory or hf://buckets/namespace/bucket_name(/prefix)", + ), + ] = None, + delete: Annotated[ + bool, + Option( + help="Delete destination files not present in source.", + ), + ] = False, + ignore_times: Annotated[ + bool, + Option( + "--ignore-times", + help="Skip files only based on size, ignoring modification times.", + ), + ] = False, + ignore_sizes: Annotated[ + bool, + Option( + "--ignore-sizes", + help="Skip files only based on modification times, ignoring sizes.", + ), + ] = False, + plan: Annotated[ + str | None, + Option( + help="Save sync plan to JSONL file for review instead of executing.", + ), + ] = None, + apply: Annotated[ + str | None, + Option( + help="Apply a previously saved plan file.", + ), + ] = None, + dry_run: Annotated[ + bool, + Option( + "--dry-run", + help="Print sync plan to stdout as JSONL without executing.", + ), + ] = False, + include: Annotated[ + list[str] | None, + Option( + help="Include files matching pattern (can specify multiple).", + ), + ] = None, + exclude: Annotated[ + list[str] | None, + Option( + help="Exclude files matching pattern (can specify multiple).", + ), + ] = None, + filter_from: Annotated[ + str | None, + Option( + help="Read include/exclude patterns from file.", + ), + ] = None, + existing: Annotated[ + bool, + Option( + "--existing", + help="Skip creating new files on receiver (only update existing files).", + ), + ] = False, + ignore_existing: Annotated[ + bool, + Option( + "--ignore-existing", + help="Skip updating files that exist on receiver (only create new files).", + ), + ] = False, + verbose: Annotated[ + bool, + Option( + "--verbose", + "-v", + help="Show detailed logging with reasoning.", + ), + ] = False, + token: TokenOpt = None, +) -> None: + """Sync files between local directory and a bucket.""" + api = get_hf_api(token=token) + api.sync_bucket( + source=source, + dest=dest, + delete=delete, + ignore_times=ignore_times, + ignore_sizes=ignore_sizes, + existing=existing, + ignore_existing=ignore_existing, + include=include, + exclude=exclude, + filter_from=filter_from, + plan=plan, + apply=apply, + dry_run=dry_run, + verbose=verbose, + quiet=out.is_quiet(), + ) + if plan and not out.is_quiet(): + out.hint(f"Run `hf buckets sync --apply {plan}` to execute this plan.") + + +# ============================================================================= +# Cp command +# ============================================================================= + + +# `hf buckets cp` is an alias for the top-level `hf cp` command (see `cli/_cp.py`). +buckets_cli.command( + name="cp", + examples=[ + # Download (repo or bucket -> local / stdout) + "hf buckets cp hf://buckets/username/my-bucket/config.json config.json", + "hf buckets cp hf://buckets/username/my-bucket/data.csv data/", + "hf buckets cp hf://buckets/username/my-bucket/config.json -", + # Upload (local / stdin -> bucket) + "hf buckets cp model.safetensors hf://buckets/username/my-bucket/model.safetensors", + "hf buckets cp config.json hf://buckets/username/my-bucket/logs/", + "hf buckets cp - hf://buckets/username/my-bucket/config.json", + # Remote to remote (repo or bucket -> bucket) + "hf buckets cp hf://buckets/username/my-bucket/data.csv hf://buckets/username/dest-bucket/", + "hf buckets cp hf://buckets/username/source-bucket/logs/ hf://buckets/username/dest-bucket/logs/", + ], +)(make_cp("buckets")) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/cache.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/cache.py new file mode 100644 index 0000000000000000000000000000000000000000..fc59ca7720bc91c0c54a0d10092ccb34060c8899 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/cache.py @@ -0,0 +1,800 @@ +# Copyright 2025-present, the HuggingFace Inc. team. +# +# 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. +"""Contains the 'hf cache' command group with cache management subcommands.""" + +import re +import time +from collections import defaultdict +from collections.abc import Callable, Mapping +from dataclasses import dataclass +from enum import Enum +from typing import Annotated, Any + +import click + +from huggingface_hub.errors import CLIError + +from ..utils import ( + ANSI, + CachedRepoInfo, + CachedRevisionInfo, + CacheNotFound, + HFCacheInfo, + _format_size, + parse_hf_uri, + scan_cache_dir, +) +from ..utils._parsing import parse_duration, parse_size +from ._cli_utils import RepoIdArg, RepoTypeOpt, RevisionOpt, TokenOpt, get_hf_api, typer_factory +from ._framework import Argument, Option +from ._output import out + + +cache_cli = typer_factory(help="Manage local cache directory.") + + +#### Cache helper utilities + + +@dataclass(frozen=True) +class _DeletionResolution: + revisions: frozenset[str] + selected: dict[CachedRepoInfo, frozenset[CachedRevisionInfo]] + missing: tuple[str, ...] + + +_FILTER_PATTERN = re.compile(r"^(?P[a-zA-Z_]+)\s*(?P==|!=|>=|<=|>|<|=)\s*(?P.+)$") +_ALLOWED_OPERATORS = {"=", "!=", ">", "<", ">=", "<="} +_FILTER_KEYS = {"accessed", "modified", "refs", "size", "type"} +_SORT_KEYS = {"accessed", "modified", "name", "size"} +_SORT_PATTERN = re.compile(r"^(?P[a-zA-Z_]+)(?::(?Pasc|desc))?$") +_SORT_DEFAULT_ORDER = { + # Default ordering: accessed/modified/size are descending (newest/biggest first), name is ascending + "accessed": "desc", + "modified": "desc", + "size": "desc", + "name": "asc", +} + + +# Dynamically generate SortOptions enum from _SORT_KEYS +_sort_options_dict = {} +for key in sorted(_SORT_KEYS): + _sort_options_dict[key] = key + _sort_options_dict[f"{key}_asc"] = f"{key}:asc" + _sort_options_dict[f"{key}_desc"] = f"{key}:desc" + +SortOptions = Enum("SortOptions", _sort_options_dict, type=str, module=__name__) # type: ignore + + +@dataclass(frozen=True) +class CacheDeletionCounts: + """Simple counters summarizing cache deletions for CLI messaging.""" + + repo_count: int + partial_revision_count: int + total_revision_count: int + + +CacheEntry = tuple[CachedRepoInfo, CachedRevisionInfo | None] +RepoRefsMap = dict[CachedRepoInfo, frozenset[str]] + + +def summarize_deletions( + selected_by_repo: Mapping[CachedRepoInfo, frozenset[CachedRevisionInfo]], +) -> CacheDeletionCounts: + """Summarize deletions across repositories.""" + repo_count = 0 + total_revisions = 0 + revisions_in_full_repos = 0 + + for repo, revisions in selected_by_repo.items(): + total_revisions += len(revisions) + if len(revisions) == len(repo.revisions): + repo_count += 1 + revisions_in_full_repos += len(revisions) + + partial_revision_count = total_revisions - revisions_in_full_repos + return CacheDeletionCounts(repo_count, partial_revision_count, total_revisions) + + +def _prune_summary(revision_count: int, incomplete_count: int) -> str: + """Build the human-readable summary of what `hf cache prune` is about to delete.""" + parts: list[str] = [] + if revision_count: + parts.append(f"{revision_count} unreferenced revision(s)") + if incomplete_count: + parts.append(f"{incomplete_count} incomplete download(s)") + return " and ".join(parts) + + +def print_cache_selected_revisions(selected_by_repo: Mapping[CachedRepoInfo, frozenset[CachedRevisionInfo]]) -> None: + """Pretty-print selected cache revisions during confirmation prompts.""" + for repo in sorted(selected_by_repo.keys(), key=lambda repo: (repo.repo_type, repo.repo_id.lower())): + repo_key = f"{repo.repo_type}/{repo.repo_id}" + revisions = sorted(selected_by_repo[repo], key=lambda rev: rev.commit_hash) + if len(revisions) == len(repo.revisions): + out.text(f" - {repo_key} (entire repo)") + continue + + out.text(f" - {repo_key}:") + for revision in revisions: + refs = " ".join(sorted(revision.refs)) or "(detached)" + out.text(f" {revision.commit_hash} [{refs}] {revision.size_on_disk_str}") + + +def build_cache_index( + hf_cache_info: HFCacheInfo, +) -> tuple[ + dict[str, CachedRepoInfo], + dict[str, tuple[CachedRepoInfo, CachedRevisionInfo]], +]: + """Create lookup tables so CLI commands can resolve repo ids and revisions quickly.""" + repo_lookup: dict[str, CachedRepoInfo] = {} + revision_lookup: dict[str, tuple[CachedRepoInfo, CachedRevisionInfo]] = {} + for repo in hf_cache_info.repos: + repo_key = repo.cache_id.lower() + repo_lookup[repo_key] = repo + for revision in repo.revisions: + revision_lookup[revision.commit_hash.lower()] = (repo, revision) + return repo_lookup, revision_lookup + + +def _repo_cache_id_from_target(target: str) -> str: + """Return the cache id matching a repo target passed to `hf cache rm`.""" + if not target.startswith("hf://"): + return target + + uri = parse_hf_uri(target) + if not uri.is_repo: + raise CLIError("Only repository hf:// URIs are supported by `hf cache rm`.") + if uri.revision is not None or uri.path_in_repo: + raise CLIError("Only repo-level hf:// URIs are supported by `hf cache rm` for now.") + return f"{uri.type}/{uri.id}" + + +def collect_cache_entries( + hf_cache_info: HFCacheInfo, *, include_revisions: bool +) -> tuple[list[CacheEntry], RepoRefsMap]: + """Flatten cache metadata into rows consumed by `hf cache ls`.""" + entries: list[CacheEntry] = [] + repo_refs_map: RepoRefsMap = {} + sorted_repos = sorted(hf_cache_info.repos, key=lambda repo: (repo.repo_type, repo.repo_id.lower())) + for repo in sorted_repos: + repo_refs_map[repo] = frozenset({ref for revision in repo.revisions for ref in revision.refs}) + if include_revisions: + for revision in sorted(repo.revisions, key=lambda rev: rev.commit_hash): + entries.append((repo, revision)) + else: + entries.append((repo, None)) + if include_revisions: + entries.sort( + key=lambda entry: ( + entry[0].cache_id, + entry[1].commit_hash if entry[1] is not None else "", + ) + ) + else: + entries.sort(key=lambda entry: entry[0].cache_id) + return entries, repo_refs_map + + +def compile_cache_filter( + expr: str, repo_refs_map: RepoRefsMap +) -> Callable[[CachedRepoInfo, CachedRevisionInfo | None, float], bool]: + """Convert a `hf cache ls` filter expression into the yes/no test we apply to each cache entry before displaying it.""" + match = _FILTER_PATTERN.match(expr.strip()) + if not match: + raise ValueError(f"Invalid filter expression: '{expr}'.") + + key = match.group("key").lower() + op = match.group("op") + value_raw = match.group("value").strip() + + if op not in _ALLOWED_OPERATORS: + raise ValueError(f"Unsupported operator '{op}' in filter '{expr}'. Must be one of {list(_ALLOWED_OPERATORS)}.") + + if key not in _FILTER_KEYS: + raise ValueError(f"Unsupported filter key '{key}' in '{expr}'. Must be one of {list(_FILTER_KEYS)}.") + # at this point we know that key is in `_FILTER_KEYS` + if key == "size": + size_threshold = parse_size(value_raw) + return lambda repo, revision, _: _compare_numeric( + revision.size_on_disk if revision is not None else repo.size_on_disk, + op, + size_threshold, + ) + + if key in {"modified", "accessed"}: + seconds = parse_duration(value_raw.strip()) + + def _time_filter(repo: CachedRepoInfo, revision: CachedRevisionInfo | None, now: float) -> bool: + timestamp = ( + repo.last_accessed + if key == "accessed" + else revision.last_modified + if revision is not None + else repo.last_modified + ) + if timestamp is None: + return False + return _compare_numeric(now - timestamp, op, seconds) + + return _time_filter + + if key == "type": + expected = value_raw.lower() + + if op != "=": + raise ValueError(f"Only '=' is supported for 'type' filters. Got '{op}'.") + + def _type_filter(repo: CachedRepoInfo, revision: CachedRevisionInfo | None, _: float) -> bool: + return repo.repo_type.lower() == expected + + return _type_filter + + else: # key == "refs" + if op != "=": + raise ValueError(f"Only '=' is supported for 'refs' filters. Got {op}.") + + def _refs_filter(repo: CachedRepoInfo, revision: CachedRevisionInfo | None, _: float) -> bool: + refs = revision.refs if revision is not None else repo_refs_map.get(repo, frozenset()) + return value_raw.lower() in [ref.lower() for ref in refs] + + return _refs_filter + + +def _compare_numeric(left: float | None, op: str, right: float) -> bool: + """Evaluate numeric comparisons for filters.""" + if left is None: + return False + + comparisons = { + "=": left == right, + "!=": left != right, + ">": left > right, + "<": left < right, + ">=": left >= right, + "<=": left <= right, + } + + if op not in comparisons: + raise ValueError(f"Unsupported numeric comparison operator: {op}") + + return comparisons[op] + + +def compile_cache_sort(sort_expr: str) -> tuple[Callable[[CacheEntry], tuple[Any, ...]], bool]: + """Convert a `hf cache ls` sort expression into a key function for sorting entries. + + Returns: + A tuple of (key_function, reverse_flag) where reverse_flag indicates whether + to sort in descending order (True) or ascending order (False). + """ + match = _SORT_PATTERN.match(sort_expr.strip().lower()) + if not match: + raise ValueError(f"Invalid sort expression: '{sort_expr}'. Expected format: 'key' or 'key:asc' or 'key:desc'.") + + key = match.group("key").lower() + explicit_order = match.group("order") + + if key not in _SORT_KEYS: + raise ValueError(f"Unsupported sort key '{key}' in '{sort_expr}'. Must be one of {list(_SORT_KEYS)}.") + + # Use explicit order if provided, otherwise use default for the key + order = explicit_order if explicit_order else _SORT_DEFAULT_ORDER[key] + reverse = order == "desc" + + def _sort_key(entry: CacheEntry) -> tuple[Any, ...]: + repo, revision = entry + + if key == "name": + # Sort by cache_id (repo type/id) + value: Any = repo.cache_id.lower() + return (value,) + + if key == "size": + # Use revision size if available, otherwise repo size + value = revision.size_on_disk if revision is not None else repo.size_on_disk + return (value,) + + if key == "accessed": + # For revisions, accessed is not available per-revision, use repo's last_accessed + # For repos, use repo's last_accessed + value = repo.last_accessed if repo.last_accessed is not None else 0.0 + return (value,) + + if key == "modified": + # Use revision's last_modified if available, otherwise repo's last_modified + if revision is not None: + value = revision.last_modified if revision.last_modified is not None else 0.0 + else: + value = repo.last_modified if repo.last_modified is not None else 0.0 + return (value,) + + # Should never reach here due to validation above + raise ValueError(f"Unsupported sort key: {key}") + + return _sort_key, reverse + + +def _resolve_deletion_targets(hf_cache_info: HFCacheInfo, targets: list[str]) -> _DeletionResolution: + """Resolve the deletion targets into a deletion resolution.""" + repo_lookup, revision_lookup = build_cache_index(hf_cache_info) + + selected: dict[CachedRepoInfo, set[CachedRevisionInfo]] = defaultdict(set) + revisions: set[str] = set() + missing: list[str] = [] + + for raw_target in targets: + target = raw_target.strip() + if not target: + continue + lowered = target.lower() + + if re.fullmatch(r"[0-9a-fA-F]{40}", lowered): + match = revision_lookup.get(lowered) + if match is None: + missing.append(raw_target) + continue + repo, revision = match + selected[repo].add(revision) + revisions.add(revision.commit_hash) + continue + + matched_repo = repo_lookup.get(_repo_cache_id_from_target(target).lower()) + if matched_repo is None: + missing.append(raw_target) + continue + + for revision in matched_repo.revisions: + selected[matched_repo].add(revision) + revisions.add(revision.commit_hash) + + frozen_selected = {repo: frozenset(revs) for repo, revs in selected.items()} + return _DeletionResolution( + revisions=frozenset(revisions), + selected=frozen_selected, + missing=tuple(missing), + ) + + +#### Cache CLI commands + + +@cache_cli.command( + "list | ls", + examples=[ + "hf cache ls", + "hf cache ls --revisions", + 'hf cache ls --filter "size>1GB" --limit 20', + "hf cache ls --format json", + ], +) +def ls( + cache_dir: Annotated[ + str | None, + Option( + help="Cache directory to scan (defaults to Hugging Face cache).", + ), + ] = None, + revisions: Annotated[ + bool, + Option( + help="Include revisions in the output instead of aggregated repositories.", + ), + ] = False, + filter: Annotated[ + list[str] | None, + Option( + "-f", + "--filter", + help="Filter entries (e.g. 'size>1GB', 'type=model', 'accessed>7d'). Can be used multiple times.", + ), + ] = None, + sort: Annotated[ + SortOptions | None, + Option( + help="Sort entries by key. Supported keys: 'accessed', 'modified', 'name', 'size'. " + "Append ':asc' or ':desc' to explicitly set the order (e.g., 'modified:asc'). " + "Defaults: 'accessed', 'modified', 'size' default to 'desc' (newest/biggest first); " + "'name' defaults to 'asc' (alphabetical).", + ), + ] = None, + limit: Annotated[ + int | None, + Option( + help="Limit the number of results returned. Returns only the top N entries after sorting.", + ), + ] = None, +) -> None: + """List cached repositories or revisions.""" + try: + hf_cache_info = scan_cache_dir(cache_dir) + except CacheNotFound as exc: + raise CLIError(f"Cache directory not found: {exc.cache_dir}") from exc + + filters = filter or [] + + entries, repo_refs_map = collect_cache_entries(hf_cache_info, include_revisions=revisions) + try: + filter_fns = [compile_cache_filter(expr, repo_refs_map) for expr in filters] + except ValueError as exc: + raise click.BadParameter(str(exc)) from exc + + now = time.time() + for fn in filter_fns: + entries = [entry for entry in entries if fn(entry[0], entry[1], now)] + + # Apply sorting if requested + if sort: + try: + sort_key_fn, reverse = compile_cache_sort(sort.value) + entries.sort(key=sort_key_fn, reverse=reverse) + except ValueError as exc: + raise click.BadParameter(str(exc)) from exc + + # Apply limit if requested + if limit is not None: + if limit < 0: + raise click.BadParameter(f"Limit must be a positive integer, got {limit}.") + entries = entries[:limit] + + if revisions: + items = [ + { + "id": repo.cache_id, + "repo_id": repo.repo_id, + "repo_type": repo.repo_type, + "revision": revision.commit_hash, + "snapshot_path": str(revision.snapshot_path), + "size": revision.size_on_disk_str, + "last_modified": revision.last_modified_str, + "refs": sorted(revision.refs), + } + for repo, revision in entries + if revision is not None + ] + out.table( + items, + headers=["id", "revision", "size", "last_modified", "refs"], + id_key="revision", + alignments={"size": "right"}, + ) + else: + items = [ + { + "id": repo.cache_id, + "repo_id": repo.repo_id, + "repo_type": repo.repo_type, + "size": repo.size_on_disk_str, + "last_accessed": repo.last_accessed_str or "", + "last_modified": repo.last_modified_str, + "refs": sorted(repo_refs_map.get(repo, frozenset())), + } + for repo, _ in entries + ] + out.table( + items, + headers=["id", "size", "last_accessed", "last_modified", "refs"], + id_key="id", + alignments={"size": "right"}, + ) + + if entries: + unique_repos = {repo for repo, _ in entries} + repo_count = len(unique_repos) + if revisions: + revision_count = sum(1 for _, rev in entries if rev is not None) + total_size = sum(rev.size_on_disk for _, rev in entries if rev is not None) + else: + revision_count = sum(len(repo.revisions) for repo in unique_repos) + total_size = sum(repo.size_on_disk for repo in unique_repos) + out.text( + ANSI.bold( + f"\nFound {repo_count} repo(s) for a total of {revision_count} revision(s)" + f" and {_format_size(total_size)} on disk." + ) + ) + + incomplete_files = hf_cache_info.incomplete_files + if incomplete_files: + out.hint( + f"Found {len(incomplete_files)} incomplete download(s) totalling " + f"{_format_size(hf_cache_info.incomplete_size_on_disk)}. " + "Remove them with 'hf cache prune'." + ) + + +@cache_cli.command( + examples=[ + "hf cache rm model/gpt2", + "hf cache rm hf://models/openai-community/gpt2", + "hf cache rm ", + "hf cache rm model/gpt2 --dry-run", + "hf cache rm model/gpt2 --yes", + ], +) +def rm( + targets: Annotated[ + list[str], + Argument( + help="One or more repo IDs (e.g. model/bert-base-uncased), repo-level hf:// URIs, or revision hashes to delete.", + ), + ], + cache_dir: Annotated[ + str | None, + Option( + help="Cache directory to scan (defaults to Hugging Face cache).", + ), + ] = None, + yes: Annotated[ + bool, + Option( + "-y", + "--yes", + help="Skip confirmation prompt.", + ), + ] = False, + dry_run: Annotated[ + bool, + Option( + help="Preview deletions without removing anything.", + ), + ] = False, +) -> None: + """Remove cached repositories or revisions.""" + try: + hf_cache_info = scan_cache_dir(cache_dir) + except CacheNotFound as exc: + raise CLIError(f"Cache directory not found: {exc.cache_dir}") from exc + + resolution = _resolve_deletion_targets(hf_cache_info, targets) + + if resolution.missing: + details = "\n".join(f" - {entry}" for entry in resolution.missing) + out.warning(f"Could not find in cache:\n{details}") + + if len(resolution.revisions) == 0: + out.text("Nothing to delete.") + raise click.exceptions.Exit(code=0) + + strategy = hf_cache_info.delete_revisions(*sorted(resolution.revisions)) + counts = summarize_deletions(resolution.selected) + + summary_parts: list[str] = [] + if counts.repo_count: + summary_parts.append(f"{counts.repo_count} repo(s)") + if counts.partial_revision_count: + summary_parts.append(f"{counts.partial_revision_count} revision(s)") + if not summary_parts: + summary_parts.append(f"{counts.total_revision_count} revision(s)") + + summary_text = " and ".join(summary_parts) + out.text(f"About to delete {summary_text} totalling {strategy.expected_freed_size_str}.") + print_cache_selected_revisions(resolution.selected) + + if dry_run: + out.result( + "Dry run: no files were deleted.", + dry_run=True, + repos=counts.repo_count, + revisions=counts.total_revision_count, + size=strategy.expected_freed_size_str, + ) + return + + out.confirm("Proceed with deletion?", yes=yes) + + strategy.execute() + counts = summarize_deletions(resolution.selected) + out.result( + f"Deleted {counts.repo_count} repo(s) and {counts.total_revision_count} revision(s);" + f" freed {strategy.expected_freed_size_str}.", + repos_deleted=counts.repo_count, + revisions_deleted=counts.total_revision_count, + freed=strategy.expected_freed_size_str, + ) + + +@cache_cli.command(examples=["hf cache prune", "hf cache prune --dry-run"]) +def prune( + cache_dir: Annotated[ + str | None, + Option( + help="Cache directory to scan (defaults to Hugging Face cache).", + ), + ] = None, + yes: Annotated[ + bool, + Option( + "-y", + "--yes", + help="Skip confirmation prompt.", + ), + ] = False, + dry_run: Annotated[ + bool, + Option( + help="Preview deletions without removing anything.", + ), + ] = False, +) -> None: + """Remove detached revisions and incomplete downloads from the cache.""" + try: + hf_cache_info = scan_cache_dir(cache_dir) + except CacheNotFound as exc: + raise CLIError(f"Cache directory not found: {exc.cache_dir}") from exc + + selected: dict[CachedRepoInfo, frozenset[CachedRevisionInfo]] = {} + revisions: set[str] = set() + for repo in hf_cache_info.repos: + detached = frozenset(revision for revision in repo.revisions if len(revision.refs) == 0) + if not detached: + continue + selected[repo] = detached + revisions.update(revision.commit_hash for revision in detached) + + incomplete_files = hf_cache_info.incomplete_files + + if len(revisions) == 0 and not incomplete_files: + out.text("No unreferenced revisions or incomplete downloads found. Nothing to prune.") + return + + strategy = hf_cache_info.delete_revisions(*sorted(revisions)) + counts = summarize_deletions(selected) + total_freed = strategy.expected_freed_size + hf_cache_info.incomplete_size_on_disk + + summary = _prune_summary(counts.total_revision_count, len(incomplete_files)) + out.text(f"About to delete {summary} ({_format_size(total_freed)} total).") + print_cache_selected_revisions(selected) + + if dry_run: + out.result( + "Dry run: no files were deleted.", + dry_run=True, + revisions=counts.total_revision_count, + incomplete=len(incomplete_files), # might be overstated but it's fine + size=_format_size(total_freed), + ) + return + + out.confirm("Proceed?", yes=yes) + + strategy.execute() + for incomplete_file in incomplete_files: + try: + incomplete_file.file_path.unlink() + except FileNotFoundError: + pass # already removed (e.g. by a full-repo deletion above) + except OSError as exc: + out.warning(f"Could not delete incomplete file {incomplete_file.file_path}: {exc}") + out.result( + f"Deleted {summary}; freed {_format_size(total_freed)}.", + revisions_deleted=counts.total_revision_count, + incomplete_deleted=len(incomplete_files), + freed=_format_size(total_freed), + ) + + +@cache_cli.command( + examples=[ + "hf cache verify gpt2", + "hf cache verify gpt2 --revision refs/pr/1", + "hf cache verify my-dataset --repo-type dataset", + ], +) +def verify( + repo_id: RepoIdArg, + repo_type: RepoTypeOpt = RepoTypeOpt.model, + revision: RevisionOpt = None, + cache_dir: Annotated[ + str | None, + Option( + help="Cache directory to use when verifying files from cache (defaults to Hugging Face cache).", + ), + ] = None, + local_dir: Annotated[ + str | None, + Option( + help="If set, verify files under this directory instead of the cache.", + ), + ] = None, + fail_on_missing_files: Annotated[ + bool, + Option( + "--fail-on-missing-files", + help="Fail if some files exist on the remote but are missing locally.", + ), + ] = False, + fail_on_extra_files: Annotated[ + bool, + Option( + "--fail-on-extra-files", + help="Fail if some files exist locally but are not present on the remote revision.", + ), + ] = False, + token: TokenOpt = None, +) -> None: + """Verify checksums for a single repo revision from cache or a local directory. + + Examples: + - Verify main revision in cache: `hf cache verify gpt2` + - Verify specific revision: `hf cache verify gpt2 --revision refs/pr/1` + - Verify dataset: `hf cache verify karpathy/fineweb-edu-100b-shuffle --repo-type dataset` + - Verify local dir: `hf cache verify deepseek-ai/DeepSeek-OCR --local-dir /path/to/repo` + """ + + if local_dir is not None and cache_dir is not None: + out.error("Cannot pass both --local-dir and --cache-dir. Use one or the other.") + raise click.exceptions.Exit(code=2) + + api = get_hf_api(token=token) + + result = api.verify_repo_checksums( + repo_id=repo_id, + repo_type=repo_type.value if hasattr(repo_type, "value") else str(repo_type), + revision=revision, + local_dir=local_dir, + cache_dir=cache_dir, + token=token, + ) + + exit_code = 0 + + if result.mismatches: + details = "\n".join( + f" - {m['path']}: expected {m['expected']} ({m['algorithm']}), got {m['actual']}" + for m in result.mismatches + ) + out.text(f"❌ Checksum verification failed for the following file(s):\n{details}") + exit_code = 1 + + if result.missing_paths: + if fail_on_missing_files: + details = "\n".join(f" - {p}" for p in result.missing_paths) + out.text(f"❌ Missing files (present remotely, absent locally):\n{details}") + exit_code = 1 + else: + out.warning( + f"{len(result.missing_paths)} remote file(s) are missing locally. " + "Use --fail-on-missing-files for details." + ) + + if result.extra_paths: + if fail_on_extra_files: + details = "\n".join(f" - {p}" for p in result.extra_paths) + out.text(f"❌ Extra files (present locally, absent remotely):\n{details}") + exit_code = 1 + else: + out.warning( + f"{len(result.extra_paths)} local file(s) do not exist on the remote repo. " + "Use --fail-on-extra-files for details." + ) + + verified_location = result.verified_path + + if exit_code != 0: + out.error( + f"Verification failed for '{repo_id}' ({repo_type.value}) in {verified_location}.\n Revision: {result.revision}" + ) + raise click.exceptions.Exit(code=exit_code) + + out.result( + f"Verified {result.checked_count} file(s) for {repo_type.value} '{repo_id}'. All checksums match.", + repo_id=repo_id, + repo_type=repo_type.value, + checked=result.checked_count, + path=str(verified_location), + ) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/collections.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/collections.py new file mode 100644 index 0000000000000000000000000000000000000000..a60c5f60b2000fd3999f7155e4f884a52e890433 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/collections.py @@ -0,0 +1,293 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains commands to interact with collections on the Hugging Face Hub.""" + +import enum +from typing import Annotated, get_args + +from huggingface_hub.hf_api import CollectionItemType_T, CollectionSort_T + +from ._cli_utils import LimitOpt, TokenOpt, get_hf_api, typer_factory +from ._framework import Argument, Option +from ._output import _dataclass_to_dict, out + + +# Build enums dynamically from Literal types to avoid duplication +_COLLECTION_ITEM_TYPES = get_args(CollectionItemType_T) +CollectionItemType = enum.Enum("CollectionItemType", {t: t for t in _COLLECTION_ITEM_TYPES}, type=str) # type: ignore[misc] + +_COLLECTION_SORT_OPTIONS = get_args(CollectionSort_T) +CollectionSort = enum.Enum("CollectionSort", {s: s for s in _COLLECTION_SORT_OPTIONS}, type=str) # type: ignore[misc] + + +collections_cli = typer_factory(help="Interact with collections on the Hub.") + + +@collections_cli.command( + "list | ls", + examples=[ + "hf collections ls", + "hf collections ls --owner nvidia", + "hf collections ls --item models/teknium/OpenHermes-2.5-Mistral-7B --limit 10", + ], +) +def collections_ls( + owner: Annotated[ + str | None, + Option(help="Filter by owner username or organization."), + ] = None, + item: Annotated[ + str | None, + Option( + help='Filter collections containing a specific item (e.g., "models/gpt2", "datasets/squad", "papers/2311.12983").' + ), + ] = None, + sort: Annotated[ + CollectionSort | None, + Option(help="Sort results by last modified, trending, or upvotes."), + ] = None, + limit: LimitOpt = 10, + token: TokenOpt = None, +) -> None: + """List collections on the Hub.""" + api = get_hf_api(token=token) + sort_key = sort.value if sort else None + results = [ + _dataclass_to_dict(collection) + for collection in api.list_collections( + owner=owner, + item=item, + sort=sort_key, # type: ignore[arg-type] + limit=limit, + ) + ] + out.table(results) + + +@collections_cli.command( + "info", + examples=[ + "hf collections info username/my-collection-slug", + ], +) +def collections_info( + collection_slug: Annotated[str, Argument(help="The collection slug (e.g., 'username/collection-slug').")], + token: TokenOpt = None, +) -> None: + """Get info about a collection on the Hub.""" + api = get_hf_api(token=token) + collection = api.get_collection(collection_slug) + out.dict(collection) + + +@collections_cli.command( + "create", + examples=[ + 'hf collections create "My Models"', + 'hf collections create "My Models" --description "A collection of my favorite models" --private', + 'hf collections create "Org Collection" --namespace my-org', + ], +) +def collections_create( + title: Annotated[str, Argument(help="The title of the collection.")], + namespace: Annotated[ + str | None, + Option(help="The namespace (username or organization). Defaults to the authenticated user."), + ] = None, + description: Annotated[ + str | None, + Option(help="A description for the collection."), + ] = None, + private: Annotated[ + bool, + Option(help="Create a private collection."), + ] = False, + exists_ok: Annotated[ + bool, + Option(help="Do not raise an error if the collection already exists."), + ] = False, + token: TokenOpt = None, +) -> None: + """Create a new collection on the Hub.""" + api = get_hf_api(token=token) + collection = api.create_collection( + title=title, + namespace=namespace, + description=description, + private=private, + exists_ok=exists_ok, + ) + out.result("Collection created", slug=collection.slug, url=collection.url) + + +@collections_cli.command( + "update", + examples=[ + 'hf collections update username/my-collection --title "New Title"', + 'hf collections update username/my-collection --description "Updated description"', + "hf collections update username/my-collection --private --theme green", + ], +) +def collections_update( + collection_slug: Annotated[str, Argument(help="The collection slug (e.g., 'username/collection-slug').")], + title: Annotated[ + str | None, + Option(help="The new title for the collection."), + ] = None, + description: Annotated[ + str | None, + Option(help="The new description for the collection."), + ] = None, + position: Annotated[ + int | None, + Option(help="The new position of the collection in the owner's list."), + ] = None, + private: Annotated[ + bool | None, + Option(help="Whether the collection should be private."), + ] = None, + theme: Annotated[ + str | None, + Option(help="The theme color for the collection (e.g., 'green', 'blue')."), + ] = None, + token: TokenOpt = None, +) -> None: + """Update a collection's metadata on the Hub.""" + api = get_hf_api(token=token) + collection = api.update_collection_metadata( + collection_slug=collection_slug, + title=title, + description=description, + position=position, + private=private, + theme=theme, + ) + out.result("Collection updated", slug=collection.slug, url=collection.url) + + +@collections_cli.command( + "delete", + examples=[ + "hf collections delete username/my-collection", + "hf collections delete username/my-collection --missing-ok", + ], +) +def collections_delete( + collection_slug: Annotated[str, Argument(help="The collection slug (e.g., 'username/collection-slug').")], + missing_ok: Annotated[ + bool, + Option(help="Do not raise an error if the collection doesn't exist."), + ] = False, + token: TokenOpt = None, +) -> None: + """Delete a collection from the Hub.""" + api = get_hf_api(token=token) + api.delete_collection(collection_slug, missing_ok=missing_ok) + out.result("Collection deleted", slug=collection_slug) + + +@collections_cli.command( + "add-item", + examples=[ + "hf collections add-item username/my-collection moonshotai/kimi-k2 model", + 'hf collections add-item username/my-collection Qwen/DeepPlanning dataset --note "Useful dataset"', + "hf collections add-item username/my-collection Tongyi-MAI/Z-Image space", + ], +) +def collections_add_item( + collection_slug: Annotated[str, Argument(help="The collection slug (e.g., 'username/collection-slug').")], + item_id: Annotated[str, Argument(help="The ID of the item to add (repo_id for repos, paper ID for papers).")], + item_type: Annotated[ + CollectionItemType, + Argument(help="The type of item (model, dataset, space, paper, collection, or bucket)."), + ], + note: Annotated[ + str | None, + Option(help="A note to attach to the item (max 500 characters)."), + ] = None, + exists_ok: Annotated[ + bool, + Option(help="Do not raise an error if the item is already in the collection."), + ] = False, + token: TokenOpt = None, +) -> None: + """Add an item to a collection.""" + api = get_hf_api(token=token) + collection = api.add_collection_item( + collection_slug=collection_slug, + item_id=item_id, + item_type=item_type.value, # type: ignore[arg-type] + note=note, + exists_ok=exists_ok, + ) + out.result("Item added to collection", slug=collection_slug, url=collection.url) + + +@collections_cli.command( + "update-item", + examples=[ + 'hf collections update-item username/my-collection ITEM_OBJECT_ID --note "Updated note"', + "hf collections update-item username/my-collection ITEM_OBJECT_ID --position 0", + ], +) +def collections_update_item( + collection_slug: Annotated[str, Argument(help="The collection slug (e.g., 'username/collection-slug').")], + item_object_id: Annotated[ + str, + Argument(help="The ID of the item in the collection (from 'item_object_id' field, not the repo_id)."), + ], + note: Annotated[ + str | None, + Option(help="A new note for the item (max 500 characters)."), + ] = None, + position: Annotated[ + int | None, + Option(help="The new position of the item in the collection."), + ] = None, + token: TokenOpt = None, +) -> None: + """Update an item in a collection.""" + api = get_hf_api(token=token) + api.update_collection_item( + collection_slug=collection_slug, + item_object_id=item_object_id, + note=note, + position=position, + ) + out.result("Item updated in collection", slug=collection_slug) + + +@collections_cli.command("delete-item") +def collections_delete_item( + collection_slug: Annotated[str, Argument(help="The collection slug (e.g., 'username/collection-slug').")], + item_object_id: Annotated[ + str, + Argument( + help="The ID of the item in the collection (retrieved from `item_object_id` field returned by 'hf collections info'." + ), + ], + missing_ok: Annotated[ + bool, + Option(help="Do not raise an error if the item doesn't exist."), + ] = False, + token: TokenOpt = None, +) -> None: + """Delete an item from a collection.""" + api = get_hf_api(token=token) + api.delete_collection_item( + collection_slug=collection_slug, + item_object_id=item_object_id, + missing_ok=missing_ok, + ) + out.result("Item deleted from collection", slug=collection_slug) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/datasets.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/datasets.py new file mode 100644 index 0000000000000000000000000000000000000000..15625504da845c384f7ab77b2b553e69be76d30f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/datasets.py @@ -0,0 +1,274 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains commands to interact with datasets on the Hugging Face Hub.""" + +import enum +from typing import Annotated, get_args + +import click + +from huggingface_hub._dataset_viewer import execute_raw_sql_query +from huggingface_hub.errors import CLIError, RepositoryNotFoundError, RevisionNotFoundError +from huggingface_hub.hf_api import DatasetSort_T, ExpandDatasetProperty_T +from huggingface_hub.repocard import DatasetCard + +from ._cli_utils import ( + REPO_LIST_DEFAULT_LIMIT, + AuthorOpt, + FilterOpt, + LimitOpt, + RevisionOpt, + SearchOpt, + TokenOpt, + get_hf_api, + make_expand_properties_parser, + typer_factory, +) +from ._file_listing import list_repo_files_cmd +from ._framework import Argument, Option +from ._output import _dataclass_to_dict, out + + +_EXPAND_PROPERTIES = sorted(get_args(ExpandDatasetProperty_T)) +_SORT_OPTIONS = get_args(DatasetSort_T) +DatasetSortEnum = enum.Enum("DatasetSortEnum", {s: s for s in _SORT_OPTIONS}, type=str) # type: ignore[misc] + + +ExpandOpt = Annotated[ + str | None, + Option( + help=f"Comma-separated properties to return. When used, only the listed properties (and id) are returned. Example: '--expand=downloads,likes,tags'. Valid: {', '.join(_EXPAND_PROPERTIES)}.", + callback=make_expand_properties_parser(_EXPAND_PROPERTIES), + ), +] + + +datasets_cli = typer_factory(help="Interact with datasets on the Hub.") + + +@datasets_cli.command( + "list | ls", + examples=[ + "hf datasets ls", + "hf datasets ls --sort downloads --limit 10", + 'hf datasets ls --search "code"', + "hf datasets ls --filter benchmark:official", + "hf datasets ls HuggingFaceFW/fineweb", + "hf datasets ls HuggingFaceFW/fineweb -R", + "hf datasets ls HuggingFaceFW/fineweb --tree -h", + ], +) +def datasets_ls( + repo_id: Annotated[ + str | None, + Argument(help="Dataset ID (e.g. `username/repo-name`) to list files from. If omitted, lists datasets."), + ] = None, + search: SearchOpt = None, + author: AuthorOpt = None, + filter: FilterOpt = None, + sort: Annotated[ + DatasetSortEnum | None, + Option(help="Sort results."), + ] = None, + limit: LimitOpt = REPO_LIST_DEFAULT_LIMIT, + expand: ExpandOpt = None, + human_readable: Annotated[ + bool, + Option("--human-readable", "-h", help="Show sizes in human readable format (only for listing files)."), + ] = False, + as_tree: Annotated[ + bool, + Option("--tree", help="List files in tree format (only for listing files)."), + ] = False, + recursive: Annotated[ + bool, + Option("--recursive", "-R", help="List files recursively (only for listing files)."), + ] = False, + revision: RevisionOpt = None, + token: TokenOpt = None, +) -> None: + """List datasets on the Hub, or files in a dataset repo. + + When called with no argument, lists datasets on the Hub. + When called with a dataset ID, lists files in that dataset repo. + """ + if repo_id is not None: + if search is not None: + raise click.BadParameter("Cannot use --search when listing files.") + if author is not None: + raise click.BadParameter("Cannot use --author when listing files.") + if filter is not None: + raise click.BadParameter("Cannot use --filter when listing files.") + if sort is not None: + raise click.BadParameter("Cannot use --sort when listing files.") + if limit != REPO_LIST_DEFAULT_LIMIT: + raise click.BadParameter("Cannot use --limit when listing files.") + if expand is not None: + raise click.BadParameter("Cannot use --expand when listing files.") + return list_repo_files_cmd( + repo_id=repo_id, + repo_type="dataset", + human_readable=human_readable, + as_tree=as_tree, + recursive=recursive, + revision=revision, + token=token, + ) + + if as_tree: + raise click.BadParameter("Cannot use --tree when listing datasets.") + if recursive: + raise click.BadParameter("Cannot use --recursive when listing datasets.") + if human_readable: + raise click.BadParameter("Cannot use --human-readable when listing datasets.") + if revision is not None: + raise click.BadParameter("Cannot use --revision when listing datasets.") + + api = get_hf_api(token=token) + sort_key = sort.value if sort else None + results = [ + _dataclass_to_dict(dataset_info) + for dataset_info in api.list_datasets( + filter=filter, + author=author, + search=search, + sort=sort_key, + limit=limit, + expand=expand, # type: ignore + ) + ] + out.table(results) + + +@datasets_cli.command( + "leaderboard", + examples=[ + "hf datasets leaderboard SWE-bench/SWE-bench_Verified", + "hf datasets leaderboard SWE-bench/SWE-bench_Verified --limit 5 --format json", + "hf datasets ls --filter benchmark:official # list available leaderboards", + ], +) +def datasets_leaderboard( + dataset_id: Annotated[str, Argument(help="The benchmark dataset ID (e.g. `SWE-bench/SWE-bench_Verified`).")], + limit: LimitOpt = 20, + token: TokenOpt = None, +) -> None: + """List model scores from a dataset leaderboard. This command helps find the best models for a task or compare models by benchmark scores. Use 'hf datasets ls --filter benchmark:official' to list available leaderboards.""" + api = get_hf_api(token=token) + leaderboard = api.get_dataset_leaderboard(repo_id=dataset_id) + results = [_dataclass_to_dict(entry) for entry in leaderboard[:limit]] + out.table( + results, + headers=["rank", "model_id", "value", "source"], + id_key="model_id", + ) + out.hint("Use 'hf datasets ls --filter benchmark:official' to list available leaderboards.") + if leaderboard: + out.hint(f"Use 'hf models info {leaderboard[0].model_id}' to get details about a model.") + + +@datasets_cli.command( + "info", + examples=[ + "hf datasets info HuggingFaceFW/fineweb", + "hf datasets info my-dataset --expand downloads,likes,tags", + ], +) +def datasets_info( + dataset_id: Annotated[str, Argument(help="The dataset ID (e.g. `username/repo-name`).")], + revision: RevisionOpt = None, + expand: ExpandOpt = None, + token: TokenOpt = None, +) -> None: + """Get info about a dataset on the Hub.""" + api = get_hf_api(token=token) + try: + info = api.dataset_info(repo_id=dataset_id, revision=revision, expand=expand) # type: ignore + except RepositoryNotFoundError as e: + raise CLIError(f"Dataset '{dataset_id}' not found.") from e + except RevisionNotFoundError as e: + raise CLIError(f"Revision '{revision}' not found on '{dataset_id}'.") from e + out.dict(info) + + +@datasets_cli.command( + "parquet", + examples=[ + "hf datasets parquet cfahlgren1/hub-stats", + "hf datasets parquet cfahlgren1/hub-stats --subset models", + "hf datasets parquet cfahlgren1/hub-stats --split train", + "hf datasets parquet cfahlgren1/hub-stats --format json", + ], +) +def datasets_parquet( + dataset_id: Annotated[str, Argument(help="The dataset ID (e.g. `username/repo-name`).")], + subset: Annotated[str | None, Option("--subset", help="Filter parquet entries by subset/config.")] = None, + split: Annotated[str | None, Option(help="Filter parquet entries by split.")] = None, + token: TokenOpt = None, +) -> None: + """List parquet file URLs available for a dataset.""" + api = get_hf_api(token=token) + entries = api.list_dataset_parquet_files(repo_id=dataset_id, config=subset) + filtered = [entry for entry in entries if split is None or entry.split == split] + results = [ + {"subset": entry.config, "split": entry.split, "url": entry.url, "size": entry.size} for entry in filtered + ] + out.table(results, headers=["subset", "split", "url", "size"], id_key="url") + + +@datasets_cli.command( + "sql", + examples=[ + "hf datasets sql \"SELECT COUNT(*) AS rows FROM read_parquet('https://huggingface.co/api/datasets/cfahlgren1/hub-stats/parquet/models/train/0.parquet')\"", + "hf datasets sql \"SELECT * FROM read_parquet('https://huggingface.co/api/datasets/cfahlgren1/hub-stats/parquet/models/train/0.parquet') LIMIT 5\" --format json", + ], +) +def datasets_sql( + sql: Annotated[str, Argument(help="Raw SQL query to execute.")], + token: TokenOpt = None, +) -> None: + """Execute a raw SQL query with DuckDB against dataset parquet URLs.""" + try: + result = execute_raw_sql_query(sql_query=sql, token=token) + except ImportError as e: + raise CLIError(str(e)) from e + out.table(result) + + +@datasets_cli.command( + "card", + examples=[ + "hf datasets card HuggingFaceFW/fineweb", + "hf datasets card HuggingFaceFW/fineweb --metadata", + "hf datasets card HuggingFaceFW/fineweb --metadata --format json", + "hf datasets card HuggingFaceFW/fineweb --text", + ], +) +def datasets_card( + dataset_id: Annotated[str, Argument(help="The dataset ID (e.g. `username/repo-name`).")], + metadata: Annotated[bool, Option("--metadata", help="Output only the metadata from the card.")] = False, + text: Annotated[bool, Option("--text", help="Output only the text body (no metadata).")] = False, + token: TokenOpt = None, +) -> None: + """Get the dataset card (README) for a dataset on the Hub.""" + if metadata and text: + raise CLIError("--metadata and --text are mutually exclusive.") + card = DatasetCard.load(dataset_id, token=token) + if metadata: + out.dict(card.data.to_dict()) + elif text: + out.text(card.text) + else: + out.text(card.content) + out.hint(f"Use `hf datasets card {dataset_id} --metadata` to extract only the card metadata.") diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/deprecated_cli.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/deprecated_cli.py new file mode 100644 index 0000000000000000000000000000000000000000..4fbdd8adaba77accf24fbe0d459b4714d503b781 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/deprecated_cli.py @@ -0,0 +1,35 @@ +"""Deprecated `huggingface-cli` entry point. Warns and exits.""" + +import shutil +import sys + +from ._output import out + + +def main() -> None: + out.warning("`huggingface-cli` is deprecated and no longer works. Use `hf` instead.\n") + + if shutil.which("hf"): + from huggingface_hub.cli._cli_utils import check_cli_update + + check_cli_update("huggingface_hub") + out.hint("`hf` is already installed! Use it directly.\n") + else: + out.hint( + "Install `hf`:\n" + " Standalone (recommended): curl -LsSf https://hf.co/cli/install.sh | bash\n" + " Using Homebrew: brew install hf\n" + " Using pip: pip install huggingface_hub\n", + ) + + out.hint( + "Examples:\n" + " hf auth login\n" + " hf download unsloth/gemma-4-31B-it-GGUF\n" + " hf upload my-cool-model . .\n" + ' hf models ls --search "gemma"\n' + " hf repos ls --format json\n" + " hf jobs run python:3.12 python -c 'print(\"Hello!\")'\n" + " hf --help\n", + ) + sys.exit(1) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/discussions.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/discussions.py new file mode 100644 index 0000000000000000000000000000000000000000..3fd3b4217bfa0d143ba7906d12791b013369c912 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/discussions.py @@ -0,0 +1,497 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains commands to interact with discussions and pull requests on the Hugging Face Hub.""" + +import enum +import sys +from pathlib import Path +from typing import Annotated + +import click + +from huggingface_hub import constants + +from ._cli_utils import ( + AuthorOpt, + LimitOpt, + RepoIdArg, + RepoType, + RepoTypeOpt, + TokenOpt, + get_hf_api, + typer_factory, +) +from ._framework import Argument, Option +from ._output import _dataclass_to_dict, out + + +class DiscussionStatus(str, enum.Enum): + open = "open" + closed = "closed" + merged = "merged" + draft = "draft" + all = "all" + + +class DiscussionKind(str, enum.Enum): + all = "all" + discussion = "discussion" + pull_request = "pull_request" + + +# "merged" and "draft" are valid Discussion statuses but the Hub API filter +# (DiscussionStatusFilter) only accepts "all", "open", "closed". When the user +# asks for merged/draft we fetch with api_status=None (i.e. all) and filter +# client-side. +_CLIENT_SIDE_STATUSES = {"merged", "draft"} + + +DiscussionNumArg = Annotated[ + int, + Argument( + help="The discussion or pull request number.", + min=1, + ), +] + + +def _read_body(body: str | None, body_file: Path | None) -> str | None: + """Resolve body text from --body or --body-file (supports '-' for stdin).""" + if body is not None and body_file is not None: + raise click.BadParameter("Cannot use both --body and --body-file.") + if body_file is not None: + if str(body_file) == "-": + return sys.stdin.read() + return body_file.read_text(encoding="utf-8") + return body + + +discussions_cli = typer_factory(help="Manage discussions and pull requests on the Hub.") + + +@discussions_cli.command( + "list | ls", + examples=[ + "hf discussions list username/my-model", + "hf discussions list username/my-model --kind pull_request --status merged", + "hf discussions list username/my-dataset --type dataset --status closed", + "hf discussions list username/my-model --author alice --format json", + ], +) +def discussion_list( + repo_id: RepoIdArg, + status: Annotated[ + DiscussionStatus, + Option( + "-s", + "--status", + help="Filter by status (open, closed, merged, draft, all).", + ), + ] = DiscussionStatus.open, + kind: Annotated[ + DiscussionKind, + Option( + "-k", + "--kind", + help="Filter by kind (discussion, pull_request, all).", + ), + ] = DiscussionKind.all, + author: AuthorOpt = None, + limit: LimitOpt = 30, + repo_type: RepoTypeOpt = RepoType.model, + token: TokenOpt = None, +) -> None: + """List discussions and pull requests on a repo.""" + api = get_hf_api(token=token) + + api_status: constants.DiscussionStatusFilter | None + if status == DiscussionStatus.open: + api_status = "open" + elif status == DiscussionStatus.closed: + api_status = "closed" + else: + api_status = None + + api_discussion_type: constants.DiscussionTypeFilter | None + if kind == DiscussionKind.all: + api_discussion_type = None + else: + api_discussion_type = kind.value # type: ignore[assignment] + + discussions = [] + for d in api.get_repo_discussions( + repo_id=repo_id, + author=author, + discussion_type=api_discussion_type, + discussion_status=api_status, + repo_type=repo_type.value, + ): + if status.value in _CLIENT_SIDE_STATUSES and d.status != status.value: + continue + discussions.append(d) + if len(discussions) >= limit: + break + + items = [_dataclass_to_dict(d) for d in discussions] + out.table( + items, + headers=["num", "title", "is_pull_request", "status", "author", "created_at"], + id_key="num", + ) + + +@discussions_cli.command( + "info", + examples=[ + "hf discussions info username/my-model 5", + "hf discussions info username/my-model 5 --format json", + ], +) +def discussion_info( + repo_id: RepoIdArg, + num: DiscussionNumArg, + repo_type: RepoTypeOpt = RepoType.model, + token: TokenOpt = None, +) -> None: + """Get info about a discussion or pull request.""" + api = get_hf_api(token=token) + details = api.get_discussion_details( + repo_id=repo_id, + discussion_num=num, + repo_type=repo_type.value, + ) + out.dict(details) + + +@discussions_cli.command( + "create", + examples=[ + 'hf discussions create username/my-model --title "Bug report"', + 'hf discussions create username/my-model --title "Feature request" --body "Please add X"', + 'hf discussions create username/my-model --title "Fix typo" --pull-request', + 'hf discussions create username/my-dataset --type dataset --title "Data quality issue"', + ], +) +def discussion_create( + repo_id: RepoIdArg, + title: Annotated[ + str, + Option( + "--title", + help="The title of the discussion or pull request.", + ), + ], + body: Annotated[ + str | None, + Option( + "--body", + help="The description (supports Markdown).", + ), + ] = None, + body_file: Annotated[ + Path | None, + Option( + "--body-file", + help="Read the description from a file. Use '-' for stdin.", + ), + ] = None, + pull_request: Annotated[ + bool, + Option( + "--pull-request", + "--pr", + help="Create a pull request instead of a discussion.", + ), + ] = False, + repo_type: RepoTypeOpt = RepoType.model, + token: TokenOpt = None, +) -> None: + """Create a new discussion or pull request on a repo.""" + description = _read_body(body, body_file) + api = get_hf_api(token=token) + discussion = api.create_discussion( + repo_id=repo_id, + title=title, + description=description, + repo_type=repo_type.value, + pull_request=pull_request, + ) + kind = "pull request" if pull_request else "discussion" + ref = f"refs/pr/{discussion.num}" if pull_request else None + out.result(f"Created {kind} #{discussion.num} on {repo_id}", num=discussion.num, url=discussion.url, ref=ref) + + +@discussions_cli.command( + "comment", + examples=[ + 'hf discussions comment username/my-model 5 --body "Thanks for reporting!"', + 'hf discussions comment username/my-model 5 --body "LGTM!"', + ], +) +def discussion_comment( + repo_id: RepoIdArg, + num: DiscussionNumArg, + body: Annotated[ + str | None, + Option( + "--body", + help="The comment text (supports Markdown).", + ), + ] = None, + body_file: Annotated[ + Path | None, + Option( + "--body-file", + help="Read the comment from a file. Use '-' for stdin.", + ), + ] = None, + repo_type: RepoTypeOpt = RepoType.model, + token: TokenOpt = None, +) -> None: + """Comment on a discussion or pull request.""" + comment = _read_body(body, body_file) + if comment is None: + raise click.BadParameter("Either --body or --body-file is required.") + api = get_hf_api(token=token) + api.comment_discussion( + repo_id=repo_id, + discussion_num=num, + comment=comment, + repo_type=repo_type.value, + ) + out.result(f"Commented on #{num} in {repo_id}", num=num, repo=repo_id) + + +@discussions_cli.command( + "edit", + examples=[ + 'hf discussions edit username/my-model 5 abc123 --body "Updated comment."', + "hf discussions edit username/my-model 5 abc123 --body-file fixed.md", + ], +) +def discussion_edit( + repo_id: RepoIdArg, + num: DiscussionNumArg, + comment_id: Annotated[ + str, + Argument( + help="The ID of the comment to edit (see 'hf discussions info ... --format json').", + ), + ], + body: Annotated[ + str | None, + Option( + "--body", + help="The new comment text (supports Markdown).", + ), + ] = None, + body_file: Annotated[ + Path | None, + Option( + "--body-file", + help="Read the new comment from a file. Use '-' for stdin.", + ), + ] = None, + repo_type: RepoTypeOpt = RepoType.model, + token: TokenOpt = None, +) -> None: + """Edit an existing comment on a discussion or pull request.""" + new_content = _read_body(body, body_file) + if new_content is None: + raise click.BadParameter("Either --body or --body-file is required.") + api = get_hf_api(token=token) + api.edit_discussion_comment( + repo_id=repo_id, + discussion_num=num, + comment_id=comment_id, + new_content=new_content, + repo_type=repo_type.value, + ) + out.result(f"Edited comment {comment_id} on #{num} in {repo_id}", num=num, repo=repo_id, comment_id=comment_id) + + +@discussions_cli.command( + "close", + examples=[ + "hf discussions close username/my-model 5", + 'hf discussions close username/my-model 5 --comment "Closing as resolved."', + ], +) +def discussion_close( + repo_id: RepoIdArg, + num: DiscussionNumArg, + comment: Annotated[ + str | None, + Option( + "--comment", + help="An optional comment to post when closing.", + ), + ] = None, + yes: Annotated[ + bool, + Option( + "--yes", + "-y", + help="Skip confirmation prompt.", + ), + ] = False, + repo_type: RepoTypeOpt = RepoType.model, + token: TokenOpt = None, +) -> None: + """Close a discussion or pull request.""" + out.confirm(f"Close #{num} on '{repo_id}'?", yes=yes) + api = get_hf_api(token=token) + api.change_discussion_status( + repo_id=repo_id, + discussion_num=num, + new_status="closed", + comment=comment, + repo_type=repo_type.value, + ) + out.result(f"Closed #{num} in {repo_id}", num=num, repo=repo_id) + + +@discussions_cli.command( + "reopen", + examples=[ + "hf discussions reopen username/my-model 5", + 'hf discussions reopen username/my-model 5 --comment "Reopening for further investigation."', + ], +) +def discussion_reopen( + repo_id: RepoIdArg, + num: DiscussionNumArg, + comment: Annotated[ + str | None, + Option( + "--comment", + help="An optional comment to post when reopening.", + ), + ] = None, + yes: Annotated[ + bool, + Option( + "--yes", + "-y", + help="Skip confirmation prompt.", + ), + ] = False, + repo_type: RepoTypeOpt = RepoType.model, + token: TokenOpt = None, +) -> None: + """Reopen a closed discussion or pull request.""" + out.confirm(f"Reopen #{num} on '{repo_id}'?", yes=yes) + api = get_hf_api(token=token) + api.change_discussion_status( + repo_id=repo_id, + discussion_num=num, + new_status="open", + comment=comment, + repo_type=repo_type.value, + ) + out.result(f"Reopened #{num} in {repo_id}", num=num, repo=repo_id) + + +@discussions_cli.command( + "rename", + examples=[ + 'hf discussions rename username/my-model 5 "Updated title"', + ], +) +def discussion_rename( + repo_id: RepoIdArg, + num: DiscussionNumArg, + new_title: Annotated[ + str, + Argument( + help="The new title.", + ), + ], + repo_type: RepoTypeOpt = RepoType.model, + token: TokenOpt = None, +) -> None: + """Rename a discussion or pull request.""" + api = get_hf_api(token=token) + api.rename_discussion( + repo_id=repo_id, + discussion_num=num, + new_title=new_title, + repo_type=repo_type.value, + ) + out.result(f"Renamed #{num} in {repo_id}", num=num, repo=repo_id, title=new_title) + + +@discussions_cli.command( + "merge", + examples=[ + "hf discussions merge username/my-model 5", + 'hf discussions merge username/my-model 5 --comment "Merging, thanks!"', + ], +) +def discussion_merge( + repo_id: RepoIdArg, + num: DiscussionNumArg, + comment: Annotated[ + str | None, + Option( + "--comment", + help="An optional comment to post when merging.", + ), + ] = None, + yes: Annotated[ + bool, + Option( + "--yes", + "-y", + help="Skip confirmation prompt.", + ), + ] = False, + repo_type: RepoTypeOpt = RepoType.model, + token: TokenOpt = None, +) -> None: + """Merge a pull request.""" + out.confirm(f"Merge #{num} on '{repo_id}'?", yes=yes) + api = get_hf_api(token=token) + api.merge_pull_request( + repo_id=repo_id, + discussion_num=num, + comment=comment, + repo_type=repo_type.value, + ) + out.result(f"Merged #{num} in {repo_id}", num=num, repo=repo_id) + + +@discussions_cli.command( + "diff", + examples=[ + "hf discussions diff username/my-model 5", + ], +) +def discussion_diff( + repo_id: RepoIdArg, + num: DiscussionNumArg, + repo_type: RepoTypeOpt = RepoType.model, + token: TokenOpt = None, +) -> None: + """Show the diff of a pull request.""" + api = get_hf_api(token=token) + details = api.get_discussion_details( + repo_id=repo_id, + discussion_num=num, + repo_type=repo_type.value, + ) + if details.diff: + out.text(details.diff) + else: + out.text("No diff available.") diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/download.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/download.py new file mode 100644 index 0000000000000000000000000000000000000000..3be639228e564697deb45bf6882daab3998e4899 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/download.py @@ -0,0 +1,225 @@ +# Copyright 202-present, the HuggingFace Inc. team. +# +# 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. +"""Contains command to download files from the Hub with the CLI.""" + +import warnings +from typing import Annotated + +from huggingface_hub import constants +from huggingface_hub._snapshot_download import snapshot_download +from huggingface_hub.errors import CLIError +from huggingface_hub.file_download import DryRunFileInfo, hf_hub_download +from huggingface_hub.utils import _format_size, parse_hf_uri + +from ._cli_utils import RepoIdArg, RepoType, RepoTypeOptionalOpt, RevisionOpt, TokenOpt +from ._framework import Argument, Option +from ._output import out + + +DOWNLOAD_EXAMPLES = [ + "hf download meta-llama/Llama-3.2-1B-Instruct", + "hf download meta-llama/Llama-3.2-1B-Instruct config.json tokenizer.json", + 'hf download meta-llama/Llama-3.2-1B-Instruct --include "*.safetensors" --exclude "*.bin"', + "hf download meta-llama/Llama-3.2-1B-Instruct --local-dir ./models/llama", + "hf download HuggingFaceM4/FineVision art/ --repo-type dataset", + "hf download hf://datasets/HuggingFaceH4/ultrachat_200k", +] + + +def download( + repo_id: RepoIdArg, + filenames: Annotated[ + list[str] | None, + Argument( + help="Files to download (e.g. `config.json`, `data/metadata.jsonl`).", + ), + ] = None, + repo_type: RepoTypeOptionalOpt = None, + revision: RevisionOpt = None, + include: Annotated[ + list[str] | None, + Option( + help="Glob patterns to include from files to download. eg: *.json", + ), + ] = None, + exclude: Annotated[ + list[str] | None, + Option( + help="Glob patterns to exclude from files to download.", + ), + ] = None, + cache_dir: Annotated[ + str | None, + Option( + help="Directory where to save files.", + ), + ] = None, + local_dir: Annotated[ + str | None, + Option( + help="If set, the downloaded file will be placed under this directory. Check out https://huggingface.co/docs/huggingface_hub/guides/download#download-files-to-a-local-folder for more details.", + ), + ] = None, + force_download: Annotated[ + bool, + Option( + help="If True, the files will be downloaded even if they are already cached.", + ), + ] = False, + dry_run: Annotated[ + bool, + Option( + help="If True, perform a dry run without actually downloading the file.", + ), + ] = False, + token: TokenOpt = None, + max_workers: Annotated[ + int, + Option( + help="Maximum number of workers to use for downloading files. Default is 8.", + ), + ] = 8, +) -> None: + """Download files from the Hub.""" + if local_dir is not None and cache_dir is not None: + raise CLIError( + "Cannot use both `--local-dir` and `--cache-dir` at the same time. " + "Use `--cache-dir` (or set the HF_HOME environment variable) for shared caching, " + "or `--local-dir` for a one-off download to a specific directory." + ) + + # `repo_id` may be a plain repo id or an `hf://` URI (e.g. `hf://datasets/my-org/my-dataset@v1.0/data/`). + # When a URI is provided, it is authoritative for the repo type, revision and (optionally) file path, + # so explicit `--repo-type` / `--revision` options are forbidden alongside it. + # We branch on the `hf://` prefix (the user's *intent*) rather than on whether the string parses as a + # valid URI: a malformed URI then surfaces a precise `HfUriError` (formatted globally in `cli/_errors.py`) + # instead of silently falling through to the plain-repo-id path and failing later with an opaque error. + if repo_id.startswith(constants.HF_PROTOCOL): + if repo_type is not None: + raise CLIError(f"'--repo-type' cannot be used with an 'hf://' URI ('{repo_id}').") + if revision is not None: + raise CLIError(f"'--revision' cannot be used with an 'hf://' URI ('{repo_id}').") + uri = parse_hf_uri(repo_id) + if uri.is_bucket: + raise CLIError("Buckets are not supported by `hf download`. Use `hf sync` instead.") + # The URI parser strips trailing slashes, but `hf download` uses a trailing '/' to denote a subfolder + # download (e.g. `data/` -> `data/**`). Re-append it when the URI explicitly ended with '/' so a folder + # URI keeps routing through the subfolder code path below. + path_in_repo = uri.path_in_repo + if path_in_repo and repo_id.endswith("/"): + path_in_repo += "/" + repo_id, repo_type_str, revision = uri.id, uri.type, uri.revision + if path_in_repo: + if filenames: + raise CLIError( + f"Cannot combine a file path in the hf:// URI ('{path_in_repo}') with positional filenames {filenames}." + ) + filenames = [path_in_repo] + else: + repo_type_str = (repo_type or RepoType.model).value + + def run_download() -> str | DryRunFileInfo | list[DryRunFileInfo]: + filenames_list = filenames if filenames is not None else [] + + # Separate subfolder patterns (ending with '/') from regular filenames + # Subfolders like "art/" are converted to include patterns like "art/**" + subfolders = [f for f in filenames_list if f.endswith("/")] + subfolder_patterns = [f"{f.rstrip('/')}/**" for f in subfolders] + regular_filenames = [f for f in filenames_list if not f.endswith("/")] + + # Error if subfolder patterns are combined with --include/--exclude + # Guide user to use --include instead of subfolder argument + if len(subfolder_patterns) > 0: + if include is not None and len(include) > 0: + raise CLIError( + f"Cannot combine subfolder argument ('{subfolders[0]}') with `--include`. " + f'Please use `--include "{subfolders[0]}*"` instead.' + ) + if exclude is not None and len(exclude) > 0: + raise CLIError( + f"Cannot combine subfolder argument ('{subfolders[0]}') with `--exclude`. " + f'Please use `--include "{subfolders[0]}*"` with `--exclude` instead.' + ) + + # Warn user if patterns are ignored (only if regular filenames are provided) + if len(regular_filenames) > 0: + if include is not None and len(include) > 0: + warnings.warn("Ignoring `--include` since filenames have been explicitly set.") + if exclude is not None and len(exclude) > 0: + warnings.warn("Ignoring `--exclude` since filenames have been explicitly set.") + + # Single file to download (not a subfolder): use `hf_hub_download` + if len(regular_filenames) == 1 and len(subfolder_patterns) == 0: + return hf_hub_download( + repo_id=repo_id, + repo_type=repo_type_str, + revision=revision, + filename=regular_filenames[0], + cache_dir=cache_dir, + force_download=force_download, + token=token, + local_dir=local_dir, + library_name="huggingface-cli", + dry_run=dry_run, + ) + + # Otherwise: use `snapshot_download` to ensure all files comes from same revision + if len(regular_filenames) == 0 and len(subfolder_patterns) == 0: + # No filenames provided: use include/exclude patterns + allow_patterns = include + ignore_patterns = exclude + else: + # Combine regular filenames and subfolder patterns as allow_patterns + allow_patterns = regular_filenames + subfolder_patterns + ignore_patterns = None + + return snapshot_download( + repo_id=repo_id, + repo_type=repo_type_str, + revision=revision, + allow_patterns=allow_patterns, + ignore_patterns=ignore_patterns, + force_download=force_download, + cache_dir=cache_dir, + token=token, + local_dir=local_dir, + library_name="huggingface-cli", + max_workers=max_workers, + dry_run=dry_run, + ) + + def _print_result(result: str | DryRunFileInfo | list[DryRunFileInfo]) -> None: + if isinstance(result, str): + out.result("Downloaded", path=result) + return + + # Print dry run info + if isinstance(result, DryRunFileInfo): + result = [result] + will_download = [r for r in result if r.will_download] + out.text( + f"[dry-run] Will download {len(will_download)} files" + f" (out of {len(result)})" + f" totalling {_format_size(sum(r.file_size for r in will_download))}." + ) + items = [ + { + "file": info.filename, + "size": _format_size(info.file_size) if info.will_download else "-", + } + for info in sorted(result, key=lambda x: x.filename) + ] + out.table(items) + + _print_result(run_download()) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/extensions.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/extensions.py new file mode 100644 index 0000000000000000000000000000000000000000..c8b8f51936194c6bbd3e1fbef8be4b31400061ab --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/extensions.py @@ -0,0 +1,697 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains helper utilities for hf CLI extensions.""" + +import errno +import json +import os +import re +import shutil +import subprocess +import venv +from dataclasses import asdict, dataclass +from datetime import datetime, timezone +from enum import Enum +from pathlib import Path +from typing import Annotated, Literal + +import click + +from huggingface_hub.errors import CLIError, CLIExtensionInstallError, ConfirmationError +from huggingface_hub.utils import get_session, logging + +from ._cli_utils import typer_factory +from ._framework import Argument, Option +from ._output import out + + +DEFAULT_EXTENSION_OWNER = "huggingface" +EXTENSIONS_ROOT = Path("~/.local/share/hf/extensions") +MANIFEST_FILENAME = "manifest.json" +EXTENSIONS_HELP = ( + "Manage hf CLI extensions.\n\n" + "Security Warning: extensions are third-party executables or Python packages. " + "Install only from sources you trust." +) +extensions_cli = typer_factory(help=EXTENSIONS_HELP) +_EXTENSIONS_GITHUB_TOPIC = "hf-extension" +_EXTENSIONS_DOWNLOAD_TIMEOUT = 10 +_EXTENSIONS_PIP_INSTALL_TIMEOUT = 300 + +logger = logging.get_logger(__name__) + + +class _ExtensionUpdateStatus(str, Enum): + UPDATED = "updated" + UP_TO_DATE = "up_to_date" + SKIPPED = "skipped" + + +@dataclass +class ExtensionManifest: + owner: str + repo: str + repo_id: str + short_name: str + executable_path: str + type: Literal["binary", "python"] + installed_at: datetime + description: str | None = None + commit_sha: str | None = None + + @classmethod + def load(cls, path: Path) -> "ExtensionManifest": + manifest_path = path / MANIFEST_FILENAME + if not manifest_path.is_file(): + raise CLIError(f"Manifest file not found at {manifest_path}. Your extension may be corrupted.") + data = json.loads(manifest_path.read_text()) + # Ignore keys not in the dataclass (e.g. fields dropped since the manifest was written). + data = {key: value for key, value in data.items() if key in cls.__dataclass_fields__} + data["installed_at"] = datetime.fromisoformat(data["installed_at"]) + return ExtensionManifest(**data) + + def save(self, path: Path) -> None: + manifest_path = path / MANIFEST_FILENAME + manifest_path.parent.mkdir(parents=True, exist_ok=True) + data = asdict(self) + data["installed_at"] = self.installed_at.isoformat() + manifest_path.write_text(json.dumps(data, indent=2, sort_keys=True)) + + +@extensions_cli.command( + "install", + examples=[ + "hf extensions install hf-claude", + "hf extensions install hanouticelina/hf-claude", + "hf extensions install alvarobartt/hf-mem", + ], +) +def extension_install( + ctx: click.Context, + repo_id: Annotated[ + str, + Argument(help="GitHub extension repository in `[OWNER/]hf-` format."), + ], + force: Annotated[bool, Option("--force", help="Overwrite if already installed.")] = False, +) -> None: + """Install an extension from a public GitHub repository. + + Security warning: this installs a third-party executable or Python package. + Install only from sources you trust. + """ + owner, repo_name, short_name = _normalize_repo_id(repo_id) + root_ctx = ctx.find_root() + reserved_commands = set(getattr(root_ctx.command, "commands", {}).keys()) + if short_name in reserved_commands: + raise CLIError( + f"Cannot install extension '{short_name}' because it conflicts with an existing `hf {short_name}` command." + ) + + extension_dir = _get_extension_dir(short_name) + if extension_dir.exists() and not force: + raise CLIError(f"Extension '{short_name}' is already installed. Use --force to overwrite.") + + branch, description = _fetch_github_repo_info(owner=owner, repo_name=repo_name) + if extension_dir.exists(): + # --force reinstall: only remove the previous install once the repo metadata is resolved. + shutil.rmtree(extension_dir) + manifest = _install_extension( + owner=owner, repo_name=repo_name, short_name=short_name, branch=branch, description=description + ) + ext_type = manifest.type.capitalize() + out.result( + f"{ext_type} extension installed", + source=f"{owner}/{repo_name}", + command=f"hf {short_name}", + ) + out.hint(f"Run it with: hf {short_name}") + + +@extensions_cli.command( + "update", + examples=[ + "hf extensions update", + "hf extensions update hf-claude", + "hf extensions update alvarobartt/hf-mem", + ], +) +def extension_update( + name: Annotated[ + str | None, + Argument( + help=( + "Extension to update (with or without `hf-` prefix, optionally as `OWNER/hf-`). " + "If omitted, all installed extensions are checked and the outdated ones are updated." + ), + ), + ] = None, +) -> None: + """Update installed extension(s) to their latest version.""" + if name is not None: + manifest = _load_installed_extension_for_update(name) + update_status = _update_installed_extension(manifest) + match update_status: + case _ExtensionUpdateStatus.UPDATED: + out.result("Extension updated", name=manifest.short_name, source=manifest.repo_id) + case _ExtensionUpdateStatus.UP_TO_DATE: + out.result(f"Extension '{manifest.short_name}' is already up to date", name=manifest.short_name) + case _ExtensionUpdateStatus.SKIPPED: + pass # warning already emitted by _update_installed_extension + return + + manifests = _list_installed_extensions() + if not manifests: + out.warning("No extensions installed.") + out.hint("Install one with: hf extensions install ") + return + + updated = [] + up_to_date = [] + for manifest in manifests: + out.log(f"Checking '{manifest.short_name}' ({manifest.repo_id})...") + try: + update_status = _update_installed_extension(manifest) + except Exception as error: + # Keep updating the other extensions even if one fails. + out.warning(f"Could not update '{manifest.short_name}' ({manifest.repo_id}): {error}. Skipping.") + continue + match update_status: + case _ExtensionUpdateStatus.UPDATED: + updated.append(manifest.short_name) + case _ExtensionUpdateStatus.UP_TO_DATE: + up_to_date.append(manifest.short_name) + case _ExtensionUpdateStatus.SKIPPED: + pass # warning already emitted by _update_installed_extension + out.result( + "Extensions update complete", + updated=", ".join(updated) if updated else None, + up_to_date=", ".join(up_to_date) if up_to_date else None, + ) + + +@extensions_cli.command( + "exec", + context_settings={"allow_extra_args": True, "allow_interspersed_args": False, "ignore_unknown_options": True}, + examples=[ + "hf extensions exec claude -- --help", + "hf extensions exec claude --model zai-org/GLM-5", + ], +) +def extension_exec( + ctx: click.Context, + name: Annotated[ + str, + Argument(help="Extension name (with or without `hf-` prefix)."), + ], +) -> None: + """Execute an installed extension.""" + short_name = _normalize_extension_name(name) + executable_path = _resolve_installed_executable_path(short_name) + + if not executable_path.is_file(): + raise CLIError(f"Extension '{short_name}' is not installed.") + + exit_code = _execute_extension_binary(executable_path=executable_path, args=list(ctx.args)) + raise click.exceptions.Exit(code=exit_code) + + +@extensions_cli.command("list | ls", examples=["hf extensions list"]) +def extension_list() -> None: + """List installed extension commands.""" + rows = [ + { + "command": f"hf {manifest.short_name}", + "source": str(manifest.repo_id), + "type": str(manifest.type), + "installed": manifest.installed_at.strftime("%Y-%m-%d"), + "description": manifest.description, + } + for manifest in _list_installed_extensions() + ] + out.table(rows, id_key="command") + + +@extensions_cli.command("search", examples=["hf extensions search"]) +def extension_search() -> None: + """Search extensions available on GitHub (tagged with 'hf-extension' topic).""" + response = _github_get( + "https://api.github.com/search/repositories", + params={"q": f"topic:{_EXTENSIONS_GITHUB_TOPIC}", "sort": "stars", "order": "desc", "per_page": 100}, + ) + data = response.json() + + installed = {m.short_name for m in _list_installed_extensions()} + + rows = [] + for repo in data.get("items", []): + short_name = repo["name"].removeprefix("hf-") + rows.append( + { + "name": short_name, + "repo": repo["full_name"], + "stars": repo.get("stargazers_count", 0), + "description": repo.get("description") or "", + "installed": "yes" if short_name in installed else "", + } + ) + + out.table(rows, id_key="repo") + + +@extensions_cli.command("remove | rm", examples=["hf extensions remove claude"]) +def extension_remove( + name: Annotated[ + str, + Argument(help="Extension name to remove (with or without `hf-` prefix)."), + ], +) -> None: + """Remove an installed extension.""" + short_name = _normalize_extension_name(name) + extension_dir = _get_extension_dir(short_name) + + if not extension_dir.is_dir(): + raise CLIError(f"Extension '{short_name}' is not installed.") + + shutil.rmtree(extension_dir) + out.result("Extension removed", name=short_name) + + +### HELPER FUNCTIONS + + +def _list_installed_extensions() -> list[ExtensionManifest]: + """Return manifests for all validly-installed extensions, sorted by directory name.""" + root_dir = EXTENSIONS_ROOT.expanduser() + if not root_dir.is_dir(): + return [] + manifests = [] + for extension_dir in sorted(root_dir.iterdir()): + if not extension_dir.is_dir() or not extension_dir.name.startswith("hf-"): + continue + try: + manifests.append(ExtensionManifest.load(extension_dir)) + except Exception as e: + logger.debug(f"Failed to load manifest for extension '{extension_dir.name}': {e}") + continue + return manifests + + +def list_installed_extensions_for_help() -> list[tuple[str, str]]: + entries = [] + for manifest in _list_installed_extensions(): + tag = f"[extension {manifest.repo_id}]" + help_text = f"{manifest.description} {tag}" if manifest.description is not None else tag + entries.append((manifest.short_name, help_text)) + return entries + + +def dispatch_unknown_top_level_extension(args: list[str], known_commands: set[str]) -> int | None: + if not args: + return None + + command_name = args[0] + if command_name.startswith("-"): + return None + all_known = {a.strip() for cmd in known_commands for a in cmd.split("|")} + if command_name in all_known: + return None + + try: + short_name = _validate_extension_short_name(command_name.removeprefix("hf-"), original_input=command_name) + except CLIError: + return None + + executable_path: Path | None + try: + executable_path = _resolve_installed_executable_path(short_name) + except Exception: + executable_path = _auto_install_official_extension(short_name) + + if executable_path is None or not executable_path.is_file(): + return None + + return _execute_extension_binary(executable_path=executable_path, args=list(args[1:])) + + +def _auto_install_official_extension(short_name: str) -> Path | None: + """Try to auto-install huggingface/hf-. Returns executable path or None.""" + owner, repo_name = DEFAULT_EXTENSION_OWNER, f"hf-{short_name}" + if _get_extension_dir(short_name).exists(): + return None + + try: + branch, description = _fetch_github_repo_info(owner=owner, repo_name=repo_name) + except Exception: + return None + + try: + out.confirm(f"'{short_name}' is an official Hugging Face extension ({owner}/{repo_name}). Install it?") + except ConfirmationError: + return None + try: + manifest = _install_extension( + owner=owner, repo_name=repo_name, short_name=short_name, branch=branch, description=description + ) + return Path(manifest.executable_path).expanduser() + except Exception: + return None + + +def _load_installed_extension_for_update(name: str) -> ExtensionManifest: + short_name = _normalize_extension_name(name) + extension_dir = _get_extension_dir(short_name) + if not extension_dir.is_dir(): + owner, _, _ = name.strip().rpartition("/") + install_target = f"{owner}/hf-{short_name}" if owner else f"hf-{short_name}" + raise CLIError( + f"Extension '{short_name}' is not installed. Install it first with: hf extensions install {install_target}" + ) + return ExtensionManifest.load(extension_dir) + + +def _update_installed_extension(manifest: ExtensionManifest) -> _ExtensionUpdateStatus: + owner, repo_name, short_name = manifest.owner, manifest.repo, manifest.short_name + + try: + branch, description = _fetch_github_repo_info(owner=owner, repo_name=repo_name) + except Exception as error: + out.warning(f"Could not check updates for '{short_name}' ({owner}/{repo_name}): {error}. Skipping.") + return _ExtensionUpdateStatus.SKIPPED + + latest_sha = _fetch_latest_commit_sha(owner=owner, repo_name=repo_name, branch=branch, warn=False) + if latest_sha is None: + out.warning( + f"Could not check updates for '{short_name}' ({owner}/{repo_name}): GitHub is unreachable. Skipping." + ) + return _ExtensionUpdateStatus.SKIPPED + + if latest_sha == manifest.commit_sha: + return _ExtensionUpdateStatus.UP_TO_DATE + + _install_extension( + owner=owner, + repo_name=repo_name, + short_name=short_name, + branch=branch, + description=description, + commit_sha=latest_sha, + ) + return _ExtensionUpdateStatus.UPDATED + + +def _install_extension( + *, + owner: str, + repo_name: str, + short_name: str, + branch: str, + description: str | None = None, + commit_sha: str | None = None, +) -> ExtensionManifest: + """Fetch and install an extension (binary or Python package), then persist its manifest. + + Installs in place: an existing install is overwritten without being removed first, so a failed + update keeps the previous version working. A failed fresh install is cleaned up entirely. + """ + extension_dir = _get_extension_dir(short_name) + fresh_install = not extension_dir.exists() + installed = False + try: + try: + binary = _fetch_remote_binary(owner=owner, repo_name=repo_name, branch=branch, short_name=short_name) + except Exception: + binary = None + + if binary is not None: + executable_path = _install_binary_extension( + extension_dir=extension_dir, short_name=short_name, binary=binary + ) + else: + executable_path = _install_python_extension( + extension_dir=extension_dir, owner=owner, repo_name=repo_name, short_name=short_name, branch=branch + ) + + manifest = ExtensionManifest( + owner=owner, + repo=repo_name, + repo_id=f"{owner}/{repo_name}", + short_name=short_name, + executable_path=str(executable_path), + type="binary" if binary is not None else "python", + installed_at=datetime.now(timezone.utc), + description=_try_fetch_remote_description( + owner=owner, repo_name=repo_name, branch=branch, candidate_description=description + ), + commit_sha=commit_sha or _fetch_latest_commit_sha(owner=owner, repo_name=repo_name, branch=branch), + ) + manifest.save(extension_dir) + installed = True + return manifest + except CLIError: + raise + except subprocess.TimeoutExpired as e: + raise CLIExtensionInstallError( + f"Pip install timed out after {_EXTENSIONS_PIP_INSTALL_TIMEOUT}s for '{owner}/{repo_name}'. " + "See pip output above for details." + ) from e + except subprocess.CalledProcessError as e: + raise CLIExtensionInstallError( + f"Failed to install pip package from '{owner}/{repo_name}' (exit code {e.returncode}). " + "See pip output above for details." + ) from e + except Exception as e: + raise CLIExtensionInstallError(f"Failed to install extension from '{owner}/{repo_name}': {e}") from e + finally: + if not installed and fresh_install: + shutil.rmtree(extension_dir, ignore_errors=True) + + +def _fetch_latest_commit_sha(*, owner: str, repo_name: str, branch: str, warn: bool = True) -> str | None: + """Best-effort fetch of the latest commit SHA for a branch, used to detect available updates.""" + try: + response = _github_get( + f"https://api.github.com/repos/{owner}/{repo_name}/commits/{branch}", + headers={"Accept": "application/vnd.github.sha"}, + ) + return response.text.strip() or None + except Exception as error: + if warn: + out.warning(f"Could not fetch latest commit SHA for '{repo_name}' ({owner}/{repo_name}): {error}") + return None + + +def _fetch_remote_binary(*, owner: str, repo_name: str, branch: str, short_name: str) -> bytes: + executable_name = _get_executable_name(short_name) + raw_url = f"https://raw.githubusercontent.com/{owner}/{repo_name}/refs/heads/{branch}/{executable_name}" + response = _github_get(raw_url) + return response.content + + +def _install_binary_extension(*, extension_dir: Path, short_name: str, binary: bytes) -> Path: + extension_dir.mkdir(parents=True, exist_ok=True) + executable_path = extension_dir / _get_executable_name(short_name) + executable_path.write_bytes(binary) + + if os.name != "nt": + os.chmod(executable_path, 0o755) + + return executable_path + + +def _install_python_extension( + *, extension_dir: Path, owner: str, repo_name: str, short_name: str, branch: str +) -> Path: + source_url = f"https://github.com/{owner}/{repo_name}/archive/refs/heads/{branch}.zip" + venv_dir = extension_dir / "venv" + venv_python = _get_venv_bin_path(venv_dir, "python.exe" if os.name == "nt" else "python") + uv_path = shutil.which("uv") + + status = out.status() + if not venv_python.is_file(): + status.update(f"Creating virtual environment in {venv_dir}") + extension_dir.mkdir(parents=True, exist_ok=True) + if uv_path: + subprocess.run([uv_path, "venv", str(venv_dir)], check=True) + else: + venv.EnvBuilder(with_pip=True).create(str(venv_dir)) + status.done(f"Virtual environment created in {venv_dir}") + + status.update(f"Installing package from {source_url}") + if uv_path: + # --reinstall: the source URL is the same for every commit, so cached data must be refreshed. + install_cmd = [uv_path, "pip", "install", "--reinstall", "--python", str(venv_python), source_url] + else: + install_cmd = [ + str(venv_python), + "-m", + "pip", + "install", + "--disable-pip-version-check", + "--no-input", + "--force-reinstall", + source_url, + ] + subprocess.run(install_cmd, check=True, timeout=_EXTENSIONS_PIP_INSTALL_TIMEOUT) + status.done(f"Package installed from {source_url}") + + executable_name = _get_executable_name(short_name) + venv_executable = _get_venv_bin_path(venv_dir, executable_name) + if not venv_executable.is_file(): + raise CLIError( + f"Installed package from '{owner}/{repo_name}' does not expose the required console script " + f"'{executable_name}'." + ) + return venv_executable.resolve() + + +def _try_fetch_remote_description( + owner: str, repo_name: str, branch: str, candidate_description: str | None +) -> str | None: + """Try to fetch project description either from: + - manifest.json + - pyproject.toml + + Only best effort, no error handling. + """ + base = f"https://raw.githubusercontent.com/{owner}/{repo_name}/refs/heads/{branch}" + + # from manifest.json + try: + response = _github_get(f"{base}/{MANIFEST_FILENAME}") + description = response.json().get("description") + if isinstance(description, str): + return description + except Exception: + pass + + # from pyproject.toml + try: + response = _github_get(f"{base}/pyproject.toml") + + # Weak parser but ok for "best effort" + for line in response.text.splitlines(): + line = line.strip() + if line.startswith("description"): + _, _, value = line.partition("=") + return value.strip().strip("\"'") + except Exception: + pass + + # fallback to value fetched from GH API directly + return candidate_description + + +def _get_extension_dir(short_name: str) -> Path: + # Callers validate at the parse boundary already; re-validate here as defense-in-depth since + # this path is rmtree'd on removal. + _validate_extension_short_name(short_name, original_input=short_name) + return EXTENSIONS_ROOT.expanduser() / f"hf-{short_name}" + + +def _github_get(url: str, *, params: dict | None = None, headers: dict | None = None): + """Perform a GitHub GET request. + + Shared by every GitHub/Raw fetch in this module so the timeout and redirect policy are shared. + """ + response = get_session().get( + url, + params=params, + headers=headers, + follow_redirects=True, + timeout=_EXTENSIONS_DOWNLOAD_TIMEOUT, + ) + response.raise_for_status() + return response + + +def _fetch_github_repo_info(*, owner: str, repo_name: str) -> tuple[str, str | None]: + """Fetch `default_branch` + `description` for a GitHub repo from `GET /repos/{owner}/{repo}`.""" + response = _github_get(f"https://api.github.com/repos/{owner}/{repo_name}") + data = response.json() + return data["default_branch"], data.get("description") + + +def _get_executable_name(short_name: str) -> str: + name = f"hf-{short_name}" + if os.name == "nt": + name += ".exe" + return name + + +def _resolve_installed_executable_path(short_name: str) -> Path: + extension_dir = _get_extension_dir(short_name) + manifest = ExtensionManifest.load(extension_dir) + return Path(manifest.executable_path).expanduser() + + +def _get_venv_bin_path(venv_dir: Path, executable_name: str) -> Path: + if os.name == "nt": + return venv_dir / "Scripts" / executable_name + return venv_dir / "bin" / executable_name + + +_ALLOWED_EXTENSION_NAME = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]*$") + + +def _validate_extension_short_name(short_name: str, *, original_input: str) -> str: + name = short_name.strip() + if not name: + raise CLIError("Extension name cannot be empty.") + if any(sep in name for sep in ("/", "\\")): + raise CLIError(f"Invalid extension name '{original_input}'.") + if ".." in name or ":" in name: + raise CLIError(f"Invalid extension name '{original_input}'.") + if not _ALLOWED_EXTENSION_NAME.fullmatch(name): + raise CLIError( + f"Invalid extension name '{original_input}'. Allowed characters: letters, digits, '.', '_' and '-'." + ) + return name + + +def _normalize_repo_id(repo_id: str) -> tuple[str, str, str]: + if "://" in repo_id: + raise CLIError("Only GitHub repositories in `[OWNER/]hf-` format are supported.") + + parts = repo_id.split("/") + if len(parts) == 1: + owner = DEFAULT_EXTENSION_OWNER + repo_name = parts[0] + elif len(parts) == 2 and all(parts): + owner, repo_name = parts + else: + raise CLIError(f"Expected `[OWNER/]REPO` format, got '{repo_id}'.") + + if not repo_name.startswith("hf-"): + raise CLIError(f"Extension repository name must start with 'hf-', got '{repo_name}'.") + + short_name = repo_name.removeprefix("hf-") + if not short_name: + raise CLIError("Invalid extension repository name 'hf-'.") + _validate_extension_short_name(short_name, original_input=repo_id) + + return owner, repo_name, short_name + + +def _normalize_extension_name(name: str) -> str: + repo_name = name.strip().rsplit("/", 1)[-1] + return _validate_extension_short_name(repo_name.removeprefix("hf-"), original_input=name) + + +def _execute_extension_binary(executable_path: Path, args: list[str]) -> int: + try: + return subprocess.call([str(executable_path)] + args) + except OSError as e: + if os.name == "nt" or e.errno != errno.ENOEXEC: + raise + return subprocess.call(["sh", str(executable_path)] + args) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/hf.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/hf.py new file mode 100644 index 0000000000000000000000000000000000000000..cefe5e2e050ec10afb4813fcaa6d54b6a0974abc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/hf.py @@ -0,0 +1,142 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# 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. + +import os +import sys +import traceback +from typing import Annotated + +import click + +from huggingface_hub import __version__, constants +from huggingface_hub.cli._cli_utils import check_cli_update, fallback_typer_group_factory, typer_factory +from huggingface_hub.cli._cp import CP_EXAMPLES, make_cp +from huggingface_hub.cli._errors import format_known_exception +from huggingface_hub.cli._output import out +from huggingface_hub.cli.auth import auth_cli +from huggingface_hub.cli.buckets import buckets_cli, sync +from huggingface_hub.cli.cache import cache_cli +from huggingface_hub.cli.collections import collections_cli +from huggingface_hub.cli.datasets import datasets_cli +from huggingface_hub.cli.discussions import discussions_cli +from huggingface_hub.cli.download import DOWNLOAD_EXAMPLES, download +from huggingface_hub.cli.extensions import ( + dispatch_unknown_top_level_extension, + extensions_cli, + list_installed_extensions_for_help, +) +from huggingface_hub.cli.inference_endpoints import ie_cli +from huggingface_hub.cli.jobs import jobs_cli +from huggingface_hub.cli.lfs import lfs_enable_largefiles, lfs_multipart_upload +from huggingface_hub.cli.models import models_cli +from huggingface_hub.cli.papers import papers_cli +from huggingface_hub.cli.repo_files import repo_files_cli +from huggingface_hub.cli.repos import repos_cli +from huggingface_hub.cli.sandbox import sandbox_cli +from huggingface_hub.cli.skills import skills_cli +from huggingface_hub.cli.spaces import spaces_cli +from huggingface_hub.cli.system import env, update, version +from huggingface_hub.cli.upload import UPLOAD_EXAMPLES, upload +from huggingface_hub.cli.upload_large_folder import UPLOAD_LARGE_FOLDER_EXAMPLES, upload_large_folder +from huggingface_hub.cli.webhooks import webhooks_cli +from huggingface_hub.utils import logging + +from ._completion import _COMPLETE_VAR, InstallCompletionOpt, ShowCompletionOpt +from ._framework import Option + + +app = typer_factory( + help="Hugging Face Hub CLI", + cls=fallback_typer_group_factory( + dispatch_unknown_top_level_extension, + extra_commands_provider=list_installed_extensions_for_help, + ), +) + + +def _version_callback(value: bool) -> None: + if value: + print(__version__) + raise click.exceptions.Exit() + + +@app.group_callback(invoke_without_command=True) +def app_callback( + version: Annotated[ + bool | None, Option("-v", "--version", callback=_version_callback, is_eager=True, hidden=True) + ] = None, + install_completion: InstallCompletionOpt = False, + show_completion: ShowCompletionOpt = False, +) -> None: + pass + + +# top level single commands (defined in their respective files) +app.command(examples=CP_EXAMPLES)(make_cp()) +app.command()(sync) +app.command(examples=DOWNLOAD_EXAMPLES)(download) +app.command(examples=UPLOAD_EXAMPLES)(upload) +app.command(examples=UPLOAD_LARGE_FOLDER_EXAMPLES)(upload_large_folder) + +app.command(topic="help")(env) +app.command(topic="help")(update) +app.command(topic="help")(version) + +app.command(hidden=True)(lfs_enable_largefiles) +app.command(hidden=True)(lfs_multipart_upload) + +# command groups +app.add_group(auth_cli, name="auth") +app.add_group(buckets_cli, name="buckets") +app.add_group(cache_cli, name="cache") +app.add_group(collections_cli, name="collections") +app.add_group(datasets_cli, name="datasets") +app.add_group(discussions_cli, name="discussions") +app.add_group(jobs_cli, name="jobs") +app.add_group(models_cli, name="models") +app.add_group(papers_cli, name="papers") +app.add_group(repos_cli, name="repos | repo") +app.add_group(repo_files_cli, name="repo-files", hidden=True) +app.add_group(sandbox_cli, name="sandbox") +app.add_group(skills_cli, name="skills") +app.add_group(spaces_cli, name="spaces") +app.add_group(webhooks_cli, name="webhooks") +app.add_group(ie_cli, name="endpoints") +app.add_group(extensions_cli, name="extensions | ext") + + +def main(): + # Shell-completion requests must stay fast and emit nothing but candidates: + # skip the startup work and let click handle the env var inside `app()`. + if _COMPLETE_VAR not in os.environ: + if not constants.HF_DEBUG: + logging.set_verbosity_info() + check_cli_update("huggingface_hub") + + try: + app() + except Exception as e: + message = format_known_exception(e) + if message: + out.error(message) + if constants.HF_DEBUG: + traceback.print_exc() + else: + out.hint("set HF_DEBUG=1 as environment variable for full traceback.") + sys.exit(1) + raise + + +if __name__ == "__main__": + main() diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/inference_endpoints.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/inference_endpoints.py new file mode 100644 index 0000000000000000000000000000000000000000..a95d5968090def26bce4fc7662b02137dc0f670d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/inference_endpoints.py @@ -0,0 +1,535 @@ +"""CLI commands for Hugging Face Inference Endpoints.""" + +import shlex +from typing import Annotated + +import click + +from huggingface_hub._inference_endpoints import InferenceEndpointScalingMetric, InferenceEndpointType +from huggingface_hub.errors import CLIError, HfHubHTTPError + +from ._cli_utils import ( + EnvFileOpt, + EnvOpt, + RevisionOpt, + SecretsFileOpt, + SecretsOpt, + SoftChoice, + TokenOpt, + get_hf_api, + parse_env_map, + typer_factory, +) +from ._framework import Argument, Option +from ._output import out + + +ie_cli = typer_factory(help="Manage Hugging Face Inference Endpoints.") + +catalog_app = typer_factory(help="Interact with the Inference Endpoints catalog.") + + +NameArg = Annotated[ + str, + Argument(help="Endpoint name."), +] +NameOpt = Annotated[ + str | None, + Option(help="Endpoint name."), +] + +NamespaceOpt = Annotated[ + str | None, + Option( + help="The namespace associated with the Inference Endpoint. Defaults to the current user's namespace.", + ), +] + + +@ie_cli.command("list | ls", examples=["hf endpoints ls", "hf endpoints ls --namespace my-org"]) +def ls( + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Lists all Inference Endpoints for the given namespace.""" + api = get_hf_api(token=token) + try: + endpoints = api.list_inference_endpoints(namespace=namespace, token=token) + except HfHubHTTPError as error: + out.error(f"Listing failed: {error}") + raise click.exceptions.Exit(code=error.response.status_code) from error + + results = [] + for endpoint in endpoints: + raw = endpoint.raw + status = raw.get("status", {}) + model = raw.get("model", {}) + compute = raw.get("compute", {}) + provider = raw.get("provider", {}) + results.append( + { + "name": raw.get("name", ""), + "model": model.get("repository", "") if isinstance(model, dict) else "", + "status": status.get("state", "") if isinstance(status, dict) else "", + "task": model.get("task", "") if isinstance(model, dict) else "", + "framework": model.get("framework", "") if isinstance(model, dict) else "", + "instance": compute.get("instanceType", "") if isinstance(compute, dict) else "", + "vendor": provider.get("vendor", "") if isinstance(provider, dict) else "", + "region": provider.get("region", "") if isinstance(provider, dict) else "", + } + ) + out.table(results, id_key="name") + + +@ie_cli.command(name="deploy", examples=["hf endpoints deploy my-endpoint --repo gpt2 --framework pytorch ..."]) +def deploy( + name: NameArg, + repo: Annotated[ + str, + Option( + help="The name of the model repository associated with the Inference Endpoint (e.g. 'openai/gpt-oss-120b').", + ), + ], + framework: Annotated[ + str, + Option( + help="The machine learning framework used for the model (e.g. 'vllm').", + ), + ], + accelerator: Annotated[ + str, + Option( + help="The hardware accelerator to be used for inference (e.g. 'cpu').", + ), + ], + instance_size: Annotated[ + str, + Option( + help="The size or type of the instance to be used for hosting the model (e.g. 'x4').", + ), + ], + instance_type: Annotated[ + str, + Option( + help="The cloud instance type where the Inference Endpoint will be deployed (e.g. 'intel-icl').", + ), + ], + region: Annotated[ + str, + Option( + help="The cloud region in which the Inference Endpoint will be created (e.g. 'us-east-1').", + ), + ], + vendor: Annotated[ + str, + Option( + help="The cloud provider or vendor where the Inference Endpoint will be hosted (e.g. 'aws').", + ), + ], + *, + namespace: NamespaceOpt = None, + task: Annotated[ + str | None, + Option( + help="The task on which to deploy the model (e.g. 'text-classification').", + ), + ] = None, + token: TokenOpt = None, + min_replica: Annotated[ + int, + Option( + help="The minimum number of replicas (instances) to keep running for the Inference Endpoint.", + ), + ] = 1, + max_replica: Annotated[ + int, + Option( + help="The maximum number of replicas (instances) to scale to for the Inference Endpoint.", + ), + ] = 1, + scale_to_zero_timeout: Annotated[ + int | None, + Option( + help="The duration in minutes before an inactive endpoint is scaled to zero.", + ), + ] = None, + scaling_metric: Annotated[ + InferenceEndpointScalingMetric | None, + Option( + help="The metric reference for scaling.", + ), + ] = None, + scaling_threshold: Annotated[ + float | None, + Option( + help="The scaling metric threshold used to trigger a scale up. Ignored when scaling metric is not provided.", + ), + ] = None, + revision: RevisionOpt = None, + custom_image: Annotated[ + str | None, + Option( + "--custom-image", + help="Docker image URL for a custom container (e.g. 'nexagi/sglang:v0.5.12'). Requires '--framework custom'.", + ), + ] = None, + health_route: Annotated[ + str | None, + Option( + help="Health check route exposed by the custom container (e.g. '/health'). Requires --custom-image.", + ), + ] = None, + port: Annotated[ + int | None, + Option( + help="Port the custom container listens on (e.g. 30000). Requires --custom-image.", + ), + ] = None, + container_command: Annotated[ + str | None, + Option( + "--container-command", + help=( + "Override the container entrypoint, as a quoted string split into tokens " + '(e.g. "python -m sglang.launch_server"). Requires --custom-image.' + ), + ), + ] = None, + container_args: Annotated[ + str | None, + Option( + "--container-args", + help=( + "Arguments appended to the container entrypoint, as a quoted string split into tokens " + '(e.g. "--tp 8 --reasoning-parser qwen3"). Requires --custom-image.' + ), + ), + ] = None, + env: EnvOpt = None, + env_file: EnvFileOpt = None, + secrets: SecretsOpt = None, + secrets_file: SecretsFileOpt = None, + endpoint_type: Annotated[ + str | None, + Option( + "--type", + click_type=SoftChoice(InferenceEndpointType), + help="Endpoint access type. Defaults to 'authenticated' (token-gated, publicly reachable).", + ), + ] = None, +) -> None: + """Deploy an Inference Endpoint from a Hub repository.""" + # Custom-container knobs only make sense alongside a custom image. + if custom_image is None and (health_route is not None or port is not None or container_command or container_args): + raise CLIError("--health-route, --port, --container-command and --container-args require --custom-image.") + custom_image_dict: dict | None = None + if custom_image is not None: + custom_image_dict = {"url": custom_image} + if health_route is not None: + custom_image_dict["healthRoute"] = health_route + if port is not None: + custom_image_dict["port"] = port + + env_map = {key: value or "" for key, value in parse_env_map(env, env_file).items()} + secrets_map = {key: value or "" for key, value in parse_env_map(secrets, secrets_file).items()} + + # Only forward the values the user actually set and let `create_inference_endpoint` own the defaults. + params: dict = {} + if endpoint_type is not None: + params["type"] = endpoint_type + if custom_image_dict is not None: + params["custom_image"] = custom_image_dict + if container_command: + params["container_command"] = shlex.split(container_command) + if container_args: + params["container_args"] = shlex.split(container_args) + if env_map: + params["env"] = env_map + if secrets_map: + params["secrets"] = secrets_map + + api = get_hf_api(token=token) + endpoint = api.create_inference_endpoint( + name=name, + repository=repo, + framework=framework, + accelerator=accelerator, + instance_size=instance_size, + instance_type=instance_type, + region=region, + vendor=vendor, + namespace=namespace, + task=task, + token=token, + min_replica=min_replica, + max_replica=max_replica, + scaling_metric=scaling_metric, + scaling_threshold=scaling_threshold, + scale_to_zero_timeout=scale_to_zero_timeout, + revision=revision, + **params, + ) + out.dict(endpoint.raw) + out.hint(f"Use 'hf endpoints describe {name}' to check the deployment status.") + + +@catalog_app.command(name="deploy", examples=["hf endpoints catalog deploy --repo meta-llama/Llama-3.2-1B-Instruct"]) +def deploy_from_catalog( + repo: Annotated[ + str, + Option( + help="The name of the model repository associated with the Inference Endpoint (e.g. 'openai/gpt-oss-120b').", + ), + ], + name: NameOpt = None, + accelerator: Annotated[ + str | None, + Option( + help="The hardware accelerator to be used for inference (e.g. 'cpu', 'gpu', 'neuron').", + ), + ] = None, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Deploy an Inference Endpoint from the Model Catalog.""" + api = get_hf_api(token=token) + try: + endpoint = api.create_inference_endpoint_from_catalog( + repo_id=repo, + name=name, + accelerator=accelerator, + namespace=namespace, + token=token, + ) + except HfHubHTTPError as error: + out.error(f"Deployment failed: {error}") + raise click.exceptions.Exit(code=error.response.status_code) from error + + out.dict(endpoint.raw) + + +def list_catalog( + token: TokenOpt = None, +) -> None: + """List available Catalog models.""" + api = get_hf_api(token=token) + try: + models = api.list_inference_catalog(token=token) + except HfHubHTTPError as error: + out.error(f"Catalog fetch failed: {error}") + raise click.exceptions.Exit(code=error.response.status_code) from error + + out.dict({"models": models}) + + +catalog_app.command(name="list | ls", examples=["hf endpoints catalog ls"])(list_catalog) +ie_cli.command(name="list-catalog", hidden=True)(list_catalog) + + +ie_cli.add_group(catalog_app, name="catalog") + + +@ie_cli.command(examples=["hf endpoints describe my-endpoint"]) +def describe( + name: NameArg, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Get information about an existing endpoint.""" + api = get_hf_api(token=token) + try: + endpoint = api.get_inference_endpoint(name=name, namespace=namespace, token=token) + except HfHubHTTPError as error: + out.error(f"Fetch failed: {error}") + raise click.exceptions.Exit(code=error.response.status_code) from error + + out.dict(endpoint.raw) + + +@ie_cli.command(examples=["hf endpoints update my-endpoint --min-replica 2"]) +def update( + name: NameArg, + namespace: NamespaceOpt = None, + repo: Annotated[ + str | None, + Option( + help="The name of the model repository associated with the Inference Endpoint (e.g. 'openai/gpt-oss-120b').", + ), + ] = None, + accelerator: Annotated[ + str | None, + Option( + help="The hardware accelerator to be used for inference (e.g. 'cpu').", + ), + ] = None, + instance_size: Annotated[ + str | None, + Option( + help="The size or type of the instance to be used for hosting the model (e.g. 'x4').", + ), + ] = None, + instance_type: Annotated[ + str | None, + Option( + help="The cloud instance type where the Inference Endpoint will be deployed (e.g. 'intel-icl').", + ), + ] = None, + framework: Annotated[ + str | None, + Option( + help="The machine learning framework used for the model (e.g. 'custom').", + ), + ] = None, + revision: Annotated[ + str | None, + Option( + help="The specific model revision to deploy on the Inference Endpoint (e.g. '6c0e6080953db56375760c0471a8c5f2929baf11').", + ), + ] = None, + task: Annotated[ + str | None, + Option( + help="The task on which to deploy the model (e.g. 'text-classification').", + ), + ] = None, + min_replica: Annotated[ + int | None, + Option( + help="The minimum number of replicas (instances) to keep running for the Inference Endpoint.", + ), + ] = None, + max_replica: Annotated[ + int | None, + Option( + help="The maximum number of replicas (instances) to scale to for the Inference Endpoint.", + ), + ] = None, + scale_to_zero_timeout: Annotated[ + int | None, + Option( + help="The duration in minutes before an inactive endpoint is scaled to zero.", + ), + ] = None, + scaling_metric: Annotated[ + InferenceEndpointScalingMetric | None, + Option( + help="The metric reference for scaling.", + ), + ] = None, + scaling_threshold: Annotated[ + float | None, + Option( + help="The scaling metric threshold used to trigger a scale up. Ignored when scaling metric is not provided.", + ), + ] = None, + token: TokenOpt = None, +) -> None: + """Update an existing endpoint.""" + api = get_hf_api(token=token) + try: + endpoint = api.update_inference_endpoint( + name=name, + namespace=namespace, + repository=repo, + framework=framework, + revision=revision, + task=task, + accelerator=accelerator, + instance_size=instance_size, + instance_type=instance_type, + min_replica=min_replica, + max_replica=max_replica, + scale_to_zero_timeout=scale_to_zero_timeout, + scaling_metric=scaling_metric, + scaling_threshold=scaling_threshold, + token=token, + ) + except HfHubHTTPError as error: + out.error(f"Update failed: {error}") + raise click.exceptions.Exit(code=error.response.status_code) from error + out.dict(endpoint.raw) + + +@ie_cli.command(examples=["hf endpoints delete my-endpoint"]) +def delete( + name: NameArg, + namespace: NamespaceOpt = None, + yes: Annotated[ + bool, + Option("--yes", help="Skip confirmation prompts."), + ] = False, + token: TokenOpt = None, +) -> None: + """Delete an Inference Endpoint permanently.""" + out.confirm(f"Delete endpoint '{name}'?", yes=yes) + + api = get_hf_api(token=token) + try: + api.delete_inference_endpoint(name=name, namespace=namespace, token=token) + except HfHubHTTPError as error: + out.error(f"Delete failed: {error}") + raise click.exceptions.Exit(code=error.response.status_code) from error + + out.result(f"Deleted '{name}'.", name=name) + + +@ie_cli.command(examples=["hf endpoints pause my-endpoint"]) +def pause( + name: NameArg, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Pause an Inference Endpoint.""" + api = get_hf_api(token=token) + try: + endpoint = api.pause_inference_endpoint(name=name, namespace=namespace, token=token) + except HfHubHTTPError as error: + out.error(f"Pause failed: {error}") + raise click.exceptions.Exit(code=error.response.status_code) from error + + out.dict(endpoint.raw) + + +@ie_cli.command(examples=["hf endpoints resume my-endpoint"]) +def resume( + name: NameArg, + namespace: NamespaceOpt = None, + fail_if_already_running: Annotated[ + bool, + Option( + "--fail-if-already-running", + help="If `True`, the method will raise an error if the Inference Endpoint is already running.", + ), + ] = False, + token: TokenOpt = None, +) -> None: + """Resume an Inference Endpoint.""" + api = get_hf_api(token=token) + try: + endpoint = api.resume_inference_endpoint( + name=name, + namespace=namespace, + token=token, + running_ok=not fail_if_already_running, + ) + except HfHubHTTPError as error: + out.error(f"Resume failed: {error}") + raise click.exceptions.Exit(code=error.response.status_code) from error + out.dict(endpoint.raw) + + +@ie_cli.command(examples=["hf endpoints scale-to-zero my-endpoint"]) +def scale_to_zero( + name: NameArg, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Scale an Inference Endpoint to zero.""" + api = get_hf_api(token=token) + try: + endpoint = api.scale_to_zero_inference_endpoint(name=name, namespace=namespace, token=token) + except HfHubHTTPError as error: + out.error(f"Scale To Zero failed: {error}") + raise click.exceptions.Exit(code=error.response.status_code) from error + + out.dict(endpoint.raw) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/jobs.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/jobs.py new file mode 100644 index 0000000000000000000000000000000000000000..b8acfdb4c1b4709361a3badfc81be192f71ef126 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/jobs.py @@ -0,0 +1,1335 @@ +# Copyright 2025 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains commands to interact with jobs on the Hugging Face Hub.""" + +import itertools +import multiprocessing +import multiprocessing.pool +import shutil +import time +from collections.abc import Callable, Iterable +from fnmatch import fnmatch +from pathlib import Path +from queue import Empty, Queue +from typing import Annotated, Any, TypeVar +from urllib.parse import urlsplit + +from huggingface_hub import HfApi, JobHardware, JobInfo, JobStage, Volume, constants +from huggingface_hub._jobs_api import TERMINAL_JOB_STAGES +from huggingface_hub.errors import CLIError +from huggingface_hub.utils import logging +from huggingface_hub.utils._cache_manager import _format_size +from huggingface_hub.utils._hf_uris import _split_mount +from huggingface_hub.utils._parsing import format_duration, parse_duration + +from ._cli_utils import ( + EnvFileOpt, + EnvOpt, + SecretsFileOpt, + SecretsOpt, + SoftChoice, + SshDryRunOpt, + SshIdentityFileOpt, + TokenOpt, + exec_ssh, + get_hf_api, + parse_env_map, + parse_volumes, + typer_factory, +) +from ._framework import Argument, Option +from ._output import _dataclass_to_dict, out + + +logger = logging.get_logger(__name__) + + +def _parse_namespace_from_job_id(job_id: str, namespace: str | None) -> tuple[str, str | None]: + """Extract namespace from job_id if provided in 'namespace/job_id' format. + + Allows users to pass job IDs copied from the Hub UI (e.g. 'username/job_id') + instead of only bare job IDs. If the namespace is also provided explicitly via + --namespace and conflicts, a CLIError is raised. + """ + if not job_id: + raise CLIError("Job ID cannot be empty.") + + if job_id.count("/") > 1: + raise CLIError(f"Job ID must be in the form 'job_id' or 'namespace/job_id': '{job_id}'.") + + if "/" not in job_id: + return job_id, namespace + + extracted_namespace, parsed_job_id = job_id.split("/", 1) + if not extracted_namespace or not parsed_job_id: + raise CLIError(f"Job ID must be in the form 'job_id' or 'namespace/job_id': '{job_id}'.") + + if namespace is not None and namespace != extracted_namespace: + raise CLIError( + f"Conflicting namespace: got --namespace='{namespace}' but job ID implies namespace='{extracted_namespace}'" + ) + + return parsed_job_id, extracted_namespace + + +def _parse_and_sync_job_volumes( + volumes: list[str] | None, *, api: HfApi, namespace: str | None +) -> list[Volume] | None: + """Parse `-v` specs for Jobs commands. + + Same as [`parse_volumes`] but the source side can also be a local directory: it is synced to a + bucket via [`HfApi.sync_job_volume`] and the resulting bucket subfolder is mounted (read-only + unless ':rw' is specified). + """ + if not volumes: + return None + + result: list[Volume] = [] + for raw_spec in volumes: + if raw_spec.startswith(constants.HF_PROTOCOL): + result.extend(parse_volumes([raw_spec]) or []) + continue + + # Not a 'hf://' URI: treat the source as a local directory. + source, mount_path, read_only = _split_mount(raw_spec, raw=raw_spec) + if mount_path is None: + raise CLIError( + f"Missing mount path in volume spec '{raw_spec}'. Expected 'LOCAL_DIR:/MOUNT_PATH[:ro|:rw]' (e.g. './data:/data')." + ) + if not Path(source).expanduser().is_dir(): + raise CLIError( + f"Volume source '{source}' is not an existing local directory. " + "To mount a repo or bucket instead, use the 'hf://' syntax (e.g. 'hf://buckets/my-org/my-bucket:/data')." + ) + volume = api.sync_job_volume( + source, + mount_path, + read_only=read_only if read_only is not None else True, + namespace=namespace, + ) + if volume.read_only is False: + out.hint( + f"Volume '{mount_path}' is mounted read-write. Once the job is over, pull back its data with:\n" + f" hf buckets sync hf://buckets/{volume.source}/{volume.path} {source}" + ) + result.append(volume) + return result + + +STATS_UPDATE_MIN_INTERVAL = 0.1 # we set a limit here since there is one update per second per job + +# Common job-related options +ImageArg = Annotated[ + str, + Argument( + help="The Docker image to use.", + ), +] + +ImageOpt = Annotated[ + str | None, + Option( + help="Use a custom Docker image with `uv` installed.", + ), +] + +FlavorOpt = Annotated[ + str | None, + Option( + help="Flavor for the hardware. Run 'hf jobs hardware' to list available flavors. Defaults to `cpu-basic`.", + click_type=SoftChoice(JobHardware), + ), +] + +LabelsOpt = Annotated[ + list[str] | None, + Option( + "-l", + "--label", + help="Set labels. E.g. --label KEY=VALUE or --label LABEL", + ), +] + +TimeoutOpt = Annotated[ + str | None, + Option( + help="Max duration: int with s (seconds, default), m (minutes), h (hours) or d (days).", + ), +] + +DetachOpt = Annotated[ + bool, + Option( + "-d", + "--detach", + help="Run the Job in the background and print the Job ID.", + ), +] + +NamespaceOpt = Annotated[ + str | None, + Option( + help="The namespace where the job will be running. Defaults to the current user's namespace.", + ), +] + +ExposeOpt = Annotated[ + list[int] | None, + Option( + "--expose", + help="Expose a container port through the jobs proxy. Repeat the flag for multiple ports (e.g. `--expose 8000 --expose 8001`). Each exposed port is reachable on the public jobs domain; access requires an HF token with read access to the job's namespace.", + ), +] + +SshEnabledOpt = Annotated[ + bool, + Option( + "--ssh", + help="Make the job's container reachable over SSH. Connect with `hf jobs ssh `. Requires an SSH public key registered on https://huggingface.co/settings/keys.", + ), +] + +WithOpt = Annotated[ + list[str] | None, + Option( + "--with", + help="Run with the given packages installed", + ), +] + +PythonOpt = Annotated[ + str | None, + Option( + "-p", + "--python", + help="The Python interpreter to use for the run environment", + ), +] + +SuspendOpt = Annotated[ + bool | None, + Option( + help="Suspend (pause) the scheduled Job", + ), +] + +ConcurrencyOpt = Annotated[ + bool | None, + Option( + help="Allow multiple instances of this Job to run concurrently", + ), +] + +ScheduleArg = Annotated[ + str, + Argument( + help="One of annually, yearly, monthly, weekly, daily, hourly, or a CRON schedule expression.", + ), +] + +ScriptArg = Annotated[ + str, + Argument( + help="UV script to run (local file or URL)", + ), +] + +ScriptArgsArg = Annotated[ + list[str] | None, + Argument( + help="Arguments for the script", + ), +] + + +CommandArg = Annotated[ + list[str], + Argument( + help="The command to run.", + ), +] + +JobIdArg = Annotated[ + str, + Argument( + help="Job ID (or 'namespace/job_id')", + ), +] + +JobIdsArg = Annotated[ + list[str] | None, + Argument( + help="Job IDs (or 'namespace/job_id')", + ), +] + +ScheduledJobIdArg = Annotated[ + str, + Argument( + help="Scheduled Job ID (or 'namespace/scheduled_job_id')", + ), +] + +JobVolumesOpt = Annotated[ + list[str] | None, + Option( + "-v", + "--volume", + help="Mount one or more volumes. Format: hf://[TYPE/]SOURCE:/MOUNT_PATH[:ro|:rw] or LOCAL_DIR:/MOUNT_PATH[:ro|:rw]. " + "TYPE is one of: models, datasets, spaces, buckets. " + "TYPE defaults to models if omitted. " + "models, datasets and spaces are always mounted read-only. buckets are read+write by default. " + "A local directory source is first synced to a bucket and mounted read-only by default. " + "E.g. -v hf://datasets/org/ds:/data or -v hf://buckets/org/b:/mnt:ro or -v ./inputs:/inputs", + ), +] + + +jobs_cli = typer_factory(help="Run and manage Jobs on the Hub.") + + +def _stream_logs_and_check_status(api: HfApi, job: JobInfo) -> None: + """Stream Job logs until the Job ends, then fail the command if the Job did not complete successfully.""" + for log in api.fetch_job_logs(job_id=job.id, namespace=job.owner.name, follow=True): + out.text(log) + # The log stream can end while the Job is still scheduling or shutting down: settle the final state. + final = api.wait_for_job(job_id=job.id, namespace=job.owner.name) + if final.status.stage != JobStage.COMPLETED: + message = f": {final.status.message}" if final.status.message else "" + raise CLIError(f"Job {final.id} finished with stage '{final.status.stage}'{message}") + out.text(f"Job {final.id} completed") + + +@jobs_cli.command( + "run", + context_settings={"ignore_unknown_options": True}, + examples=[ + "hf jobs run python:3.12 python -c 'print(\"Hello!\")'", + "hf jobs run --detach python:3.12 python script.py", + "hf jobs run -e FOO=foo python:3.12 python script.py", + "hf jobs run --secrets HF_TOKEN python:3.12 python script.py", + "hf jobs run -v hf://org/my-model:/data -v hf://buckets/org/b:/mnt python:3.12 python script.py", + ], +) +def jobs_run( + image: ImageArg, + command: CommandArg, + env: EnvOpt = None, + secrets: SecretsOpt = None, + label: LabelsOpt = None, + volume: JobVolumesOpt = None, + env_file: EnvFileOpt = None, + secrets_file: SecretsFileOpt = None, + flavor: FlavorOpt = None, + timeout: TimeoutOpt = None, + detach: DetachOpt = False, + expose: ExposeOpt = None, + ssh: SshEnabledOpt = False, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Run a Job.""" + env_map = parse_env_map(env, env_file) + secrets_map = parse_env_map(secrets, secrets_file) + + api = get_hf_api(token=token) + job = api.run_job( + image=image, + command=command, + env=env_map, + secrets=secrets_map, + labels=_parse_labels_map(label), + volumes=_parse_and_sync_job_volumes(volume, api=api, namespace=namespace), + flavor=flavor, + timeout=timeout, + expose=expose, + ssh=ssh, + namespace=namespace, + ) + out.result("Job started", id=job.id, url=job.url) + if isinstance(job.status.expose_urls, list): + urls = "\n".join(f" {url}" for url in job.status.expose_urls) + out.hint(f"Exposed ports are reachable at (requires an HF token with read access to the job):\n{urls}") + if isinstance(job.status.ssh_url, str): + out.hint(f"Use `hf jobs ssh {job.owner.name}/{job.id}` to open an SSH session into the job.") + if detach: + job_ref = f"{job.owner.name}/{job.id}" + out.hint(f"Use `hf jobs logs -f {job_ref}` to stream logs, or `hf jobs inspect {job_ref}` to check status.") + out.hint(f"Use `hf jobs wait {job_ref}` to block until it finishes.") + return + _stream_logs_and_check_status(api, job) + + +@jobs_cli.command( + "logs", + examples=[ + "hf jobs logs ", + "hf jobs logs -f ", + "hf jobs logs --tail 20 ", + "hf jobs logs -f --tail 100 ", + ], +) +def jobs_logs( + job_id: JobIdArg, + follow: Annotated[ + bool, + Option( + "-f", + "--follow", + help="Follow log output (stream until the job completes). Without this flag, only currently available logs are printed.", + ), + ] = False, + tail: Annotated[ + int | None, + Option( + "-n", + "--tail", + help="Number of lines to show from the end of the logs. When combined with --follow, starts streaming from the last N lines.", + ), + ] = None, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Fetch the logs of a Job. + + By default, prints currently available logs and exits (non-blocking). + Use --follow/-f to stream logs in real-time until the job completes. + Use --tail/-n to limit the number of lines returned (server-side when supported). + + Note: following exits when the log stream ends, regardless of whether the Job + succeeded or failed. Run `hf jobs inspect ` to check the final status. + """ + job_id, namespace = _parse_namespace_from_job_id(job_id, namespace) + + api = get_hf_api(token=token) + logs = api.fetch_job_logs(job_id=job_id, namespace=namespace, follow=follow, tail=tail) + for log in logs: + out.text(log) + if follow: + job_ref = f"{namespace}/{job_id}" if namespace else job_id + out.hint(f"Stream ended. Run `hf jobs inspect {job_ref}` to check the final status (e.g. COMPLETED or ERROR).") + + +def _matches_filters(job_properties: dict[str, str], filters: list[tuple[str, str, str]]) -> bool: + """Check if scheduled job matches all specified filters.""" + for key, op_str, pattern in filters: + value = job_properties.get(key) + if value is None: + if op_str == "!=": + continue + return False + match = fnmatch(value.lower(), pattern.lower()) + if (op_str == "=" and not match) or (op_str == "!=" and match): + return False + return True + + +def _clear_line(n: int) -> None: + LINE_UP = "\033[1A" + LINE_CLEAR = "\x1b[2K" + for i in range(n): + print(LINE_UP, end=LINE_CLEAR) + + +def _get_jobs_stats_rows( + job_id: str, metrics_stream: Iterable[dict[str, Any]], table_headers: list[str] +) -> Iterable[tuple[bool, str, list[list[str | int]]]]: + for metrics in metrics_stream: + row = [ + job_id, + f"{metrics['cpu_usage_pct']}%", + round(metrics["cpu_millicores"] / 1000.0, 1), + f"{round(100 * metrics['memory_used_bytes'] / metrics['memory_total_bytes'], 2)}%", + f"{_format_size(metrics['memory_used_bytes'])}B / {_format_size(metrics['memory_total_bytes'])}B", + f"{_format_size(metrics['rx_bps'])}bps / {_format_size(metrics['tx_bps'])}bps", + ] + if metrics["gpus"] and isinstance(metrics["gpus"], dict): + rows = [row] + [[""] * len(row)] * (len(metrics["gpus"]) - 1) + for row, gpu_id in zip(rows, sorted(metrics["gpus"])): + gpu = metrics["gpus"][gpu_id] + row += [ + f"{gpu['utilization']}%", + f"{round(100 * gpu['memory_used_bytes'] / gpu['memory_total_bytes'], 2)}%", + f"{_format_size(gpu['memory_used_bytes'])}B / {_format_size(gpu['memory_total_bytes'])}B", + ] + else: + row += ["N/A"] * (len(table_headers) - len(row)) + rows = [row] + yield False, job_id, rows + yield True, job_id, [] + + +@jobs_cli.command("stats", examples=["hf jobs stats "]) +def jobs_stats( + job_ids: JobIdsArg = None, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Fetch the resource usage statistics and metrics of Jobs""" + if job_ids is not None: + parsed_ids = [] + for job_id in job_ids: + job_id, namespace = _parse_namespace_from_job_id(job_id, namespace) + parsed_ids.append(job_id) + job_ids = parsed_ids + api = get_hf_api(token=token) + if namespace is None: + namespace = api.whoami()["name"] + if job_ids is None: + job_ids = [ + job.id + for job in api.list_jobs(namespace=namespace) + if (job.status.stage if job.status else "UNKNOWN") in ("RUNNING", "UPDATING") + ] + if len(job_ids) == 0: + out.text("No running jobs found") + return + table_headers = [ + "JOB ID", + "CPU %", + "NUM CPU", + "MEM %", + "MEM USAGE", + "NET I/O", + "GPU UTIL %", + "GPU MEM %", + "GPU MEM USAGE", + ] + with multiprocessing.pool.ThreadPool(len(job_ids)) as pool: + rows_per_job_id: dict[str, list[list[str | int]]] = {} + for job_id in job_ids: + row: list[str | int] = [job_id] + row += ["-- / --" if ("/" in header or "USAGE" in header) else "--" for header in table_headers[1:]] + rows_per_job_id[job_id] = [row] + last_update_time = time.time() + total_rows = [row for job_id in rows_per_job_id for row in rows_per_job_id[job_id]] + # In-place refresh (cursor-up + clear) requires a fixed line count and layout — + # `out.table`'s mode-dependent formatting would break it. + print(_tabulate(total_rows, headers=table_headers)) + + kwargs_list = [ + { + "job_id": job_id, + "metrics_stream": api.fetch_job_metrics(job_id=job_id, namespace=namespace), + "table_headers": table_headers, + } + for job_id in job_ids + ] + for done, job_id, rows in iflatmap_unordered(pool, _get_jobs_stats_rows, kwargs_list=kwargs_list): + if done: + rows_per_job_id.pop(job_id, None) + else: + rows_per_job_id[job_id] = rows + now = time.time() + if now - last_update_time >= STATS_UPDATE_MIN_INTERVAL: + _clear_line(2 + len(total_rows)) + total_rows = [row for job_id in rows_per_job_id for row in rows_per_job_id[job_id]] + print(_tabulate(total_rows, headers=table_headers)) + last_update_time = now + + +@jobs_cli.command( + "list | ls | ps", + examples=[ + "hf jobs ls", + "hf jobs ls -a", + "hf jobs ls --status running,scheduling", + "hf jobs ls --label env=prod --label team=ml", + "hf jobs ls --all --label hf-sandbox=1", + ], +) +def jobs_ps( + all: Annotated[ + bool, + Option( + "-a", + "--all", + help="Show all Jobs (default shows running and scheduling). Cannot be combined with --status.", + ), + ] = False, + status: Annotated[ + list[str] | None, + Option( + "--status", + click_type=SoftChoice(JobStage), + help="Only show Jobs with the given status. Comma-separated or repeated, e.g. `--status running,scheduling`.", + ), + ] = None, + label: Annotated[ + list[str] | None, + Option( + "-l", + "--label", + help="Only show Jobs with the given `key=value` label. Repeat to require several labels, e.g. `--label env=prod --label team=ml`.", + ), + ] = None, + limit: Annotated[ + int, + Option( + "--limit", + help="Maximum number of Jobs to display. Set to 0 to show all (no limit).", + ), + ] = 100, + namespace: NamespaceOpt = None, + token: TokenOpt = None, + filter: Annotated[ + list[str] | None, + Option( + "-f", + "--filter", + help="(Deprecated) Use `--status` and `--label` instead.", + ), + ] = None, +) -> None: + """List Jobs. + + Use `--status` to filter by status (see [`JobStage`] for possible values) and `--label` to filter by `key=value` + labels. A Job must match every filter to be listed. + """ + api = get_hf_api(token=token) + + if filter: + out.warning( + f"Ignoring filter '{filter}'." + " `-f`/`--filter` is deprecated and will be removed in a future release. Use `--status`/`--label`." + ) + + if all and status: + raise CLIError("`-a`/`--all` cannot be combined with `--status`.") + + # Status filtering (default to active Jobs, unless `--all` or `--status` is provided). + raw_statuses: list[str] = [] + for value in status or []: + raw_statuses.extend(part.strip() for part in value.split(",") if part.strip()) + + server_statuses: list[str] | None + if raw_statuses: + server_statuses = raw_statuses + elif all: + server_statuses = None + else: + server_statuses = [JobStage.RUNNING.value, JobStage.SCHEDULING.value] + + # Labels filtering + labels: dict[str, str] = {} + for item in label or []: + if "=" not in item: + raise CLIError(f"Invalid label filter '{item}': must be in the form 'key=value'") + key, value = item.split("=") + labels[key] = value + + jobs_iter = api.list_jobs(namespace=namespace, status=server_statuses, labels=labels or None) + + # Apply the display limit. Fetch one extra Job to detect (and warn about) truncation. + truncated = False + if limit > 0: + jobs = list(itertools.islice(jobs_iter, limit + 1)) + if len(jobs) > limit: + truncated = True + jobs = jobs[:limit] + else: + jobs = list(jobs_iter) + + # Build display items. Augment the raw api dict with curated, table-friendly columns. + job_items: list[dict[str, Any]] = [] + for job in jobs: + job_item = _dataclass_to_dict(job) + durations = job_item.get("durations") or {} + cmd = job_item.get("command") or [] + job_item["job_id"] = job_item.get("id", "") + job_item["image/space"] = job_item.get("docker_image") or "N/A" + job_item["command"] = " ".join(cmd) if cmd else "N/A" + job_item["created"] = job_item["created_at"][:19].replace("T", " ") if job_item.get("created_at") else "N/A" + job_item["status"] = (job_item.get("status") or {}).get("stage", "UNKNOWN") + job_item["runtime"] = format_duration(durations.get("running_secs")) + job_items.append(job_item) + + out.table( + job_items, + headers=["job_id", "image/space", "command", "created", "status", "runtime"], + id_key="job_id", + ) + if truncated: + out.hint(f"Output truncated to {limit} Jobs. Use `--limit 0` to show all (or `--limit N`).") + if not job_items: + if raw_statuses or labels: + filters_msg = ", ".join( + [*(f"status={s}" for s in raw_statuses), *(f"label={k}={v}" for k, v in labels.items())] + ) + out.text(f"No jobs matched filters: {filters_msg}") + elif not all: + out.hint("No running jobs. Use `-a`/`--all` to include finished (and failed) jobs.") + + +@jobs_cli.command("hardware", examples=["hf jobs hardware"]) +def jobs_hardware() -> None: + """List available hardware options for Jobs""" + api = get_hf_api() + hardware_list = api.list_jobs_hardware() + items = [] + for hw in hardware_list: + accelerator_info = "" + if hw.accelerator: + accelerator_info = f"{hw.accelerator.quantity}x {hw.accelerator.model} ({hw.accelerator.vram})" + cost_min = f"${hw.unit_cost_usd:.4f}" if hw.unit_cost_usd else "free" + cost_hour = f"${hw.unit_cost_usd * 60:.2f}" if hw.unit_cost_usd else "free" + items.append( + { + "name": hw.name, + "pretty name": hw.pretty_name, + "cpu": hw.cpu, + "ram": hw.ram, + "storage": hw.ephemeral_storage, + "accelerator": accelerator_info, + "cost/min": cost_min, + "cost/hour": cost_hour, + } + ) + out.table(items) + out.hint("Use `hf jobs run --flavor ...` to request a specific hardware flavor.") + + +@jobs_cli.command("inspect", examples=["hf jobs inspect "]) +def jobs_inspect( + job_ids: Annotated[ + list[str], + Argument( + help="Job IDs to inspect (or 'namespace/job_id')", + ), + ], + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Display detailed information on one or more Jobs""" + parsed_ids = [] + for job_id in job_ids: + job_id, namespace = _parse_namespace_from_job_id(job_id, namespace) + parsed_ids.append(job_id) + job_ids = parsed_ids + api = get_hf_api(token=token) + jobs = [api.inspect_job(job_id=job_id, namespace=namespace) for job_id in job_ids] + out.table([_dataclass_to_dict(job) for job in jobs]) + + +@jobs_cli.command("cancel", examples=["hf jobs cancel "]) +def jobs_cancel( + job_id: JobIdArg, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Cancel a Job""" + job_id, namespace = _parse_namespace_from_job_id(job_id, namespace) + api = get_hf_api(token=token) + api.cancel_job(job_id=job_id, namespace=namespace) + out.result("Job cancelled", id=job_id) + + +@jobs_cli.command( + "wait", + examples=[ + "hf jobs wait ", + "hf jobs wait ", + "hf jobs ls -q | xargs hf jobs wait", + ], +) +def jobs_wait( + job_ids: Annotated[ + list[str], + Argument( + help="Job IDs to wait for (or 'namespace/job_id').", + ), + ], + timeout: Annotated[ + str | None, + Option( + help="Max time to wait: int with s (seconds, default), m (minutes), h (hours) or d (days).", + ), + ] = None, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Wait for one or more Jobs to reach a terminal state. + + Blocks until every Job has finished, then exits with code 0 if all Jobs completed + successfully, or a non-zero exit code if any Job was canceled, errored or deleted. + + All Jobs must belong to the same namespace. + """ + parsed_ids = [] + namespaces = set() + for job_id in job_ids: + parsed_id, parsed_namespace = _parse_namespace_from_job_id(job_id, namespace) + parsed_ids.append(parsed_id) + namespaces.add(parsed_namespace) + if len(namespaces) > 1: + raise CLIError( + "All Job IDs must be in the same namespace, got: " + + ", ".join(str(ns) for ns in sorted(namespaces, key=str)) + ) + namespace = namespaces.pop() + timeout_secs = parse_duration(timeout) if timeout is not None else None + + api = get_hf_api(token=token) + status = out.status(f"Waiting for {len(parsed_ids)} Job(s) to finish...") + try: + jobs = api.wait_for_job(parsed_ids, timeout=timeout_secs, namespace=namespace) + except TimeoutError: + status.done("Timed out.") + raise CLIError(f"Timed out after {timeout} waiting for Job(s) to finish.") from None + status.done(f"{len(jobs)} Job(s) finished.") + + out.table([{"id": job.id, "stage": str(job.status.stage), "message": job.status.message} for job in jobs]) + failed = [job for job in jobs if job.status.stage != JobStage.COMPLETED] + if failed: + raise CLIError( + f"{len(failed)} of {len(jobs)} Job(s) did not complete successfully: " + + ", ".join(f"{job.id} ({job.status.stage})" for job in failed) + ) + + +@jobs_cli.command( + "labels", + examples=[ + "hf jobs labels --label env=prod --label team=ml", + "hf jobs labels --clear", + ], +) +def jobs_labels( + job_id: JobIdArg, + label: LabelsOpt = None, + clear: Annotated[bool, Option("--clear", help="Remove all labels from the job.")] = False, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Update labels on a Job. Replaces all existing labels.""" + if not label and not clear: + raise CLIError("Please set at least one label with --label. To remove all labels, pass --clear.") + if label and clear: + raise CLIError( + "Cannot set labels and clear them at the same time. Please use either --label or --clear, not both." + ) + job_id, namespace = _parse_namespace_from_job_id(job_id, namespace) + labels = _parse_labels_map(label) or {} + api = get_hf_api(token=token) + job = api.update_job_labels(job_id=job_id, labels=labels, namespace=namespace) + out.result("Labels updated", id=job.id) + + +@jobs_cli.command( + "ssh", + examples=[ + "hf jobs ssh ", + "hf jobs ssh --dry-run", + "hf jobs ssh -i ~/.ssh/id_ed25519", + ], +) +def jobs_ssh( + job_id: JobIdArg, + identity_file: SshIdentityFileOpt = None, + dry_run: SshDryRunOpt = False, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """SSH into a running Job. + + If the Job is not yet running, waits until it reaches the RUNNING state before + connecting. Requires the Job to be started with SSH enabled (`hf jobs run --ssh ...`) + and your SSH public key to be registered at https://huggingface.co/settings/keys. + """ + job_id, namespace = _parse_namespace_from_job_id(job_id, namespace) + api = get_hf_api(token=token) + job = api.inspect_job(job_id=job_id, namespace=namespace) + if job.status.ssh_url is None: + raise CLIError("SSH is not enabled on this job. Start a job with SSH support using `hf jobs run --ssh ...`.") + if job.status.stage in TERMINAL_JOB_STAGES: + raise CLIError(f"Cannot SSH into job '{job.id}': job has already finished (stage: '{job.status.stage}').") + if job.status.stage != JobStage.RUNNING: + status = out.status(f"Waiting for job '{job.id}' to be running (stage: '{job.status.stage}')...") + job = api.wait_for_job(job_id=job.id, namespace=namespace, stages=[JobStage.RUNNING]) + if job.status.stage != JobStage.RUNNING: + status.done("Job finished.") + raise CLIError( + f"Cannot SSH into job '{job.id}': job finished before reaching RUNNING (stage: '{job.status.stage}')." + ) + status.done("Job is running.") + ssh_url = urlsplit(job.status.ssh_url) + exec_ssh( + f"{ssh_url.username}@{ssh_url.hostname}", # type: ignore + port=ssh_url.port, + identity_file=identity_file, + dry_run=dry_run, + ) + + +uv_app = typer_factory(help="Run UV scripts (Python with inline dependencies) on HF infrastructure.") +jobs_cli.add_group(uv_app, name="uv") + + +@uv_app.command( + "run", + context_settings={"ignore_unknown_options": True}, + examples=[ + "hf jobs uv run my_script.py", + "hf jobs uv run --detach my_script.py", + "hf jobs uv run ml_training.py --flavor a10g-small", + "hf jobs uv run --with transformers train.py", + "hf jobs uv run -v hf://org/my-model:/data -v hf://buckets/org/b:/mnt script.py", + ], +) +def jobs_uv_run( + script: ScriptArg, + script_args: ScriptArgsArg = None, + image: ImageOpt = None, + flavor: FlavorOpt = None, + env: EnvOpt = None, + secrets: SecretsOpt = None, + label: LabelsOpt = None, + volume: JobVolumesOpt = None, + env_file: EnvFileOpt = None, + secrets_file: SecretsFileOpt = None, + timeout: TimeoutOpt = None, + detach: DetachOpt = False, + expose: ExposeOpt = None, + ssh: SshEnabledOpt = False, + namespace: NamespaceOpt = None, + token: TokenOpt = None, + with_: WithOpt = None, + python: PythonOpt = None, +) -> None: + """Run a UV script (local file or URL) on HF infrastructure""" + env_map = parse_env_map(env, env_file) + secrets_map = parse_env_map(secrets, secrets_file) + + api = get_hf_api(token=token) + job = api.run_uv_job( + script=script, + script_args=script_args or [], + dependencies=with_, + python=python, + image=image, + env=env_map, + secrets=secrets_map, + labels=_parse_labels_map(label), + volumes=_parse_and_sync_job_volumes(volume, api=api, namespace=namespace), + flavor=flavor, + timeout=timeout, + expose=expose, + ssh=ssh, + namespace=namespace, + ) + out.result("Job started", id=job.id, url=job.url) + if isinstance(job.status.expose_urls, list): + urls = "\n".join(f" {url}" for url in job.status.expose_urls) + out.hint(f"Exposed ports are reachable at (requires an HF token with read access to the job):\n{urls}") + if isinstance(job.status.ssh_url, str): + out.hint(f"Use `hf jobs ssh {job.owner.name}/{job.id}` to open an SSH session into the job.") + if detach: + job_ref = f"{job.owner.name}/{job.id}" + out.hint(f"Use `hf jobs logs -f {job_ref}` to stream logs, or `hf jobs inspect {job_ref}` to check status.") + out.hint(f"Use `hf jobs wait {job_ref}` to block until it finishes.") + return + _stream_logs_and_check_status(api, job) + + +scheduled_app = typer_factory(help="Create and manage scheduled Jobs on the Hub.") +jobs_cli.add_group(scheduled_app, name="scheduled") + + +@scheduled_app.command( + "run", + context_settings={"ignore_unknown_options": True}, + examples=['hf jobs scheduled run "0 0 * * *" python:3.12 python script.py'], +) +def scheduled_run( + schedule: ScheduleArg, + image: ImageArg, + command: CommandArg, + suspend: SuspendOpt = None, + concurrency: ConcurrencyOpt = None, + env: EnvOpt = None, + secrets: SecretsOpt = None, + label: LabelsOpt = None, + volume: JobVolumesOpt = None, + env_file: EnvFileOpt = None, + secrets_file: SecretsFileOpt = None, + flavor: FlavorOpt = None, + timeout: TimeoutOpt = None, + expose: ExposeOpt = None, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Schedule a Job.""" + env_map = parse_env_map(env, env_file) + secrets_map = parse_env_map(secrets, secrets_file) + + api = get_hf_api(token=token) + scheduled_job = api.create_scheduled_job( + image=image, + command=command, + schedule=schedule, + suspend=suspend, + concurrency=concurrency, + env=env_map, + secrets=secrets_map, + labels=_parse_labels_map(label), + volumes=_parse_and_sync_job_volumes(volume, api=api, namespace=namespace), + flavor=flavor, + timeout=timeout, + expose=expose, + namespace=namespace, + ) + out.result("Scheduled Job created", id=scheduled_job.id) + out.hint(f"Use `hf jobs scheduled inspect {scheduled_job.id}` to view its details.") + + +@scheduled_app.command("list | ls | ps", examples=["hf jobs scheduled ls"]) +def scheduled_ps( + all: Annotated[ + bool, + Option( + "-a", + "--all", + help="Show all scheduled Jobs (default hides suspended)", + ), + ] = False, + namespace: NamespaceOpt = None, + token: TokenOpt = None, + filter: Annotated[ + list[str] | None, + Option( + "-f", + "--filter", + help="Filter output based on conditions provided (format: key=value)", + ), + ] = None, +) -> None: + """List scheduled Jobs""" + api = get_hf_api(token=token) + scheduled_jobs = api.list_scheduled_jobs(namespace=namespace) + filters: list[tuple[str, str, str]] = [] + for f in filter or []: + if "=" in f: + key, value = f.split("=", 1) + # Negate predicate in case of key!=value + if key.endswith("!"): + op = "!=" + key = key[:-1] + else: + op = "=" + filters.append((key.lower(), op, value.lower())) + else: + out.warning(f"Ignoring invalid filter format '{f}'. Use key=value format.") + + # Filter scheduled jobs (operating on ScheduledJobInfo objects to preserve existing filter behavior) + filtered_jobs = [] + for scheduled_job in scheduled_jobs: + suspend = scheduled_job.suspend or False + if not all and suspend: + continue + image_or_space = scheduled_job.job_spec.docker_image or "N/A" + cmd = scheduled_job.job_spec.command or [] + command_str = " ".join(cmd) if cmd else "N/A" + props = {"id": scheduled_job.id, "image": image_or_space, "suspend": str(suspend), "command": command_str} + if not _matches_filters(props, filters): + continue + filtered_jobs.append(scheduled_job) + + # Build display items. Augment with curated columns. + items: list[dict[str, Any]] = [] + for sj in filtered_jobs: + item = _dataclass_to_dict(sj) + job_spec = item.get("job_spec") or {} + status_dict = item.get("status") or {} + last_job = status_dict.get("last_job") + cmd = job_spec.get("command") or [] + item["image/space"] = job_spec.get("docker_image") or "N/A" + item["command"] = " ".join(cmd) if cmd else "N/A" + item["last_run"] = last_job["at"][:19].replace("T", " ") if last_job and last_job.get("at") else "N/A" + item["next_run"] = ( + status_dict["next_job_run_at"][:19].replace("T", " ") if status_dict.get("next_job_run_at") else "N/A" + ) + item["suspend"] = item.get("suspend") or False + items.append(item) + + out.table( + items, + headers=["id", "schedule", "image/space", "command", "last_run", "next_run", "suspend"], + id_key="id", + ) + if not items and filters: + filters_msg = ", ".join(f"{k}{o}{v}" for k, o, v in filters) + out.text(f"No scheduled jobs matched filters: {filters_msg}") + if items: + first_item_id = items[0]["id"] + out.hint(f"Use `hf jobs scheduled inspect {first_item_id}` to view details about a scheduled job.") + out.hint(f"Use `hf jobs scheduled trigger {first_item_id}` to trigger a scheduled job immediately.") + + +@scheduled_app.command("inspect", examples=["hf jobs scheduled inspect "]) +def scheduled_inspect( + scheduled_job_ids: Annotated[ + list[str], + Argument( + help="Scheduled Job IDs to inspect (or 'namespace/scheduled_job_id')", + ), + ], + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Display detailed information on one or more scheduled Jobs""" + parsed_ids = [] + for job_id in scheduled_job_ids: + job_id, namespace = _parse_namespace_from_job_id(job_id, namespace) + parsed_ids.append(job_id) + scheduled_job_ids = parsed_ids + api = get_hf_api(token=token) + scheduled_jobs = [ + api.inspect_scheduled_job(scheduled_job_id=scheduled_job_id, namespace=namespace) + for scheduled_job_id in scheduled_job_ids + ] + out.table([_dataclass_to_dict(scheduled_job) for scheduled_job in scheduled_jobs]) + + +@scheduled_app.command("delete", examples=["hf jobs scheduled delete "]) +def scheduled_delete( + scheduled_job_id: ScheduledJobIdArg, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Delete a scheduled Job.""" + scheduled_job_id, namespace = _parse_namespace_from_job_id(scheduled_job_id, namespace) + api = get_hf_api(token=token) + api.delete_scheduled_job(scheduled_job_id=scheduled_job_id, namespace=namespace) + out.result("Scheduled Job deleted", id=scheduled_job_id) + + +@scheduled_app.command("suspend", examples=["hf jobs scheduled suspend "]) +def scheduled_suspend( + scheduled_job_id: ScheduledJobIdArg, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Suspend (pause) a scheduled Job.""" + scheduled_job_id, namespace = _parse_namespace_from_job_id(scheduled_job_id, namespace) + api = get_hf_api(token=token) + api.suspend_scheduled_job(scheduled_job_id=scheduled_job_id, namespace=namespace) + out.result("Scheduled Job suspended", id=scheduled_job_id) + out.hint(f"Use `hf jobs scheduled resume {scheduled_job_id}` to resume it.") + + +@scheduled_app.command("resume", examples=["hf jobs scheduled resume "]) +def scheduled_resume( + scheduled_job_id: ScheduledJobIdArg, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Resume (unpause) a scheduled Job.""" + scheduled_job_id, namespace = _parse_namespace_from_job_id(scheduled_job_id, namespace) + api = get_hf_api(token=token) + api.resume_scheduled_job(scheduled_job_id=scheduled_job_id, namespace=namespace) + out.result("Scheduled Job resumed", id=scheduled_job_id) + + +@scheduled_app.command("trigger", examples=["hf jobs scheduled trigger "]) +def scheduled_trigger( + scheduled_job_id: ScheduledJobIdArg, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Trigger a scheduled Job to run immediately (does not change the schedule).""" + scheduled_job_id, namespace = _parse_namespace_from_job_id(scheduled_job_id, namespace) + api = get_hf_api(token=token) + job = api.trigger_scheduled_job(scheduled_job_id=scheduled_job_id, namespace=namespace) + out.result("Scheduled Job triggered", id=job.id, url=job.url) + out.hint(f"Use `hf jobs logs -f {job.owner.name}/{job.id}` to stream logs.") + + +@scheduled_app.command( + "labels", + examples=[ + "hf jobs scheduled labels --label env=prod --label team=ml", + "hf jobs scheduled labels --clear", + ], +) +def scheduled_labels( + scheduled_job_id: ScheduledJobIdArg, + label: LabelsOpt = None, + clear: Annotated[bool, Option("--clear", help="Remove all labels from the scheduled job.")] = False, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Update labels on a scheduled Job. Replaces all existing labels.""" + if not label and not clear: + raise CLIError("Please set at least one label with --label. To remove all labels, pass --clear.") + if label and clear: + raise CLIError( + "Cannot set labels and clear them at the same time. Please use either --label or --clear, not both." + ) + scheduled_job_id, namespace = _parse_namespace_from_job_id(scheduled_job_id, namespace) + labels = _parse_labels_map(label) or {} + api = get_hf_api(token=token) + scheduled_job = api.update_scheduled_job_labels( + scheduled_job_id=scheduled_job_id, labels=labels, namespace=namespace + ) + out.result("Labels updated", id=scheduled_job.id) + + +scheduled_uv_app = typer_factory(help="Schedule UV scripts on HF infrastructure.") +scheduled_app.add_group(scheduled_uv_app, name="uv") + + +@scheduled_uv_app.command( + "run", + context_settings={"ignore_unknown_options": True}, + examples=[ + 'hf jobs scheduled uv run "0 0 * * *" script.py', + 'hf jobs scheduled uv run "0 0 * * *" script.py --with pandas', + ], +) +def scheduled_uv_run( + schedule: ScheduleArg, + script: ScriptArg, + script_args: ScriptArgsArg = None, + suspend: SuspendOpt = None, + concurrency: ConcurrencyOpt = None, + image: ImageOpt = None, + flavor: FlavorOpt = None, + env: EnvOpt = None, + secrets: SecretsOpt = None, + label: LabelsOpt = None, + volume: JobVolumesOpt = None, + env_file: EnvFileOpt = None, + secrets_file: SecretsFileOpt = None, + timeout: TimeoutOpt = None, + expose: ExposeOpt = None, + namespace: NamespaceOpt = None, + token: TokenOpt = None, + with_: WithOpt = None, + python: PythonOpt = None, +) -> None: + """Run a UV script (local file or URL) on HF infrastructure""" + env_map = parse_env_map(env, env_file) + secrets_map = parse_env_map(secrets, secrets_file) + + api = get_hf_api(token=token) + job = api.create_scheduled_uv_job( + script=script, + script_args=script_args or [], + schedule=schedule, + suspend=suspend, + concurrency=concurrency, + dependencies=with_, + python=python, + image=image, + env=env_map, + secrets=secrets_map, + labels=_parse_labels_map(label), + volumes=_parse_and_sync_job_volumes(volume, api=api, namespace=namespace), + flavor=flavor, + timeout=timeout, + expose=expose, + namespace=namespace, + ) + out.result("Scheduled Job created", id=job.id) + out.hint(f"Use `hf jobs scheduled inspect {job.id}` to view its details.") + + +### UTILS + + +def _parse_labels_map(labels: list[str] | None) -> dict[str, str] | None: + """Parse label key-value pairs from CLI arguments. + + Args: + labels: List of label strings in KEY=VALUE format. If KEY only, then VALUE is set to empty string. + + Returns: + Dictionary mapping label keys to values, or None if no labels provided. + """ + if not labels: + return None + labels_map: dict[str, str] = {} + for label_var in labels: + key, value = label_var.split("=", 1) if "=" in label_var else (label_var, "") + labels_map[key] = value + return labels_map + + +def _tabulate(rows: list[list[str | int]], headers: list[str]) -> str: + """ + Inspired by: + + - stackoverflow.com/a/8356620/593036 + - stackoverflow.com/questions/9535954/printing-lists-as-tabular-data + """ + col_widths = [max(len(str(x)) for x in col) for col in zip(*rows, headers)] + terminal_width = max(shutil.get_terminal_size().columns, len(headers) * 12) + while len(headers) + sum(col_widths) > terminal_width: + col_to_minimize = col_widths.index(max(col_widths)) + col_widths[col_to_minimize] //= 2 + if len(headers) + sum(col_widths) <= terminal_width: + col_widths[col_to_minimize] = terminal_width - sum(col_widths) - len(headers) + col_widths[col_to_minimize] + row_format = ("{{:{}}} " * len(headers)).format(*col_widths) + lines = [] + lines.append(row_format.format(*headers)) + lines.append(row_format.format(*["-" * w for w in col_widths])) + for row in rows: + row_format_args = [ + str(x)[: col_width - 3] + "..." if len(str(x)) > col_width else str(x) + for x, col_width in zip(row, col_widths) + ] + lines.append(row_format.format(*row_format_args)) + return "\n".join(lines) + + +T = TypeVar("T") + + +def _write_generator_to_queue(queue: Queue[T], func: Callable[..., Iterable[T]], kwargs: dict) -> None: + for result in func(**kwargs): + queue.put(result) + + +def iflatmap_unordered( + pool: multiprocessing.pool.ThreadPool, + func: Callable[..., Iterable[T]], + *, + kwargs_list: list[dict], +) -> Iterable[T]: + """ + Takes a function that returns an iterable of items, and run it in parallel using threads to return the flattened iterable of items as they arrive. + + This is inspired by those three `map()` variants, and is the mix of all three: + + * `imap()`: like `map()` but returns an iterable instead of a list of results + * `imap_unordered()`: like `imap()` but the output is sorted by time of arrival + * `flatmap()`: like `map()` but given a function which returns a list, `flatmap()` returns the flattened list that is the concatenation of all the output lists + """ + queue: Queue[T] = Queue() + async_results = [pool.apply_async(_write_generator_to_queue, (queue, func, kwargs)) for kwargs in kwargs_list] + try: + while True: + try: + yield queue.get(timeout=0.05) + except Empty: + if all(async_result.ready() for async_result in async_results) and queue.empty(): + break + except KeyboardInterrupt: + pass + finally: + # we get the result in case there's an error to raise + try: + [async_result.get(timeout=0.05) for async_result in async_results] + except multiprocessing.TimeoutError: + pass diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/lfs.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/lfs.py new file mode 100644 index 0000000000000000000000000000000000000000..7b5e8b3ea68e3aabe023e9475e5c97c2fae28209 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/lfs.py @@ -0,0 +1,175 @@ +""" +Implementation of a custom transfer agent for the transfer type "multipart" for +git-lfs. + +Inspired by: +github.com/cbartz/git-lfs-swift-transfer-agent/blob/master/git_lfs_swift_transfer.py + +Spec is: github.com/git-lfs/git-lfs/blob/master/docs/custom-transfers.md + + +To launch debugger while developing: + +``` [lfs "customtransfer.multipart"] +path = /path/to/huggingface_hub/.venv/bin/python args = -m debugpy --listen 5678 +--wait-for-client +/path/to/huggingface_hub/src/huggingface_hub/commands/huggingface_cli.py +lfs-multipart-upload ```""" + +import json +import os +import subprocess +import sys +from typing import Annotated + +from huggingface_hub.errors import CLIError +from huggingface_hub.lfs import LFS_MULTIPART_UPLOAD_COMMAND + +from ..utils import get_session, hf_raise_for_status, logging +from ..utils._lfs import SliceFileObj +from ._framework import Argument +from ._output import out + + +logger = logging.get_logger(__name__) + + +def lfs_enable_largefiles( + path: Annotated[ + str, + Argument( + help="Local path to repository you want to configure.", + ), + ], +) -> None: + """ + Configure your repository to enable upload of files > 5GB. + + This command sets up git-lfs to use the custom multipart transfer agent + which enables efficient uploading of large files in chunks. + """ + local_path = os.path.abspath(path) + if not os.path.isdir(local_path): + raise CLIError("This does not look like a valid git repo.") + subprocess.run( + "git config lfs.customtransfer.multipart.path hf".split(), + check=True, + cwd=local_path, + ) + subprocess.run( + f"git config lfs.customtransfer.multipart.args {LFS_MULTIPART_UPLOAD_COMMAND}".split(), + check=True, + cwd=local_path, + ) + out.result("Local repo set up for largefiles", path=local_path) + + +def write_msg(msg: dict): + """Write out the message in Line delimited JSON.""" + msg_str = json.dumps(msg) + "\n" + sys.stdout.write(msg_str) + sys.stdout.flush() + + +def read_msg() -> dict | None: + """Read Line delimited JSON from stdin.""" + msg = json.loads(sys.stdin.readline().strip()) + + if "terminate" in (msg.get("type"), msg.get("event")): + # terminate message received + return None + + if msg.get("event") not in ("download", "upload"): + logger.critical("Received unexpected message") + sys.exit(1) + + return msg + + +def lfs_multipart_upload() -> None: + """Internal git-lfs custom transfer agent for multipart uploads. + + This function implements the custom transfer protocol for git-lfs multipart uploads. + Handles chunked uploads of large files to Hugging Face Hub. + """ + # Immediately after invoking a custom transfer process, git-lfs + # sends initiation data to the process over stdin. + # This tells the process useful information about the configuration. + init_msg = json.loads(sys.stdin.readline().strip()) + if not (init_msg.get("event") == "init" and init_msg.get("operation") == "upload"): + write_msg({"error": {"code": 32, "message": "Wrong lfs init operation"}}) + sys.exit(1) + + # The transfer process should use the information it needs from the + # initiation structure, and also perform any one-off setup tasks it + # needs to do. It should then respond on stdout with a simple empty + # confirmation structure, as follows: + write_msg({}) + + # After the initiation exchange, git-lfs will send any number of + # transfer requests to the stdin of the transfer process, in a serial sequence. + while True: + msg = read_msg() + if msg is None: + # When all transfers have been processed, git-lfs will send + # a terminate event to the stdin of the transfer process. + # On receiving this message the transfer process should + # clean up and terminate. No response is expected. + sys.exit(0) + + oid = msg["oid"] + filepath = msg["path"] + completion_url = msg["action"]["href"] + header = msg["action"]["header"] + chunk_size = int(header.pop("chunk_size")) + presigned_urls: list[str] = list(header.values()) + + # Send a "started" progress event to allow other workers to start. + # Otherwise they're delayed until first "progress" event is reported, + # i.e. after the first 5GB by default (!) + write_msg( + { + "event": "progress", + "oid": oid, + "bytesSoFar": 1, + "bytesSinceLast": 0, + } + ) + + parts = [] + with open(filepath, "rb") as file: + for i, presigned_url in enumerate(presigned_urls): + with SliceFileObj( + file, + seek_from=i * chunk_size, + read_limit=chunk_size, + ) as data: + r = get_session().put(presigned_url, data=data) + hf_raise_for_status(r) + parts.append( + { + "etag": r.headers.get("etag"), + "partNumber": i + 1, + } + ) + # In order to support progress reporting while data is uploading / downloading, + # the transfer process should post messages to stdout + write_msg( + { + "event": "progress", + "oid": oid, + "bytesSoFar": (i + 1) * chunk_size, + "bytesSinceLast": chunk_size, + } + ) + + r = get_session().post( + completion_url, + json={ + "oid": oid, + "parts": parts, + }, + ) + hf_raise_for_status(r) + + write_msg({"event": "complete", "oid": oid}) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/models.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/models.py new file mode 100644 index 0000000000000000000000000000000000000000..7ba7e10fb43ac766469b1c11cf17cd0a735dabbd --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/models.py @@ -0,0 +1,265 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains commands to interact with models on the Hugging Face Hub.""" + +import enum +from typing import Annotated, get_args + +import click + +from huggingface_hub.errors import CLIError, RepositoryNotFoundError, RevisionNotFoundError +from huggingface_hub.hf_api import ExpandModelProperty_T, ModelSort_T +from huggingface_hub.inference._providers import PROVIDER_T +from huggingface_hub.repocard import ModelCard + +from ._cli_utils import ( + REPO_LIST_DEFAULT_LIMIT, + AuthorOpt, + FilterOpt, + LimitOpt, + RevisionOpt, + SearchOpt, + SoftChoice, + TokenOpt, + get_hf_api, + make_expand_properties_parser, + typer_factory, +) +from ._file_listing import list_repo_files_cmd +from ._framework import Argument, Option +from ._output import _dataclass_to_dict, out + + +_EXPAND_PROPERTIES = sorted(get_args(ExpandModelProperty_T)) +_SORT_OPTIONS = get_args(ModelSort_T) +ModelSortEnum = enum.Enum("ModelSortEnum", {s: s for s in _SORT_OPTIONS}, type=str) # type: ignore[misc] +InferenceProviderEnum = enum.Enum( # type: ignore[misc] + "InferenceProviderEnum", {p: p for p in sorted(get_args(PROVIDER_T))}, type=str +) + + +ExpandOpt = Annotated[ + str | None, + Option( + help=f"Comma-separated properties to return. When used, only the listed properties (and id) are returned. Example: '--expand=downloads,likes,tags'. Valid: {', '.join(_EXPAND_PROPERTIES)}.", + callback=make_expand_properties_parser(_EXPAND_PROPERTIES), + ), +] + + +models_cli = typer_factory(help="Interact with models on the Hub.") + + +@models_cli.command( + "list | ls", + examples=[ + "hf models ls --sort downloads --limit 10", + 'hf models ls --search "llama" --author meta-llama', + "hf models ls --pipeline-tag text-generation --warm", + "hf models ls --num-parameters min:6B,max:128B --sort likes", + "hf models ls --no-gated --author google", + "hf models ls --apps llama.cpp --apps vllm", + "hf models ls --inference-provider fireworks-ai --sort downloads", + "hf models ls --warm --search llama", + "hf models ls meta-llama/Llama-3.2-1B-Instruct", + "hf models ls meta-llama/Llama-3.2-1B-Instruct -R", + "hf models ls meta-llama/Llama-3.2-1B-Instruct --tree -h", + ], +) +def models_ls( + repo_id: Annotated[ + str | None, + Argument(help="Model ID (e.g. `username/repo-name`) to list files from. If omitted, lists models."), + ] = None, + search: SearchOpt = None, + author: AuthorOpt = None, + filter: FilterOpt = None, + pipeline_tag: Annotated[ + str | None, + Option("--pipeline-tag", help="Filter by pipeline tag (canonical task), e.g. 'summarization'."), + ] = None, + gated: Annotated[ + bool | None, + Option( + "--gated/--no-gated", + help="Filter by gated status. '--gated' for gated only, '--no-gated' for non-gated only.", + ), + ] = None, + apps: Annotated[ + list[str] | None, + Option("--apps", help="Filter by app(s) that can run the model, e.g. 'ollama' or 'vllm'."), + ] = None, + num_parameters: Annotated[ + str | None, + Option(help="Filter by parameter count, e.g. 'min:6B,max:128B'."), + ] = None, + inference_provider: Annotated[ + list[str] | None, + Option( + "--inference-provider", + click_type=SoftChoice(InferenceProviderEnum), + help="Filter by inference provider(s) serving the model, e.g. 'fireworks-ai'.", + ), + ] = None, + warm: Annotated[ + bool, + Option("--warm", help="Only list models currently served by at least one inference provider."), + ] = False, + sort: Annotated[ + ModelSortEnum | None, + Option(help="Sort results."), + ] = None, + limit: LimitOpt = REPO_LIST_DEFAULT_LIMIT, + expand: ExpandOpt = None, + human_readable: Annotated[ + bool, + Option("--human-readable", "-h", help="Show sizes in human readable format (only for listing files)."), + ] = False, + as_tree: Annotated[ + bool, + Option("--tree", help="List files in tree format (only for listing files)."), + ] = False, + recursive: Annotated[ + bool, + Option("--recursive", "-R", help="List files recursively (only for listing files)."), + ] = False, + revision: RevisionOpt = None, + token: TokenOpt = None, +) -> None: + """List models on the Hub, or files in a model repo. + + When called with no argument, lists models on the Hub. + When called with a model ID, lists files in that model repo. + """ + if repo_id is not None: + if search is not None: + raise click.BadParameter("Cannot use --search when listing files.") + if author is not None: + raise click.BadParameter("Cannot use --author when listing files.") + if filter is not None: + raise click.BadParameter("Cannot use --filter when listing files.") + if pipeline_tag is not None: + raise click.BadParameter("Cannot use --pipeline-tag when listing files.") + if gated is not None: + raise click.BadParameter("Cannot use --gated/--no-gated when listing files.") + if apps is not None: + raise click.BadParameter("Cannot use --apps when listing files.") + if num_parameters is not None: + raise click.BadParameter("Cannot use --num-parameters when listing files.") + if inference_provider is not None: + raise click.BadParameter("Cannot use --inference-provider when listing files.") + if warm: + raise click.BadParameter("Cannot use --warm when listing files.") + if sort is not None: + raise click.BadParameter("Cannot use --sort when listing files.") + if limit != REPO_LIST_DEFAULT_LIMIT: + raise click.BadParameter("Cannot use --limit when listing files.") + if expand is not None: + raise click.BadParameter("Cannot use --expand when listing files.") + return list_repo_files_cmd( + repo_id=repo_id, + repo_type="model", + human_readable=human_readable, + as_tree=as_tree, + recursive=recursive, + revision=revision, + token=token, + ) + + if as_tree: + raise click.BadParameter("Cannot use --tree when listing models.") + if recursive: + raise click.BadParameter("Cannot use --recursive when listing models.") + if human_readable: + raise click.BadParameter("Cannot use --human-readable when listing models.") + if revision is not None: + raise click.BadParameter("Cannot use --revision when listing models.") + if warm and inference_provider is not None: + raise click.BadParameter("Cannot use --warm together with --inference-provider.") + api = get_hf_api(token=token) + sort_key = sort.value if sort else None + results = [ + _dataclass_to_dict(model_info) + for model_info in api.list_models( + filter=filter, + author=author, + search=search, + pipeline_tag=pipeline_tag, + gated=gated, + apps=apps, + num_parameters=num_parameters, + inference="warm" if warm else None, + inference_provider=inference_provider, + sort=sort_key, + limit=limit, + expand=expand, # type: ignore + ) + ] + out.table(results) + if (inference_provider is not None or warm) and not expand: + out.hint( + "Use `--expand inferenceProviderMapping` to see which provider serves each model and the provider-specific model id." + ) + + +@models_cli.command( + "info", + examples=[ + "hf models info meta-llama/Llama-3.2-1B-Instruct", + "hf models info Qwen/Qwen3.5-9B --expand downloads,likes,tags", + ], +) +def models_info( + model_id: Annotated[str, Argument(help="The model ID (e.g. `username/repo-name`).")], + revision: RevisionOpt = None, + expand: ExpandOpt = None, + token: TokenOpt = None, +) -> None: + """Get info about a model on the Hub.""" + api = get_hf_api(token=token) + try: + info = api.model_info(repo_id=model_id, revision=revision, expand=expand) # type: ignore + except RepositoryNotFoundError as e: + raise CLIError(f"Model '{model_id}' not found.") from e + except RevisionNotFoundError as e: + raise CLIError(f"Revision '{revision}' not found on '{model_id}'.") from e + out.dict(info) + + +@models_cli.command( + "card", + examples=[ + "hf models card google/gemma-4-31B-it", + "hf models card google/gemma-4-31B-it --metadata", + "hf models card google/gemma-4-31B-it --metadata --format json", + "hf models card google/gemma-4-31B-it --text", + ], +) +def models_card( + model_id: Annotated[str, Argument(help="The model ID (e.g. `username/repo-name`).")], + metadata: Annotated[bool, Option("--metadata", help="Output only the metadata from the card.")] = False, + text: Annotated[bool, Option("--text", help="Output only the text body (no metadata).")] = False, + token: TokenOpt = None, +) -> None: + """Get the model card (README) for a model on the Hub.""" + if metadata and text: + raise CLIError("--metadata and --text are mutually exclusive.") + card = ModelCard.load(model_id, token=token) + if metadata: + out.dict(card.data.to_dict()) + elif text: + out.text(card.text) + else: + out.text(card.content) + out.hint(f"Use `hf models card {model_id} --metadata` to extract only the card metadata.") diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/papers.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/papers.py new file mode 100644 index 0000000000000000000000000000000000000000..5f33db0d90c9febdaea8e26186c13aadc6ea3708 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/papers.py @@ -0,0 +1,167 @@ +# Copyright 2025 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains commands to interact with papers on the Hugging Face Hub.""" + +import datetime +import enum +from typing import Annotated, get_args + +from huggingface_hub.errors import CLIError, HfHubHTTPError +from huggingface_hub.hf_api import DailyPapersSort_T + +from ._cli_utils import ( + LimitOpt, + TokenOpt, + get_hf_api, + typer_factory, +) +from ._framework import Argument, Option +from ._output import _dataclass_to_dict, out + + +_SORT_OPTIONS = get_args(DailyPapersSort_T) +PaperSortEnum = enum.Enum("PaperSortEnum", {s: s for s in _SORT_OPTIONS}, type=str) # type: ignore[misc] + + +def _parse_date(value: str | None) -> str | None: + """Parse date option, converting 'today' to current date.""" + if value is None: + return None + if value.lower() == "today": + return datetime.date.today().isoformat() + return value + + +papers_cli = typer_factory(help="Interact with papers on the Hub.") + + +@papers_cli.command( + "list | ls", + examples=[ + "hf papers ls", + "hf papers ls --sort trending", + "hf papers ls --date 2025-01-23", + "hf papers ls --week 2025-W09", + "hf papers ls --submitter akhaliq", + "hf papers ls --format json", + ], +) +def papers_ls( + date: Annotated[ + str | None, + Option( + help="Date in ISO format (YYYY-MM-DD) or 'today'.", + callback=_parse_date, + ), + ] = None, + week: Annotated[ + str | None, + Option(help="ISO week to filter by, e.g. '2025-W09'."), + ] = None, + month: Annotated[ + str | None, + Option(help="Month to filter by in ISO format (YYYY-MM), e.g. '2025-02'."), + ] = None, + submitter: Annotated[ + str | None, + Option(help="Filter by username of the submitter."), + ] = None, + sort: Annotated[ + PaperSortEnum | None, + Option(help="Sort results."), + ] = None, + limit: LimitOpt = 50, + token: TokenOpt = None, +) -> None: + """List daily papers on the Hub.""" + api = get_hf_api(token=token) + sort_key = sort.value if sort else None + results = [] + for paper_info in api.list_daily_papers( + date=date, + week=week, + month=month, + submitter=submitter, + sort=sort_key, + limit=limit, + ): + item = _dataclass_to_dict(paper_info) + submitted_by = item.get("submitted_by") or {} + item["submitted_by_name"] = submitted_by.get("fullname") or submitted_by.get("username") or "" + results.append(item) + out.table( + results, + headers=["id", "title", "upvotes", "comments", "published_at", "submitted_by_name"], + ) + + +@papers_cli.command( + "search", + examples=[ + 'hf papers search "vision language"', + 'hf papers search "attention mechanism" --limit 10', + 'hf papers search "diffusion" --format json', + ], +) +def papers_search( + query: Annotated[str, Argument(help="Search query string.")], + limit: LimitOpt = 20, + token: TokenOpt = None, +) -> None: + """Search papers on the Hub.""" + api = get_hf_api(token=token) + results = [_dataclass_to_dict(paper_info) for paper_info in api.list_papers(query=query, limit=limit)] + out.table(results, headers=["id", "title", "summary", "upvotes", "published_at"]) + + +@papers_cli.command( + "info", + examples=[ + "hf papers info 2601.15621", + ], +) +def papers_info( + paper_id: Annotated[str, Argument(help="The arXiv paper ID (e.g. '2502.08025').")], + token: TokenOpt = None, +) -> None: + """Get info about a paper on the Hub.""" + api = get_hf_api(token=token) + try: + info = api.paper_info(id=paper_id) + except HfHubHTTPError as e: + if e.response.status_code == 404: + raise CLIError(f"Paper '{paper_id}' not found on the Hub.") from e + raise + out.dict(info) + + +@papers_cli.command( + "read", + examples=[ + "hf papers read 2601.15621", + ], +) +def papers_read( + paper_id: Annotated[str, Argument(help="The arXiv paper ID (e.g. '2502.08025').")], + token: TokenOpt = None, +) -> None: + """Read a paper as markdown.""" + api = get_hf_api(token=token) + try: + content = api.read_paper(id=paper_id) + except HfHubHTTPError as e: + if e.response.status_code == 404: + raise CLIError(f"Paper '{paper_id}' not found on the Hub.") from e + raise + out.text(content) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/repo_files.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/repo_files.py new file mode 100644 index 0000000000000000000000000000000000000000..57005845c026a742f67f4985f1a021b02649dcb3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/repo_files.py @@ -0,0 +1,83 @@ +# Copyright 2023-present, the HuggingFace Inc. team. +# +# 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. +"""Legacy `hf repo-files` command. + +Kept for backward compatibility. Users are nudged to use `hf repos delete-files` instead. +""" + +from typing import Annotated + +from ._cli_utils import ( + RepoIdArg, + RepoType, + RepoTypeOpt, + RevisionOpt, + TokenOpt, + get_hf_api, + typer_factory, +) +from ._framework import Argument, Option +from ._output import out + + +repo_files_cli = typer_factory( + help="(Deprecated) Manage files in a repo on the Hub. Use `hf repos delete-files` instead." +) + + +@repo_files_cli.command( + "delete", +) +def repo_files_delete( + repo_id: RepoIdArg, + patterns: Annotated[ + list[str], + Argument( + help="Glob patterns to match files to delete. Based on fnmatch, '*' matches files recursively.", + ), + ], + repo_type: RepoTypeOpt = RepoType.model, + revision: RevisionOpt = None, + commit_message: Annotated[ + str | None, + Option( + help="The summary / title / first line of the generated commit.", + ), + ] = None, + commit_description: Annotated[ + str | None, + Option( + help="The description of the generated commit.", + ), + ] = None, + create_pr: Annotated[ + bool, + Option( + help="Whether to create a new Pull Request for these changes.", + ), + ] = False, + token: TokenOpt = None, +) -> None: + out.warning("`hf repo-files delete` is deprecated. Use `hf repos delete-files` instead.") + api = get_hf_api(token=token) + url = api.delete_files( + delete_patterns=patterns, + repo_id=repo_id, + repo_type=repo_type.value, + revision=revision, + commit_message=commit_message, + commit_description=commit_description, + create_pr=create_pr, + ) + out.result("Files deleted", repo_id=repo_id, commit_url=url) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/repos.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/repos.py new file mode 100644 index 0000000000000000000000000000000000000000..193e3ada122fa08594e6a821cd5f0c04f44e6c9c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/repos.py @@ -0,0 +1,633 @@ +# Copyright 2025 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains commands to interact with repositories on the Hugging Face Hub.""" + +import enum +from typing import Annotated + +import click + +from huggingface_hub import SpaceHardware, SpaceStorage +from huggingface_hub.cli._cli_utils import SoftChoice +from huggingface_hub.errors import CLIError, HfHubHTTPError, RepositoryNotFoundError, RevisionNotFoundError +from huggingface_hub.hf_api import REPO_REGIONS + +from ._city_game import run_city_game +from ._cli_utils import ( + REPO_LIST_DEFAULT_LIMIT, + EnvFileOpt, + EnvOpt, + LimitOpt, + PrivateOpt, + RepoIdArg, + RepoType, + RepoTypeOpt, + RevisionOpt, + SearchOpt, + SecretsFileOpt, + SecretsOpt, + TokenOpt, + VolumesOpt, + env_map_to_key_value_list, + get_hf_api, + parse_env_map, + parse_volumes, + typer_factory, +) +from ._cp import make_cp +from ._file_listing import format_size +from ._framework import Argument, Option +from ._output import OutputFormat, out + + +repos_cli = typer_factory(help="Manage repos on the Hub.") + + +@repos_cli.group_callback(invoke_without_command=True) +def _repos_callback(ctx: click.Context) -> None: + if ctx.info_name == "repo": + out.warning("`hf repo` is deprecated in favor of `hf repos`.") + + +class RepoTypeAll(str, enum.Enum): + model = "model" + dataset = "dataset" + space = "space" + bucket = "bucket" + + +class GatedChoices(str, enum.Enum): + auto = "auto" + manual = "manual" + false = "false" + + +PublicOpt = Annotated[ + bool | None, + Option( + "--public", + help="Whether to make the repo public. Ignored if the repo already exists.", + ), +] + +ProtectedOpt = Annotated[ + bool | None, + Option( + "--protected", + help="Whether to make the Space protected (Spaces only). Ignored if the repo already exists.", + ), +] +SpaceHardwareOpt = Annotated[ + str | None, + Option( + "--flavor", + help="Space hardware flavor (e.g. 'cpu-basic', 't4-medium', 'l4x4'). Only for Spaces.", + click_type=SoftChoice(SpaceHardware), + ), +] + +SpaceStorageOpt = Annotated[ + SpaceStorage | None, + Option( + "--storage", + help="(Deprecated, use volumes instead) Space persistent storage tier ('small', 'medium', or 'large'). Only for Spaces.", + ), +] + +SpaceSleepTimeOpt = Annotated[ + int | None, + Option( + "--sleep-time", + help="Seconds of inactivity before the Space is put to sleep. Use -1 to disable. Only for Spaces.", + ), +] + + +tag_cli = typer_factory(help="Manage tags for a repo on the Hub.") +branch_cli = typer_factory(help="Manage branches for a repo on the Hub.") +repos_cli.add_group(tag_cli, name="tag") +repos_cli.add_group(branch_cli, name="branch") + + +@repos_cli.command( + "list | ls", + examples=[ + "hf repos ls", + "hf repos ls --explore", + "hf repos ls --namespace my-org --search bert", + ], +) +def repo_list( + namespace: Annotated[ + str | None, + Option( + help="Organization name. If not provided, lists repos for the authenticated user.", + ), + ] = None, + repo_type: Annotated[ + RepoTypeAll | None, + Option( + "--type", + "--repo-type", + help="Filter by repository type (model, dataset, space, or bucket).", + ), + ] = None, + search: SearchOpt = None, + limit: LimitOpt = REPO_LIST_DEFAULT_LIMIT, + explore: Annotated[ + bool, + Option("--explore", help="Explore your repos as an interactive 3D city."), + ] = False, + token: TokenOpt = None, +) -> None: + """List all repos (models, datasets, spaces, buckets) with storage info.""" + api = get_hf_api(token=token) + repos = list(api.list_user_repos(namespace=namespace)) + if repo_type is not None: + repos = [r for r in repos if r.type == repo_type.value] + if search is not None: + search_lower = search.lower() + repos = [r for r in repos if search_lower in r.id.lower()] + total = len(repos) + + if explore: + if out.mode == OutputFormat.human: + run_city_game(repos) + return + raise CLIError("Repository exploration is only available in terminal.") + + if limit > 0: + repos = repos[:limit] + items = [ + { + "id": r.id, + "type": r.type, + "updated": r.updated_at.strftime("%Y-%m-%d"), + "visibility": r.visibility, + "storage": format_size(r.storage, human_readable=True), + "%_of_total": f"{r.storage_percent:.1f}%", + } + for r in repos + ] + out.table(items, id_key="id", alignments={"storage": "right", "%_of_total": "right"}) + if limit > 0 and total > limit: + out.hint(f"Showing {limit} of {total} repos. Use `--limit 0` to list all.") + + +@repos_cli.command( + "create", + examples=[ + "hf repos create my-model", + "hf repos create my-dataset --repo-type dataset --private", + "hf repos create my-space --type space --sdk gradio --flavor t4-medium --secrets HF_TOKEN -e THEME=dark --protected", + "hf repos create my-jupyterlab --type space --template SpacesExamples/jupyterlab", + "hf repos create my-space --type space --sdk gradio -v hf://org/my-model:/models -v hf://buckets/org/b:/data", + "hf repos create my-model --region us", + ], +) +def repo_create( + repo_id: RepoIdArg, + repo_type: RepoTypeOpt = RepoType.model, + sdk: Annotated[ + str | None, + Option( + "--sdk", + "--space-sdk", + help="Hugging Face Spaces SDK type. Required when --type is set to 'space'.", + ), + ] = None, + template: Annotated[ + str | None, + Option( + "--template", + help=( + "Create a Space from an official template. Pass a template repo id (e.g. " + "'SpacesExamples/jupyterlab') or its short name (e.g. 'JupyterLab'). List available templates with " + "`hf spaces templates`. Spaces only." + ), + ), + ] = None, + private: PrivateOpt = None, + public: PublicOpt = None, + protected: ProtectedOpt = None, + token: TokenOpt = None, + exist_ok: Annotated[ + bool, + Option( + help="Do not raise an error if repo already exists.", + ), + ] = False, + resource_group_id: Annotated[ + str | None, + Option( + help="Resource group in which to create the repo. Resource groups is only available for Enterprise Hub organizations.", + ), + ] = None, + region: Annotated[ + REPO_REGIONS | None, + Option( + "--region", + help="Cloud region in which to create the repo. Can be one of 'us' or 'eu'. Requires Team plan or above.", + ), + ] = None, + hardware: SpaceHardwareOpt = None, + storage: SpaceStorageOpt = None, + sleep_time: SpaceSleepTimeOpt = None, + secrets: SecretsOpt = None, + secrets_file: SecretsFileOpt = None, + env: EnvOpt = None, + env_file: EnvFileOpt = None, + volume: VolumesOpt = None, +) -> None: + """Create a new repo on the Hub.""" + api = get_hf_api(token=token) + repo_url = api.create_repo( + repo_id=repo_id, + repo_type=repo_type.value, + visibility="private" if private else "public" if public else "protected" if protected else None, # type: ignore [arg-type] + token=token, + exist_ok=exist_ok, + resource_group_id=resource_group_id, + region=region, + space_sdk=sdk, + space_hardware=hardware, + space_storage=storage, + space_sleep_time=sleep_time, + space_secrets=env_map_to_key_value_list(parse_env_map(secrets, secrets_file)), + space_variables=env_map_to_key_value_list(parse_env_map(env, env_file)), + space_volumes=parse_volumes(volume), + space_template=template, + ) + out.result("Repo created", repo_id=repo_url.repo_id, url=str(repo_url)) + + +@repos_cli.command( + "duplicate", + examples=[ + "hf repos duplicate openai/gdpval --type dataset", + "hf repos duplicate multimodalart/dreambooth-training my-dreambooth --type space --flavor l4x4 --secrets HF_TOKEN --private", + "hf repos duplicate org/my-space my-space --type space -v hf://org/my-model:/models -v hf://buckets/org/b:/data", + ], +) +def repo_duplicate( + from_id: RepoIdArg, + to_id: Annotated[ + str | None, + Argument( + help="Destination repo ID (e.g. `myorg/my-copy`). Defaults to your namespace with the same repo name.", + ), + ] = None, + repo_type: RepoTypeOpt = RepoType.model, + private: PrivateOpt = None, + public: PublicOpt = None, + protected: ProtectedOpt = None, + token: TokenOpt = None, + exist_ok: Annotated[ + bool, + Option( + help="Do not raise an error if repo already exists.", + ), + ] = False, + hardware: SpaceHardwareOpt = None, + storage: SpaceStorageOpt = None, + sleep_time: SpaceSleepTimeOpt = None, + secrets: SecretsOpt = None, + secrets_file: SecretsFileOpt = None, + env: EnvOpt = None, + env_file: EnvFileOpt = None, + volume: VolumesOpt = None, +) -> None: + """Duplicate a repo on the Hub (model, dataset, or Space).""" + api = get_hf_api(token=token) + repo_url = api.duplicate_repo( + from_id=from_id, + to_id=to_id, + repo_type=repo_type.value, + visibility="private" if private else "public" if public else "protected" if protected else None, # type: ignore [arg-type] + token=token, + exist_ok=exist_ok, + space_hardware=hardware, + space_storage=storage, + space_sleep_time=sleep_time, + space_secrets=env_map_to_key_value_list(parse_env_map(secrets, secrets_file)), + space_variables=env_map_to_key_value_list(parse_env_map(env, env_file)), + space_volumes=parse_volumes(volume), + ) + out.result("Repo duplicated", from_id=from_id, to_id=repo_url.repo_id, url=str(repo_url)) + + +@repos_cli.command("delete", examples=["hf repos delete my-model"]) +def repo_delete( + repo_id: RepoIdArg, + repo_type: RepoTypeOpt = RepoType.model, + token: TokenOpt = None, + missing_ok: Annotated[ + bool, + Option( + help="If set to True, do not raise an error if repo does not exist.", + ), + ] = False, + yes: Annotated[ + bool, + Option( + "-y", + "--yes", + help="Answer Yes to prompt automatically.", + ), + ] = False, +) -> None: + """Delete a repo from the Hub. This is an irreversible operation.""" + out.confirm(f"You are about to permanently delete {repo_type.value} '{repo_id}'. Proceed?", yes=yes) + api = get_hf_api(token=token) + api.delete_repo( + repo_id=repo_id, + repo_type=repo_type.value, + missing_ok=missing_ok, + ) + out.result("Repo deleted", repo_id=repo_id) + + +@repos_cli.command("move", examples=["hf repos move old-namespace/my-model new-namespace/my-model"]) +def repo_move( + from_id: RepoIdArg, + to_id: RepoIdArg, + token: TokenOpt = None, + repo_type: RepoTypeOpt = RepoType.model, +) -> None: + """Move a repository from a namespace to another namespace.""" + api = get_hf_api(token=token) + api.move_repo( + from_id=from_id, + to_id=to_id, + repo_type=repo_type.value, + ) + out.result("Repo moved", from_id=from_id, to_id=to_id) + + +@repos_cli.command( + "settings", + examples=[ + "hf repos settings my-model --private", + "hf repos settings my-model --gated auto", + "hf repos settings my-space --repo-type space --protected", + ], +) +def repo_settings( + repo_id: RepoIdArg, + gated: Annotated[ + GatedChoices | None, + Option( + help="The gated status for the repository.", + ), + ] = None, + private: PrivateOpt = None, + public: PublicOpt = None, + protected: ProtectedOpt = None, + token: TokenOpt = None, + repo_type: RepoTypeOpt = RepoType.model, +) -> None: + """Update the settings of a repository.""" + api = get_hf_api(token=token) + api.update_repo_settings( + repo_id=repo_id, + gated=(None if gated is None else False if gated is GatedChoices.false else gated.value), + visibility="private" if private else "public" if public else "protected" if protected else None, # type: ignore [arg-type] + repo_type=repo_type.value, + ) + out.result("Repo settings updated", repo_id=repo_id) + + +@repos_cli.command( + "delete-files", + examples=[ + "hf repos delete-files my-model file.txt", + 'hf repos delete-files my-model "*.json"', + "hf repos delete-files my-model folder/", + ], +) +def repo_delete_files( + repo_id: RepoIdArg, + patterns: Annotated[ + list[str], + Argument( + help="Glob patterns to match files to delete. Based on fnmatch, '*' matches files recursively.", + ), + ], + repo_type: RepoTypeOpt = RepoType.model, + revision: RevisionOpt = None, + commit_message: Annotated[ + str | None, + Option( + help="The summary / title / first line of the generated commit.", + ), + ] = None, + commit_description: Annotated[ + str | None, + Option( + help="The description of the generated commit.", + ), + ] = None, + create_pr: Annotated[ + bool, + Option( + help="Whether to create a new Pull Request for these changes.", + ), + ] = False, + token: TokenOpt = None, +) -> None: + """Delete files from a repo on the Hub.""" + api = get_hf_api(token=token) + url = api.delete_files( + delete_patterns=patterns, + repo_id=repo_id, + repo_type=repo_type.value, + revision=revision, + commit_message=commit_message, + commit_description=commit_description, + create_pr=create_pr, + ) + out.result("Files deleted", repo_id=repo_id, commit_url=url) + + +# `hf repos cp` is an alias for the top-level `hf cp` command (see `cli/_cp.py`). +repos_cli.command( + name="cp", + examples=[ + # Download (repo or bucket -> local / stdout) + "hf repos cp hf://username/my-model/config.json config.json", + "hf repos cp hf://datasets/username/my-dataset/data.csv data/", + "hf repos cp hf://username/my-model/config.json -", + # Upload (local / stdin -> repo) + "hf repos cp model.safetensors hf://username/my-model/model.safetensors", + "hf repos cp config.json hf://username/my-model/logs/", + "hf repos cp - hf://username/my-model/config.json", + # Remote to remote (repo -> repo) + "hf repos cp hf://username/source-model/config.json hf://username/dest-model/config.json", + "hf repos cp hf://datasets/username/my-dataset/processed/ hf://datasets/username/dest-dataset/processed/", + "hf repos cp hf://username/my-model/logs/ hf://username/archive-model/logs/", + ], +)(make_cp("repos")) + + +@branch_cli.command( + "create", + examples=[ + "hf repos branch create my-model dev", + "hf repos branch create my-model dev --revision abc123", + ], +) +def branch_create( + repo_id: RepoIdArg, + branch: Annotated[ + str, + Argument( + help="The name of the branch to create.", + ), + ], + revision: RevisionOpt = None, + token: TokenOpt = None, + repo_type: RepoTypeOpt = RepoType.model, + exist_ok: Annotated[ + bool, + Option( + help="If set to True, do not raise an error if branch already exists.", + ), + ] = False, +) -> None: + """Create a new branch for a repo on the Hub.""" + api = get_hf_api(token=token) + api.create_branch( + repo_id=repo_id, + branch=branch, + revision=revision, + repo_type=repo_type.value, + exist_ok=exist_ok, + ) + out.result("Branch created", branch=branch, repo_type=repo_type.value, repo_id=repo_id) + + +@branch_cli.command("delete", examples=["hf repos branch delete my-model dev"]) +def branch_delete( + repo_id: RepoIdArg, + branch: Annotated[ + str, + Argument( + help="The name of the branch to delete.", + ), + ], + token: TokenOpt = None, + repo_type: RepoTypeOpt = RepoType.model, +) -> None: + """Delete a branch from a repo on the Hub.""" + api = get_hf_api(token=token) + api.delete_branch( + repo_id=repo_id, + branch=branch, + repo_type=repo_type.value, + ) + out.result("Branch deleted", branch=branch, repo_type=repo_type.value, repo_id=repo_id) + + +@tag_cli.command( + "create", + examples=[ + "hf repos tag create my-model v1.0", + 'hf repos tag create my-model v1.0 -m "First release"', + ], +) +def tag_create( + repo_id: RepoIdArg, + tag: Annotated[ + str, + Argument( + help="The name of the tag to create.", + ), + ], + message: Annotated[ + str | None, + Option( + "-m", + "--message", + help="The description of the tag to create.", + ), + ] = None, + revision: RevisionOpt = None, + token: TokenOpt = None, + repo_type: RepoTypeOpt = RepoType.model, +) -> None: + """Create a tag for a repo.""" + repo_type_str = repo_type.value + api = get_hf_api(token=token) + try: + api.create_tag(repo_id=repo_id, tag=tag, tag_message=message, revision=revision, repo_type=repo_type_str) + except RepositoryNotFoundError as e: + raise CLIError(f"{repo_type_str.capitalize()} '{repo_id}' not found.") from e + except RevisionNotFoundError as e: + raise CLIError(f"Revision '{revision}' not found.") from e + except HfHubHTTPError as e: + if e.response.status_code == 409: + raise CLIError(f"Tag '{tag}' already exists on '{repo_id}'.") from e + raise + out.result("Tag created", tag=tag, repo_type=repo_type_str, repo_id=repo_id) + + +@tag_cli.command("list | ls", examples=["hf repos tag list my-model"]) +def tag_list( + repo_id: RepoIdArg, + token: TokenOpt = None, + repo_type: RepoTypeOpt = RepoType.model, +) -> None: + """List tags for a repo.""" + repo_type_str = repo_type.value + api = get_hf_api(token=token) + try: + refs = api.list_repo_refs(repo_id=repo_id, repo_type=repo_type_str) + except RepositoryNotFoundError as e: + raise CLIError(f"{repo_type_str.capitalize()} '{repo_id}' not found.") from e + items = [{"name": t.name, "target_commit": t.target_commit, "ref": t.ref} for t in refs.tags] + out.table(items) + + +@tag_cli.command("delete", examples=["hf repos tag delete my-model v1.0"]) +def tag_delete( + repo_id: RepoIdArg, + tag: Annotated[ + str, + Argument( + help="The name of the tag to delete.", + ), + ], + yes: Annotated[ + bool, + Option( + "-y", + "--yes", + help="Answer Yes to prompt automatically", + ), + ] = False, + token: TokenOpt = None, + repo_type: RepoTypeOpt = RepoType.model, +) -> None: + """Delete a tag for a repo.""" + repo_type_str = repo_type.value + out.text(f"You are about to delete tag {tag} on {repo_type_str} {repo_id}") + out.confirm("Proceed?", yes=yes) + api = get_hf_api(token=token) + try: + api.delete_tag(repo_id=repo_id, tag=tag, repo_type=repo_type_str) + except RepositoryNotFoundError as e: + raise CLIError(f"{repo_type_str.capitalize()} '{repo_id}' not found.") from e + except RevisionNotFoundError as e: + raise CLIError(f"Tag '{tag}' not found on '{repo_id}'.") from e + out.result("Tag deleted", tag=tag, repo_type=repo_type_str, repo_id=repo_id) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/sandbox.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/sandbox.py new file mode 100644 index 0000000000000000000000000000000000000000..e147bf22820b85c8a9d7367ed0212fb065159ef8 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/sandbox.py @@ -0,0 +1,480 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains commands to run and manage sandboxes on Hugging Face Jobs.""" + +import sys +import time +from contextlib import contextmanager +from typing import Annotated, Any, Iterator + +import click + +from huggingface_hub._sandbox import ( + DEFAULT_IDLE_TIMEOUT, + DEFAULT_IMAGE, + DEFAULT_SANDBOXES_PER_HOST, + MODE_LABEL, + MODE_POOL, + POOL_LABEL, + SANDBOX_LABEL, + SHARED_ID_SEP, + Sandbox, + SandboxPool, + SandboxProcess, + _split_sandbox_id, +) +from huggingface_hub._sandbox_cache import delete_pool_cache +from huggingface_hub.errors import CLIError, SandboxError + +from ._cli_utils import ( + EnvFileOpt, + EnvOpt, + SecretsFileOpt, + SecretsOpt, + TokenOpt, + VolumesOpt, + get_hf_api, + parse_env_map, + parse_volumes, + typer_factory, +) +from ._framework import Argument, Option +from ._output import out +from .jobs import FlavorOpt, NamespaceOpt + + +sandbox_cli = typer_factory(help="Run and manage sandboxes on Hugging Face Jobs.") +pool_cli = typer_factory(help="Warm pools of host VMs and spawn cheap shared sandboxes from them.") +sandbox_cli.add_group(pool_cli, name="pool") +process_cli = typer_factory(help="List and stop background processes running in a sandbox.") +sandbox_cli.add_group(process_cli, name="process") + +SandboxIdArg = Annotated[str, Argument(help="The sandbox id as printed by `hf sandbox create`.")] + + +@contextmanager +def _connect(sandbox_id: str, *, namespace: str | None, token: str | None) -> Iterator[Sandbox]: + """Reattach to a sandbox and close the HTTP client when the command is done.""" + sandbox = Sandbox.connect(sandbox_id, namespace=namespace, token=token) + try: + yield sandbox + finally: + sandbox.close() + + +@sandbox_cli.command( + "create", + examples=[ + "hf sandbox create", + "hf sandbox create ubuntu:24.04", + "hf sandbox create --flavor a10g-small", + "hf sandbox create --pool pool-ab12cd34ef56 --env LOG_LEVEL=debug", + ], +) +def sandbox_create( + image: Annotated[str | None, Argument(help="Docker image (needs /bin/sh).")] = None, + pool: Annotated[ + str | None, + Option("--pool", help="Spawn a cheap shared sandbox in this pool (from `hf sandbox pool create`)."), + ] = None, + flavor: FlavorOpt = None, + idle_timeout: Annotated[ + str | None, + Option(help="Auto-terminate the sandbox after this much inactivity (e.g. '10m'). Defaults to 10m."), + ] = None, + env: EnvOpt = None, + secrets: SecretsOpt = None, + env_file: EnvFileOpt = None, + secrets_file: SecretsFileOpt = None, + volume: VolumesOpt = None, + namespace: NamespaceOpt = None, + forward_hf_token: Annotated[ + bool, Option("--forward-hf-token", help="Inject your HF token as HF_TOKEN in the sandbox.") + ] = False, + token: TokenOpt = None, +) -> None: + """Create a sandbox: a dedicated VM by default, or a cheap shared one with `--pool`. + + Env and idle-timeout apply to the sandbox in both modes. With `--pool`, the image and + flavor come from the pool, so passing them here is an error; `--secrets` is also + rejected since pooled sandboxes have no encrypted-secrets channel (use `--env`). Define + a pool first with `hf sandbox pool create`. + """ + start = time.time() + idle = idle_timeout if idle_timeout is not None else DEFAULT_IDLE_TIMEOUT + + if pool is not None: + if image is not None or flavor is not None or volume: + raise CLIError("--pool fixes the image/flavor (and volumes aren't supported); drop those options.") + if secrets or secrets_file: + raise CLIError("--pool can't encrypt secrets; pass them with --env/--env-file instead.") + sbx = SandboxPool.connect(pool, namespace=namespace, token=token).create( + env=parse_env_map(env, env_file), + idle_timeout=idle, + forward_hf_token=forward_hf_token, + ) + out.result("Sandbox ready", id=sbx.id, host=sbx.host_id, pool=pool, elapsed=f"{time.time() - start:.1f}s") + out.hint(f"Run a command with `hf sandbox exec {sbx.id} -- echo hello`.") + out.hint(f"Terminate it with `hf sandbox kill {sbx.id}`.") + return + + sandbox = Sandbox.create( + image=image or DEFAULT_IMAGE, + flavor=flavor or "cpu-basic", + idle_timeout=idle, + env=parse_env_map(env, env_file), + secrets=parse_env_map(secrets, secrets_file), + volumes=parse_volumes(volume), + namespace=namespace, + forward_hf_token=forward_hf_token, + token=token, + ) + # Release the HTTP client (the sandbox keeps running) + sandbox.close() + out.result("Sandbox ready", id=sandbox.id, image=sandbox.image, elapsed=f"{time.time() - start:.1f}s") + out.hint(f"Run a command with `hf sandbox exec {sandbox.id} -- echo hello`.") + out.hint(f"Terminate it with `hf sandbox kill {sandbox.id}`.") + + +@sandbox_cli.command( + "exec", + context_settings={"ignore_unknown_options": True}, + examples=[ + 'hf sandbox exec -- python -c "print(42)"', + "hf sandbox exec -w /app -- pytest -x", + ], +) +def sandbox_exec( + sandbox_id: SandboxIdArg, + command: Annotated[list[str], Argument(help="The command to run.")], + workdir: Annotated[str | None, Option("-w", "--workdir", help="Working directory.")] = None, + env: EnvOpt = None, + env_file: EnvFileOpt = None, + exec_timeout: Annotated[ + float | None, Option("--timeout", help="Kill the command after this many seconds.") + ] = None, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Run a command in a sandbox, streaming output. Exits with the command's exit code. + + To start a long-running command in the background instead of waiting for it, use + `hf sandbox spawn`. + """ + + def write_stdout(data: str) -> None: + sys.stdout.write(data) + sys.stdout.flush() + + def write_stderr(data: str) -> None: + sys.stderr.write(data) + sys.stderr.flush() + + with _connect(sandbox_id, namespace=namespace, token=token) as sandbox: + result = sandbox.run( + list(command), + env=parse_env_map(env, env_file), + cwd=workdir, + timeout=exec_timeout, + on_stdout=write_stdout, + on_stderr=write_stderr, + check=False, + ) + if result.timed_out: + out.error(f"Command timed out after {exec_timeout}s.") + raise click.exceptions.Exit(code=result.exit_code or 124) # 124: conventional timeout exit code + if result.exit_code != 0: + raise click.exceptions.Exit(code=result.exit_code if result.exit_code is not None else 1) + + +@sandbox_cli.command( + "spawn", + context_settings={"ignore_unknown_options": True}, + examples=[ + "hf sandbox spawn -- python -m http.server 8000", + "hf sandbox spawn -w /app -- uvicorn app:app", + ], +) +def sandbox_spawn( + sandbox_id: SandboxIdArg, + command: Annotated[list[str], Argument(help="The command to run in the background.")], + workdir: Annotated[str | None, Option("-w", "--workdir", help="Working directory.")] = None, + env: EnvOpt = None, + env_file: EnvFileOpt = None, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Start a long-running command in the background and return its pid (don't wait). + + List a sandbox's processes with `hf sandbox process ls` and stop one with + `hf sandbox process kill`. + """ + with _connect(sandbox_id, namespace=namespace, token=token) as sandbox: + process = sandbox.run(list(command), env=parse_env_map(env, env_file), cwd=workdir, background=True) + out.result("Process started", sandbox=sandbox_id, pid=process.pid) + out.hint(f"List processes with `hf sandbox process ls {sandbox_id}`.") + out.hint(f"Stop it with `hf sandbox process kill {sandbox_id} {process.pid}`.") + + +@sandbox_cli.command( + "cp", + examples=[ + "hf sandbox cp data.csv :/data/data.csv", + "hf sandbox cp :/app/result.json result.json", + ], +) +def sandbox_cp( + src: Annotated[str, Argument(help="Source: a local path or :.")], + dst: Annotated[str, Argument(help="Destination: a local path or :.")], + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Copy a file between the local machine and a sandbox (docker-style).""" + + def parse(ref: str) -> tuple[str | None, str]: + # Only treat as a sandbox ref when the part before ':' looks like a sandbox id + # (more than one char): this leaves local paths and Windows drive letters like + # 'C:\data\file.csv' or 'C:/data/file.csv' (single-letter prefix) untouched. + if ":" in ref and not ref.startswith((".", "/", "~")): + sandbox_id, path = ref.split(":", 1) + if len(sandbox_id) > 1: + return sandbox_id, path + return None, ref + + src_sandbox, src_path = parse(src) + dst_sandbox, dst_path = parse(dst) + if (src_sandbox is None) == (dst_sandbox is None): + raise CLIError("Exactly one of SRC and DST must be a sandbox path (:).") + if src_sandbox is not None: + with _connect(src_sandbox, namespace=namespace, token=token) as sandbox: + sandbox.files.download(src_path, dst_path) + else: + assert dst_sandbox is not None + with _connect(dst_sandbox, namespace=namespace, token=token) as sandbox: + sandbox.files.upload(src_path, dst_path) + out.result("Copied", src=src, dst=dst) + + +@sandbox_cli.command( + "kill", + examples=[ + "hf sandbox kill ", + "hf sandbox kill # kills a whole shared host (all its sandboxes)", + "hf sandbox kill --all", + ], +) +def sandbox_kill( + sandbox_id: Annotated[str | None, Argument(help="The sandbox or host id to terminate.")] = None, + all_: Annotated[bool, Option("--all", help="Terminate every sandbox and host in the namespace.")] = False, + yes: Annotated[bool, Option("-y", "--yes", help="Answer Yes to prompts automatically.")] = False, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Terminate a sandbox, a whole shared host, or everything (--all).""" + api = get_hf_api(token=token) + + if all_: + jobs = list(api.list_jobs(status=["RUNNING", "SCHEDULING"], labels={SANDBOX_LABEL: "1"}, namespace=namespace)) + if not jobs: + out.text("No running sandboxes.") + return + out.confirm(f"Terminate {len(jobs)} sandbox job(s) (including shared hosts and all their sandboxes)?", yes=yes) + for job in jobs: + api.cancel_job(job_id=job.id, namespace=job.owner.name) + out.result("Terminated", jobs=len(jobs)) + return + + if sandbox_id is None: + raise CLIError("Provide a sandbox id, a host id, or --all.") + + sid, ns = _split_sandbox_id(sandbox_id, namespace) + if SHARED_ID_SEP in sid: + # One shared sandbox: remove it from its host (frees a slot; host keeps running). + try: + with _connect(sandbox_id, namespace=namespace, token=token) as sandbox: + sandbox.kill() + except SandboxError as e: + raise CLIError(str(e)) from e + out.result("Sandbox terminated", id=sandbox_id) + return + + # A bare id: either a dedicated sandbox job or a shared host job. + job = api.inspect_job(job_id=sid, namespace=ns) + if (job.labels or {}).get(MODE_LABEL) == MODE_POOL: + out.confirm(f"Terminate shared host {sid} and all of its sandboxes?", yes=yes) + api.cancel_job(job_id=job.id, namespace=job.owner.name) + out.result("Host terminated", id=sid) + return + try: + with _connect(sandbox_id, namespace=namespace, token=token) as sandbox: + sandbox.kill() + except SandboxError as e: + raise CLIError(str(e)) from e + out.result("Sandbox terminated", id=sandbox_id) + + +@pool_cli.command( + "create", + examples=[ + "hf sandbox pool create", + "hf sandbox pool create python:3.12 --flavor cpu-basic", + "hf sandbox pool create --per-host 50 --idle-timeout 30m", + ], +) +def pool_create( + image: Annotated[str | None, Argument(help="Docker image for the hosts (needs /bin/sh).")] = None, + flavor: FlavorOpt = None, + per_host: Annotated[ + int, + Option("--per-host", min=1, help=f"Sandboxes packed per host VM (default {DEFAULT_SANDBOXES_PER_HOST})."), + ] = DEFAULT_SANDBOXES_PER_HOST, + max_hosts: Annotated[ + int | None, Option("--max-hosts", min=1, help="Optional cap on the number of host VMs.") + ] = None, + idle_timeout: Annotated[ + str | None, + Option(help="Shut a host down once it has had no sandboxes for this long (e.g. '10m'). Defaults to 10m."), + ] = None, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Warm a pool: boot one host VM now, tagged so it can be found later by its pool id.""" + start = time.time() + image = image or DEFAULT_IMAGE + pool = SandboxPool( + image=image, + flavor=flavor or "cpu-basic", + sandboxes_per_host=per_host, + max_hosts=max_hosts, + idle_timeout=idle_timeout if idle_timeout is not None else DEFAULT_IDLE_TIMEOUT, + namespace=namespace, + token=token, + ) + pool_id = pool.name + host_ids = pool.host_ids + out.result( + "Pool created", + id=pool_id, + image=image, + flavor=flavor or "cpu-basic", + host=host_ids[0], + elapsed=f"{time.time() - start:.1f}s", + ) + out.hint(f"Spawn a sandbox with `hf sandbox create --pool {pool_id}`.") + out.hint(f"Delete the pool (and its hosts) with `hf sandbox pool delete {pool_id}`.") + + +@pool_cli.command("ls | list", examples=["hf sandbox pool ls"]) +def pool_ls( + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """List running sandbox pools (grouped from their host VMs).""" + api = get_hf_api(token=token) + pools: dict[str, dict[str, Any]] = {} + for job in api.list_jobs(status="RUNNING", labels={MODE_LABEL: MODE_POOL}, namespace=namespace): + pid = (job.labels or {}).get(POOL_LABEL) + if not pid: + continue + env = job.environment if isinstance(job.environment, dict) else {} + info = pools.setdefault( + pid, + { + "id": pid, + "image": job.docker_image or job.space_id, + "flavor": job.flavor, + "per_host": env.get("SBX_CAPACITY", ""), + "hosts": 0, + }, + ) + info["hosts"] += 1 + rows = list(pools.values()) + out.table(rows, id_key="id") + if not rows: + out.hint("Create one with `hf sandbox pool create`.") + else: + out.hint("Spawn a sandbox with `hf sandbox create --pool `.") + + +@pool_cli.command( + "delete | rm", + examples=["hf sandbox pool delete "], +) +def pool_delete( + pool_id: Annotated[str, Argument(help="Pool id to delete.")], + yes: Annotated[bool, Option("-y", "--yes", help="Answer Yes to prompts automatically.")] = False, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Terminate every host VM of a pool (and therefore all its sandboxes).""" + api = get_hf_api(token=token) + hosts = list( + api.list_jobs( + status=["RUNNING", "SCHEDULING"], + labels={MODE_LABEL: MODE_POOL, POOL_LABEL: pool_id}, + namespace=namespace, + ) + ) + if not hosts: + delete_pool_cache(pool_id) + out.text(f"No running hosts for pool '{pool_id}'.") + return + out.confirm(f"Terminate {len(hosts)} host(s) of pool '{pool_id}' (and all their sandboxes)?", yes=yes) + for job in hosts: + api.cancel_job(job_id=job.id, namespace=job.owner.name) + delete_pool_cache(pool_id) + out.result("Pool deleted", id=pool_id, hosts_terminated=len(hosts)) + + +def _fmt_cmd(cmd: str | list[str]) -> str: + return cmd if isinstance(cmd, str) else " ".join(cmd) + + +def _fmt_status(process: SandboxProcess) -> str: + if process.running: + return "running" + return "exited" if process.exit_code is None else f"exited ({process.exit_code})" + + +@process_cli.command("ls | list", examples=["hf sandbox process ls "]) +def process_ls( + sandbox_id: SandboxIdArg, + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """List the background processes running in a sandbox (started with `hf sandbox spawn`).""" + with _connect(sandbox_id, namespace=namespace, token=token) as sandbox: + processes = sandbox.processes() + rows = [{"pid": p.pid, "status": _fmt_status(p), "cmd": _fmt_cmd(p.cmd)} for p in processes] + out.table(rows, id_key="pid") + if not rows: + out.hint(f"Start one with `hf sandbox spawn {sandbox_id} -- `.") + else: + out.hint(f"Stop one with `hf sandbox process kill {sandbox_id} `.") + + +@process_cli.command("kill", examples=["hf sandbox process kill "]) +def process_kill( + sandbox_id: SandboxIdArg, + pid: Annotated[int, Argument(help="The pid as printed by `hf sandbox process ls`.")], + namespace: NamespaceOpt = None, + token: TokenOpt = None, +) -> None: + """Stop a background process running in a sandbox.""" + with _connect(sandbox_id, namespace=namespace, token=token) as sandbox: + process = next((p for p in sandbox.processes() if p.pid == pid), None) + if process is None: + raise CLIError(f"No process with pid {pid} in sandbox {sandbox_id}.") + process.kill() + out.result("Process stopped", sandbox=sandbox_id, pid=pid) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/skills.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/skills.py new file mode 100644 index 0000000000000000000000000000000000000000..df433dcdc3b35520da1e8a2f92501b8aa556c4dc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/skills.py @@ -0,0 +1,511 @@ +# Copyright 2025 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains commands to manage skills for AI assistants.""" + +import os +import shutil +from pathlib import Path +from typing import Annotated + +from click import Command, Context, Group + +from huggingface_hub.errors import CLIError + +from ..utils import disable_progress_bars +from . import _skills +from ._cli_utils import TokenOpt, _has_local_formatting_option, get_hf_api, typer_factory +from ._framework import Argument, Option +from ._output import out +from ._skills import DEFAULT_SKILL_ID + + +_SKILL_DESCRIPTION = ( + "Hugging Face Hub CLI (`hf`) for downloading, uploading, and managing" + " models, datasets, spaces, buckets, repos, papers, jobs, and more on the Hugging Face Hub." + " Use when: handling authentication;" + " managing local cache;" + " managing Hugging Face Buckets;" + " running or scheduling jobs on Hugging Face infrastructure;" + " managing Hugging Face repos;" + " discussions and pull requests;" + " browsing models, datasets and spaces;" + " reading, searching, or browsing academic papers;" + " managing collections;" + " querying datasets;" + " configuring spaces;" + " setting up webhooks;" + " or deploying and managing HF Inference Endpoints." + " Make sure to use this skill whenever the user mentions" + " 'hf', 'huggingface', 'Hugging Face', 'huggingface-cli', or 'hugging face cli'," + " or wants to do anything related to the Hugging Face ecosystem and to AI and ML in general." + " Also use for cloud storage needs like training checkpoints, data pipelines, or agent traces." + " Use even if the user doesn't explicitly ask for a CLI command." + " Replaces the deprecated `huggingface-cli`." +) + +_SKILL_YAML_PREFIX = f"""\ +--- +name: hf-cli +description: "{_SKILL_DESCRIPTION}" +--- + +Install: `curl -LsSf https://hf.co/cli/install.sh | bash -s`. + +The Hugging Face Hub CLI tool `hf` is available. IMPORTANT: The `hf` command replaces the deprecated `huggingface-cli` command. + +Use `hf --help` to view available functions. Note that auth commands are now all under `hf auth` e.g. `hf auth whoami`. +""" + +_SKILL_TIPS = """ +## Mounting repos as local filesystems + +To mount Hub repositories or buckets as local filesystems — no download, no copy, no waiting — use `hf-mount`. Files are fetched on demand. GitHub: https://github.com/huggingface/hf-mount + +Install: `curl -fsSL https://raw.githubusercontent.com/huggingface/hf-mount/main/install.sh | sh` + +Some command examples: +- `hf-mount start repo openai-community/gpt2 /tmp/gpt2` — mount a repo (read-only) +- `hf-mount start --hf-token $HF_TOKEN bucket myuser/my-bucket /tmp/data` — mount a bucket (read-write) +- `hf-mount status` / `hf-mount stop /tmp/data` — list or unmount + +## Tips + +- Use `hf --help` for full options, descriptions, usage, and real-world examples +- Authenticate with `HF_TOKEN` env var (recommended) or with `--token` +- Update the CLI with `hf update` (uses the correct command for the detected install method) +""" + +CENTRAL_LOCAL = Path(".agents/skills") +CENTRAL_GLOBAL = Path("~/.agents/skills") +CLAUDE_LOCAL = Path(".claude/skills") +CLAUDE_GLOBAL = Path("~/.claude/skills") +# Flags worth explaining in the common-options glossary. Self-explanatory flags +# (--namespace, --yes, --private, …) are omitted even if they appear frequently. +_COMMON_FLAG_ALLOWLIST = {"--token", "--quiet", "--type", "--format", "--revision"} +# Keep token out of inline command signatures to encourage env based auth. +_INLINE_FLAG_EXCLUDE = {"--token"} + +_COMMON_FLAG_HELP_OVERRIDES: dict[str, str] = { + "--format": "Output format: `--format json` (or `--json`) or `--format table` (default).", + "--token": "Use a User Access Token. Prefer setting `HF_TOKEN` env var instead of passing `--token`.", +} + +# Global formatting flags injected into the skill markdown for commands that +# accept them. They aren't real click params on the command (they're consumed +# globally — see ``_consume_format_flags_for_leaf`` in ``_cli_utils.py``) so we +# add them synthetically here. +_GLOBAL_FORMAT_INLINE_FLAGS = ["--format [auto|human|agent|json|quiet]"] +_GLOBAL_COMMON_FLAGS: dict[str, tuple[str, str]] = { + "--format": ("--format", "Output format."), + "--quiet": ("-q / --quiet", "Quiet output (one ID per line)."), +} + +skills_cli = typer_factory(help="Manage skills for AI assistants.") + + +def _type_hint(param) -> str: + """Value hint for an option: enum choices inline as ``[a|b|c]``, otherwise the TYPE name. + + e.g. `--sort [downloads|likes|trending_score]` instead of `--sort CHOICE`. + """ + choices = getattr(param.type, "choices", None) + if choices: + return "[" + "|".join(str(c) for c in choices) + "]" + return getattr(param.type, "name", "").upper() or "VALUE" + + +def _format_params(cmd: Command) -> str: + """Format required params: positional as UPPER_CASE, options as ``--name TYPE``.""" + parts = [] + for p in cmd.params: + if not p.required or p.human_readable_name == "--help": + continue + if p.name and p.name.startswith("_"): + continue + long_name = next((o for o in getattr(p, "opts", []) if o.startswith("--")), None) + if long_name is not None: + type_name = _type_hint(p) + parts.append(f"{long_name} {type_name}") + elif p.name: + parts.append(p.human_readable_name) + return " ".join(parts) + + +def _collect_leaf_commands(group: Group, ctx: Context, path_parts: list[str]) -> list[tuple[list[str], Command]]: + """Recursively walk a Click Group, returning (full_path_parts, cmd) for every leaf command.""" + leaves: list[tuple[list[str], Command]] = [] + sub_ctx = Context(group, parent=ctx, info_name=path_parts[-1]) + for name in group.list_commands(sub_ctx): + cmd = group.get_command(sub_ctx, name) + if cmd is None or cmd.hidden: + continue + child_path = [*path_parts, name] + if isinstance(cmd, Group): + leaves.extend(_collect_leaf_commands(cmd, sub_ctx, child_path)) + else: + leaves.append((child_path, cmd)) + return leaves + + +def _iter_optional_params(cmd: Command): + """Yield (param, long_name, short_name) for each optional, non-internal param.""" + for p in cmd.params: + if p.required or p.human_readable_name == "--help": + continue + if p.name and p.name.startswith("_"): + continue + long_name = None + short_name = None + for opt in getattr(p, "opts", []): + if opt.startswith("--"): + long_name = long_name or opt + elif opt.startswith("-"): + short_name = opt + if long_name: + yield p, long_name, short_name + + +def _accepts_global_format_flags(cmd: Command) -> bool: + """Return True if the leaf command accepts the global '--format' / '--json' / '-q' flags.""" + if cmd.context_settings.get("ignore_unknown_options"): + return False + return not _has_local_formatting_option(cmd) + + +def _get_flag_names(cmd: Command, *, exclude: set[str] | None = None) -> list[str]: + """Return long-form flag names (--foo) for optional, non-internal params. + + Boolean flags are bare ('--dry-run'). Value-taking options include a type hint ('--include TEXT', '--max-workers INTEGER'). + Synthetic global formatting flags are appended for commands that accept them. + """ + flags: list[str] = [] + for p, long_name, _short in _iter_optional_params(cmd): + if exclude and long_name in exclude: + continue + if getattr(p, "is_flag", False): + flags.append(long_name) + else: + type_name = _type_hint(p) + flags.append(f"{long_name} {type_name}") + if _accepts_global_format_flags(cmd): + flags.extend(flag for flag in _GLOBAL_FORMAT_INLINE_FLAGS if not (exclude and flag.split()[0] in exclude)) + return flags + + +def _compute_common_flags( + leaf_commands: list[tuple[list[str], Command]], +) -> dict[str, tuple[str, str]]: + """Collect display info for flags in the allowlist.""" + flag_info: dict[str, tuple[str, str]] = {} + + for _path, cmd in leaf_commands: + for p, long_name, short_name in _iter_optional_params(cmd): + if long_name not in _COMMON_FLAG_ALLOWLIST: + continue + # Prefer the version with a short form (e.g. "-q / --quiet" over just "--quiet") + if long_name not in flag_info or (short_name and " / " not in flag_info[long_name][0]): + display = f"{short_name} / {long_name}" if short_name else long_name + help_text = (getattr(p, "help", None) or "").split("\n")[0].strip() + flag_info[long_name] = (display, help_text) + + # Inject the global formatting flags as common flags whenever any leaf + # command accepts them (the vast majority do). + if any(_accepts_global_format_flags(cmd) for _path, cmd in leaf_commands): + for long_name, entry in _GLOBAL_COMMON_FLAGS.items(): + flag_info.setdefault(long_name, entry) + + return flag_info + + +def _render_leaf(path_parts: list[str], cmd: Command) -> str: + """Render a single leaf command as a markdown list entry.""" + help_text = (cmd.help or "").split("\n")[0].strip() + params = _format_params(cmd) + parts = ["hf", *path_parts] + ([params] if params else []) + entry = f"- `{' '.join(parts)}` — {help_text}" + flags = _get_flag_names(cmd, exclude=_INLINE_FLAG_EXCLUDE) + if flags: + entry += f" `[{' '.join(flags)}]`" + return entry + + +def build_skill_md() -> str: + # Lazy import to avoid circular dependency (hf.py imports skills_cli from this module) + from huggingface_hub import __version__ + from huggingface_hub.cli.hf import app + + click_app = app # the app is already a click.Group + ctx = Context(click_app, info_name="hf") + + top_level: list[tuple[list[str], Command]] = [] + groups: list[tuple[str, Group]] = [] + for name in sorted(click_app.list_commands(ctx)): # type: ignore[attr-defined] + cmd = click_app.get_command(ctx, name) # type: ignore[attr-defined] + if cmd is None or cmd.hidden: + continue + if isinstance(cmd, Group): + groups.append((name, cmd)) + else: + top_level.append(([name], cmd)) + + group_leaves: list[tuple[str, list[tuple[list[str], Command]]]] = [] + all_leaf_commands: list[tuple[list[str], Command]] = list(top_level) + for name, group in groups: + leaves = _collect_leaf_commands(group, ctx, [name]) + group_leaves.append((name, leaves)) + all_leaf_commands.extend(leaves) + + common_flags = _compute_common_flags(all_leaf_commands) + + # wrap in list to widen list[LiteralString] -> list[str] for `ty` + lines: list[str] = list(_SKILL_YAML_PREFIX.splitlines()) + lines.append("") + lines.append(f"Generated with `huggingface_hub v{__version__}`. Run `hf skills add --force` to regenerate.") + lines.append("") + lines.append("## Commands") + lines.append("") + + for path_parts, cmd in top_level: + lines.append(_render_leaf(path_parts, cmd)) + + groups_dict = dict(groups) + for name, leaves in group_leaves: + group_cmd = groups_dict[name] + help_text = (group_cmd.help or "").split("\n")[0].strip() + lines.append("") + lines.append(f"### `hf {name}` — {help_text}") + lines.append("") + for path_parts, cmd in leaves: + lines.append(_render_leaf(path_parts, cmd)) + + if common_flags: + lines.append("") + lines.append("## Common options") + lines.append("") + for long_name, (display, help_text) in sorted(common_flags.items()): + help_text = _COMMON_FLAG_HELP_OVERRIDES.get(long_name, help_text) + if help_text: + lines.append(f"- `{display}` — {help_text}") + else: + lines.append(f"- `{display}`") + + lines.extend(_SKILL_TIPS.splitlines()) + + return "\n".join(lines) + + +def _remove_existing(path: Path, force: bool) -> None: + """Remove existing file/directory/symlink if force is True, otherwise raise an error.""" + if not (path.exists() or path.is_symlink()): + return + if not force: + raise CLIError(f"Skill already exists at {path}.\nRe-run with --force to overwrite.") + if path.is_dir() and not path.is_symlink(): + shutil.rmtree(path) + else: + path.unlink() + + +def _install_to(skills_dir: Path, skill_name: str, force: bool) -> Path: + """Install a marketplace skill into a skills directory. Returns the installed path.""" + try: + if skill_name.strip() == DEFAULT_SKILL_ID: + return _skills.install_generated_skill(build_skill_md(), skills_dir, force=force) + return _skills.add_skill(skill_name, skills_dir, force=force) + except FileExistsError as exc: + raise CLIError(f"{exc}\nRe-run with --force to overwrite.") from exc + + +def _create_symlink(agent_skills_dir: Path, skill_name: str, central_skill_path: Path, force: bool) -> Path: + """Create a relative symlink from agent directory to the central skill location.""" + agent_skills_dir = agent_skills_dir.expanduser().resolve() + agent_skills_dir.mkdir(parents=True, exist_ok=True) + link_path = agent_skills_dir / skill_name + + _remove_existing(link_path, force) + link_path.symlink_to(os.path.relpath(central_skill_path, agent_skills_dir)) + + return link_path + + +def _resolve_update_roots( + *, + claude: bool, + global_: bool, + dest: Path | None, +) -> list[Path]: + if dest is not None: + if claude or global_: + raise CLIError("--dest cannot be combined with --claude or --global.") + return [dest.expanduser().resolve()] + + roots: list[Path] = [CENTRAL_GLOBAL if global_ else CENTRAL_LOCAL] + if claude: + roots.append(CLAUDE_GLOBAL if global_ else CLAUDE_LOCAL) + return [root.expanduser().resolve() for root in roots] + + +@skills_cli.command("preview") +def skills_preview() -> None: + """Print the generated `hf-cli` SKILL.md to stdout.""" + print(build_skill_md()) + + +@skills_cli.command( + "list | ls", + examples=[ + "hf skills list", + "hf skills list --format json", + ], +) +def skills_list( + token: TokenOpt = None, +) -> None: + """List available skills from the Hugging Face marketplace.""" + install_locations: list[tuple[str, Path]] = [ + ("project", CENTRAL_LOCAL), + ("project (claude)", CLAUDE_LOCAL), + ("global", CENTRAL_GLOBAL), + ("global (claude)", CLAUDE_GLOBAL), + ] + installed: dict[str, set[str]] = {} + for label, root in install_locations: + for skill_dir in _skills._iter_unique_skill_dirs([root]): + installed.setdefault(skill_dir.name.lower(), set()).add(label) + + api = get_hf_api(token=token) + with disable_progress_bars(): + skills = _skills._load_marketplace_skills(api) + results = [ + { + "name": skill.name, + "description": skill.description or "", + **{ + label: "yes" if label in installed.get(skill.name.lower(), set()) else "" + for label, _ in install_locations + }, + } + for skill in skills + ] + out.table( + results, + id_key="name", + alignments={"project": "right", "global": "right", "project (claude)": "right", "global (claude)": "right"}, + ) + + +@skills_cli.command( + "add", + examples=[ + "hf skills add", + "hf skills add huggingface-gradio --dest=~/my-skills", + "hf skills add --global", + "hf skills add --claude", + "hf skills add huggingface-gradio --claude --global", + ], +) +def skills_add( + name: Annotated[ + str, + Argument(help="Marketplace skill name.", show_default=False), + ] = DEFAULT_SKILL_ID, + claude: Annotated[bool, Option("--claude", help="Install for Claude.")] = False, + global_: Annotated[ + bool, + Option( + "--global", + "-g", + help="Install globally (user-level) instead of in the current project directory.", + ), + ] = False, + dest: Annotated[ + Path | None, + Option( + help="Install into a custom destination (path to skills directory).", + ), + ] = None, + force: Annotated[ + bool, + Option( + "--force", + help="Overwrite existing skills in the destination.", + ), + ] = False, +) -> None: + """Install a Hugging Face skill for an AI assistant. + + The default `hf-cli` skill is generated locally from the installed CLI version; + other skills are downloaded from the Hugging Face marketplace. + Default location is in the current directory (.agents/skills) or user-level (~/.agents/skills). + If `--claude` is specified, the skill is also symlinked into Claude's legacy skills directory. + """ + if dest is not None: + if claude or global_: + raise CLIError("--dest cannot be combined with --claude or --global.") + skill_dest = _install_to(dest, name, force) + print(f"Installed '{name}' to {skill_dest}") + return + + # Install to central location + central_path = CENTRAL_GLOBAL if global_ else CENTRAL_LOCAL + central_skill_path = _install_to(central_path, name, force) + print(f"Installed '{name}' to central location: {central_skill_path}") + + if claude: + agent_target = CLAUDE_GLOBAL if global_ else CLAUDE_LOCAL + link_path = _create_symlink(agent_target, name, central_skill_path, force) + print(f"Created symlink: {link_path}") + + +@skills_cli.command( + "update", + examples=[ + "hf skills update", + "hf skills update hf-cli", + "hf skills update huggingface-gradio --dest=~/my-skills", + "hf skills update --claude", + ], +) +def skills_update( + name: Annotated[ + str | None, + Argument(help="Optional installed skill name to update.", show_default=False), + ] = None, + claude: Annotated[bool, Option("--claude", help="Update skills installed for Claude.")] = False, + global_: Annotated[ + bool, + Option( + "--global", + "-g", + help="Use global skills directories instead of the current project.", + ), + ] = False, + dest: Annotated[ + Path | None, + Option( + help="Update skills in a custom skills directory.", + ), + ] = None, +) -> None: + """Update installed Hugging Face marketplace skills.""" + roots = _resolve_update_roots(claude=claude, global_=global_, dest=dest) + + results = _skills.update_skills(roots, selector=name, hf_cli_content=build_skill_md()) + if not results: + print("No installed skills found.") + return + + for result in results: + detail = f" ({result.detail})" if result.detail else "" + print(f"{result.name}: {result.status}{detail}") diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/spaces.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/spaces.py new file mode 100644 index 0000000000000000000000000000000000000000..11bdeea97f60f66a7423b921fb1d376d1af9d7b7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/spaces.py @@ -0,0 +1,1090 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains commands to interact with spaces on the Hugging Face Hub.""" + +import enum +import functools +import itertools +import os +import shlex +import shutil +import subprocess +import sys +import tempfile +import time +from collections import deque +from pathlib import Path +from typing import TYPE_CHECKING, Annotated, Literal, get_args + +import click +from packaging import version +from typing_extensions import assert_never + +from huggingface_hub._hot_reload.client import multi_replica_reload_events +from huggingface_hub._hot_reload.types import ApiGetReloadEventSourceData, ReloadRegion +from huggingface_hub._space_api import SpaceHardware, SpaceStage +from huggingface_hub.cli._cli_utils import SoftChoice +from huggingface_hub.errors import CLIError, RemoteEntryNotFoundError, RepositoryNotFoundError, RevisionNotFoundError +from huggingface_hub.file_download import hf_hub_download +from huggingface_hub.hf_api import ExpandSpaceProperty_T, HfApi, SpaceSort_T +from huggingface_hub.repocard import SpaceCard +from huggingface_hub.utils import disable_progress_bars +from huggingface_hub.utils._parsing import parse_duration + +from ._cli_utils import ( + REPO_LIST_DEFAULT_LIMIT, + AuthorOpt, + EnvFileOpt, + EnvOpt, + FilterOpt, + LimitOpt, + RevisionOpt, + SearchOpt, + SecretsFileOpt, + SecretsOpt, + SshDryRunOpt, + SshIdentityFileOpt, + TokenOpt, + VolumesOpt, + exec_ssh, + get_hf_api, + make_expand_properties_parser, + parse_env_map, + parse_volumes, + typer_factory, +) +from ._file_listing import list_repo_files_cmd +from ._framework import Argument, Option +from ._output import _dataclass_to_dict, out + + +HOT_RELOADING_MIN_GRADIO = "6.1.0" + + +_EXPAND_PROPERTIES = sorted(get_args(ExpandSpaceProperty_T)) +_SORT_OPTIONS = get_args(SpaceSort_T) +SpaceSortEnum = enum.Enum("SpaceSortEnum", {s: s for s in _SORT_OPTIONS}, type=str) # type: ignore[misc] + + +ExpandOpt = Annotated[ + str | None, + Option( + help=f"Comma-separated properties to return. When used, only the listed properties (and id) are returned. Example: '--expand=likes,tags'. Valid: {', '.join(_EXPAND_PROPERTIES)}.", + callback=make_expand_properties_parser(_EXPAND_PROPERTIES), + ), +] + +spaces_cli = typer_factory(help="Interact with spaces on the Hub.") +volumes_cli = typer_factory(help="Manage volumes for a Space on the Hub.") +secrets_cli = typer_factory(help="Manage secrets for a Space on the Hub.") +variables_cli = typer_factory(help="Manage environment variables for a Space on the Hub.") +spaces_cli.add_group(volumes_cli, name="volumes") +spaces_cli.add_group(secrets_cli, name="secrets") +spaces_cli.add_group(variables_cli, name="variables") + + +@spaces_cli.command( + "list | ls", + examples=[ + "hf spaces ls --limit 10", + 'hf spaces ls --search "chatbot" --author huggingface', + "hf spaces ls victor/deepsite", + "hf spaces ls victor/deepsite -R", + "hf spaces ls victor/deepsite --tree -h", + ], +) +def spaces_ls( + repo_id: Annotated[ + str | None, + Argument(help="Space ID (e.g. `username/repo-name`) to list files from. If omitted, lists spaces."), + ] = None, + search: SearchOpt = None, + author: AuthorOpt = None, + filter: FilterOpt = None, + sort: Annotated[ + SpaceSortEnum | None, + Option(help="Sort results."), + ] = None, + limit: LimitOpt = REPO_LIST_DEFAULT_LIMIT, + expand: ExpandOpt = None, + human_readable: Annotated[ + bool, + Option("--human-readable", "-h", help="Show sizes in human readable format (only for listing files)."), + ] = False, + as_tree: Annotated[ + bool, + Option("--tree", help="List files in tree format (only for listing files)."), + ] = False, + recursive: Annotated[ + bool, + Option("--recursive", "-R", help="List files recursively (only for listing files)."), + ] = False, + revision: RevisionOpt = None, + token: TokenOpt = None, +) -> None: + """List spaces on the Hub, or files in a space repo. + + When called with no argument, lists spaces on the Hub. + When called with a space ID, lists files in that space repo. + """ + if repo_id is not None: + if search is not None: + raise click.BadParameter("Cannot use --search when listing files.") + if author is not None: + raise click.BadParameter("Cannot use --author when listing files.") + if filter is not None: + raise click.BadParameter("Cannot use --filter when listing files.") + if sort is not None: + raise click.BadParameter("Cannot use --sort when listing files.") + if limit != REPO_LIST_DEFAULT_LIMIT: + raise click.BadParameter("Cannot use --limit when listing files.") + if expand is not None: + raise click.BadParameter("Cannot use --expand when listing files.") + return list_repo_files_cmd( + repo_id=repo_id, + repo_type="space", + human_readable=human_readable, + as_tree=as_tree, + recursive=recursive, + revision=revision, + token=token, + ) + + if as_tree: + raise click.BadParameter("Cannot use --tree when listing spaces.") + if recursive: + raise click.BadParameter("Cannot use --recursive when listing spaces.") + if human_readable: + raise click.BadParameter("Cannot use --human-readable when listing spaces.") + if revision is not None: + raise click.BadParameter("Cannot use --revision when listing spaces.") + api = get_hf_api(token=token) + sort_key = sort.value if sort else None + results = [ + _dataclass_to_dict(space_info) + for space_info in api.list_spaces( + filter=filter, + author=author, + search=search, + sort=sort_key, + limit=limit, + expand=expand, # type: ignore[arg-type] + ) + ] + out.table(results) + + +@spaces_cli.command( + "info", + examples=[ + "hf spaces info enzostvs/deepsite", + "hf spaces info gradio/theme_builder --expand sdk,runtime,likes", + ], +) +def spaces_info( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + revision: RevisionOpt = None, + expand: ExpandOpt = None, + token: TokenOpt = None, +) -> None: + """Get info about a space on the Hub.""" + api = get_hf_api(token=token) + try: + info = api.space_info(repo_id=space_id, revision=revision, expand=expand) # type: ignore[arg-type] + except RepositoryNotFoundError as e: + raise CLIError(f"Space '{space_id}' not found.") from e + except RevisionNotFoundError as e: + raise CLIError(f"Revision '{revision}' not found on '{space_id}'.") from e + out.dict(info) + + +@spaces_cli.command( + "card", + examples=[ + "hf spaces card mteb/leaderboard", + "hf spaces card mteb/leaderboard --metadata", + "hf spaces card mteb/leaderboard --metadata --format json", + "hf spaces card mteb/leaderboard --text", + ], +) +def spaces_card( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + metadata: Annotated[bool, Option("--metadata", help="Output only the metadata from the card.")] = False, + text: Annotated[bool, Option("--text", help="Output only the text body (no metadata).")] = False, + token: TokenOpt = None, +) -> None: + """Get the Space card (README) for a Space on the Hub.""" + if metadata and text: + raise CLIError("--metadata and --text are mutually exclusive.") + card = SpaceCard.load(space_id, token=token) + if metadata: + out.dict(card.data.to_dict()) + elif text: + out.text(card.text) + else: + out.text(card.content) + out.hint(f"Use `hf spaces card {space_id} --metadata` to extract only the card metadata.") + + +@spaces_cli.command( + "templates", + examples=["hf spaces templates"], +) +def spaces_templates( + token: TokenOpt = None, +) -> None: + """List the available Space templates. + + The `repo_id` (or `name`) of a template can be passed to `hf repos create --template ...` to + create a new Space from that template. + """ + api = get_hf_api(token=token) + templates = [_dataclass_to_dict(template) for template in api.list_space_templates()] + out.table(templates, id_key="name") + out.hint( + "Create a Space from a template with `hf repos create --type space --space-sdk --template `." + ) + + +@spaces_cli.command( + "search", + examples=[ + 'hf spaces search "generate image"', + 'hf spaces search "identify objects in pictures" --sdk gradio --limit 5', + 'hf spaces search "remove background from photo" --description --json', + ], +) +def spaces_search( + query: Annotated[str, Argument(help="Search query.")], + filter: FilterOpt = None, + sdk: Annotated[list[str] | None, Option(help="Filter by SDK (e.g. gradio, docker, static).")] = None, + include_non_running: Annotated[bool, Option(help="Include non-running spaces in results.")] = False, + description: Annotated[bool, Option(help="Show AI-generated descriptions.")] = False, + limit: LimitOpt = 10, + token: TokenOpt = None, +) -> None: + """Search spaces on the Hub using semantic search.""" + api = get_hf_api(token=token) + results = api.search_spaces( + query=query, + filter=filter, + sdk=sdk, + include_non_running=include_non_running, + token=token, + ) + items = [] + for r in itertools.islice(results, limit): + item: dict = { + "id": r.id, + "title": r.title, + "sdk": r.sdk, + "likes": r.likes, + "stage": r.runtime.stage if r.runtime else None, + "category": r.ai_category, + "score": round(r.semantic_relevancy_score, 2) if r.semantic_relevancy_score is not None else None, + } + if description: + item["description"] = r.ai_short_description + items.append(item) + out.table(items) + if not description: + out.hint("Use --description to show AI-generated descriptions.") + + +@spaces_cli.command( + "wait", + examples=[ + "hf spaces wait username/my-space", + "hf spaces wait username/my-space --timeout 5m", + ], +) +def spaces_wait( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + timeout: Annotated[ + str | None, + Option( + help="Max time to wait: int with s (seconds, default), m (minutes), h (hours) or d (days).", + ), + ] = None, + token: TokenOpt = None, +) -> None: + """Wait for a Space to finish building/starting. + + Blocks until the Space leaves an intermediate stage (BUILDING, APP_STARTING, etc.) + and reaches a settled stage. Exits with code 0 if the Space is RUNNING, + or a non-zero exit code otherwise (e.g. BUILD_ERROR, RUNTIME_ERROR). + """ + timeout_secs = parse_duration(timeout) if timeout is not None else None + api = get_hf_api(token=token) + status = out.status("Waiting for Space to be ready...") + try: + runtime = api.wait_for_space(space_id, timeout=timeout_secs) + except TimeoutError: + status.done("Timed out.") + raise CLIError(f"Timed out after {timeout} waiting for Space '{space_id}' to be ready.") from None + status.done(f"Space reached stage '{runtime.stage}'.") + if runtime.stage != SpaceStage.RUNNING: + raise CLIError(f"Space '{space_id}' is not running (stage='{runtime.stage}').") + out.result("Space ready", space_id=space_id, stage=str(runtime.stage)) + out.hint(f"Use `hf spaces logs {space_id}` to view run logs.") + + +@spaces_cli.command( + "dev-mode", + examples=[ + "hf spaces dev-mode my-user-name/deepsite", + ], +) +def dev_mode( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + stop: Annotated[bool, Option(help="Stop dev mode.")] = False, + token: TokenOpt = None, +): + """ + Enable or disable dev mode on a Space. + + Spaces Dev Mode eases the debugging of your application and makes iterating on Spaces faster by allowing you to + restart your application without stopping the Space container itself. This feature is available as part of a PRO + or Team & Enterprise plan. + + See docs: https://huggingface.co/docs/hub/spaces-dev-mode + """ + api = get_hf_api(token=token) + if stop: + api.disable_space_dev_mode(space_id) + print(f"Dev mode disabled for '{space_id}'") + return + api.enable_space_dev_mode(space_id) + runtime = api.wait_for_space(space_id) + if runtime.stage != SpaceStage.RUNNING: + out.warning(f"Dev mode is not ready (stage='{runtime.stage}')") + return + info = api.space_info(space_id) + folder = getattr(info.card_data, "dev-mode-folder", "" if info.sdk == "docker" else "/home/user/app") + folder_query_param = f"folder={folder}" if folder else "" + print("Connect to dev environment:") + print("") + print("Web:") + vscode_web_url = f"https://huggingface.co/spaces/{info.id}/dev-mode/vscode-web" + if folder_query_param: + vscode_web_url += f"?{folder_query_param}" + ssh_host = f"{info.subdomain}@ssh.hf.space" + print(f" * VSCode: {vscode_web_url}") + print("") + print("Local:") + print("1. Add your SSH key to https://huggingface.co/settings/keys") + print(f"2. SSH with `hf spaces ssh {space_id}` (or `ssh -i {ssh_host}`)") + print(" Or open") + print(f" * VSCode: vscode://vscode-remote/ssh-remote+{ssh_host}{folder}") + print(f" * Cursor: cursor://vscode-remote/ssh-remote+{ssh_host}{folder}") + print("") + print("PS: Dev mode stops after 48h of inactivity, don't forget to save your changes regularly.") + + +@spaces_cli.command( + "ssh", + examples=[ + "hf spaces ssh username/my-space", + "hf spaces ssh username/my-space --dry-run", + "hf spaces ssh username/my-space -i ~/.ssh/id_ed25519", + "hf spaces ssh username/my-space --auto", + ], +) +def spaces_ssh( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + identity_file: SshIdentityFileOpt = None, + dry_run: SshDryRunOpt = False, + auto: Annotated[ + bool, + Option("--auto", help="Enable Dev Mode without prompting if not already enabled."), + ] = False, + token: TokenOpt = None, +) -> None: + """SSH into a Space's Dev Mode container. + + Requires Dev Mode to be running on the Space and your SSH public key to be registered at https://huggingface.co/settings/keys. + + See: https://huggingface.co/docs/hub/spaces-dev-mode + """ + api = get_hf_api(token=token) + info = api.space_info(space_id) + if info.runtime is None or not info.runtime.dev_mode: + out.confirm( + f"Dev Mode is disabled on '{space_id}'. Enable it now?", yes=auto, default=True, confirm_param="--auto" + ) + api.enable_space_dev_mode(space_id) + runtime = api.wait_for_space(space_id) + if runtime.stage != SpaceStage.RUNNING: + raise CLIError(f"Space '{space_id}' is not running (stage='{runtime.stage}').") + info = api.space_info(space_id) + exec_ssh(f"{info.subdomain}@ssh.hf.space", identity_file=identity_file, dry_run=dry_run) + + +@spaces_cli.command( + "pause", + examples=[ + "hf spaces pause username/my-space", + ], +) +def spaces_pause( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + token: TokenOpt = None, +) -> None: + """Pause a Space.""" + api = get_hf_api(token=token) + runtime = api.pause_space(space_id) + out.result("Space paused", space_id=space_id, stage=runtime.stage) + out.hint(f"Use `hf spaces restart {space_id}` to restart it.") + out.hint( + f"Mount a Volume or bucket to persist data across restarts: `hf spaces volumes set {space_id} -v hf://...`" + ) + + +@spaces_cli.command( + "restart", + examples=[ + "hf spaces restart username/my-space", + "hf spaces restart username/my-space --factory-reboot", + ], +) +def spaces_restart( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + factory_reboot: Annotated[ + bool, + Option( + "--factory-reboot", + help="Rebuild the Space from scratch without using the build cache.", + ), + ] = False, + token: TokenOpt = None, +) -> None: + """Restart a Space.""" + api = get_hf_api(token=token) + runtime = api.restart_space(space_id, factory_reboot=factory_reboot) + out.result( + "Space restart triggered", + space_id=space_id, + stage=runtime.stage, + factory_reboot=factory_reboot, + ) + out.hint(f"Use `hf spaces wait {space_id}` to wait until the Space is ready.") + out.hint( + f"Mount a Volume or bucket to persist data across restarts: `hf spaces volumes set {space_id} -v hf://...`" + ) + + +@spaces_cli.command( + "hardware", + examples=[ + "hf spaces hardware", + ], +) +def spaces_hardware(token: TokenOpt = None) -> None: + """List available hardware options for Spaces.""" + api = get_hf_api(token=token) + hardware_list = api.list_spaces_hardware() + items = [] + for hw in hardware_list: + accelerator = ( + f"{hw.accelerator.quantity}x {hw.accelerator.model} ({hw.accelerator.vram})" if hw.accelerator else None + ) + cost_min = f"${hw.unit_cost_usd:.4f}" if hw.unit_cost_usd else "free" + cost_hour = f"${hw.unit_cost_usd * 60:.2f}" if hw.unit_cost_usd else "free" + items.append( + { + "name": hw.name, + "pretty name": hw.pretty_name, + "cpu": hw.cpu, + "ram": hw.ram, + "accelerator": accelerator, + "cost/min": cost_min, + "cost/hour": cost_hour, + } + ) + out.table(items) + out.hint("Use `hf spaces settings --hardware ` to request hardware for a Space.") + + +@spaces_cli.command( + "settings", + examples=[ + "hf spaces settings username/my-space --sleep-time 300", + "hf spaces settings username/my-space --hardware t4-medium", + ], +) +def spaces_settings( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + sleep_time: Annotated[ + int | None, + Option( + "--sleep-time", + help="Idle time in seconds after which the Space goes to sleep. Use -1 to never sleep. Only available on upgraded hardware.", + ), + ] = None, + hardware: Annotated[ + str | None, + Option( + "--hardware", + help="Space hardware flavor (e.g. 'cpu-basic', 't4-medium', 'l4x4'). Run 'hf spaces hardware' to list available options.", + click_type=SoftChoice(SpaceHardware), + ), + ] = None, + token: TokenOpt = None, +) -> None: + """Update the settings of a Space.""" + api = get_hf_api(token=token) + if hardware is not None: + runtime = api.request_space_hardware(space_id, hardware=hardware, sleep_time=sleep_time) # type: ignore[arg-type] + elif sleep_time is not None: + runtime = api.set_space_sleep_time(space_id, sleep_time=sleep_time) + else: + raise CLIError("Specify at least one setting to update.") + out.result( + "Space settings updated", + space_id=space_id, + hardware=runtime.requested_hardware, + sleep_time=runtime.sleep_time, + ) + out.hint(f"Use `hf spaces info {space_id}` to verify the runtime configuration.") + + +@spaces_cli.command( + "logs", + examples=[ + "hf spaces logs username/my-space", + "hf spaces logs username/my-space --build", + "hf spaces logs -f username/my-space", + "hf spaces logs -n 50 username/my-space", + ], +) +def spaces_logs( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + build: Annotated[ + bool, + Option( + "--build", + help="Fetch the container build logs instead of the run logs. Useful when a Space is stuck in BUILD_ERROR.", + ), + ] = False, + follow: Annotated[ + bool, + Option( + "-f", + "--follow", + help="Follow log output (stream until the server closes the stream). Without this flag, only currently available logs are printed.", + ), + ] = False, + tail: Annotated[ + int | None, + Option( + "-n", + "--tail", + help="Number of lines to show from the end of the logs.", + ), + ] = None, + token: TokenOpt = None, +) -> None: + """Fetch the run or build logs of a Space. + + By default, prints currently available run logs and exits (non-blocking, like + `docker logs`). Use --follow/-f to stream until the server closes the stream. + Use --build to see the container build logs instead (useful when a Space is + stuck in BUILD_ERROR). + """ + if follow and tail is not None: + raise CLIError( + "Cannot use --follow and --tail together. Use --follow to stream logs or --tail to show recent logs." + ) + + api = get_hf_api(token=token) + logs = api.fetch_space_logs(space_id, build=build, follow=follow) + if tail is not None: + logs = deque(logs, maxlen=tail) + found_logs = False + for line in logs: + clean_line = line.strip() + out.text(clean_line) + if clean_line: + found_logs = True + if not found_logs and not build: + out.hint(f"No run logs found for space {space_id}. Try passing --build to fetch build logs instead.") + + +@spaces_cli.command( + "hot-reload", + examples=[ + "hf spaces hot-reload username/repo-name app.py # Open an interactive editor to the remote app.py file", + "hf spaces hot-reload username/repo-name -f app.py # Take local version from ./app.py and patch app.py remotely", + "hf spaces hot-reload username/repo-name app.py -f src/app.py # Take local version from ./src/app.py", + ], +) +def spaces_hot_reload( + space_id: Annotated[ + str, + Argument( + help="The space ID (e.g. `username/repo-name`).", + ), + ], + filename: Annotated[ + str | None, + Argument( + help="Path to the Python file in the Space repository. Can be omitted when --local-file is specified and path in repository matches." + ), + ] = None, + local_file: Annotated[ + Path | None, + Option( + "--local-file", + "-f", + help="Path of local file. Interactive editor mode if not specified", + ), + ] = None, + skip_checks: Annotated[bool, Option(help="Skip hot-reload compatibility checks.")] = False, + skip_summary: Annotated[bool, Option(help="Skip summary display after hot-reload is triggered")] = False, + token: TokenOpt = None, +) -> None: + """ + Hot-reload any Python file of a Space without a full rebuild + restart. + + ⚠ This feature is experimental ⚠ + + Only works with Gradio SDK (6.1+) + Opens an interactive editor unless --local-file/-f is specified. + + This command patches the live Python process using https://github.com/breuleux/jurigged + (AST-based diffing, in-place function updates, etc.), integrated with Gradio's native hot-reload support + (meaning that Gradio demo object changes are reflected in the UI) + + The command creates a remote commit. + If you are working from a local clone, run `git pull --autostash` afterwards + to bring the commit back and keep your local git state in sync. + """ + + click.secho("This feature is experimental and subject to change", fg="bright_black") + + api = get_hf_api(token=token) + + if not skip_checks: + space_info = api.space_info(space_id) + if space_info.sdk != "gradio": + raise CLIError(f"Hot-reloading is only available on Gradio SDK. Found {space_info.sdk} SDK") + if (card_data := space_info.card_data) is None: + raise CLIError(f"Unable to read cardData for Space {space_id}") + if (sdk_version := card_data.sdk_version) is None: + raise CLIError(f"Unable to read sdk_version from {space_id} cardData") + if version.parse(sdk_version) < version.Version(HOT_RELOADING_MIN_GRADIO): + raise CLIError(f"Hot-reloading requires Gradio >= {HOT_RELOADING_MIN_GRADIO} (found {sdk_version})") + if (current_sha := space_info.sha) is None: + raise CLIError(f"Unexpected `None` running SHA for Space {space_id}") + else: + current_sha = None + + if local_file: + local_path = str(local_file) + filename = local_file.as_posix() if filename is None else filename + elif filename: + if not skip_checks: + try: + api.auth_check( + repo_type="space", + repo_id=space_id, + write=True, + ) + except RepositoryNotFoundError as e: + raise CLIError( + f"Write access check to {space_id} repository failed. Make sure that you are authenticated" + ) from e + temp_dir = tempfile.TemporaryDirectory() + local_path = os.path.join(temp_dir.name, filename) + with disable_progress_bars(): + try: + hf_hub_download(repo_type="space", repo_id=space_id, filename=filename, local_dir=temp_dir.name) + except RemoteEntryNotFoundError: + click.secho(f"{filename} not found in remote repository. Assuming new file", fg="bright_black") + + editor_res = _editor_open(local_path) + if editor_res == "no-tty": + persistent_temp_dir = tempfile.mkdtemp() + shutil.copytree(temp_dir.name, persistent_temp_dir, dirs_exist_ok=True) + local_path = os.path.join(persistent_temp_dir, filename) + click.secho("No TTY detected. Non-interactive fallback:") + click.secho(f"- Edit {local_path}") + click.secho(f"- Run `hf spaces hot-reload {space_id} {filename} -f {local_path}`") + return + if editor_res == "no-editor": + raise CLIError("No editor found in local environment. Use -f flag to hot-reload from local path") + if editor_res != 0: + raise CLIError(f"Editor returned a non-zero exit code while attempting to edit {local_path}") + else: + raise CLIError("Either filename or --local-file/-f must be specified") + + commit_info = api.upload_file( + repo_type="space", + repo_id=space_id, + path_or_fileobj=local_path, + path_in_repo=filename, + parent_commit=current_sha, + _hot_reload=True, + ) + + if local_file is not None and local_file.resolve().is_relative_to(Path.cwd()): + click.secho(f"Created commit {commit_info.oid} in remote Space repository.") + click.secho("Consider running `git pull --autostash` to stay synced if you are working from a local clone.") + + if not skip_summary: + click.secho("Hot-reload summary:") + _spaces_hot_reload_summary( + api=api, + space_id=space_id, + current_sha=current_sha, + commit_sha=commit_info.oid, + local_path=local_path if local_file else filename, + filename=filename, + token=token, + ) + + +def _spaces_hot_reload_summary( + api: HfApi, + space_id: str, + current_sha: str | None, + commit_sha: str, + filename: str, + local_path: str, + token: str | None, +) -> None: + while (space_info := api.space_info(space_id)).sha == current_sha: + if current_sha is None or current_sha == commit_sha: + break + click.secho("Waiting for up-to-date Space infos", fg="bright_black", err=True) + time.sleep(2) + if space_info.sha != commit_sha: + raise CLIError(f"Expected SHA {commit_sha} after hot-reload but got {space_info.sha}") + if (runtime := space_info.runtime) is None: + raise CLIError(f"Unable to read SpaceRuntime from {space_id} infos") + if (hot_reloading := runtime.hot_reloading) is None: + raise CLIError(f"Space {space_id} current running version has not been hot-reloaded") + if hot_reloading.status != "created": + click.echo(f"Failed creating hot-reloaded commit. {hot_reloading.replica_statuses=}") + return + + if (space_host := space_info.host) is None: + raise CLIError("Unexpected None host on hotReloaded Space") + if (space_subdomain := space_info.subdomain) is None: + raise CLIError("Unexpected None subdomain on hotReloaded Space") + + def render_region(region: ReloadRegion) -> str: + res = f"{local_path}, " + if region["startLine"] == region["endLine"]: + res += f"line {region['startLine'] - 1}" + else: + res += f"lines {region['startLine'] - 1}-{region['endLine']}" + return res + + def display_event(event: ApiGetReloadEventSourceData) -> None: + if event["data"]["kind"] == "error": + click.secho("✘ Unexpected hot-reloading error", bold=True) + click.secho(event["data"]["traceback"], italic=True) + elif event["data"]["kind"] == "exception": + click.secho(f"✘ Exception at {render_region(event['data']['region'])}", bold=True) + click.secho(event["data"]["traceback"], italic=True) + elif event["data"]["kind"] == "add": + click.secho(f"✔︎ Created {event['data']['objectName']} {event['data']['objectType']}", bold=True) + elif event["data"]["kind"] == "delete": + click.secho(f"∅ Deleted {event['data']['objectName']} {event['data']['objectType']}", bold=True) + elif event["data"]["kind"] == "update": + click.secho(f"✔︎ Updated {event['data']['objectName']} {event['data']['objectType']}", bold=True) + elif event["data"]["kind"] == "run": + click.secho(f"▶ Run {render_region(event['data']['region'])}", bold=True) + click.secho(event["data"]["codeLines"], italic=True) + elif event["data"]["kind"] == "ui": + if event["data"]["updated"]: + click.secho("⟳ UI updated", bold=True) + else: + click.secho("∅ UI untouched", bold=True) + elif event["data"]["kind"] == "file": + if event["data"]["created"]: + click.secho(f"✔︎ {filename} created", bold=True) + else: + click.secho(f"✔︎ {filename} updated", bold=True) + else: + click.secho(f"❓ Unknown update event: {event=}") + if TYPE_CHECKING: + assert_never(event["data"]["kind"]) + + for replica_stream_event in multi_replica_reload_events( + commit_sha=commit_sha, + host=space_host, + subdomain=space_subdomain, + replica_hashes=[hash for hash, _ in hot_reloading.replica_statuses], + token=token, + ): + if replica_stream_event["kind"] == "event": + display_event(replica_stream_event["event"]) + elif replica_stream_event["kind"] == "replicaHash": + click.secho(f"---- Replica {replica_stream_event['hash']} ----") + elif replica_stream_event["kind"] == "fullMatch": + click.echo("✔︎ Same as first replica") + elif replica_stream_event["kind"] == "warning": + click.secho(f"⚠ {replica_stream_event['message']}", fg="bright_black") + else: + assert_never(replica_stream_event) + + +PREFERRED_EDITORS = ( + ("code", "code --wait"), + ("nvim", "nvim"), + ("nano", "nano"), + ("vim", "vim"), + ("vi", "vi"), +) + + +@functools.cache +def _get_editor_command() -> str | None: + for env in ("HF_EDITOR", "VISUAL", "EDITOR"): + if command := os.getenv(env, "").strip(): + return command + for binary_path, editor_command in PREFERRED_EDITORS: + if shutil.which(binary_path) is not None: + return editor_command + return None + + +def _editor_open(local_path: str) -> int | Literal["no-tty", "no-editor"]: + if not (sys.stdin.isatty() and sys.stdout.isatty()): + return "no-tty" + if (editor_command := _get_editor_command()) is None: + return "no-editor" + command = [*shlex.split(editor_command), local_path] + res = subprocess.run(command, start_new_session=True) + return res.returncode + + +@volumes_cli.command( + "list | ls", + examples=[ + "hf spaces volumes ls username/my-space", + ], +) +def volumes_ls( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + token: TokenOpt = None, +) -> None: + """List volumes mounted in a Space.""" + api = get_hf_api(token=token) + info = api.space_info(space_id) + if info.runtime is None: + raise CLIError(f"Runtime not available for Space '{space_id}'.") + volumes = info.runtime.volumes or [] + items = [_dataclass_to_dict(v) for v in volumes] + out.table(items) + out.hint( + f"Use `hf spaces volumes set {space_id} -v hf:///:/` to set volumes for a Space." + ) + + +@volumes_cli.command( + "set", + examples=[ + "hf spaces volumes set username/my-space -v hf://models/username/my-model:/models", + "hf spaces volumes set username/my-space -v hf://buckets/username/my-bucket:/data -v hf://datasets/username/my-dataset:/datasets:ro", + ], +) +def volumes_set( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + volume: VolumesOpt = None, + token: TokenOpt = None, +) -> None: + """Set (replace) volumes for a Space.""" + volumes = parse_volumes(volume) + if not volumes: + raise CLIError("At least one volume must be specified with -v/--volume.") + api = get_hf_api(token=token) + api.set_space_volumes(space_id, volumes=volumes) + out.result("Volumes set", space_id=space_id, volumes=[v.to_uri() for v in volumes]) + out.hint(f"Use `hf spaces volumes ls {space_id}` to list volumes for a Space.") + + +@volumes_cli.command( + "delete", + examples=[ + "hf spaces volumes delete username/my-space", + "hf spaces volumes delete username/my-space --yes", + ], +) +def volumes_delete( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + yes: Annotated[ + bool, + Option( + "-y", + "--yes", + help="Answer Yes to prompt automatically.", + ), + ] = False, + token: TokenOpt = None, +) -> None: + """Remove all volumes from a Space.""" + out.confirm(f"You are about to remove all volumes from Space '{space_id}'. Proceed?", yes=yes) + api = get_hf_api(token=token) + api.delete_space_volumes(space_id) + out.result("Volumes deleted", space_id=space_id) + out.hint( + f"Use `hf spaces volumes set {space_id} -v hf:///:/` to set volumes for a Space." + ) + + +@secrets_cli.command( + "list | ls", + examples=["hf spaces secrets ls username/my-space"], +) +def secrets_ls( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + token: TokenOpt = None, +) -> None: + """List secrets for a Space. Secret values are write-only and not returned.""" + api = get_hf_api(token=token) + secrets = api.get_space_secrets(space_id) + items = [_dataclass_to_dict(s) for s in secrets.values()] + out.table(items) + out.hint(f"Use `hf spaces secrets add {space_id} -s KEY=VALUE` to add secrets to a Space.") + + +@secrets_cli.command( + "add", + examples=[ + "hf spaces secrets add username/my-space -s HF_TOKEN", + "hf spaces secrets add username/my-space -s OPENAI_API_KEY=sk-... -s ANTHROPIC_API_KEY=sk-...", + "hf spaces secrets add username/my-space --secrets-file .env.secrets", + ], +) +def secrets_add( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + secrets: SecretsOpt = None, + secrets_file: SecretsFileOpt = None, + token: TokenOpt = None, +) -> None: + """Add or update secrets for a Space.""" + secrets_map = parse_env_map(secrets, secrets_file) + if not secrets_map: + raise CLIError("At least one secret must be specified with -s/--secrets or --secrets-file.") + api = get_hf_api(token=token) + for key, value in secrets_map.items(): + api.add_space_secret(space_id, key=key, value=value or "") + out.result("Secrets added", space_id=space_id, keys=list(secrets_map)) + out.hint(f"Use `hf spaces secrets delete {space_id} ` to remove a secret from a Space.") + + +@secrets_cli.command( + "delete", + examples=[ + "hf spaces secrets delete username/my-space HF_TOKEN", + "hf spaces secrets delete username/my-space HF_TOKEN --yes", + ], +) +def secrets_delete( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + key: Annotated[str, Argument(help="Name of the secret to remove.")], + yes: Annotated[ + bool, + Option( + "-y", + "--yes", + help="Answer Yes to prompt automatically.", + ), + ] = False, + token: TokenOpt = None, +) -> None: + """Remove a secret from a Space.""" + out.confirm( + f"You are about to remove secret '{key}' from Space '{space_id}'. The value cannot be recovered. Proceed?", + yes=yes, + ) + api = get_hf_api(token=token) + api.delete_space_secret(space_id, key=key) + out.result("Secret deleted", space_id=space_id, key=key) + out.hint(f"Use `hf spaces secrets add {space_id} -s {key}=` to re-add a secret to a Space.") + + +@variables_cli.command( + "list | ls", + examples=["hf spaces variables ls username/my-space"], +) +def variables_ls( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + token: TokenOpt = None, +) -> None: + """List environment variables for a Space.""" + api = get_hf_api(token=token) + variables = api.get_space_variables(space_id) + items = [_dataclass_to_dict(v) for v in variables.values()] + out.table(items) + out.hint(f"Use `hf spaces variables add {space_id} -e KEY=VALUE` to add variables to a Space.") + + +@variables_cli.command( + "add", + examples=[ + "hf spaces variables add username/my-space -e DEBUG=1", + "hf spaces variables add username/my-space -e MODEL_ID=gpt2 -e MAX_TOKENS=512", + "hf spaces variables add username/my-space --env-file .env", + ], +) +def variables_add( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + env: EnvOpt = None, + env_file: EnvFileOpt = None, + token: TokenOpt = None, +) -> None: + """Add or update environment variables for a Space.""" + env_map = parse_env_map(env, env_file) + if not env_map: + raise CLIError("At least one variable must be specified with -e/--env or --env-file.") + api = get_hf_api(token=token) + for key, value in env_map.items(): + api.add_space_variable(space_id, key=key, value=value or "") + out.result("Variables added", space_id=space_id, keys=list(env_map)) + out.hint(f"Use `hf spaces variables ls {space_id}` to list variables for a Space.") + + +@variables_cli.command( + "delete", + examples=[ + "hf spaces variables delete username/my-space DEBUG", + "hf spaces variables delete username/my-space DEBUG --yes", + ], +) +def variables_delete( + space_id: Annotated[str, Argument(help="The space ID (e.g. `username/repo-name`).")], + key: Annotated[str, Argument(help="Name of the variable to remove.")], + yes: Annotated[ + bool, + Option( + "-y", + "--yes", + help="Answer Yes to prompt automatically.", + ), + ] = False, + token: TokenOpt = None, +) -> None: + """Remove an environment variable from a Space.""" + out.confirm( + f"You are about to remove variable '{key}' from Space '{space_id}'. Proceed?", + yes=yes, + ) + api = get_hf_api(token=token) + api.delete_space_variable(space_id, key=key) + out.result("Variable deleted", space_id=space_id, key=key) + out.hint(f"Use `hf spaces variables ls {space_id}` to list remaining variables for a Space.") diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/system.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/system.py new file mode 100644 index 0000000000000000000000000000000000000000..b2bf84a133044328b6b7632c5e1262e225c5e1e6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/system.py @@ -0,0 +1,50 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains commands to print information about the environment and version.""" + +import click + +from huggingface_hub import __version__ + +from ..utils import dump_environment_info +from ._cli_utils import _fetch_latest_pypi_version, run_update +from ._output import out + + +def env() -> None: + """Print information about the environment.""" + dump_environment_info() + + +def version() -> None: + """Print information about the hf version.""" + out.result("hf version", version=__version__) + + +def update() -> None: + """Update the `hf` CLI to the latest version.""" + out.text(f"Current version: {__version__}") + out.text("Checking for updates to latest version...") + latest_version = _fetch_latest_pypi_version("huggingface_hub") + if latest_version is not None and __version__ == latest_version: + out.text(f"hf is up to date ({__version__})") + return + + returncode = run_update() + if returncode != 0: + raise click.exceptions.Exit(code=returncode) + out.hint( + "You may also want to run `hf skills update` to refresh any installed skills " + "so your AI agent sees the latest command surface." + ) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/upload.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/upload.py new file mode 100644 index 0000000000000000000000000000000000000000..0eda15e098d153308197ac3fa0cb175203529d60 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/upload.py @@ -0,0 +1,279 @@ +# Copyright 2023-present, the HuggingFace Inc. team. +# +# 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. +"""Contains command to upload a repo or file with the CLI.""" + +import os +import time +import warnings +from typing import Annotated + +import click + +from huggingface_hub import constants, logging +from huggingface_hub._commit_scheduler import CommitScheduler +from huggingface_hub.errors import CLIError, RevisionNotFoundError +from huggingface_hub.utils import parse_hf_uri + +from ._cli_utils import ( + PrivateOpt, + RepoIdArg, + RepoType, + RepoTypeOptionalOpt, + RevisionOpt, + TokenOpt, + get_hf_api, +) +from ._framework import Argument, Option +from ._output import out + + +logger = logging.get_logger(__name__) + + +UPLOAD_EXAMPLES = [ + "hf upload my-cool-model . .", + "hf upload Wauplin/my-cool-model ./models/model.safetensors", + "hf upload Wauplin/my-cool-dataset ./data /train --repo-type=dataset", + 'hf upload Wauplin/my-cool-model ./models . --commit-message="Epoch 34/50" --commit-description="Val accuracy: 68%"', + "hf upload bigcode/the-stack . . --repo-type dataset --create-pr", +] + + +def upload( + repo_id: RepoIdArg, + local_path: Annotated[ + str | None, + Argument( + help="Local path to the file or folder to upload. Wildcard patterns are supported. Defaults to current directory.", + ), + ] = None, + path_in_repo: Annotated[ + str | None, + Argument( + help="Path of the file or folder in the repo. Defaults to the relative path of the file or folder.", + ), + ] = None, + repo_type: RepoTypeOptionalOpt = None, + revision: RevisionOpt = None, + private: PrivateOpt = None, + include: Annotated[ + list[str] | None, + Option( + help="Glob patterns to match files to upload.", + ), + ] = None, + exclude: Annotated[ + list[str] | None, + Option( + help="Glob patterns to exclude from files to upload.", + ), + ] = None, + delete: Annotated[ + list[str] | None, + Option( + help="Glob patterns for file to be deleted from the repo while committing.", + ), + ] = None, + commit_message: Annotated[ + str | None, + Option( + help="The summary / title / first line of the generated commit.", + ), + ] = None, + commit_description: Annotated[ + str | None, + Option( + help="The description of the generated commit.", + ), + ] = None, + create_pr: Annotated[ + bool, + Option( + help="Whether to upload content as a new Pull Request.", + ), + ] = False, + every: Annotated[ + float | None, + Option( + help="If set, a background job is scheduled to create commits every `every` minutes.", + ), + ] = None, + token: TokenOpt = None, +) -> None: + """Upload a file or a folder to the Hub. Recommended for single-commit uploads.""" + + if every is not None and every <= 0: + raise click.BadParameter("--every must be a positive value", param_hint="every") + + # `repo_id` may be a plain repo id or an `hf://` URI (e.g. `hf://datasets/my-org/my-dataset@v1.0/data/`). + # When a URI is provided, it is authoritative for the repo type, revision and (optionally) path in repo, + # so explicit `--repo-type` / `--revision` options are forbidden alongside it. + # We branch on the `hf://` prefix (the user's *intent*) rather than on whether the string parses as a + # valid URI: a malformed URI then surfaces a precise `HfUriError` (formatted globally in `cli/_errors.py`) + # instead of silently falling through to the plain-repo-id path and failing later with an opaque error. + if repo_id.startswith(constants.HF_PROTOCOL): + if repo_type is not None: + raise CLIError(f"'--repo-type' cannot be used with an 'hf://' URI ('{repo_id}').") + if revision is not None: + raise CLIError(f"'--revision' cannot be used with an 'hf://' URI ('{repo_id}').") + uri = parse_hf_uri(repo_id) + if uri.is_bucket: + raise CLIError("Buckets are not supported by `hf upload`. Use `hf sync` instead.") + repo_id, repo_type_str, revision = uri.id, uri.type, uri.revision + if uri.path_in_repo: + if path_in_repo is not None: + raise CLIError( + f"Cannot combine a path in the hf:// URI ('{uri.path_in_repo}') with the `path_in_repo` argument ('{path_in_repo}')." + ) + path_in_repo = uri.path_in_repo + else: + repo_type_str = (repo_type or RepoType.model).value + + api = get_hf_api(token=token) + + # Resolve local_path and path_in_repo based on implicit/explicit rules + resolved_local_path, resolved_path_in_repo, resolved_include = _resolve_upload_paths( + repo_id=repo_id, local_path=local_path, path_in_repo=path_in_repo, include=include + ) + + def run_upload() -> str: + if os.path.isfile(resolved_local_path): + if resolved_include is not None and len(resolved_include) > 0 and isinstance(resolved_include, list): + warnings.warn("Ignoring --include since a single file is uploaded.") + if exclude is not None and len(exclude) > 0: + warnings.warn("Ignoring --exclude since a single file is uploaded.") + if delete is not None and len(delete) > 0: + warnings.warn("Ignoring --delete since a single file is uploaded.") + + # Schedule commits if `every` is set + if every is not None: + allow_patterns: list[str] | None + ignore_patterns: list[str] | None + if os.path.isfile(resolved_local_path): + # If file => watch entire folder + use allow_patterns + folder_path = os.path.dirname(resolved_local_path) + pi = ( + resolved_path_in_repo[: -len(resolved_local_path)] + if resolved_path_in_repo.endswith(resolved_local_path) + else resolved_path_in_repo + ) + allow_patterns = [resolved_local_path] + ignore_patterns = [] + else: + folder_path = resolved_local_path + pi = resolved_path_in_repo + allow_patterns = resolved_include + ignore_patterns = exclude + if delete is not None and len(delete) > 0: + warnings.warn("Ignoring --delete when uploading with scheduled commits.") + + scheduler = CommitScheduler( + folder_path=folder_path, + repo_id=repo_id, + repo_type=repo_type_str, + revision=revision, + allow_patterns=allow_patterns, + ignore_patterns=ignore_patterns, + path_in_repo=pi, + private=private, + every=every, + hf_api=api, + ) + out.text(f"Scheduling commits every {every} minutes to {scheduler.repo_id}.") + try: + while True: + time.sleep(100) + except KeyboardInterrupt: + scheduler.stop() + return "Stopped scheduled commits." + + # Otherwise, create repo and proceed with the upload + if not os.path.isfile(resolved_local_path) and not os.path.isdir(resolved_local_path): + raise FileNotFoundError(f"No such file or directory: '{resolved_local_path}'.") + created = api.create_repo( + repo_id=repo_id, + repo_type=repo_type_str, + exist_ok=True, + private=private, + space_sdk="gradio" if repo_type_str == "space" else None, + # ^ We don't want it to fail when uploading to a Space => let's set Gradio by default. + # ^ I'd rather not add CLI args to set it explicitly as we already have `hf repos create` for that. + ).repo_id + + # Check if branch already exists and if not, create it + if revision is not None and not create_pr: + try: + api.repo_info(repo_id=created, repo_type=repo_type_str, revision=revision) + except RevisionNotFoundError: + logger.info(f"Branch '{revision}' not found. Creating it...") + api.create_branch(repo_id=created, repo_type=repo_type_str, branch=revision, exist_ok=True) + # ^ `exist_ok=True` to avoid race concurrency issues + + # File-based upload + if os.path.isfile(resolved_local_path): + return api.upload_file( + path_or_fileobj=resolved_local_path, + path_in_repo=resolved_path_in_repo, + repo_id=created, + repo_type=repo_type_str, + revision=revision, + commit_message=commit_message, + commit_description=commit_description, + create_pr=create_pr, + ) + + # Folder-based upload + return api.upload_folder( + folder_path=resolved_local_path, + path_in_repo=resolved_path_in_repo, + repo_id=created, + repo_type=repo_type_str, + revision=revision, + commit_message=commit_message, + commit_description=commit_description, + create_pr=create_pr, + allow_patterns=resolved_include, + ignore_patterns=exclude, + delete_patterns=delete, + ) + + result = run_upload() + out.result("Uploaded", url=result) + + +def _resolve_upload_paths( + *, repo_id: str, local_path: str | None, path_in_repo: str | None, include: list[str] | None +) -> tuple[str, str, list[str] | None]: + repo_name = repo_id.split("/")[-1] + resolved_include = include + + if local_path is not None and any(c in local_path for c in ["*", "?", "["]): + if include is not None: + raise ValueError("Cannot set --include when local_path contains a wildcard.") + if path_in_repo is not None and path_in_repo != ".": + raise ValueError("Cannot set path_in_repo when local_path contains a wildcard.") + return ".", local_path, ["."] # will be adjusted below; placeholder for type + + if local_path is None and os.path.isfile(repo_name): + return repo_name, repo_name, resolved_include + if local_path is None and os.path.isdir(repo_name): + return repo_name, ".", resolved_include + if local_path is None: + raise ValueError(f"'{repo_name}' is not a local file or folder. Please set local_path explicitly.") + + if path_in_repo is None and os.path.isfile(local_path): + return local_path, os.path.basename(local_path), resolved_include + if path_in_repo is None: + return local_path, ".", resolved_include + return local_path, path_in_repo, resolved_include diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/upload_large_folder.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/upload_large_folder.py new file mode 100644 index 0000000000000000000000000000000000000000..d9836754569cdd0b825ee69063625c0a963436ff --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/upload_large_folder.py @@ -0,0 +1,133 @@ +# Copyright 2023-present, the HuggingFace Inc. team. +# +# 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. +"""Contains command to upload a large folder with the CLI.""" + +import os +import warnings +from typing import Annotated + +import click + +from huggingface_hub import logging +from huggingface_hub.utils import disable_progress_bars + +from ._cli_utils import ( + PrivateOpt, + RepoIdArg, + RepoType, + RepoTypeOpt, + RevisionOpt, + TokenOpt, + get_hf_api, +) +from ._framework import Argument, Option +from ._output import out + + +logger = logging.get_logger(__name__) + + +UPLOAD_LARGE_FOLDER_EXAMPLES = [ + "hf upload-large-folder Wauplin/my-cool-model ./large_model_dir", + "hf upload-large-folder Wauplin/my-cool-model ./large_model_dir --revision v1.0", +] + + +def upload_large_folder( + repo_id: RepoIdArg, + local_path: Annotated[ + str, + Argument( + help="Local path to the folder to upload.", + ), + ], + repo_type: RepoTypeOpt = RepoType.model, + revision: RevisionOpt = None, + private: PrivateOpt = None, + include: Annotated[ + list[str] | None, + Option( + help="Glob patterns to match files to upload.", + ), + ] = None, + exclude: Annotated[ + list[str] | None, + Option( + help="Glob patterns to exclude from files to upload.", + ), + ] = None, + token: TokenOpt = None, + num_workers: Annotated[ + int | None, + Option( + help="Number of workers to use to hash, upload and commit files.", + ), + ] = None, + no_report: Annotated[ + bool, + Option( + help="Whether to disable regular status report.", + ), + ] = False, + no_bars: Annotated[ + bool, + Option( + help="Whether to disable progress bars.", + ), + ] = False, +) -> None: + """[Deprecated] Upload a large folder to the Hub. Use `hf upload` instead.""" + if not os.path.isdir(local_path): + raise click.BadParameter("Large upload is only supported for folders.", param_hint="local_path") + + # Build the equivalent `hf upload` command to recommend to the user. + equivalent = [f"hf upload {repo_id} '{local_path}' --repo-type {repo_type.value}"] + if revision is not None: + equivalent.append(f"--revision '{revision}'") + if private: + equivalent.append("--private") + for pattern in include or []: + equivalent.append(f"--include '{pattern}'") + for pattern in exclude or []: + equivalent.append(f"--exclude '{pattern}'") + + out.warning( + "\n" + "================================================================================\n" + "`hf upload-large-folder` is DEPRECATED and will be removed in a future release.\n" + "\n" + "Use `hf upload` instead:\n" + "\n" + f" {' '.join(equivalent)}\n" + "================================================================================" + ) + + if no_bars: + disable_progress_bars() + + api = get_hf_api(token=token) + with warnings.catch_warnings(): + # Avoid printing the API-level deprecation warning on top of the CLI one above. + warnings.simplefilter("ignore", FutureWarning) + api.upload_large_folder( + repo_id=repo_id, + folder_path=local_path, + repo_type=repo_type.value, + revision=revision, + private=private, + allow_patterns=include, + ignore_patterns=exclude, + num_workers=num_workers, + print_report=not no_report, + ) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/cli/webhooks.py b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/webhooks.py new file mode 100644 index 0000000000000000000000000000000000000000..ddec817f1345edd86745d9a41470e22da4acfe4f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/cli/webhooks.py @@ -0,0 +1,269 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains commands to manage webhooks on the Hugging Face Hub.""" + +import enum +from typing import Annotated, get_args, get_type_hints + +import click + +from huggingface_hub.constants import WEBHOOK_DOMAIN_T +from huggingface_hub.hf_api import WebhookWatchedItem + +from ._cli_utils import ( + TokenOpt, + get_hf_api, + typer_factory, +) +from ._framework import Argument, Option +from ._output import out + + +# Build enums dynamically from Literal types to avoid duplication +_WATCHED_TYPES = get_args(get_type_hints(WebhookWatchedItem)["type"]) +WatchedItemType = enum.Enum("WatchedItemType", {t: t for t in _WATCHED_TYPES}, type=str) # type: ignore[misc] + +_DOMAIN_TYPES = get_args(WEBHOOK_DOMAIN_T) +WebhookDomain = enum.Enum("WebhookDomain", {d: d for d in _DOMAIN_TYPES}, type=str) # type: ignore[misc] + + +def _parse_watch(values: list[str]) -> list[WebhookWatchedItem]: + """Parse 'type:name' strings into WebhookWatchedItem objects. + + Args: + values: List of strings in the format 'type:name' + (e.g., 'model:bert-base-uncased', 'org:HuggingFace'). + + Returns: + List of WebhookWatchedItem objects. + + Raises: + click.BadParameter: If any value doesn't match the expected format. + """ + items = [] + valid_types = tuple(_WATCHED_TYPES) + for v in values: + if ":" not in v: + raise click.BadParameter( + f"Expected format 'type:name' (e.g. 'model:bert-base-uncased'), got '{v}'." + f" Valid types: {', '.join(valid_types)}." + ) + kind, name = v.split(":", 1) + if kind not in valid_types: + raise click.BadParameter(f"Invalid type '{kind}'. Valid types: {', '.join(valid_types)}.") + items.append(WebhookWatchedItem(type=kind, name=name)) # type: ignore + return items + + +webhooks_cli = typer_factory(help="Manage webhooks on the Hub.") + + +@webhooks_cli.command( + "list | ls", + examples=[ + "hf webhooks ls", + "hf webhooks ls --format json", + "hf webhooks ls --format quiet", + ], +) +def webhooks_ls( + token: TokenOpt = None, +) -> None: + """List all webhooks for the current user.""" + api = get_hf_api(token=token) + results = [ + { + "id": w.id, + "url": w.url or "(job)", + "disabled": w.disabled, + "domains": w.domains or [], + "watched": [f"{wi.type}:{wi.name}" for wi in (w.watched or [])], + } + for w in api.list_webhooks() + ] + out.table(results) + + +@webhooks_cli.command( + "info", + examples=[ + "hf webhooks info abc123", + ], +) +def webhooks_info( + webhook_id: Annotated[str, Argument(help="The ID of the webhook.")], + token: TokenOpt = None, +) -> None: + """Show full details for a single webhook.""" + api = get_hf_api(token=token) + webhook = api.get_webhook(webhook_id) + out.dict(webhook) + + +@webhooks_cli.command( + "create", + examples=[ + "hf webhooks create --url https://example.com/hook --watch model:bert-base-uncased", + "hf webhooks create --url https://example.com/hook --watch org:HuggingFace --watch model:gpt2 --domain repo", + "hf webhooks create --job-id 687f911eaea852de79c4a50a --watch user:julien-c", + ], +) +def webhooks_create( + watch: Annotated[ + list[str], + Option( + "--watch", + help="Item to watch, in 'type:name' format (e.g. 'model:bert-base-uncased'). Repeatable.", + ), + ], + url: Annotated[ + str | None, + Option(help="URL to send webhook payloads to. Mutually exclusive with --job-id."), + ] = None, + job_id: Annotated[ + str | None, + Option( + "--job-id", + help="ID of a Job to trigger (from job.id) instead of pinging a URL. Mutually exclusive with --url.", + ), + ] = None, + domain: Annotated[ + list[WebhookDomain] | None, + Option( + "--domain", + help="Domain to watch: 'repo' or 'discussions'. Repeatable. Defaults to all domains.", + ), + ] = None, + secret: Annotated[ + str | None, + Option(help="Optional secret used to sign webhook payloads."), + ] = None, + token: TokenOpt = None, +) -> None: + """Create a new webhook. + + Provide either --url (to ping a remote server) or --job-id (to trigger a Job), but not both. + """ + if url is not None and job_id is not None: + raise click.BadParameter("Provide either --url or --job-id, not both.") + if url is None and job_id is None: + raise click.BadParameter("Provide either --url or --job-id.") + api = get_hf_api(token=token) + watched_items = _parse_watch(watch) + domains = [d.value for d in domain] if domain else None + webhook = api.create_webhook(url=url, job_id=job_id, watched=watched_items, domains=domains, secret=secret) # type: ignore + out.result("Webhook created", id=webhook.id) + + +@webhooks_cli.command( + "update", + examples=[ + "hf webhooks update abc123 --url https://new-url.com/hook", + "hf webhooks update abc123 --watch model:gpt2 --domain repo", + "hf webhooks update abc123 --secret newsecret", + ], +) +def webhooks_update( + webhook_id: Annotated[str, Argument(help="The ID of the webhook to update.")], + url: Annotated[ + str | None, + Option(help="New URL to send webhook payloads to."), + ] = None, + watch: Annotated[ + list[str] | None, + Option( + "--watch", + help=( + "New list of items to watch, in 'type:name' format. " + "Repeatable. Replaces the entire existing watched list." + ), + ), + ] = None, + domain: Annotated[ + list[WebhookDomain] | None, + Option( + "--domain", + help="New list of domains to watch: 'repo' or 'discussions'. Repeatable.", + ), + ] = None, + secret: Annotated[ + str | None, + Option(help="New secret used to sign webhook payloads."), + ] = None, + token: TokenOpt = None, +) -> None: + """Update an existing webhook. Only provided options are changed.""" + api = get_hf_api(token=token) + watched_items = _parse_watch(watch) if watch else None + domains = [d.value for d in domain] if domain else None + webhook = api.update_webhook(webhook_id, url=url, watched=watched_items, domains=domains, secret=secret) # type: ignore + out.result("Webhook updated", id=webhook.id) + + +@webhooks_cli.command( + "enable", + examples=[ + "hf webhooks enable abc123", + ], +) +def webhooks_enable( + webhook_id: Annotated[str, Argument(help="The ID of the webhook to enable.")], + token: TokenOpt = None, +) -> None: + """Enable a disabled webhook.""" + api = get_hf_api(token=token) + webhook = api.enable_webhook(webhook_id) + out.result("Webhook enabled", id=webhook.id) + + +@webhooks_cli.command( + "disable", + examples=[ + "hf webhooks disable abc123", + ], +) +def webhooks_disable( + webhook_id: Annotated[str, Argument(help="The ID of the webhook to disable.")], + token: TokenOpt = None, +) -> None: + """Disable an active webhook.""" + api = get_hf_api(token=token) + webhook = api.disable_webhook(webhook_id) + out.result("Webhook disabled", id=webhook.id) + + +@webhooks_cli.command( + "delete", + examples=[ + "hf webhooks delete abc123", + "hf webhooks delete abc123 --yes", + ], +) +def webhooks_delete( + webhook_id: Annotated[str, Argument(help="The ID of the webhook to delete.")], + yes: Annotated[ + bool, + Option( + "--yes", + "-y", + help="Skip confirmation prompt.", + ), + ] = False, + token: TokenOpt = None, +) -> None: + """Delete a webhook permanently.""" + out.confirm(f"Are you sure you want to delete webhook '{webhook_id}'?", yes=yes) + api = get_hf_api(token=token) + api.delete_webhook(webhook_id) + out.result("Webhook deleted", id=webhook_id) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/community.py b/.venv/lib/python3.13/site-packages/huggingface_hub/community.py new file mode 100644 index 0000000000000000000000000000000000000000..58e64100c48c461bb6d4dfb42230ffbf412bff57 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/community.py @@ -0,0 +1,363 @@ +""" +Data structures to interact with Discussions and Pull Requests on the Hub. + +See [the Discussions and Pull Requests guide](https://huggingface.co/docs/hub/repositories-pull-requests-discussions) +for more information on Pull Requests, Discussions, and the community tab. +""" + +from dataclasses import dataclass +from datetime import datetime +from typing import Literal, TypedDict + +from . import constants +from .utils import parse_datetime + + +DiscussionStatus = Literal["open", "closed", "merged", "draft"] + + +@dataclass +class Discussion: + """ + A Discussion or Pull Request on the Hub. + + This dataclass is not intended to be instantiated directly. + + Attributes: + title (`str`): + The title of the Discussion / Pull Request + status (`str`): + The status of the Discussion / Pull Request. + It must be one of: + * `"open"` + * `"closed"` + * `"merged"` (only for Pull Requests ) + * `"draft"` (only for Pull Requests ) + num (`int`): + The number of the Discussion / Pull Request. + repo_id (`str`): + The id (`"{namespace}/{repo_name}"`) of the repo on which + the Discussion / Pull Request was open. + repo_type (`str`): + The type of the repo on which the Discussion / Pull Request was open. + Possible values are: `"model"`, `"dataset"`, `"space"`. + author (`str`): + The username of the Discussion / Pull Request author. + Can be `"deleted"` if the user has been deleted since. + is_pull_request (`bool`): + Whether or not this is a Pull Request. + created_at (`datetime`): + The `datetime` of creation of the Discussion / Pull Request. + endpoint (`str`): + Endpoint of the Hub. Default is https://huggingface.co. + git_reference (`str`, *optional*): + (property) Git reference to which changes can be pushed if this is a Pull Request, `None` otherwise. + url (`str`): + (property) URL of the discussion on the Hub. + """ + + title: str + status: DiscussionStatus + num: int + repo_id: str + repo_type: str + author: str + is_pull_request: bool + created_at: datetime + endpoint: str + + @property + def git_reference(self) -> str | None: + """ + If this is a Pull Request , returns the git reference to which changes can be pushed. + Returns `None` otherwise. + """ + if self.is_pull_request: + return f"refs/pr/{self.num}" + return None + + @property + def url(self) -> str: + """Returns the URL of the discussion on the Hub.""" + if self.repo_type is None or self.repo_type == constants.REPO_TYPE_MODEL: + return f"{self.endpoint}/{self.repo_id}/discussions/{self.num}" + return f"{self.endpoint}/{self.repo_type}s/{self.repo_id}/discussions/{self.num}" + + +@dataclass +class DiscussionWithDetails(Discussion): + """ + Subclass of [`Discussion`]. + + Attributes: + title (`str`): + The title of the Discussion / Pull Request + status (`str`): + The status of the Discussion / Pull Request. + It can be one of: + * `"open"` + * `"closed"` + * `"merged"` (only for Pull Requests ) + * `"draft"` (only for Pull Requests ) + num (`int`): + The number of the Discussion / Pull Request. + repo_id (`str`): + The id (`"{namespace}/{repo_name}"`) of the repo on which + the Discussion / Pull Request was open. + repo_type (`str`): + The type of the repo on which the Discussion / Pull Request was open. + Possible values are: `"model"`, `"dataset"`, `"space"`. + author (`str`): + The username of the Discussion / Pull Request author. + Can be `"deleted"` if the user has been deleted since. + is_pull_request (`bool`): + Whether or not this is a Pull Request. + created_at (`datetime`): + The `datetime` of creation of the Discussion / Pull Request. + events (`list` of [`DiscussionEvent`]) + The list of [`DiscussionEvents`] in this Discussion or Pull Request. + conflicting_files (`Union[list[str], bool, None]`, *optional*): + A list of conflicting files if this is a Pull Request. + `None` if `self.is_pull_request` is `False`. + `True` if there are conflicting files but the list can't be retrieved. + target_branch (`str`, *optional*): + The branch into which changes are to be merged if this is a + Pull Request . `None` if `self.is_pull_request` is `False`. + merge_commit_oid (`str`, *optional*): + If this is a merged Pull Request , this is set to the OID / SHA of + the merge commit, `None` otherwise. + diff (`str`, *optional*): + The git diff if this is a Pull Request , `None` otherwise. + endpoint (`str`): + Endpoint of the Hub. Default is https://huggingface.co. + git_reference (`str`, *optional*): + (property) Git reference to which changes can be pushed if this is a Pull Request, `None` otherwise. + url (`str`): + (property) URL of the discussion on the Hub. + """ + + events: list["DiscussionEvent"] + conflicting_files: list[str] | bool | None + target_branch: str | None + merge_commit_oid: str | None + diff: str | None + + +class DiscussionEventArgs(TypedDict): + id: str + type: str + created_at: datetime + author: str + _event: dict + + +@dataclass +class DiscussionEvent: + """ + An event in a Discussion or Pull Request. + + Use concrete classes: + * [`DiscussionComment`] + * [`DiscussionStatusChange`] + * [`DiscussionCommit`] + * [`DiscussionTitleChange`] + + Attributes: + id (`str`): + The ID of the event. An hexadecimal string. + type (`str`): + The type of the event. + created_at (`datetime`): + A [`datetime`](https://docs.python.org/3/library/datetime.html?highlight=datetime#datetime.datetime) + object holding the creation timestamp for the event. + author (`str`): + The username of the Discussion / Pull Request author. + Can be `"deleted"` if the user has been deleted since. + """ + + id: str + type: str + created_at: datetime + author: str + + _event: dict + """Stores the original event data, in case we need to access it later.""" + + +@dataclass +class DiscussionComment(DiscussionEvent): + """A comment in a Discussion / Pull Request. + + Subclass of [`DiscussionEvent`]. + + + Attributes: + id (`str`): + The ID of the event. An hexadecimal string. + type (`str`): + The type of the event. + created_at (`datetime`): + A [`datetime`](https://docs.python.org/3/library/datetime.html?highlight=datetime#datetime.datetime) + object holding the creation timestamp for the event. + author (`str`): + The username of the Discussion / Pull Request author. + Can be `"deleted"` if the user has been deleted since. + content (`str`): + The raw markdown content of the comment. Mentions, links and images are not rendered. + edited (`bool`): + Whether or not this comment has been edited. + hidden (`bool`): + Whether or not this comment has been hidden. + """ + + content: str + edited: bool + hidden: bool + + @property + def rendered(self) -> str: + """The rendered comment, as a HTML string""" + return self._event["data"]["latest"]["html"] + + @property + def last_edited_at(self) -> datetime: + """The last edit time, as a `datetime` object.""" + return parse_datetime(self._event["data"]["latest"]["updatedAt"]) + + @property + def last_edited_by(self) -> str: + """The last edit time, as a `datetime` object.""" + return self._event["data"]["latest"].get("author", {}).get("name", "deleted") + + @property + def edit_history(self) -> list[dict]: + """The edit history of the comment""" + return self._event["data"]["history"] + + @property + def number_of_edits(self) -> int: + return len(self.edit_history) + + +@dataclass +class DiscussionStatusChange(DiscussionEvent): + """A change of status in a Discussion / Pull Request. + + Subclass of [`DiscussionEvent`]. + + Attributes: + id (`str`): + The ID of the event. An hexadecimal string. + type (`str`): + The type of the event. + created_at (`datetime`): + A [`datetime`](https://docs.python.org/3/library/datetime.html?highlight=datetime#datetime.datetime) + object holding the creation timestamp for the event. + author (`str`): + The username of the Discussion / Pull Request author. + Can be `"deleted"` if the user has been deleted since. + new_status (`str`): + The status of the Discussion / Pull Request after the change. + It can be one of: + * `"open"` + * `"closed"` + * `"merged"` (only for Pull Requests ) + """ + + new_status: str + + +@dataclass +class DiscussionCommit(DiscussionEvent): + """A commit in a Pull Request. + + Subclass of [`DiscussionEvent`]. + + Attributes: + id (`str`): + The ID of the event. An hexadecimal string. + type (`str`): + The type of the event. + created_at (`datetime`): + A [`datetime`](https://docs.python.org/3/library/datetime.html?highlight=datetime#datetime.datetime) + object holding the creation timestamp for the event. + author (`str`): + The username of the Discussion / Pull Request author. + Can be `"deleted"` if the user has been deleted since. + summary (`str`): + The summary of the commit. + oid (`str`): + The OID / SHA of the commit, as a hexadecimal string. + """ + + summary: str + oid: str + + +@dataclass +class DiscussionTitleChange(DiscussionEvent): + """A rename event in a Discussion / Pull Request. + + Subclass of [`DiscussionEvent`]. + + Attributes: + id (`str`): + The ID of the event. An hexadecimal string. + type (`str`): + The type of the event. + created_at (`datetime`): + A [`datetime`](https://docs.python.org/3/library/datetime.html?highlight=datetime#datetime.datetime) + object holding the creation timestamp for the event. + author (`str`): + The username of the Discussion / Pull Request author. + Can be `"deleted"` if the user has been deleted since. + old_title (`str`): + The previous title for the Discussion / Pull Request. + new_title (`str`): + The new title. + """ + + old_title: str + new_title: str + + +def deserialize_event(event: dict) -> DiscussionEvent: + """Instantiates a [`DiscussionEvent`] from a dict""" + event_id: str = event["id"] + event_type: str = event["type"] + created_at = parse_datetime(event["createdAt"]) + + common_args: DiscussionEventArgs = { + "id": event_id, + "type": event_type, + "created_at": created_at, + "author": event.get("author", {}).get("name", "deleted"), + "_event": event, + } + + if event_type == "comment": + return DiscussionComment( + **common_args, + edited=event["data"]["edited"], + hidden=event["data"]["hidden"], + content=event["data"]["latest"]["raw"], + ) + if event_type == "status-change": + return DiscussionStatusChange( + **common_args, + new_status=event["data"]["status"], + ) + if event_type == "commit": + return DiscussionCommit( + **common_args, + summary=event["data"]["subject"], + oid=event["data"]["oid"], + ) + if event_type == "title-change": + return DiscussionTitleChange( + **common_args, + old_title=event["data"]["from"], + new_title=event["data"]["to"], + ) + + return DiscussionEvent(**common_args) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/constants.py b/.venv/lib/python3.13/site-packages/huggingface_hub/constants.py new file mode 100644 index 0000000000000000000000000000000000000000..20b301b6d3dc4bc0b6d0ef181172c04c95659d4d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/constants.py @@ -0,0 +1,342 @@ +import os +import re +import typing +from typing import Literal +from urllib.parse import urlsplit + + +# Possible values for env variables + + +ENV_VARS_TRUE_VALUES = {"1", "ON", "YES", "TRUE"} +ENV_VARS_TRUE_AND_AUTO_VALUES = ENV_VARS_TRUE_VALUES.union({"AUTO"}) + + +def _is_true(value: str | None) -> bool: + if value is None: + return False + return value.upper() in ENV_VARS_TRUE_VALUES + + +def _as_int(value: str | None) -> int | None: + if value is None: + return None + return int(value) + + +# Constants for file downloads + +PYTORCH_WEIGHTS_NAME = "pytorch_model.bin" +TF2_WEIGHTS_NAME = "tf_model.h5" +TF_WEIGHTS_NAME = "model.ckpt" +FLAX_WEIGHTS_NAME = "flax_model.msgpack" +CONFIG_NAME = "config.json" +REPOCARD_NAME = "README.md" +EVAL_RESULTS_FOLDER = ".eval_results" +DEFAULT_ETAG_TIMEOUT = 10 +DEFAULT_DOWNLOAD_TIMEOUT = 10 +DEFAULT_REQUEST_TIMEOUT = 10 +DOWNLOAD_CHUNK_SIZE = 10 * 1024 * 1024 +MAX_HTTP_DOWNLOAD_SIZE = 50 * 1000 * 1000 * 1000 # 50 GB + +# Constants for serialization + +PYTORCH_WEIGHTS_FILE_PATTERN = "pytorch_model{suffix}.bin" # Unsafe pickle: use safetensors instead +SAFETENSORS_WEIGHTS_FILE_PATTERN = "model{suffix}.safetensors" +TF2_WEIGHTS_FILE_PATTERN = "tf_model{suffix}.h5" + +# Constants for safetensors repos + +SAFETENSORS_SINGLE_FILE = "model.safetensors" +SAFETENSORS_INDEX_FILE = "model.safetensors.index.json" +SAFETENSORS_MAX_HEADER_LENGTH = 25_000_000 + +# Timeout of acquiring file lock and logging the attempt +FILELOCK_LOG_EVERY_SECONDS = 10 + +# Git-related constants + +DEFAULT_REVISION = "main" +REGEX_COMMIT_OID = re.compile(r"[A-Fa-f0-9]{5,40}") + +HUGGINGFACE_CO_URL_HOME = "https://huggingface.co/" + +_staging_mode = _is_true(os.environ.get("HUGGINGFACE_CO_STAGING")) + +_HF_DEFAULT_ENDPOINT = "https://huggingface.co" +_HF_DEFAULT_STAGING_ENDPOINT = "https://hub-ci.huggingface.co" +ENDPOINT = os.getenv("HF_ENDPOINT", _HF_DEFAULT_ENDPOINT).rstrip("/") +HUGGINGFACE_CO_URL_TEMPLATE = ENDPOINT + "/{repo_id}/resolve/{revision}/{filename}" + +if _staging_mode: + ENDPOINT = _HF_DEFAULT_STAGING_ENDPOINT + HUGGINGFACE_CO_URL_TEMPLATE = _HF_DEFAULT_STAGING_ENDPOINT + "/{repo_id}/resolve/{revision}/{filename}" + +# Hosts whose web URLs can be parsed into a ``hf://`` URI (see ``huggingface_hub/utils/_hf_uris.py``). +# Includes the public Hub host and its ``hf.co`` short domain, the staging host, and the host of the +# currently configured ``ENDPOINT`` so that self-hosted / staging endpoints work too. +HF_URL_HOSTS: frozenset[str] = frozenset( + {"hf.co"} + | { + host.lower() + for host in ( + urlsplit(_HF_DEFAULT_ENDPOINT).hostname, + urlsplit(_HF_DEFAULT_STAGING_ENDPOINT).hostname, + urlsplit(ENDPOINT).hostname, + ) + if host + } +) + +DATASETS_SERVER_ENDPOINT = "https://datasets-server.huggingface.co" + +HUGGINGFACE_HEADER_X_REPO_COMMIT = "X-Repo-Commit" +HUGGINGFACE_HEADER_X_LINKED_ETAG = "X-Linked-Etag" +HUGGINGFACE_HEADER_X_LINKED_SIZE = "X-Linked-Size" +HUGGINGFACE_HEADER_X_BILL_TO = "X-HF-Bill-To" + +INFERENCE_ENDPOINT = os.environ.get("HF_INFERENCE_ENDPOINT", "https://api-inference.huggingface.co") + +# See https://huggingface.co/docs/inference-endpoints/index +INFERENCE_ENDPOINTS_ENDPOINT = "https://api.endpoints.huggingface.cloud/v2" +INFERENCE_CATALOG_ENDPOINT = "https://endpoints.huggingface.co/api/catalog" + +# See https://api.endpoints.huggingface.cloud/#post-/v2/endpoint/-namespace- +INFERENCE_ENDPOINT_IMAGE_KEYS = [ + "custom", + "huggingface", + "huggingfaceNeuron", + "llamacpp", + "tei", + "tgi", + "tgiNeuron", +] + +# Proxy for third-party providers +INFERENCE_PROXY_TEMPLATE = "https://router.huggingface.co/{provider}" + +REPO_ID_SEPARATOR = "--" +# ^ this substring is not allowed in repo_ids on hf.co +# and is the canonical one we use for serialization of repo ids elsewhere. + + +REPO_TYPE_DATASET = "dataset" +REPO_TYPE_SPACE = "space" +REPO_TYPE_MODEL = "model" +REPO_TYPE_KERNEL = "kernel" +REPO_TYPES = [None, REPO_TYPE_MODEL, REPO_TYPE_DATASET, REPO_TYPE_SPACE] +REPO_TYPES_WITH_KERNEL = REPO_TYPES + [REPO_TYPE_KERNEL] +SPACES_SDK_TYPES = ["gradio", "streamlit", "docker", "static"] + +REPO_TYPES_URL_PREFIXES = { + REPO_TYPE_DATASET: "datasets/", + REPO_TYPE_SPACE: "spaces/", + REPO_TYPE_KERNEL: "kernels/", +} +REPO_TYPES_MAPPING = { + "datasets": REPO_TYPE_DATASET, + "spaces": REPO_TYPE_SPACE, + "models": REPO_TYPE_MODEL, + "kernels": REPO_TYPE_KERNEL, +} + +# HF Hub URIs (``hf://...``). See ``huggingface_hub/utils/_hf_uris.py`` +# and ``docs/source/en/package_reference/hf_uris.md`` for the full grammar. +HF_PROTOCOL = "hf://" +HfUriType = Literal["model", "dataset", "space", "kernel", "bucket"] +# Maps the plural URI prefix that may appear in a HF URI (e.g. ``datasets/``) +# to the canonical singular type name. Buckets are first-class HF URI types. +HF_URI_TYPE_PREFIXES: dict[str, HfUriType] = { + "models": "model", + "datasets": "dataset", + "spaces": "space", + "kernels": "kernel", + "buckets": "bucket", +} + + +DiscussionTypeFilter = Literal["all", "discussion", "pull_request"] +DISCUSSION_TYPES: tuple[DiscussionTypeFilter, ...] = typing.get_args(DiscussionTypeFilter) +DiscussionStatusFilter = Literal["all", "open", "closed"] +DISCUSSION_STATUS: tuple[DiscussionTypeFilter, ...] = typing.get_args(DiscussionStatusFilter) + +# Webhook subscription types +WEBHOOK_DOMAIN_T = Literal["repo", "discussions"] + +# default cache +default_home = os.path.join(os.path.expanduser("~"), ".cache") +HF_HOME = os.path.expandvars( + os.path.expanduser( + os.getenv( + "HF_HOME", + os.path.join(os.getenv("XDG_CACHE_HOME", default_home), "huggingface"), + ) + ) +) + +default_cache_path = os.path.join(HF_HOME, "hub") +default_assets_cache_path = os.path.join(HF_HOME, "assets") + +# Legacy env variables +HUGGINGFACE_HUB_CACHE = os.getenv("HUGGINGFACE_HUB_CACHE", default_cache_path) +HUGGINGFACE_ASSETS_CACHE = os.getenv("HUGGINGFACE_ASSETS_CACHE", default_assets_cache_path) + +# New env variables +HF_HUB_CACHE = os.path.expandvars( + os.path.expanduser( + os.getenv( + "HF_HUB_CACHE", + HUGGINGFACE_HUB_CACHE, + ) + ) +) +HF_ASSETS_CACHE = os.path.expandvars( + os.path.expanduser( + os.getenv( + "HF_ASSETS_CACHE", + HUGGINGFACE_ASSETS_CACHE, + ) + ) +) + +HF_HUB_OFFLINE = _is_true(os.environ.get("HF_HUB_OFFLINE") or os.environ.get("TRANSFORMERS_OFFLINE")) + + +def is_offline_mode() -> bool: + """Returns whether we are in offline mode for the Hub. + + When offline mode is enabled, all HTTP requests made with `get_session` will raise an `OfflineModeIsEnabled` exception. + + Example: + ```py + from huggingface_hub import is_offline_mode + + def list_files(repo_id: str): + if is_offline_mode(): + ... # list files from local cache (degraded experience but still functional) + else: + ... # list files from Hub (complete experience) + ``` + """ + return HF_HUB_OFFLINE + + +# File created to mark that the version check has been done. +# Check is performed once per 24 hours at most. +CHECK_FOR_UPDATE_DONE_PATH = os.path.join(HF_HOME, ".check_for_update_done") + +# File caching the AI agent harnesses registry fetched from `{ENDPOINT}/api/agent-harnesses`. +# Refreshed once per 24 hours at most (see `utils/_detect_agent.py`). +AGENT_HARNESSES_PATH = os.path.join(HF_HOME, ".agent_harnesses.json") + +# Set to skip the CLI update check (PyPI query + "new version available" warning at startup). +HF_HUB_DISABLE_UPDATE_CHECK = _is_true(os.environ.get("HF_HUB_DISABLE_UPDATE_CHECK")) + +# If set, log level will be set to DEBUG and all requests made to the Hub will be logged +# as curl commands for reproducibility. +HF_DEBUG = _is_true(os.environ.get("HF_DEBUG")) + +# Opt-out from telemetry requests +HF_HUB_DISABLE_TELEMETRY = ( + _is_true(os.environ.get("HF_HUB_DISABLE_TELEMETRY")) # HF-specific env variable + or _is_true(os.environ.get("DISABLE_TELEMETRY")) + or _is_true(os.environ.get("DO_NOT_TRACK")) # https://consoledonottrack.com/ +) + +HF_TOKEN_PATH = os.path.expandvars( + os.path.expanduser( + os.getenv( + "HF_TOKEN_PATH", + os.path.join(HF_HOME, "token"), + ) + ) +) +HF_STORED_TOKENS_PATH = os.path.join(os.path.dirname(HF_TOKEN_PATH), "stored_tokens") + +if _staging_mode: + # In staging mode, we use a different cache to ensure we don't mix up production and staging data or tokens + # In practice in `huggingface_hub` tests, we monkeypatch these values with temporary directories. The following + # lines are only used in third-party libraries tests (e.g. `transformers`, `diffusers`, etc.). + _staging_home = os.path.join(os.path.expanduser("~"), ".cache", "huggingface_staging") + HUGGINGFACE_HUB_CACHE = os.path.join(_staging_home, "hub") + HF_TOKEN_PATH = os.path.join(_staging_home, "token") + +# Here, `True` will disable progress bars globally without possibility of enabling it +# programmatically. `False` will enable them without possibility of disabling them. +# If environment variable is not set (None), then the user is free to enable/disable +# them programmatically. +# TL;DR: env variable has priority over code +__HF_HUB_DISABLE_PROGRESS_BARS = os.environ.get("HF_HUB_DISABLE_PROGRESS_BARS") +HF_HUB_DISABLE_PROGRESS_BARS: bool | None = ( + _is_true(__HF_HUB_DISABLE_PROGRESS_BARS) if __HF_HUB_DISABLE_PROGRESS_BARS is not None else None +) + +# Disable symlinks in the cache (files are copied instead of symlinked) +HF_HUB_DISABLE_SYMLINKS: bool = _is_true(os.environ.get("HF_HUB_DISABLE_SYMLINKS")) + +# Disable warning on machines that do not support symlinks (e.g. Windows non-developer) +HF_HUB_DISABLE_SYMLINKS_WARNING: bool = _is_true(os.environ.get("HF_HUB_DISABLE_SYMLINKS_WARNING")) + +# Disable warning when using experimental features +HF_HUB_DISABLE_EXPERIMENTAL_WARNING: bool = _is_true(os.environ.get("HF_HUB_DISABLE_EXPERIMENTAL_WARNING")) + +# Disable sending the cached token by default is all HTTP requests to the Hub +HF_HUB_DISABLE_IMPLICIT_TOKEN: bool = _is_true(os.environ.get("HF_HUB_DISABLE_IMPLICIT_TOKEN")) + +HF_XET_HIGH_PERFORMANCE: bool = _is_true(os.environ.get("HF_XET_HIGH_PERFORMANCE")) + +# Bucket and mount path used when launching Jobs +HF_JOBS_ARTIFACTS_BUCKET_NAME: str = "jobs-artifacts" +HF_JOBS_ARTIFACTS_MOUNT_PATH: str = "/data" + +# hf_transfer is not used anymore. Let's warn user is case they set the env variable. +# Note: we use FutureWarning (shown by default) instead of DeprecationWarning (silenced +# by default for end users) so users running standard `python` actually see the message. +if _is_true(os.environ.get("HF_HUB_ENABLE_HF_TRANSFER")) and not HF_XET_HIGH_PERFORMANCE: + import warnings + + warnings.warn( + "The `HF_HUB_ENABLE_HF_TRANSFER` environment variable is deprecated as 'hf_transfer' is not used anymore. " + "Please use `HF_XET_HIGH_PERFORMANCE` instead to enable high performance transfer with Xet. " + "Visit https://huggingface.co/docs/huggingface_hub/package_reference/environment_variables#hfxethighperformance for more details.", + FutureWarning, + ) + +# Used to override the etag timeout on a system level +HF_HUB_ETAG_TIMEOUT: int = _as_int(os.environ.get("HF_HUB_ETAG_TIMEOUT")) or DEFAULT_ETAG_TIMEOUT + +# Used to override the get request timeout on a system level +# Also used as a default timeout for other requests if not specified (kept the naming for legacy reasons) +HF_HUB_DOWNLOAD_TIMEOUT: int = _as_int(os.environ.get("HF_HUB_DOWNLOAD_TIMEOUT")) or DEFAULT_DOWNLOAD_TIMEOUT + +# Allows to add information about the requester in the user-agent (e.g. partner name) +HF_HUB_USER_AGENT_ORIGIN: str | None = os.environ.get("HF_HUB_USER_AGENT_ORIGIN") + +# If OAuth didn't work after 2 redirects, there's likely a third-party cookie issue in the Space iframe view. +# In this case, we redirect the user to the non-iframe view. +OAUTH_MAX_REDIRECTS = 2 + +# OAuth-related environment variables injected by the Space +OAUTH_CLIENT_ID = os.environ.get("OAUTH_CLIENT_ID") +OAUTH_CLIENT_SECRET = os.environ.get("OAUTH_CLIENT_SECRET") +OAUTH_SCOPES = os.environ.get("OAUTH_SCOPES") +OPENID_PROVIDER_URL = os.environ.get("OPENID_PROVIDER_URL") + +# OAuth client ID of the Device Code login flow (RFC 8628) used by `hf auth login` / `login()`. +# Overridable for Hub deployments (staging, Enterprise) where the default client ID is not provisioned. +DEVICE_CODE_OAUTH_CLIENT_ID = os.environ.get("HF_DEVICE_CODE_OAUTH_CLIENT_ID", "26be6b09-91c5-47da-9861-d2d2bb7a7e36") + +# Xet constants +HUGGINGFACE_HEADER_X_XET_ENDPOINT = "X-Xet-Cas-Url" +HUGGINGFACE_HEADER_X_XET_ACCESS_TOKEN = "X-Xet-Access-Token" +HUGGINGFACE_HEADER_X_XET_EXPIRATION = "X-Xet-Token-Expiration" +HUGGINGFACE_HEADER_X_XET_HASH = "X-Xet-Hash" +HUGGINGFACE_HEADER_X_XET_REFRESH_ROUTE = "X-Xet-Refresh-Route" +HUGGINGFACE_HEADER_LINK_XET_AUTH_KEY = "xet-auth" + +default_xet_cache_path = os.path.join(HF_HOME, "xet") +HF_XET_CACHE = os.getenv("HF_XET_CACHE", default_xet_cache_path) +HF_HUB_DISABLE_XET: bool = _is_true(os.environ.get("HF_HUB_DISABLE_XET")) + +# Bucket hosting the static sandbox server binary (see huggingface_hub.Sandbox) +SANDBOX_SERVER_BUCKET: str = "huggingface/sbx-server" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/dataclasses.py b/.venv/lib/python3.13/site-packages/huggingface_hub/dataclasses.py new file mode 100644 index 0000000000000000000000000000000000000000..e7c04dd3d7b5d4a0ab088645d0c28894054ffe94 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/dataclasses.py @@ -0,0 +1,684 @@ +import collections.abc +import inspect +import types +from collections.abc import Callable +from dataclasses import MISSING, Field, field, fields, make_dataclass +from functools import lru_cache, wraps +from typing import ( + Annotated, + Any, + ForwardRef, + Literal, + Type, + TypeVar, + Union, + get_args, + get_origin, + overload, +) + + +try: + # Python 3.11+ + from typing import NotRequired, Required # type: ignore +except ImportError: + try: + # In case typing_extensions is installed + from typing_extensions import NotRequired, Required # type: ignore + except ImportError: + # Fallback: create dummy types that will never match + Required = type("Required", (), {}) # type: ignore + NotRequired = type("NotRequired", (), {}) # type: ignore + +from .errors import ( + StrictDataclassClassValidationError, + StrictDataclassDefinitionError, + StrictDataclassFieldValidationError, +) + + +Validator_T = Callable[[Any], None] +T = TypeVar("T") +TypedDictType = TypeVar("TypedDictType", bound=dict[str, Any]) + +_TYPED_DICT_DEFAULT_VALUE = object() # used as default value in TypedDict fields (to distinguish from None) + + +# The overload decorator helps type checkers understand the different return types +@overload +def strict(cls: Type[T]) -> Type[T]: ... + + +@overload +def strict(*, accept_kwargs: bool = False) -> Callable[[Type[T]], Type[T]]: ... + + +def strict(cls: Type[T] | None = None, *, accept_kwargs: bool = False) -> Type[T] | Callable[[Type[T]], Type[T]]: + """ + Decorator to add strict validation to a dataclass. + + This decorator must be used on top of `@dataclass` to ensure IDEs and static typing tools + recognize the class as a dataclass. + + Can be used with or without arguments: + - `@strict` + - `@strict(accept_kwargs=True)` + + Args: + cls: + The class to convert to a strict dataclass. + accept_kwargs (`bool`, *optional*): + If True, allows arbitrary keyword arguments in `__init__`. Defaults to False. + + Returns: + The enhanced dataclass with strict validation on field assignment. + + Example: + ```py + >>> from dataclasses import dataclass + >>> from huggingface_hub.dataclasses import as_validated_field, strict, validated_field + + >>> @as_validated_field + >>> def positive_int(value: int): + ... if not value >= 0: + ... raise ValueError(f"Value must be positive, got {value}") + + >>> @strict(accept_kwargs=True) + ... @dataclass + ... class User: + ... name: str + ... age: int = positive_int(default=10) + + # Initialize + >>> User(name="John") + User(name='John', age=10) + + # Extra kwargs are accepted + >>> User(name="John", age=30, lastname="Doe") + User(name='John', age=30, *lastname='Doe') + + # Invalid type => raises + >>> User(name="John", age="30") + huggingface_hub.errors.StrictDataclassFieldValidationError: Validation error for field 'age': + TypeError: Field 'age' expected int, got str (value: '30') + + # Invalid value => raises + >>> User(name="John", age=-1) + huggingface_hub.errors.StrictDataclassFieldValidationError: Validation error for field 'age': + ValueError: Value must be positive, got -1 + ``` + """ + + def wrap(cls: Type[T]) -> Type[T]: + if not hasattr(cls, "__dataclass_fields__"): + raise StrictDataclassDefinitionError( + f"Class '{cls.__name__}' must be a dataclass before applying @strict." + ) + + # List and store validators + field_validators: dict[str, list[Validator_T]] = {} + for f in fields(cls): # type: ignore [arg-type] + validators = [] + validators.append(_create_type_validator(f)) + custom_validator = f.metadata.get("validator") + if custom_validator is not None: + if not isinstance(custom_validator, list): + custom_validator = [custom_validator] + for validator in custom_validator: + if not _is_validator(validator): + raise StrictDataclassDefinitionError( + f"Invalid validator for field '{f.name}': {validator}. Must be a callable taking a single argument." + ) + validators.extend(custom_validator) + field_validators[f.name] = validators + cls.__validators__ = field_validators # type: ignore + + # Override __setattr__ to validate fields on assignment + original_setattr = cls.__setattr__ + + def __strict_setattr__(self: Any, name: str, value: Any) -> None: + """Custom __setattr__ method for strict dataclasses.""" + # Run all validators + for validator in self.__validators__.get(name, []): + try: + validator(value) + except (ValueError, TypeError) as e: + raise StrictDataclassFieldValidationError(field=name, cause=e) from e + + # If validation passed, set the attribute + original_setattr(self, name, value) + + cls.__setattr__ = __strict_setattr__ # type: ignore + + if accept_kwargs: + # (optional) Override __init__ to accept arbitrary keyword arguments + original_init = cls.__init__ + + @wraps(original_init) + def __init__(self, *args, **kwargs: Any) -> None: + # Extract only the fields that are part of the dataclass + dataclass_fields = {f.name for f in fields(cls)} # type: ignore [arg-type] + standard_kwargs = {k: v for k, v in kwargs.items() if k in dataclass_fields} + + # User shouldn't define custom `__init__` when `accepts_kwargs`, and instead + # are advised to move field manipulation to `__post_init__` (e.g., derive new field from existing ones) + # We need to call bare `__init__` here without `__post_init__` but the``original_init`` would call + # post-init right away with no kwargs. + if len(args) > 0: + raise ValueError( + f"When `accept_kwargs=True`, {cls.__name__} accepts only keyword arguments, " + f"but found `{len(args)}` positional args." + ) + + for f in fields(cls): # type: ignore + if f.name in standard_kwargs: + setattr(self, f.name, standard_kwargs[f.name]) + elif f.default is not MISSING: + setattr(self, f.name, f.default) + elif f.default_factory is not MISSING: + setattr(self, f.name, f.default_factory()) + else: + raise TypeError(f"Missing required field - '{f.name}'") + + # Pass any additional kwargs to `__post_init__` and let the object + # decide whether to set the attr or use for different purposes (e.g. BC checks) + additional_kwargs = {} + for name, value in kwargs.items(): + if name not in dataclass_fields: + additional_kwargs[name] = value + + self.__post_init__(**additional_kwargs) + + cls.__init__ = __init__ # type: ignore + + # Define a default __post_init__ if not defined + if not hasattr(cls, "__post_init__"): + + def __post_init__(self, **kwargs: Any) -> None: + """Default __post_init__ to accept additional kwargs.""" + for name, value in kwargs.items(): + setattr(self, name, value) + + cls.__post_init__ = __post_init__ # type: ignore + + # (optional) Override __repr__ to include additional kwargs + original_repr = cls.__repr__ + + @wraps(original_repr) + def __repr__(self) -> str: + # Call the original __repr__ to get the standard fields + standard_repr = original_repr(self) + + # Get additional kwargs + additional_kwargs = [ + # add a '*' in front of additional kwargs to let the user know they are not part of the dataclass + f"*{k}={v!r}" + for k, v in self.__dict__.items() + if k not in cls.__dataclass_fields__ # type: ignore [attr-defined] + ] + additional_repr = ", ".join(additional_kwargs) + + # Combine both representations + return f"{standard_repr[:-1]}, {additional_repr})" if additional_kwargs else standard_repr + + if cls.__dataclass_params__.repr is True: # type: ignore [attr-defined] + cls.__repr__ = __repr__ # type: ignore + + # List all public methods starting with `validate_` => class validators. + class_validators = [] + + for name in dir(cls): + if not name.startswith("validate_"): + continue + method = getattr(cls, name) + if not callable(method): + continue + if len(inspect.signature(method).parameters) != 1: + raise StrictDataclassDefinitionError( + f"Class '{cls.__name__}' has a class validator '{name}' that takes more than one argument." + " Class validators must take only 'self' as an argument. Methods starting with 'validate_'" + " are considered to be class validators." + ) + class_validators.append(method) + + cls.__class_validators__ = class_validators # type: ignore + + # Add `validate` method to the class, but first check if it already exists + def validate(self: T) -> None: + """Run class validators on the instance.""" + for validator in cls.__class_validators__: # type: ignore [attr-defined] + try: + validator(self) + except (ValueError, TypeError) as e: + raise StrictDataclassClassValidationError(validator=validator.__name__, cause=e) from e + + # Hack to be able to raise if `.validate()` already exists except if it was created by this decorator on a parent class + # (in which case we just override it) + validate.__is_defined_by_strict_decorator__ = True # type: ignore [attr-defined] + + if hasattr(cls, "validate"): + if not getattr(cls.validate, "__is_defined_by_strict_decorator__", False): # type: ignore [attr-defined] + raise StrictDataclassDefinitionError( + f"Class '{cls.__name__}' already implements a method called 'validate'." + " This method name is reserved when using the @strict decorator on a dataclass." + " If you want to keep your own method, please rename it." + ) + + cls.validate = validate # type: ignore + + # Run class validators after initialization + initial_init = cls.__init__ + + @wraps(initial_init) + def init_with_validate(self, *args, **kwargs) -> None: + """Run class validators after initialization.""" + initial_init(self, *args, **kwargs) # type: ignore [call-arg] + cls.validate(self) # type: ignore [attr-defined] + + setattr(cls, "__init__", init_with_validate) + + return cls + + # Return wrapped class or the decorator itself + return wrap(cls) if cls is not None else wrap + + +def validate_typed_dict(schema: type[TypedDictType], data: dict) -> None: + """ + Validate that a dictionary conforms to the types defined in a TypedDict class. + + Under the hood, the typed dict is converted to a strict dataclass and validated using the `@strict` decorator. + + Args: + schema (`type[TypedDictType]`): + The TypedDict class defining the expected structure and types. + data (`dict`): + The dictionary to validate. + + Raises: + `StrictDataclassFieldValidationError`: + If any field in the dictionary does not conform to the expected type. + + Example: + ```py + >>> from typing import Annotated, TypedDict + >>> from huggingface_hub.dataclasses import validate_typed_dict + + >>> def positive_int(value: int): + ... if not value >= 0: + ... raise ValueError(f"Value must be positive, got {value}") + + >>> class User(TypedDict): + ... name: str + ... age: Annotated[int, positive_int] + + >>> # Valid data + >>> validate_typed_dict(User, {"name": "John", "age": 30}) + + >>> # Invalid type for age + >>> validate_typed_dict(User, {"name": "John", "age": "30"}) + huggingface_hub.errors.StrictDataclassFieldValidationError: Validation error for field 'age': + TypeError: Field 'age' expected int, got str (value: '30') + + >>> # Invalid value for age + >>> validate_typed_dict(User, {"name": "John", "age": -1}) + huggingface_hub.errors.StrictDataclassFieldValidationError: Validation error for field 'age': + ValueError: Value must be positive, got -1 + ``` + """ + # Convert typed dict to dataclass + strict_cls = _build_strict_cls_from_typed_dict(schema) + + # Validate the data by instantiating the strict dataclass + strict_cls(**data) # will raise if validation fails + + +@lru_cache +def _build_strict_cls_from_typed_dict(schema: type[TypedDictType]) -> Type: + # Extract type hints from the TypedDict class + type_hints = _get_typed_dict_annotations(schema) + + # If the TypedDict is not total, wrap fields as NotRequired (unless explicitly Required or NotRequired) + if not getattr(schema, "__total__", True): + for key, value in type_hints.items(): + origin = get_origin(value) + + if origin is Annotated: + base, *meta = get_args(value) + if not _is_required_or_notrequired(base): + base = NotRequired[base] + type_hints[key] = Annotated[tuple([base] + list(meta))] # type: ignore + elif not _is_required_or_notrequired(value): + type_hints[key] = NotRequired[value] + + # Convert type hints to dataclass fields + fields = [] + for key, value in type_hints.items(): + if get_origin(value) is Annotated: + base, *meta = get_args(value) + fields.append((key, base, field(default=_TYPED_DICT_DEFAULT_VALUE, metadata={"validator": meta[0]}))) + else: + fields.append((key, value, field(default=_TYPED_DICT_DEFAULT_VALUE))) + + # Create a strict dataclass from the TypedDict fields + return strict(make_dataclass(schema.__name__, fields)) + + +def _get_typed_dict_annotations(schema: type[TypedDictType]) -> dict[str, Any]: + """Extract type annotations from a TypedDict class.""" + try: + # Available in Python 3.14+ + import annotationlib + + return annotationlib.get_annotations(schema) + except ImportError: + return { + # We do not use `get_type_hints` here to avoid evaluating ForwardRefs (which might fail). + # ForwardRefs are not validated by @strict anyway. + name: value if value is not None else type(None) + for name, value in schema.__dict__.get("__annotations__", {}).items() + } + + +def validated_field( + validator: list[Validator_T] | Validator_T, + default: Any = MISSING, + default_factory: Any = MISSING, + init: bool = True, + repr: bool = True, + hash: bool | None = None, + compare: bool = True, + metadata: dict | None = None, + **kwargs: Any, +) -> Any: + """ + Create a dataclass field with a custom validator. + + Useful to apply several checks to a field. If only applying one rule, check out the [`as_validated_field`] decorator. + + Args: + validator (`Callable` or `list[Callable]`): + A method that takes a value as input and raises ValueError/TypeError if the value is invalid. + Can be a list of validators to apply multiple checks. + **kwargs: + Additional arguments to pass to `dataclasses.field()`. + + Returns: + A field with the validator attached in metadata + """ + if not isinstance(validator, list): + validator = [validator] + if metadata is None: + metadata = {} + metadata["validator"] = validator + return field( # type: ignore + default=default, # type: ignore [arg-type] + default_factory=default_factory, # type: ignore [arg-type] + init=init, + repr=repr, + hash=hash, + compare=compare, + metadata=metadata, + **kwargs, + ) + + +def as_validated_field(validator: Validator_T): + """ + Decorates a validator function as a [`validated_field`] (i.e. a dataclass field with a custom validator). + + Args: + validator (`Callable`): + A method that takes a value as input and raises ValueError/TypeError if the value is invalid. + """ + + def _inner( + default: Any = MISSING, + default_factory: Any = MISSING, + init: bool = True, + repr: bool = True, + hash: bool | None = None, + compare: bool = True, + metadata: dict | None = None, + **kwargs: Any, + ): + return validated_field( + validator, + default=default, + default_factory=default_factory, + init=init, + repr=repr, + hash=hash, + compare=compare, + metadata=metadata, + **kwargs, + ) + + return _inner + + +def type_validator(name: str, value: Any, expected_type: Any) -> None: + """Validate that 'value' matches 'expected_type'.""" + origin = get_origin(expected_type) + args = get_args(expected_type) + + if expected_type is Any: + return + elif expected_type is None: + _validate_none(name, value) + elif validator := _BASIC_TYPE_VALIDATORS.get(origin): + validator(name, value, args) + elif isinstance(expected_type, type): # simple types + _validate_simple_type(name, value, expected_type) + elif isinstance(expected_type, ForwardRef) or isinstance(expected_type, str): + return + elif origin is Required: + if value is _TYPED_DICT_DEFAULT_VALUE: + raise TypeError(f"Field '{name}' is required but missing.") + type_validator(name, value, args[0]) + elif origin is NotRequired: + if value is _TYPED_DICT_DEFAULT_VALUE: + return + type_validator(name, value, args[0]) + else: + raise TypeError(f"Unsupported type for field '{name}': {expected_type}") + + +def _validate_none(name: str, value: Any) -> None: + """Validate None type. + + 'None' is not a type, it's a special value. Type should be `NoneType` instead. + But in type annotations 'None' is accepted so we must support it. + """ + if value is not None: + raise TypeError(f"Field '{name}' expected None, got {type(value).__name__}") + + +def _validate_union(name: str, value: Any, args: tuple[Any, ...]) -> None: + """Validate that value matches one of the types in a Union.""" + errors = [] + for t in args: + try: + type_validator(name, value, t) + return # Valid if any type matches + except TypeError as e: + errors.append(str(e)) + + raise TypeError( + f"Field '{name}' with value {repr(value)} doesn't match any type in {args}. Errors: {'; '.join(errors)}" + ) + + +def _validate_literal(name: str, value: Any, args: tuple[Any, ...]) -> None: + """Validate Literal type.""" + if isinstance(value, bool): + if value not in [arg for arg in args if isinstance(arg, bool)]: + raise TypeError(f"Field '{name}' expected one of {args}, got {value}") + elif isinstance(value, int): + if value not in [arg for arg in args if isinstance(arg, int) and not isinstance(arg, bool)]: + raise TypeError(f"Field '{name}' expected one of {args}, got {value}") + elif value not in args: + raise TypeError(f"Field '{name}' expected one of {args}, got {value}") + + +def _validate_list(name: str, value: Any, args: tuple[Any, ...]) -> None: + """Validate list[T] type.""" + if not isinstance(value, list): + raise TypeError(f"Field '{name}' expected a list, got {type(value).__name__}") + + # Validate each item in the list + item_type = args[0] + for i, item in enumerate(value): + try: + type_validator(f"{name}[{i}]", item, item_type) + except TypeError as e: + raise TypeError(f"Invalid item at index {i} in list '{name}'") from e + + +def _validate_dict(name: str, value: Any, args: tuple[Any, ...]) -> None: + """Validate dict[K, V] type.""" + if not isinstance(value, dict): + raise TypeError(f"Field '{name}' expected a dict, got {type(value).__name__}") + + # Validate keys and values + key_type, value_type = args + for k, v in value.items(): + try: + type_validator(f"{name}.key", k, key_type) + type_validator(f"{name}[{k!r}]", v, value_type) + except TypeError as e: + raise TypeError(f"Invalid key or value in dict '{name}'") from e + + +def _validate_tuple(name: str, value: Any, args: tuple[Any, ...]) -> None: + """Validate Tuple type.""" + if not isinstance(value, tuple): + raise TypeError(f"Field '{name}' expected a tuple, got {type(value).__name__}") + + # Handle variable-length tuples: tuple[T, ...] + if len(args) == 2 and args[1] is Ellipsis: + for i, item in enumerate(value): + try: + type_validator(f"{name}[{i}]", item, args[0]) + except TypeError as e: + raise TypeError(f"Invalid item at index {i} in tuple '{name}'") from e + # Handle fixed-length tuples: tuple[T1, T2, ...] + elif len(args) != len(value): + raise TypeError(f"Field '{name}' expected a tuple of length {len(args)}, got {len(value)}") + else: + for i, (item, expected) in enumerate(zip(value, args)): + try: + type_validator(f"{name}[{i}]", item, expected) + except TypeError as e: + raise TypeError(f"Invalid item at index {i} in tuple '{name}'") from e + + +def _validate_set(name: str, value: Any, args: tuple[Any, ...]) -> None: + """Validate set[T] type.""" + if not isinstance(value, set): + raise TypeError(f"Field '{name}' expected a set, got {type(value).__name__}") + + # Validate each item in the set + item_type = args[0] + for i, item in enumerate(value): + try: + type_validator(f"{name} item", item, item_type) + except TypeError as e: + raise TypeError(f"Invalid item in set '{name}'") from e + + +def _validate_sequence(name: str, value: Any, args: tuple[Any, ...]) -> None: + """Validate Sequence or Sequence[T] type.""" + if not isinstance(value, collections.abc.Sequence): + raise TypeError(f"Field '{name}' expected a Sequence, got {type(value).__name__}") + + # If no type argument is provided (i.e., just `Sequence`), skip item validation + if not args: + return + + # Validate each item in the sequence + item_type = args[0] + for i, item in enumerate(value): + try: + type_validator(f"{name}[{i}]", item, item_type) + except TypeError as e: + raise TypeError(f"Invalid item at index {i} in sequence '{name}'") from e + + +def _validate_simple_type(name: str, value: Any, expected_type: type) -> None: + """Validate simple type (int, str, etc.).""" + if expected_type is int and isinstance(value, bool): + raise TypeError( + f"Field '{name}' expected {expected_type.__name__}, got {type(value).__name__} (value: {repr(value)})" + ) + if not isinstance(value, expected_type): + raise TypeError( + f"Field '{name}' expected {expected_type.__name__}, got {type(value).__name__} (value: {repr(value)})" + ) + + +def _create_type_validator(field: Field) -> Validator_T: + """Create a type validator function for a field.""" + # Hacky: we cannot use a lambda here because of reference issues + + def validator(value: Any) -> None: + type_validator(field.name, value, field.type) + + return validator + + +def _is_validator(validator: Any) -> bool: + """Check if a function is a validator. + + A validator is a Callable that can be called with a single positional argument. + The validator can have more arguments with default values. + + Basically, returns True if `validator(value)` is possible. + """ + if not callable(validator): + return False + + signature = inspect.signature(validator) + parameters = list(signature.parameters.values()) + if len(parameters) == 0: + return False + if parameters[0].kind not in ( + inspect.Parameter.POSITIONAL_OR_KEYWORD, + inspect.Parameter.POSITIONAL_ONLY, + inspect.Parameter.VAR_POSITIONAL, + ): + return False + for parameter in parameters[1:]: + if parameter.default == inspect.Parameter.empty: + return False + return True + + +def _is_required_or_notrequired(type_hint: Any) -> bool: + """Helper to check if a type is Required/NotRequired.""" + return type_hint in (Required, NotRequired) or (get_origin(type_hint) in (Required, NotRequired)) + + +_BASIC_TYPE_VALIDATORS: dict[Any, Callable[[str, Any, tuple[Any, ...]], None]] = { + Union: _validate_union, + Literal: _validate_literal, + list: _validate_list, + dict: _validate_dict, + tuple: _validate_tuple, + set: _validate_set, + collections.abc.Sequence: _validate_sequence, +} + +# TODO: make it first class citizen when bumping to Python 3.10+ +_BASIC_TYPE_VALIDATORS[types.UnionType] = _validate_union # x | y syntax, available only Python 3.10+ + + +__all__ = [ + "strict", + "validate_typed_dict", + "validated_field", + "Validator_T", + "StrictDataclassClassValidationError", + "StrictDataclassDefinitionError", + "StrictDataclassFieldValidationError", +] diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/errors.py b/.venv/lib/python3.13/site-packages/huggingface_hub/errors.py new file mode 100644 index 0000000000000000000000000000000000000000..9a619b3d5b80a12c327ec9eba200be70a684a308 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/errors.py @@ -0,0 +1,609 @@ +"""Contains all custom errors.""" + +from enum import Enum +from pathlib import Path + +from httpx import HTTPError, Response + + +# CACHE ERRORS + + +class CacheNotFound(Exception): + """Exception thrown when the Huggingface cache is not found.""" + + cache_dir: str | Path + + def __init__(self, msg: str, cache_dir: str | Path, *args, **kwargs): + super().__init__(msg, *args, **kwargs) + self.cache_dir = cache_dir + + +class CorruptedCacheException(Exception): + """Exception for any unexpected structure in the Huggingface cache-system.""" + + +class CachedRepoTreeNotFoundError(Exception): + """Raised by [`get_cached_repo_tree`] when no tree listing is cached for the requested revision. + + The tree listing is populated as a side effect of [`snapshot_download`]. + """ + + +# HEADERS ERRORS + + +class LocalTokenNotFoundError(EnvironmentError): + """Raised if local token is required but not found.""" + + +# OIDC ERRORS + + +class OIDCError(Exception): + """Raised when keyless CI/CD auth via OIDC token exchange ("Trusted Publishers") cannot proceed. + + Typically because `HF_OIDC_RESOURCE` is set but no id token is available: not running in a + supported CI provider and `HF_OIDC_ID_TOKEN` is unset. + + See https://huggingface.co/docs/hub/trusted-publishers. + """ + + +# DEVICE CODE OAUTH ERRORS + + +class OAuthErrorCode(str, Enum): + """Known OAuth `error` codes returned by the Hub's token endpoint (RFC 6749 / RFC 8628).""" + + AUTHORIZATION_PENDING = "authorization_pending" + SLOW_DOWN = "slow_down" + EXPIRED_TOKEN = "expired_token" + ACCESS_DENIED = "access_denied" + INVALID_GRANT = "invalid_grant" + + +class DeviceCodeError(Exception): + """Raised when the Device Code OAuth login flow (RFC 8628) or an OAuth token refresh fails. + + Covers failures at any step: requesting the device code, polling for the token, + authorization denied/expired, or unexpected server responses. + + Attributes: + error_code (`str`, *optional*): + The OAuth `error` code returned by the server, if any. Known values are listed in + [`OAuthErrorCode`] but the server may return other codes. + """ + + def __init__(self, message: str, error_code: str | None = None): + super().__init__(message) + self.error_code = error_code + + +# HTTP ERRORS + + +class OfflineModeIsEnabled(ConnectionError): + """Raised when a request is made but `HF_HUB_OFFLINE=1` is set as environment variable.""" + + +class HfHubHTTPError(HTTPError, OSError): + """ + HTTPError to inherit from for any custom HTTP Error raised in HF Hub. + + Any HTTPError is converted at least into a `HfHubHTTPError`. If some information is + sent back by the server, it will be added to the error message. + + Added details: + - Request ID sourced from headers in order of precedence: "X-Request-Id", "X-Amzn-Trace-Id", "X-Amz-Cf-Id". + - Server error message from the header "X-Error-Message". + - Server error message if we can found one in the response body. + + Example: + ```py + import httpx + from huggingface_hub.utils import get_session, hf_raise_for_status, HfHubHTTPError + + response = get_session().post(...) + try: + hf_raise_for_status(response) + except HfHubHTTPError as e: + print(str(e)) # formatted message + e.request_id, e.server_message # details returned by server + + # Complete the error message with additional information once it's raised + e.append_to_message("\n`create_commit` expects the repository to exist.") + raise + ``` + """ + + def __init__( + self, + message: str, + *, + response: Response, + server_message: str | None = None, + ): + self.request_id = ( + response.headers.get("x-request-id") + or response.headers.get("X-Amzn-Trace-Id") + or response.headers.get("x-amz-cf-id") + ) + self.server_message = server_message + self.response = response + self.request = response.request + super().__init__(message) + + def append_to_message(self, additional_message: str) -> None: + """Append additional information to the `HfHubHTTPError` initial message.""" + self.args = (self.args[0] + additional_message,) + self.args[1:] + + @classmethod + def _reconstruct_hf_hub_http_error( + cls, message: str, response: Response, server_message: str | None + ) -> "HfHubHTTPError": + return cls(message, response=response, server_message=server_message) + + def __reduce_ex__(self, protocol): + """Fix pickling of Exception subclass with kwargs. We need to override __reduce_ex__ of the parent class""" + return (self.__class__._reconstruct_hf_hub_http_error, (str(self), self.response, self.server_message)) + + +# INFERENCE CLIENT ERRORS + + +class InferenceTimeoutError(HTTPError, TimeoutError): + """Error raised when a model is unavailable or the request times out.""" + + +# INFERENCE ENDPOINT ERRORS + + +class InferenceEndpointError(Exception): + """Generic exception when dealing with Inference Endpoints.""" + + +class InferenceEndpointTimeoutError(InferenceEndpointError, TimeoutError): + """Exception for timeouts while waiting for Inference Endpoint.""" + + +# SAFETENSORS ERRORS + + +class SafetensorsParsingError(Exception): + """Raised when failing to parse a safetensors file metadata. + + This can be the case if the file is not a safetensors file or does not respect the specification. + """ + + +class NotASafetensorsRepoError(Exception): + """Raised when a repo is not a Safetensors repo i.e. doesn't have either a `model.safetensors` or a + `model.safetensors.index.json` file. + """ + + +# TEXT GENERATION ERRORS + + +class TextGenerationError(HTTPError): + """Generic error raised if text-generation went wrong.""" + + +# Text Generation Inference Errors +class ValidationError(TextGenerationError): + """Server-side validation error.""" + + +class GenerationError(TextGenerationError): + pass + + +class OverloadedError(TextGenerationError): + pass + + +class IncompleteGenerationError(TextGenerationError): + pass + + +class UnknownError(TextGenerationError): + pass + + +# VALIDATION ERRORS + + +class HFValidationError(ValueError): + """Generic exception thrown by `huggingface_hub` validators. + + Inherits from [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError). + """ + + +class HfUriError(ValueError): + """Raised when an `hf://...` URI is malformed. + + See [`parse_hf_uri`] and the + [HF URIs reference](https://huggingface.co/docs/huggingface_hub/main/en/package_reference/hf_uris) + for the canonical syntax. + + Inherits from [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError). + """ + + def __init__(self, uri: str, msg: str): + self.uri = uri + self.msg = msg + full_msg = f"Invalid HF URI '{uri}'. {msg}" if uri else f"Invalid HF URI. {msg}" + super().__init__(full_msg) + + +# FILE METADATA ERRORS + + +class DryRunError(OSError): + """Error triggered when a dry run is requested but cannot be performed (e.g. invalid repo).""" + + +class FileMetadataError(OSError): + """Error triggered when the metadata of a file on the Hub cannot be retrieved (missing ETag or commit_hash). + + Inherits from `OSError` for backward compatibility. + """ + + +# BUCKET ERRORS + + +class BucketNotFoundError(HfHubHTTPError): + """ + Raised when trying to access a bucket that does not exist. + + Attributes: + bucket_id (`str` or `None`): + The bucket id (namespace/name) that was not found, if it could be determined from the request URL. + + Example: + + ```py + >>> from huggingface_hub import bucket_info + >>> bucket_info("") + (...) + huggingface_hub.errors.BucketNotFoundError: 404 Client Error. (Request ID: XXX) + + Bucket Not Found for url: https://huggingface.co/api/buckets/namespace/name. + Please make sure you specified the correct bucket id (namespace/name). + If the bucket is private, make sure you are authenticated and your token has the required permissions. + ``` + """ + + bucket_id: str | None = None + + +# JOB ERRORS + + +class JobNotFoundError(HfHubHTTPError): + """ + Raised when trying to access a Job that does not exist. + + Attributes: + job_id (`str`): + The job id that was not found. + """ + + job_id: str + + +# REPOSITORY ERRORS + + +class RepositoryNotFoundError(HfHubHTTPError): + """ + Raised when trying to access a hf.co URL with an invalid repository name, or + with a private repo name the user does not have access to. + + Attributes: + repo_id (`str` or `None`): + The repo id that was not found, if it could be determined from the request URL. + repo_type (`str` or `None`): + The repo type ("model", "dataset", or "space"), if it could be determined from the request URL. + + Example: + + ```py + >>> from huggingface_hub import model_info + >>> model_info("") + (...) + huggingface_hub.errors.RepositoryNotFoundError: 401 Client Error. (Request ID: PvMw_VjBMjVdMz53WKIzP) + + Repository Not Found for url: https://huggingface.co/api/models/%3Cnon_existent_repository%3E. + Please make sure you specified the correct `repo_id` and `repo_type`. + If the repo is private, make sure you are authenticated and your token has the required permissions. + Invalid username or password. + ``` + """ + + repo_id: str | None = None + repo_type: str | None = None + + +class GatedRepoError(RepositoryNotFoundError): + """ + Raised when trying to access a gated repository for which the user is not on the + authorized list. + + Note: derives from `RepositoryNotFoundError` to ensure backward compatibility. + + Example: + + ```py + >>> from huggingface_hub import model_info + >>> model_info("") + (...) + huggingface_hub.errors.GatedRepoError: 403 Client Error. (Request ID: ViT1Bf7O_026LGSQuVqfa) + + Cannot access gated repo for url https://huggingface.co/api/models/ardent-figment/gated-model. + Access to model ardent-figment/gated-model is restricted and you are not in the authorized list. + Visit https://huggingface.co/ardent-figment/gated-model to ask for access. + ``` + """ + + +class DisabledRepoError(HfHubHTTPError): + """ + Raised when trying to access a repository that has been disabled by its author. + + Example: + + ```py + >>> from huggingface_hub import dataset_info + >>> dataset_info("laion/laion-art") + (...) + huggingface_hub.errors.DisabledRepoError: 403 Client Error. (Request ID: Root=1-659fc3fa-3031673e0f92c71a2260dbe2;bc6f4dfb-b30a-4862-af0a-5cfe827610d8) + + Cannot access repository for url https://huggingface.co/api/datasets/laion/laion-art. + Access to this resource is disabled. + ``` + """ + + +# REVISION ERROR + + +class RevisionNotFoundError(HfHubHTTPError): + """ + Raised when trying to access a hf.co URL with a valid repository but an invalid + revision. + + Attributes: + repo_id (`str` or `None`): + The repo id, if it could be determined from the request URL. + repo_type (`str` or `None`): + The repo type ("model", "dataset", or "space"), if it could be determined from the request URL. + + Example: + + ```py + >>> from huggingface_hub import hf_hub_download + >>> hf_hub_download('bert-base-cased', 'config.json', revision='') + (...) + huggingface_hub.errors.RevisionNotFoundError: 404 Client Error. (Request ID: Mwhe_c3Kt650GcdKEFomX) + + Revision Not Found for url: https://huggingface.co/bert-base-cased/resolve/%3Cnon-existent-revision%3E/config.json. + ``` + """ + + repo_id: str | None = None + repo_type: str | None = None + + +# ENTRY ERRORS +class EntryNotFoundError(Exception): + """ + Raised when entry not found, either locally or remotely. + + Example: + + ```py + >>> from huggingface_hub import hf_hub_download + >>> hf_hub_download('bert-base-cased', '') + (...) + huggingface_hub.errors.RemoteEntryNotFoundError (...) + >>> hf_hub_download('bert-base-cased', '', local_files_only=True) + (...) + huggingface_hub.utils.errors.LocalEntryNotFoundError (...) + ``` + """ + + +class RemoteEntryNotFoundError(HfHubHTTPError, EntryNotFoundError): + """ + Raised when trying to access a hf.co URL with a valid repository and revision + but an invalid filename. + + Attributes: + repo_id (`str` or `None`): + The repo id, if it could be determined from the request URL. + repo_type (`str` or `None`): + The repo type ("model", "dataset", or "space"), if it could be determined from the request URL. + + Example: + + ```py + >>> from huggingface_hub import hf_hub_download + >>> hf_hub_download('bert-base-cased', '') + (...) + huggingface_hub.errors.EntryNotFoundError: 404 Client Error. (Request ID: 53pNl6M0MxsnG5Sw8JA6x) + + Entry Not Found for url: https://huggingface.co/bert-base-cased/resolve/main/%3Cnon-existent-file%3E. + ``` + """ + + repo_id: str | None = None + repo_type: str | None = None + + +class LocalEntryNotFoundError(FileNotFoundError, EntryNotFoundError): + """ + Raised when trying to access a file or snapshot that is not on the disk when network is + disabled or unavailable (connection issue). The entry may exist on the Hub. + + Example: + + ```py + >>> from huggingface_hub import hf_hub_download + >>> hf_hub_download('bert-base-cased', '', local_files_only=True) + (...) + huggingface_hub.errors.LocalEntryNotFoundError: Cannot find the requested files in the disk cache and outgoing traffic has been disabled. To enable hf.co look-ups and downloads online, set 'local_files_only' to False. + ``` + """ + + def __init__(self, message: str): + super().__init__(message) + + +class IncompleteSnapshotError(LocalEntryNotFoundError): + """ + Raised by [`snapshot_download`] when the Hub cannot be reached (offline, connection issue, or + `local_files_only=True`) and the cached snapshot is known to be incomplete: some files listed in + the repository's cached tree listing are missing from the local snapshot. + + This is a subclass of [`LocalEntryNotFoundError`] for backward compatibility. + + The `snapshot_path` attribute holds the path to the incomplete local snapshot, so a downstream library can locate + the latest cached files even though they are known to be incomplete. + """ + + def __init__(self, message: str, snapshot_path: str): + super().__init__(message) + self.snapshot_path = snapshot_path + + +# REQUEST ERROR +class BadRequestError(HfHubHTTPError, ValueError): + """ + Raised by `hf_raise_for_status` when the server returns a HTTP 400 error. + + Example: + + ```py + >>> resp = httpx.post("hf.co/api/check", ...) + >>> hf_raise_for_status(resp, endpoint_name="check") + huggingface_hub.errors.BadRequestError: Bad request for check endpoint: {details} (Request ID: XXX) + ``` + """ + + +# DDUF file format ERROR + + +class DDUFError(Exception): + """Base exception for errors related to the DDUF format.""" + + +class DDUFCorruptedFileError(DDUFError): + """Exception thrown when the DDUF file is corrupted.""" + + +class DDUFExportError(DDUFError): + """Base exception for errors during DDUF export.""" + + +class DDUFInvalidEntryNameError(DDUFExportError): + """Exception thrown when the entry name is invalid.""" + + +# STRICT DATACLASSES ERRORS + + +class StrictDataclassError(Exception): + """Base exception for strict dataclasses.""" + + +class StrictDataclassDefinitionError(StrictDataclassError): + """Exception thrown when a strict dataclass is defined incorrectly.""" + + +class StrictDataclassFieldValidationError(StrictDataclassError): + """Exception thrown when a strict dataclass fails validation for a given field.""" + + def __init__(self, field: str, cause: Exception): + error_message = f"Validation error for field '{field}':" + error_message += f"\n {cause.__class__.__name__}: {cause}" + super().__init__(error_message) + + +class StrictDataclassClassValidationError(StrictDataclassError): + """Exception thrown when a strict dataclass fails validation on a class validator.""" + + def __init__(self, validator: str, cause: Exception): + error_message = f"Class validation error for validator '{validator}':" + error_message += f"\n {cause.__class__.__name__}: {cause}" + super().__init__(error_message) + + +# XET ERRORS + + +class XetDownloadError(Exception): + """Exception thrown when the download from Xet Storage fails.""" + + +# LFS ERRORS + + +class FileDuplicationError(Exception): + """Raised when duplicating files across repos fails.""" + + +# CLI ERRORS + + +class CLIError(Exception): + """CLI error with clean message (no traceback by default).""" + + +class ConfirmationError(CLIError): + """Raised when a confirmation prompt is declined (non-interactive mode).""" + + +class CLIExtensionInstallError(CLIError): + """Error during CLI extension installation.""" + + +# SANDBOX ERRORS + + +class SandboxError(Exception): + """Base exception for sandbox operations (see `huggingface_hub.Sandbox`). + + Attributes: + status_code: The HTTP status returned by the in-sandbox server, if the error + originated from an API response (e.g. `404` for a missing file). `None` otherwise. + """ + + def __init__(self, message: str, *, status_code: int | None = None) -> None: + super().__init__(message) + self.status_code = status_code + + +class SandboxCommandError(SandboxError): + """Raised when a command run in a sandbox exits with a non-zero code. + + Attributes: + cmd: The command that failed. + result: The full `SandboxCommandResult` (exit_code, stdout, stderr, ...). + """ + + def __init__(self, cmd, result) -> None: + self.cmd = cmd + self.result = result + stderr_tail = result.stderr[-1000:] if result.stderr else "" + if result.timed_out: + reason = "timed out" + elif result.signal is not None: + reason = f"was killed by signal {result.signal}" + else: + reason = f"exited with code {result.exit_code}" + super().__init__(f"Command {cmd!r} {reason}. stderr:\n{stderr_tail}") diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/fastai_utils.py b/.venv/lib/python3.13/site-packages/huggingface_hub/fastai_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..2604e7b1e598d3d1c0b9dc8115e5e3c0a3fc3de2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/fastai_utils.py @@ -0,0 +1,414 @@ +import json +import os +from pathlib import Path +from pickle import DEFAULT_PROTOCOL, PicklingError +from typing import Any + +from packaging import version + +from huggingface_hub import constants, snapshot_download +from huggingface_hub.hf_api import HfApi +from huggingface_hub.utils import ( + SoftTemporaryDirectory, + get_fastai_version, + get_fastcore_version, + get_python_version, +) + +from .utils import logging, validate_hf_hub_args + + +logger = logging.get_logger(__name__) + + +def _check_fastai_fastcore_versions( + fastai_min_version: str = "2.4", + fastcore_min_version: str = "1.3.27", +): + """ + Checks that the installed fastai and fastcore versions are compatible for pickle serialization. + + Args: + fastai_min_version (`str`, *optional*): + The minimum fastai version supported. + fastcore_min_version (`str`, *optional*): + The minimum fastcore version supported. + + > [!TIP] + > Raises the following error: + > + > - [`ImportError`](https://docs.python.org/3/library/exceptions.html#ImportError) + > if the fastai or fastcore libraries are not available or are of an invalid version. + """ + + if (get_fastcore_version() or get_fastai_version()) == "N/A": + raise ImportError( + f"fastai>={fastai_min_version} and fastcore>={fastcore_min_version} are" + f" required. Currently using fastai=={get_fastai_version()} and" + f" fastcore=={get_fastcore_version()}." + ) + + current_fastai_version = version.Version(get_fastai_version()) + current_fastcore_version = version.Version(get_fastcore_version()) + + if current_fastai_version < version.Version(fastai_min_version): + raise ImportError( + "`push_to_hub_fastai` and `from_pretrained_fastai` require a" + f" fastai>={fastai_min_version} version, but you are using fastai version" + f" {get_fastai_version()} which is incompatible. Upgrade with `pip install" + " fastai==2.5.6`." + ) + + if current_fastcore_version < version.Version(fastcore_min_version): + raise ImportError( + "`push_to_hub_fastai` and `from_pretrained_fastai` require a" + f" fastcore>={fastcore_min_version} version, but you are using fastcore" + f" version {get_fastcore_version()} which is incompatible. Upgrade with" + " `pip install fastcore==1.3.27`." + ) + + +def _check_fastai_fastcore_pyproject_versions( + storage_folder: str, + fastai_min_version: str = "2.4", + fastcore_min_version: str = "1.3.27", +): + """ + Checks that the `pyproject.toml` file in the directory `storage_folder` has fastai and fastcore versions + that are compatible with `from_pretrained_fastai` and `push_to_hub_fastai`. If `pyproject.toml` does not exist + or does not contain versions for fastai and fastcore, then it logs a warning. + + Args: + storage_folder (`str`): + Folder to look for the `pyproject.toml` file. + fastai_min_version (`str`, *optional*): + The minimum fastai version supported. + fastcore_min_version (`str`, *optional*): + The minimum fastcore version supported. + + > [!TIP] + > Raises the following errors: + > + > - [`ImportError`](https://docs.python.org/3/library/exceptions.html#ImportError) + > if the `toml` module is not installed. + > - [`ImportError`](https://docs.python.org/3/library/exceptions.html#ImportError) + > if the `pyproject.toml` indicates a lower than minimum supported version of fastai or fastcore. + """ + + try: + import toml + except ModuleNotFoundError: + raise ImportError( + "`push_to_hub_fastai` and `from_pretrained_fastai` require the toml module." + " Install it with `pip install toml`." + ) + + # Checks that a `pyproject.toml`, with `build-system` and `requires` sections, exists in the repository. If so, get a list of required packages. + if not os.path.isfile(f"{storage_folder}/pyproject.toml"): + logger.warning( + "There is no `pyproject.toml` in the repository that contains the fastai" + " `Learner`. The `pyproject.toml` would allow us to verify that your fastai" + " and fastcore versions are compatible with those of the model you want to" + " load." + ) + return + pyproject_toml = toml.load(f"{storage_folder}/pyproject.toml") + + if "build-system" not in pyproject_toml.keys(): + logger.warning( + "There is no `build-system` section in the pyproject.toml of the repository" + " that contains the fastai `Learner`. The `build-system` would allow us to" + " verify that your fastai and fastcore versions are compatible with those" + " of the model you want to load." + ) + return + build_system_toml = pyproject_toml["build-system"] + + if "requires" not in build_system_toml.keys(): + logger.warning( + "There is no `requires` section in the pyproject.toml of the repository" + " that contains the fastai `Learner`. The `requires` would allow us to" + " verify that your fastai and fastcore versions are compatible with those" + " of the model you want to load." + ) + return + package_versions = build_system_toml["requires"] + + # Extracts contains fastai and fastcore versions from `pyproject.toml` if available. + # If the package is specified but not the version (e.g. "fastai" instead of "fastai=2.4"), the default versions are the highest. + fastai_packages = [pck for pck in package_versions if pck.startswith("fastai")] + if len(fastai_packages) == 0: + logger.warning("The repository does not have a fastai version specified in the `pyproject.toml`.") + # fastai_version is an empty string if not specified + else: + fastai_version = str(fastai_packages[0]).partition("=")[2] + if fastai_version != "" and version.Version(fastai_version) < version.Version(fastai_min_version): + raise ImportError( + "`from_pretrained_fastai` requires" + f" fastai>={fastai_min_version} version but the model to load uses" + f" {fastai_version} which is incompatible." + ) + + fastcore_packages = [pck for pck in package_versions if pck.startswith("fastcore")] + if len(fastcore_packages) == 0: + logger.warning("The repository does not have a fastcore version specified in the `pyproject.toml`.") + # fastcore_version is an empty string if not specified + else: + fastcore_version = str(fastcore_packages[0]).partition("=")[2] + if fastcore_version != "" and version.Version(fastcore_version) < version.Version(fastcore_min_version): + raise ImportError( + "`from_pretrained_fastai` requires" + f" fastcore>={fastcore_min_version} version, but you are using fastcore" + f" version {fastcore_version} which is incompatible." + ) + + +README_TEMPLATE = """--- +tags: +- fastai +--- + +# Amazing! + +🥳 Congratulations on hosting your fastai model on the Hugging Face Hub! + +# Some next steps +1. Fill out this model card with more information (see the template below and the [documentation here](https://huggingface.co/docs/hub/model-repos))! + +2. Create a demo in Gradio or Streamlit using 🤗 Spaces ([documentation here](https://huggingface.co/docs/hub/spaces)). + +3. Join the fastai community on the [Fastai Discord](https://discord.com/invite/YKrxeNn)! + +Greetings fellow fastlearner 🤝! Don't forget to delete this content from your model card. + + +--- + + +# Model card + +## Model description +More information needed + +## Intended uses & limitations +More information needed + +## Training and evaluation data +More information needed +""" + +PYPROJECT_TEMPLATE = f"""[build-system] +requires = ["setuptools>=40.8.0", "wheel", "python={get_python_version()}", "fastai={get_fastai_version()}", "fastcore={get_fastcore_version()}"] +build-backend = "setuptools.build_meta:__legacy__" +""" + + +def _create_model_card(repo_dir: Path): + """ + Creates a model card for the repository. + + Args: + repo_dir (`Path`): + Directory where model card is created. + """ + readme_path = repo_dir / "README.md" + + if not readme_path.exists(): + with readme_path.open("w", encoding="utf-8") as f: + f.write(README_TEMPLATE) + + +def _create_model_pyproject(repo_dir: Path): + """ + Creates a `pyproject.toml` for the repository. + + Args: + repo_dir (`Path`): + Directory where `pyproject.toml` is created. + """ + pyproject_path = repo_dir / "pyproject.toml" + + if not pyproject_path.exists(): + with pyproject_path.open("w", encoding="utf-8") as f: + f.write(PYPROJECT_TEMPLATE) + + +def _save_pretrained_fastai( + learner, + save_directory: str | Path, + config: dict[str, Any] | None = None, +): + """ + Saves a fastai learner to `save_directory` in pickle format using the default pickle protocol for the version of python used. + + Args: + learner (`Learner`): + The `fastai.Learner` you'd like to save. + save_directory (`str` or `Path`): + Specific directory in which you want to save the fastai learner. + config (`dict`, *optional*): + Configuration object. Will be uploaded as a .json file. Example: 'https://huggingface.co/espejelomar/fastai-pet-breeds-classification/blob/main/config.json'. + + > [!TIP] + > Raises the following error: + > + > - [`RuntimeError`](https://docs.python.org/3/library/exceptions.html#RuntimeError) + > if the config file provided is not a dictionary. + """ + _check_fastai_fastcore_versions() + + os.makedirs(save_directory, exist_ok=True) + + # if the user provides config then we update it with the fastai and fastcore versions in CONFIG_TEMPLATE. + if config is not None: + if not isinstance(config, dict): + raise RuntimeError(f"Provided config should be a dict. Got: '{type(config)}'") + path = os.path.join(save_directory, constants.CONFIG_NAME) + with open(path, "w") as f: + json.dump(config, f) + + _create_model_card(Path(save_directory)) + _create_model_pyproject(Path(save_directory)) + + # learner.export saves the model in `self.path`. + learner.path = Path(save_directory) + os.makedirs(save_directory, exist_ok=True) + try: + learner.export( + fname="model.pkl", + pickle_protocol=DEFAULT_PROTOCOL, + ) + except PicklingError: + raise PicklingError( + "You are using a lambda function, i.e., an anonymous function. `pickle`" + " cannot pickle function objects and requires that all functions have" + " names. One possible solution is to name the function." + ) + + +@validate_hf_hub_args +def from_pretrained_fastai( + repo_id: str, + revision: str | None = None, +): + """ + Load pretrained fastai model from the Hub or from a local directory. + + Args: + repo_id (`str`): + The location where the pickled fastai.Learner is. It can be either of the two: + - Hosted on the Hugging Face Hub. E.g.: 'espejelomar/fatai-pet-breeds-classification' or 'distilgpt2'. + You can add a `revision` by appending `@` at the end of `repo_id`. E.g.: `dbmdz/bert-base-german-cased@main`. + Revision is the specific model version to use. Since we use a git-based system for storing models and other + artifacts on the Hugging Face Hub, it can be a branch name, a tag name, or a commit id. + - Hosted locally. `repo_id` would be a directory containing the pickle and a pyproject.toml + indicating the fastai and fastcore versions used to build the `fastai.Learner`. E.g.: `./my_model_directory/`. + revision (`str`, *optional*): + Revision at which the repo's files are downloaded. See documentation of `snapshot_download`. + + Returns: + The `fastai.Learner` model in the `repo_id` repo. + """ + _check_fastai_fastcore_versions() + + # Load the `repo_id` repo. + # `snapshot_download` returns the folder where the model was stored. + # `cache_dir` will be the default '/root/.cache/huggingface/hub' + if not os.path.isdir(repo_id): + storage_folder = snapshot_download( + repo_id=repo_id, + revision=revision, + library_name="fastai", + library_version=get_fastai_version(), + ) + else: + storage_folder = repo_id + + _check_fastai_fastcore_pyproject_versions(storage_folder) + + from fastai.learner import load_learner # type: ignore + + return load_learner(os.path.join(storage_folder, "model.pkl")) + + +@validate_hf_hub_args +def push_to_hub_fastai( + learner, + *, + repo_id: str, + commit_message: str = "Push FastAI model using huggingface_hub.", + private: bool | None = None, + token: str | None = None, + config: dict | None = None, + branch: str | None = None, + create_pr: bool | None = None, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + delete_patterns: list[str] | str | None = None, + api_endpoint: str | None = None, +): + """ + Upload learner checkpoint files to the Hub. + + Use `allow_patterns` and `ignore_patterns` to precisely filter which files should be pushed to the hub. Use + `delete_patterns` to delete existing remote files in the same commit. See [`upload_folder`] reference for more + details. + + Args: + learner (`Learner`): + The `fastai.Learner' you'd like to push to the Hub. + repo_id (`str`): + The repository id for your model in Hub in the format of "namespace/repo_name". The namespace can be your individual account or an organization to which you have write access (for example, 'stanfordnlp/stanza-de'). + commit_message (`str`, *optional*): + Message to commit while pushing. Will default to :obj:`"add model"`. + private (`bool`, *optional*): + Whether or not the repository created should be private. + If `None` (default), will default to been public except if the organization's default is private. + token (`str`, *optional*): + The Hugging Face account token to use as HTTP bearer authorization for remote files. If :obj:`None`, the token will be asked by a prompt. + config (`dict`, *optional*): + Configuration object to be saved alongside the model weights. + branch (`str`, *optional*): + The git branch on which to push the model. This defaults to + the default branch as specified in your repository, which + defaults to `"main"`. + create_pr (`boolean`, *optional*): + Whether or not to create a Pull Request from `branch` with that commit. + Defaults to `False`. + api_endpoint (`str`, *optional*): + The API endpoint to use when pushing the model to the hub. + allow_patterns (`list[str]` or `str`, *optional*): + If provided, only files matching at least one pattern are pushed. + ignore_patterns (`list[str]` or `str`, *optional*): + If provided, files matching any of the patterns are not pushed. + delete_patterns (`list[str]` or `str`, *optional*): + If provided, remote files matching any of the patterns will be deleted from the repo. + + Returns: + The url of the commit of your model in the given repository. + + > [!TIP] + > Raises the following error: + > + > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > if the user is not log on to the Hugging Face Hub. + """ + _check_fastai_fastcore_versions() + api = HfApi(endpoint=api_endpoint) + repo_id = api.create_repo(repo_id=repo_id, token=token, private=private, exist_ok=True).repo_id + + # Push the files to the repo in a single commit + with SoftTemporaryDirectory() as tmp: + saved_path = Path(tmp) / repo_id + _save_pretrained_fastai(learner, saved_path, config=config) + return api.upload_folder( + repo_id=repo_id, + token=token, + folder_path=saved_path, + commit_message=commit_message, + revision=branch, + create_pr=create_pr, + allow_patterns=allow_patterns, + ignore_patterns=ignore_patterns, + delete_patterns=delete_patterns, + ) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/file_download.py b/.venv/lib/python3.13/site-packages/huggingface_hub/file_download.py new file mode 100644 index 0000000000000000000000000000000000000000..5ba37edebe05e53ad89ecfab4c23b09b44d11e64 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/file_download.py @@ -0,0 +1,2021 @@ +import copy +import errno +import os +import re +import shutil +import stat +import time +import uuid +import warnings +from dataclasses import dataclass +from pathlib import Path +from typing import Any, BinaryIO, Literal, NoReturn, overload +from urllib.parse import quote, urlparse + +import httpx +from tqdm.auto import tqdm as base_tqdm + +from . import constants +from ._local_folder import ( + _create_cachedir_tag, + get_local_download_paths, + read_download_metadata, + write_download_metadata, +) +from ._tree_cache import read_tree_cache, tree_cache_folder_for_local_dir +from .errors import ( + FileMetadataError, + GatedRepoError, + HfHubHTTPError, + LocalEntryNotFoundError, + RemoteEntryNotFoundError, + RepositoryNotFoundError, + RevisionNotFoundError, +) +from .utils import ( + OfflineModeIsEnabled, + SoftTemporaryDirectory, + WeakFileLock, + XetFileData, + build_hf_headers, + hf_raise_for_status, + logging, + parse_xet_file_data_from_response, + tqdm, + validate_hf_hub_args, +) +from .utils._http import ( + _DEFAULT_RETRY_ON_EXCEPTIONS, + _DEFAULT_RETRY_ON_STATUS_CODES, + _adjust_range_header, + _httpx_follow_relative_redirects_with_backoff, + http_stream_backoff, +) +from .utils._runtime import is_xet_available +from .utils._xet import XetTokenType, xet_connection_info_refresh_url +from .utils.sha import sha_fileobj +from .utils.tqdm import _get_progress_bar_context + + +logger = logging.get_logger(__name__) + +# Return value when trying to load a file from cache but the file does not exist in the distant repo. +_CACHED_NO_EXIST = object() +_CACHED_NO_EXIST_T = Any + +# Regex to get filename from a "Content-Disposition" header for CDN-served files +HEADER_FILENAME_PATTERN = re.compile(r'filename="(?P.*?)";') + +# Regex to check if the revision IS directly a commit_hash +REGEX_COMMIT_HASH = re.compile(r"^[0-9a-f]{40}$") + +# Regex to check if the file etag IS a valid sha256 +REGEX_SHA256 = re.compile(r"^[0-9a-f]{64}$") + +_are_symlinks_supported_in_dir: dict[str, bool] = {} + +# Internal retry timeout for metadata fetch when no local file exists +_ETAG_RETRY_TIMEOUT = 60 + + +def are_symlinks_supported(cache_dir: str | Path | None = None) -> bool: + """Return whether the symlinks are supported on the machine. + + Since symlinks support can change depending on the mounted disk, we need to check + on the precise cache folder. By default, the default HF cache directory is checked. + + Args: + cache_dir (`str`, `Path`, *optional*): + Path to the folder where cached files are stored. + + Returns: [bool] Whether symlinks are supported in the directory. + """ + # Defaults to HF cache + if cache_dir is None: + cache_dir = constants.HF_HUB_CACHE + cache_dir = str(Path(cache_dir).expanduser().resolve()) # make it unique + + # If symlinks are explicitly disabled by the user, always return False + if constants.HF_HUB_DISABLE_SYMLINKS: + return False + + # Check symlink compatibility only once (per cache directory) at first time use + if cache_dir not in _are_symlinks_supported_in_dir: + _are_symlinks_supported_in_dir[cache_dir] = True + + os.makedirs(cache_dir, exist_ok=True) + with SoftTemporaryDirectory(dir=cache_dir) as tmpdir: + src_path = Path(tmpdir) / "dummy_file_src" + src_path.touch() + dst_path = Path(tmpdir) / "dummy_file_dst" + + # Relative source path as in `_create_symlink`` + relative_src = os.path.relpath(src_path, start=os.path.dirname(dst_path)) + try: + os.symlink(relative_src, dst_path) + except OSError: + # Likely running on Windows + _are_symlinks_supported_in_dir[cache_dir] = False + + if not constants.HF_HUB_DISABLE_SYMLINKS_WARNING: + message = ( + "`huggingface_hub` cache-system uses symlinks by default to" + " efficiently store duplicated files but your machine does not" + f" support them in {cache_dir}. Caching files will still work" + " but in a degraded version that might require more space on" + " your disk. This warning can be disabled by setting the" + " `HF_HUB_DISABLE_SYMLINKS_WARNING` environment variable. For" + " more details, see" + " https://huggingface.co/docs/huggingface_hub/how-to-cache#limitations." + ) + if os.name == "nt": + message += ( + "\nTo support symlinks on Windows, you either need to" + " activate Developer Mode or to run Python as an" + " administrator. In order to activate developer mode," + " see this article:" + " https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development" + ) + warnings.warn(message) + + return _are_symlinks_supported_in_dir[cache_dir] + + +@dataclass(frozen=True) +class HfFileMetadata: + """Data structure containing information about a file versioned on the Hub. + + Returned by [`get_hf_file_metadata`] based on a URL. + + Args: + commit_hash (`str`, *optional*): + The commit_hash related to the file. + etag (`str`, *optional*): + Etag of the file on the server. + location (`str`): + Location where to download the file. Can be a Hub url or not (CDN). + size (`size`): + Size of the file. In case of an LFS file, contains the size of the actual + LFS file, not the pointer. + xet_file_data (`XetFileData`, *optional*): + Xet information for the file. This is only set if the file is stored using Xet storage. + """ + + commit_hash: str | None + etag: str | None + location: str + size: int | None + xet_file_data: XetFileData | None + + +@dataclass +class DryRunFileInfo: + """Information returned when performing a dry run of a file download. + + Returned by [`hf_hub_download`] when `dry_run=True`. + + Args: + commit_hash (`str`): + The commit_hash related to the file. + file_size (`int`): + Size of the file. In case of an LFS file, contains the size of the actual LFS file, not the pointer. + filename (`str`): + Name of the file in the repo. + is_cached (`bool`): + Whether the file is already cached locally. + will_download (`bool`): + Whether the file will be downloaded if `hf_hub_download` is called with `dry_run=False`. + In practice, will_download is `True` if the file is not cached or if `force_download=True`. + """ + + commit_hash: str + file_size: int + filename: str + local_path: str + is_cached: bool + will_download: bool + + +@validate_hf_hub_args +def hf_hub_url( + repo_id: str, + filename: str, + *, + subfolder: str | None = None, + repo_type: str | None = None, + revision: str | None = None, + endpoint: str | None = None, +) -> str: + """Construct the URL of a file from the given information. + + The resolved address can either be a huggingface.co-hosted url, or a link to + Cloudfront (a Content Delivery Network, or CDN) for large files which are + more than a few MBs. + + Args: + repo_id (`str`): + A namespace (user or an organization) name and a repo name separated + by a `/`. + filename (`str`): + The name of the file in the repo. + subfolder (`str`, *optional*): + An optional value corresponding to a folder inside the repo. + repo_type (`str`, *optional*): + Set to `"dataset"`, `"space"` or `"kernel"` if downloading from a dataset, space or kernel repo, + `None` or `"model"` if downloading from a model. Default is `None`. + revision (`str`, *optional*): + An optional Git revision id which can be a branch name, a tag, or a + commit hash. + endpoint (`str`, *optional*): + The Hub endpoint to send the request to. Defaults to the value of `HF_ENDPOINT`. + + Example: + + ```python + >>> from huggingface_hub import hf_hub_url + + >>> hf_hub_url( + ... repo_id="julien-c/EsperBERTo-small", filename="pytorch_model.bin" + ... ) + 'https://huggingface.co/julien-c/EsperBERTo-small/resolve/main/pytorch_model.bin' + ``` + + > [!TIP] + > Notes: + > + > Cloudfront is replicated over the globe so downloads are way faster for + > the end user (and it also lowers our bandwidth costs). + > + > Cloudfront aggressively caches files by default (default TTL is 24 + > hours), however this is not an issue here because we implement a + > git-based versioning system on huggingface.co, which means that we store + > the files on S3/Cloudfront in a content-addressable way (i.e., the file + > name is its hash). Using content-addressable filenames means cache can't + > ever be stale. + > + > In terms of client-side caching from this library, we base our caching + > on the objects' entity tag (`ETag`), which is an identifier of a + > specific version of a resource [1]_. An object's ETag is: its git-sha1 + > if stored in git, or its sha256 if stored in git-lfs. + + References: + + - [1] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag + """ + if subfolder == "": + subfolder = None + if subfolder is not None: + filename = f"{subfolder}/{filename}" + + if repo_type not in constants.REPO_TYPES_WITH_KERNEL: + raise ValueError("Invalid repo type") + + if repo_type in constants.REPO_TYPES_URL_PREFIXES: + repo_id = constants.REPO_TYPES_URL_PREFIXES[repo_type] + repo_id + + if revision is None: + revision = constants.DEFAULT_REVISION + url = constants.HUGGINGFACE_CO_URL_TEMPLATE.format( + repo_id=repo_id, revision=quote(revision, safe=""), filename=quote(filename) + ) + # Update endpoint if provided + if endpoint is not None and url.startswith(constants.ENDPOINT): + url = endpoint + url[len(constants.ENDPOINT) :] + return url + + +def _get_file_length_from_http_response(response: httpx.Response) -> int | None: + """ + Get the length of the file from the HTTP response headers. + + This function extracts the file size from the HTTP response headers, either from the + `Content-Range` or `Content-Length` header, if available (in that order). + + Args: + response (`httpx.Response`): + The HTTP response object. + + Returns: + `int` or `None`: The length of the file in bytes, or None if not available. + """ + + # If HTTP response contains compressed body (e.g. gzip), the `Content-Length` header will + # contain the length of the compressed body, not the uncompressed file size. + # And at the start of transmission there's no way to know the uncompressed file size for gzip, + # thus we return None in that case. + content_encoding = response.headers.get("Content-Encoding", "identity").lower() + if content_encoding != "identity": + # gzip/br/deflate/zstd etc + return None + + content_range = response.headers.get("Content-Range") + if content_range is not None: + return int(content_range.rsplit("/")[-1]) + + content_length = response.headers.get("Content-Length") + if content_length is not None: + return int(content_length) + + return None + + +@validate_hf_hub_args +def http_get( + url: str, + temp_file: BinaryIO, + *, + resume_size: int = 0, + headers: dict[str, Any] | None = None, + expected_size: int | None = None, + displayed_filename: str | None = None, + tqdm_class: type[base_tqdm] | None = None, + _nb_retries: int = 5, + _tqdm_bar: tqdm | None = None, +) -> None: + """ + Download a remote file. Do not gobble up errors, and will return errors tailored to the Hugging Face Hub. + + If ConnectionError (SSLError) or ReadTimeout happen while streaming data from the server, it is most likely a + transient error (network outage?). We log a warning message and try to resume the download a few times before + giving up. The method gives up after 5 attempts if no new data has being received from the server. + + Args: + url (`str`): + The URL of the file to download. + temp_file (`BinaryIO`): + The file-like object where to save the file. + resume_size (`int`, *optional*): + The number of bytes already downloaded. If set to 0 (default), the whole file is download. If set to a + positive number, the download will resume at the given position. + headers (`dict`, *optional*): + Dictionary of HTTP Headers to send with the request. + expected_size (`int`, *optional*): + The expected size of the file to download. If set, the download will raise an error if the size of the + received content is different from the expected one. + displayed_filename (`str`, *optional*): + The filename of the file that is being downloaded. Value is used only to display a nice progress bar. If + not set, the filename is guessed from the URL or the `Content-Disposition` header. + """ + if expected_size is not None and resume_size == expected_size: + # If the file is already fully downloaded, we don't need to download it again. + return + + initial_headers = headers + headers = copy.deepcopy(headers) or {} + if resume_size > 0: + headers["Range"] = _adjust_range_header(headers.get("Range"), resume_size) + elif expected_size and expected_size > constants.MAX_HTTP_DOWNLOAD_SIZE: + # Any files over 50GB will not be available through basic http requests. + raise ValueError( + "The file is too large to be downloaded using the regular download method. " + " Install `hf_xet` with `pip install hf_xet` for xet-powered downloads." + ) + + with http_stream_backoff( + method="GET", + url=url, + headers=headers, + timeout=constants.HF_HUB_DOWNLOAD_TIMEOUT, + retry_on_exceptions=(), + retry_on_status_codes=(408, 429), + ) as response: + hf_raise_for_status(response) + + # If we requested a Range but got 200 back, the server ignored our Range header + # (e.g. CloudFront with Accept-Encoding: gzip). Reset file to avoid corruption. + if resume_size > 0 and response.status_code == 200: + temp_file.seek(0) + temp_file.truncate() + if _tqdm_bar is not None: + # When the progress bar is reused across retries, its counter has already been advanced by `resume_size` + # worth of chunks from earlier attempts. Those bytes are gone from disk now, so roll the counter back + # to keep the upcoming full re-download from double-counting (e.g. ending at 130/100 on a 100-byte file). + _tqdm_bar.update(-resume_size) + if callable(update_transfer := getattr(_tqdm_bar, "update_transfer", None)): + update_transfer(-resume_size) + resume_size = 0 + + total: int | None = _get_file_length_from_http_response(response) + if total is None: + # Hub serves compressible text files (e.g. vocab.json) with `Content-Encoding: gzip` and + # `Transfer-Encoding: chunked`, so the response carries no `Content-Length`. Fall back to the caller's + # `expected_size` (always known from the metadata HEAD on the hf_hub path) so the progress bar, and any + # aggregating wrapper such as snapshot_download's `_AggregatedTqdm` — still sees the file size. + total = expected_size + + if displayed_filename is None: + displayed_filename = url + content_disposition = response.headers.get("Content-Disposition") + if content_disposition is not None: + match = HEADER_FILENAME_PATTERN.search(content_disposition) + if match is not None: + # Means file is on CDN + displayed_filename = match.groupdict()["filename"] + + # Truncate filename if too long to display + if len(displayed_filename) > 40: + displayed_filename = f"(…){displayed_filename[-40:]}" + + consistency_error_message = ( + f"Consistency check failed: file should be of size {expected_size} but has size" + f" {{actual_size}} ({displayed_filename}).\nThis is usually due to network issues while downloading the file." + " Please retry with `force_download=True`." + ) + progress_cm = _get_progress_bar_context( + desc=displayed_filename, + log_level=logger.getEffectiveLevel(), + total=total, + initial=resume_size, + name="huggingface_hub.http_get", + tqdm_class=tqdm_class, + _tqdm_bar=_tqdm_bar, + ) + + with progress_cm as progress: + new_resume_size = resume_size + try: + for chunk in response.iter_bytes(chunk_size=constants.DOWNLOAD_CHUNK_SIZE): + if chunk: # filter out keep-alive new chunks + progress.update(len(chunk)) + if callable(update_transfer := getattr(progress, "update_transfer", None)): + update_transfer(len(chunk)) + temp_file.write(chunk) + new_resume_size += len(chunk) + # Some data has been downloaded from the server so we reset the number of retries. + _nb_retries = 5 + except (httpx.ConnectError, httpx.TimeoutException, httpx.RemoteProtocolError) as e: + # If ConnectionError (SSLError), ReadTimeout, or RemoteProtocolError (peer closed the connection before + # sending the complete body) happen while streaming data from the server, it is most likely a transient + # error (network outage?). We log a warning message and try to resume the download a few times before + # giving up. The retry mechanism is basic but should be enough in most cases. + if _nb_retries <= 0: + logger.warning("Error while downloading from %s: %s\nMax retries exceeded.", url, str(e)) + raise + logger.warning("Error while downloading from %s: %s\nTrying to resume download...", url, str(e)) + time.sleep(1) + return http_get( + url=url, + temp_file=temp_file, + resume_size=new_resume_size, + headers=initial_headers, + expected_size=expected_size, + tqdm_class=tqdm_class, + _nb_retries=_nb_retries - 1, + # Reuse the existing progress bar across retries so a custom `tqdm_class` (e.g. snapshot_download's `_AggregatedTqdm`, + # which mutates a shared parent bar in `__init__`) is not re-instantiated and does not double-count `total`/`initial`. + _tqdm_bar=progress, + ) + + if expected_size is not None and expected_size != temp_file.tell(): + raise OSError( + consistency_error_message.format( + actual_size=temp_file.tell(), + ) + ) + + +def xet_get( + *, + incomplete_path: Path, + xet_file_data: XetFileData, + headers: dict[str, str], + expected_size: int | None = None, + displayed_filename: str | None = None, + tqdm_class: type[base_tqdm] | None = None, + _tqdm_bar: tqdm | None = None, +) -> None: + """ + Download a file using Xet storage service. + + Args: + incomplete_path (`Path`): + The path to the file to download. + xet_file_data (`XetFileData`): + The file metadata needed to make the request to the xet storage service. + headers (`dict[str, str]`): + The headers to send to the xet storage service. + expected_size (`int`, *optional*): + The expected size of the file to download. If set, the download will raise an error if the size of the + received content is different from the expected one. + displayed_filename (`str`, *optional*): + The filename of the file that is being downloaded. Value is used only to display a nice progress bar. If + not set, the filename is guessed from the URL or the `Content-Disposition` header. + + **How it works:** + The file download system uses Xet storage, which is a content-addressable storage system that breaks files into chunks + for efficient storage and transfer. + + ``session.new_file_download_group()`` manages downloading files by: + - Registering download tasks (each with its unique content hash) and starting download immediately in the background + - Connecting to a storage server (CAS server) that knows how files are chunked + - Using authentication to ensure secure access + - Providing progress updates during download + + Authentication works transparently: the download group accepts a ``token_refresh_url`` + that is used to refresh the short-lived xet access token as needed. + + The download process works like this: + 1. Download tasks run in parallel: + 1.1. Prepare to write the file to disk or to a stream (e.g. truncate file, set up cache) + 1.2. Ask the server "how is this file split into chunks?" using the file's unique hash + The server responds with: + - Which chunks make up the complete file + - Where each chunk can be downloaded from + 1.3. For each needed chunk: + - Checks if we already have it in our local cache + - If not, download it from cloud storage (S3) + - Save it to cache for future use + - Assemble the chunks in order to recreate the original file + + """ + try: + from hf_xet import XetFileInfo # type: ignore[no-redef] + except ImportError: + raise ValueError( + "To use optimized download using Xet storage, you need to install the hf_xet package. " + 'Try `pip install "huggingface_hub[hf_xet]"` or `pip install hf_xet`.' + ) + + if not displayed_filename: + displayed_filename = incomplete_path.name + + # Truncate filename if too long to display + if len(displayed_filename) > 40: + displayed_filename = f"{displayed_filename[:40]}(…)" + + from .utils._xet import abort_xet_session, get_xet_session, xet_headers_without_auth + from .utils._xet_progress_reporting import XetDownloadProgressReporter + + xet_headers = xet_headers_without_auth(headers) + + session = get_xet_session() + + with XetDownloadProgressReporter( + reconstruction_desc=f"{displayed_filename}: reconstructing file", + transfer_desc=f"{displayed_filename}: downloading bytes", + total=expected_size, + log_level=logger.getEffectiveLevel(), + name="huggingface_hub.xet_get", + tqdm_class=tqdm_class, + external_reconstruction_bar=_tqdm_bar, + ) as progress: + try: + with session.new_file_download_group( + token_refresh_url=xet_file_data.refresh_route, + token_refresh_headers=headers, + custom_headers=xet_headers, + progress_callback=progress.update_progress, + ) as group: + group.start_download_file( + XetFileInfo(xet_file_data.file_hash, expected_size), str(incomplete_path.absolute()) + ) + except KeyboardInterrupt: + abort_xet_session() + raise + + +def _normalize_etag(etag: str | None) -> str | None: + """Normalize ETag HTTP header, so it can be used to create nice filepaths. + + The HTTP spec allows two forms of ETag: + ETag: W/"" + ETag: "" + + For now, we only expect the second form from the server, but we want to be future-proof so we support both. For + more context, see `TestNormalizeEtag` tests and https://github.com/huggingface/huggingface_hub/pull/1428. + + Args: + etag (`str`, *optional*): HTTP header + + Returns: + `str` or `None`: string that can be used as a nice directory name. + Returns `None` if input is None. + """ + if etag is None: + return None + return etag.lstrip("W/").strip('"') + + +def _create_relative_symlink(src: str, dst: str, new_blob: bool = False) -> None: + """Alias method used in `transformers` conversion script.""" + return _create_symlink(src=src, dst=dst, new_blob=new_blob) + + +def _create_symlink(src: str, dst: str, new_blob: bool = False) -> None: + """Create a symbolic link named dst pointing to src. + + By default, it will try to create a symlink using a relative path. Relative paths have 2 advantages: + - If the cache_folder is moved (example: back-up on a shared drive), relative paths within the cache folder will + not break. + - Relative paths seems to be better handled on Windows. Issue was reported 3 times in less than a week when + changing from relative to absolute paths. See https://github.com/huggingface/huggingface_hub/issues/1398, + https://github.com/huggingface/diffusers/issues/2729 and https://github.com/huggingface/transformers/pull/22228. + NOTE: The issue with absolute paths doesn't happen on admin mode. + When creating a symlink from the cache to a local folder, it is possible that a relative path cannot be created. + This happens when paths are not on the same volume. In that case, we use absolute paths. + + + The result layout looks something like + └── [ 128] snapshots + ├── [ 128] 2439f60ef33a0d46d85da5001d52aeda5b00ce9f + │ ├── [ 52] README.md -> ../../../blobs/d7edf6bd2a681fb0175f7735299831ee1b22b812 + │ └── [ 76] pytorch_model.bin -> ../../../blobs/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd + + If symlinks cannot be created on this platform (most likely to be Windows), the workaround is to avoid symlinks by + having the actual file in `dst`. If it is a new file (`new_blob=True`), we move it to `dst`. If it is not a new file + (`new_blob=False`), we don't know if the blob file is already referenced elsewhere. To avoid breaking existing + cache, the file is duplicated on the disk. + + In case symlinks are not supported, a warning message is displayed to the user once when loading `huggingface_hub`. + The warning message can be disabled with the `DISABLE_SYMLINKS_WARNING` environment variable. + """ + try: + os.remove(dst) + except OSError: + pass + + abs_src = os.path.abspath(os.path.expanduser(src)) + abs_dst = os.path.abspath(os.path.expanduser(dst)) + abs_dst_folder = os.path.dirname(abs_dst) + + # Use relative_dst in priority + try: + relative_src = os.path.relpath(abs_src, abs_dst_folder) + except ValueError: + # Raised on Windows if src and dst are not on the same volume. This is the case when creating a symlink to a + # local_dir instead of within the cache directory. + # See https://docs.python.org/3/library/os.path.html#os.path.relpath + relative_src = None + + try: + commonpath = os.path.commonpath([abs_src, abs_dst]) + _support_symlinks = are_symlinks_supported(commonpath) + except ValueError: + # Raised if src and dst are not on the same volume. Symlinks will still work on Linux/Macos. + # See https://docs.python.org/3/library/os.path.html#os.path.commonpath + _support_symlinks = os.name != "nt" and not constants.HF_HUB_DISABLE_SYMLINKS + except PermissionError: + # Permission error means src and dst are not in the same volume (e.g. destination path has been provided + # by the user via `local_dir`. Let's test symlink support there) + _support_symlinks = are_symlinks_supported(abs_dst_folder) + except OSError as e: + # OS error (errno=30) means that the commonpath is readonly on Linux/MacOS. + if e.errno == errno.EROFS: + _support_symlinks = are_symlinks_supported(abs_dst_folder) + else: + raise + + # Symlinks are supported => let's create a symlink. + if _support_symlinks: + src_rel_or_abs = relative_src or abs_src + logger.debug(f"Creating pointer from {src_rel_or_abs} to {abs_dst}") + try: + os.symlink(src_rel_or_abs, abs_dst) + return + except FileExistsError: + if os.path.islink(abs_dst) and os.path.realpath(abs_dst) == os.path.realpath(abs_src): + # `abs_dst` already exists and is a symlink to the `abs_src` blob. It is most likely that the file has + # been cached twice concurrently (exactly between `os.remove` and `os.symlink`). Do nothing. + return + else: + # Very unlikely to happen. Means a file `dst` has been created exactly between `os.remove` and + # `os.symlink` and is not a symlink to the `abs_src` blob file. Raise exception. + raise + except PermissionError: + # Permission error means src and dst are not in the same volume (e.g. download to local dir) and symlink + # is supported on both volumes but not between them. Let's just make a hard copy in that case. + pass + + # Symlinks are not supported => let's move or copy the file. + if new_blob: + logger.debug(f"Symlink not supported. Moving file from {abs_src} to {abs_dst}") + shutil.move(abs_src, abs_dst, copy_function=_copy_no_matter_what) + else: + logger.debug(f"Symlink not supported. Copying file from {abs_src} to {abs_dst}") + shutil.copyfile(abs_src, abs_dst) + + +def _cache_commit_hash_for_specific_revision(storage_folder: str, revision: str, commit_hash: str) -> None: + """Cache reference between a revision (tag, branch or truncated commit hash) and the corresponding commit hash. + + Does nothing if `revision` is already a proper `commit_hash` or reference is already cached. + """ + if revision != commit_hash: + ref_path = Path(storage_folder) / "refs" / revision + ref_path.parent.mkdir(parents=True, exist_ok=True) + if not ref_path.exists() or commit_hash != ref_path.read_text(): + # Update ref only if has been updated. Could cause useless error in case + # repo is already cached and user doesn't have write access to cache folder. + # See https://github.com/huggingface/huggingface_hub/issues/1216. + # Write atomically (tmp file + rename) so that concurrent readers never see + # a partially written ref. + tmp_path = ref_path.with_name(f"{ref_path.name}.{uuid.uuid4().hex[:8]}.tmp") + tmp_path.write_text(commit_hash) + os.replace(tmp_path, ref_path) + + +@validate_hf_hub_args +def repo_folder_name(*, repo_id: str, repo_type: str) -> str: + """Return a serialized version of a hf.co repo name and type, safe for disk storage + as a single non-nested folder. + + Example: models--julien-c--EsperBERTo-small + """ + # remove all `/` occurrences to correctly convert repo to directory name + parts = [f"{repo_type}s", *repo_id.split("/")] + return constants.REPO_ID_SEPARATOR.join(parts) + + +def _check_disk_space(expected_size: int, target_dir: str | Path) -> None: + """Check disk usage and log a warning if there is not enough disk space to download the file. + + Args: + expected_size (`int`): + The expected size of the file in bytes. + target_dir (`str`): + The directory where the file will be stored after downloading. + """ + + target_dir = Path(target_dir) # format as `Path` + for path in [target_dir] + list(target_dir.parents): # first check target_dir, then each parents one by one + try: + target_dir_free = shutil.disk_usage(path).free + if target_dir_free < expected_size: + warnings.warn( + "Not enough free disk space to download the file. " + f"The expected file size is: {expected_size / 1e6:.2f} MB. " + f"The target location {target_dir} only has {target_dir_free / 1e6:.2f} MB free disk space." + ) + return + except OSError: # raise on anything: file does not exist or space disk cannot be checked + pass + + +@overload +def hf_hub_download( + repo_id: str, + filename: str, + *, + subfolder: str | None = None, + repo_type: str | None = None, + revision: str | None = None, + library_name: str | None = None, + library_version: str | None = None, + cache_dir: str | Path | None = None, + local_dir: str | Path | None = None, + user_agent: dict | str | None = None, + force_download: bool = False, + etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT, + token: bool | str | None = None, + local_files_only: bool = False, + headers: dict[str, str] | None = None, + endpoint: str | None = None, + tqdm_class: type[base_tqdm] | None = None, + dry_run: Literal[False] = False, +) -> str: ... + + +@overload +def hf_hub_download( + repo_id: str, + filename: str, + *, + subfolder: str | None = None, + repo_type: str | None = None, + revision: str | None = None, + library_name: str | None = None, + library_version: str | None = None, + cache_dir: str | Path | None = None, + local_dir: str | Path | None = None, + user_agent: dict | str | None = None, + force_download: bool = False, + etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT, + token: bool | str | None = None, + local_files_only: bool = False, + headers: dict[str, str] | None = None, + endpoint: str | None = None, + tqdm_class: type[base_tqdm] | None = None, + dry_run: Literal[True] = True, +) -> DryRunFileInfo: ... + + +@overload +def hf_hub_download( + repo_id: str, + filename: str, + *, + subfolder: str | None = None, + repo_type: str | None = None, + revision: str | None = None, + library_name: str | None = None, + library_version: str | None = None, + cache_dir: str | Path | None = None, + local_dir: str | Path | None = None, + user_agent: dict | str | None = None, + force_download: bool = False, + etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT, + token: bool | str | None = None, + local_files_only: bool = False, + headers: dict[str, str] | None = None, + endpoint: str | None = None, + tqdm_class: type[base_tqdm] | None = None, + dry_run: bool = False, +) -> str | DryRunFileInfo: ... + + +@validate_hf_hub_args +def hf_hub_download( + repo_id: str, + filename: str, + *, + subfolder: str | None = None, + repo_type: str | None = None, + revision: str | None = None, + library_name: str | None = None, + library_version: str | None = None, + cache_dir: str | Path | None = None, + local_dir: str | Path | None = None, + user_agent: dict | str | None = None, + force_download: bool = False, + etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT, + token: bool | str | None = None, + local_files_only: bool = False, + headers: dict[str, str] | None = None, + endpoint: str | None = None, + tqdm_class: type[base_tqdm] | None = None, + dry_run: bool = False, +) -> str | DryRunFileInfo: + """Download a given file if it's not already present in the local cache. + + The new cache file layout looks like this: + - The cache directory contains one subfolder per repo_id (namespaced by repo type) + - inside each repo folder: + - refs is a list of the latest known revision => commit_hash pairs + - blobs contains the actual file blobs (identified by their git-sha or sha256, depending on + whether they're LFS files or not) + - snapshots contains one subfolder per commit, each "commit" contains the subset of the files + that have been resolved at that particular commit. Each filename is a symlink to the blob + at that particular commit. + + ``` + [ 96] . + └── [ 160] models--julien-c--EsperBERTo-small + ├── [ 160] blobs + │ ├── [321M] 403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd + │ ├── [ 398] 7cb18dc9bafbfcf74629a4b760af1b160957a83e + │ └── [1.4K] d7edf6bd2a681fb0175f7735299831ee1b22b812 + ├── [ 96] refs + │ └── [ 40] main + └── [ 128] snapshots + ├── [ 128] 2439f60ef33a0d46d85da5001d52aeda5b00ce9f + │ ├── [ 52] README.md -> ../../blobs/d7edf6bd2a681fb0175f7735299831ee1b22b812 + │ └── [ 76] pytorch_model.bin -> ../../blobs/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd + └── [ 128] bbc77c8132af1cc5cf678da3f1ddf2de43606d48 + ├── [ 52] README.md -> ../../blobs/7cb18dc9bafbfcf74629a4b760af1b160957a83e + └── [ 76] pytorch_model.bin -> ../../blobs/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd + ``` + + If `local_dir` is provided, the file structure from the repo will be replicated in this location. When using this + option, the `cache_dir` will not be used and a `.cache/huggingface/` folder will be created at the root of `local_dir` + to store some metadata related to the downloaded files. While this mechanism is not as robust as the main + cache-system, it's optimized for regularly pulling the latest version of a repository. + + Args: + repo_id (`str`): + A user or an organization name and a repo name separated by a `/`. + filename (`str`): + The name of the file in the repo. + subfolder (`str`, *optional*): + An optional value corresponding to a folder inside the model repo. + repo_type (`str`, *optional*): + Set to `"dataset"`, `"space"` or `"kernel"` if downloading from a dataset, space or kernel repo, + `None` or `"model"` if downloading from a model. Default is `None`. + revision (`str`, *optional*): + An optional Git revision id which can be a branch name, a tag, or a + commit hash. + library_name (`str`, *optional*): + The name of the library to which the object corresponds. + library_version (`str`, *optional*): + The version of the library. + cache_dir (`str`, `Path`, *optional*): + Path to the folder where cached files are stored. + local_dir (`str` or `Path`, *optional*): + If provided, the downloaded file will be placed under this directory. + user_agent (`dict`, `str`, *optional*): + The user-agent info in the form of a dictionary or a string. + force_download (`bool`, *optional*, defaults to `False`): + Whether the file should be downloaded even if it already exists in + the local cache. + etag_timeout (`float`, *optional*, defaults to `10`): + When fetching ETag, how many seconds to wait for the server to send + data before giving up which is passed to `requests.request`. + token (`str`, `bool`, *optional*): + A token to be used for the download. + - If `True`, the token is read from the HuggingFace config + folder. + - If a string, it's used as the authentication token. + local_files_only (`bool`, *optional*, defaults to `False`): + If `True`, avoid downloading the file and return the path to the + local cached file if it exists. + headers (`dict`, *optional*): + Additional headers to be sent with the request. + endpoint (`str`, *optional*): + The Hub endpoint to send the request to. Defaults to the value of `HF_ENDPOINT`. + tqdm_class (`tqdm`, *optional*): + If provided, overwrites the default behavior for the progress bar. Passed + argument must inherit from `tqdm.auto.tqdm` or at least mimic its behavior. + Defaults to the custom HF progress bar that can be disabled by setting + `HF_HUB_DISABLE_PROGRESS_BARS` environment variable. + dry_run (`bool`, *optional*, defaults to `False`): + If `True`, perform a dry run without actually downloading the file. Returns a + [`DryRunFileInfo`] object containing information about what would be downloaded. + + Returns: + `str` or [`DryRunFileInfo`]: + - If `dry_run=False`: Local path of file or if networking is off, last version of file cached on disk. + - If `dry_run=True`: A [`DryRunFileInfo`] object containing download information. + + Raises: + [`~utils.RepositoryNotFoundError`] + If the repository to download from cannot be found. This may be because it doesn't exist, + or because it is set to `private` and you do not have access. + [`~utils.RevisionNotFoundError`] + If the revision to download from cannot be found. + [`~utils.RemoteEntryNotFoundError`] + If the file to download cannot be found. + [`~utils.LocalEntryNotFoundError`] + If network is disabled or unavailable and file is not found in cache. + [`EnvironmentError`](https://docs.python.org/3/library/exceptions.html#EnvironmentError) + If `token=True` but the token cannot be found. + [`OSError`](https://docs.python.org/3/library/exceptions.html#OSError) + If ETag cannot be determined. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If some parameter value is invalid. + + """ + if constants.HF_HUB_ETAG_TIMEOUT != constants.DEFAULT_ETAG_TIMEOUT: + # Respect environment variable above user value + etag_timeout = constants.HF_HUB_ETAG_TIMEOUT + + if revision is None: + revision = constants.DEFAULT_REVISION + + if cache_dir is None: + cache_dir = constants.HF_HUB_CACHE + cache_dir = str(Path(cache_dir).expanduser().resolve()) + + if local_dir is not None: + local_dir = str(Path(local_dir).expanduser().resolve()) + + if subfolder == "": + subfolder = None + if subfolder is not None: + # This is used to create a URL, and not a local path, hence the forward slash. + filename = f"{subfolder}/{filename}" + + if repo_type is None: + repo_type = "model" + if repo_type not in constants.REPO_TYPES_WITH_KERNEL: + raise ValueError( + f"Invalid repo type: {repo_type}. Accepted repo types are: {str(constants.REPO_TYPES_WITH_KERNEL)}" + ) + + hf_headers = build_hf_headers( + token=token, + library_name=library_name, + library_version=library_version, + user_agent=user_agent, + headers=headers, + ) + + if local_dir is not None: + return _hf_hub_download_to_local_dir( + # Destination + local_dir=local_dir, + # File info + repo_id=repo_id, + repo_type=repo_type, + filename=filename, + revision=revision, + # HTTP info + endpoint=endpoint, + etag_timeout=etag_timeout, + headers=hf_headers, + token=token, + # Additional options + cache_dir=cache_dir, + force_download=force_download, + local_files_only=local_files_only, + tqdm_class=tqdm_class, + dry_run=dry_run, + ) + else: + return _hf_hub_download_to_cache_dir( + # Destination + cache_dir=cache_dir, + # File info + repo_id=repo_id, + filename=filename, + repo_type=repo_type, + revision=revision, + # HTTP info + endpoint=endpoint, + etag_timeout=etag_timeout, + headers=hf_headers, + token=token, + # Additional options + local_files_only=local_files_only, + force_download=force_download, + tqdm_class=tqdm_class, + dry_run=dry_run, + ) + + +def _hf_hub_download_to_cache_dir( + *, + # Destination + cache_dir: str, + # File info + repo_id: str, + filename: str, + repo_type: str, + revision: str, + # HTTP info + endpoint: str | None, + etag_timeout: float, + headers: dict[str, str], + token: bool | str | None, + # Additional options + local_files_only: bool, + force_download: bool, + tqdm_class: type[base_tqdm] | None, + dry_run: bool, +) -> str | DryRunFileInfo: + """Download a given file to a cache folder, if not already present. + + Method should not be called directly. Please use `hf_hub_download` instead. + """ + locks_dir = os.path.join(cache_dir, ".locks") + storage_folder = os.path.join(cache_dir, repo_folder_name(repo_id=repo_id, repo_type=repo_type)) + + # cross-platform transcription of filename, to be used as a local file path. + relative_filename = os.path.join(*filename.split("/")) + if os.name == "nt": + if relative_filename.startswith("..\\") or "\\..\\" in relative_filename: + raise ValueError( + f"Invalid filename: cannot handle filename '{relative_filename}' on Windows. Please ask the repository" + " owner to rename this file." + ) + + # if user provides a commit_hash and they already have the file on disk, shortcut everything. + if REGEX_COMMIT_HASH.match(revision): + pointer_path = _get_pointer_path(storage_folder, revision, relative_filename) + if os.path.exists(pointer_path): + if dry_run: + return DryRunFileInfo( + commit_hash=revision, + file_size=os.path.getsize(pointer_path), + filename=filename, + is_cached=True, + local_path=pointer_path, + will_download=force_download, + ) + if not force_download: + return pointer_path + + # Try to get metadata (etag, commit_hash, url, size) from the server. + # If we can't, a HEAD request error is returned. + (url_to_download, etag, commit_hash, expected_size, xet_file_data, head_call_error) = _get_metadata_or_catch_error( + repo_id=repo_id, + filename=filename, + repo_type=repo_type, + revision=revision, + endpoint=endpoint, + etag_timeout=etag_timeout, + headers=headers, + token=token, + local_files_only=local_files_only, + storage_folder=storage_folder, + relative_filename=relative_filename, + tree_cache_folder=storage_folder, + ) + + # etag can be None for several reasons: + # 1. we passed local_files_only. + # 2. we don't have a connection + # 3. Hub is down (HTTP 500, 503, 504) + # 4. repo is not found -for example private or gated- and invalid/missing token sent + # 5. Hub is blocked by a firewall or proxy is not set correctly. + # => Try to get the last downloaded one from the specified revision. + # + # If the specified revision is a commit hash, look inside "snapshots". + # If the specified revision is a branch or tag, look inside "refs". + if head_call_error is not None: + # Couldn't make a HEAD call => let's try to find a local file + if not force_download: + commit_hash = None + if REGEX_COMMIT_HASH.match(revision): + commit_hash = revision + else: + ref_path = os.path.join(storage_folder, "refs", revision) + if os.path.isfile(ref_path): + with open(ref_path) as f: + commit_hash = f.read() + + # Return pointer file if exists + if commit_hash is not None: + pointer_path = _get_pointer_path(storage_folder, commit_hash, relative_filename) + if os.path.exists(pointer_path): + if dry_run: + return DryRunFileInfo( + commit_hash=commit_hash, + file_size=os.path.getsize(pointer_path), + filename=filename, + is_cached=True, + local_path=pointer_path, + will_download=force_download, + ) + if not force_download: + return pointer_path + + if isinstance(head_call_error, _DEFAULT_RETRY_ON_EXCEPTIONS) or ( + isinstance(head_call_error, HfHubHTTPError) + and head_call_error.response.status_code in _DEFAULT_RETRY_ON_STATUS_CODES + ): + logger.info("No local file found. Retrying..") + (url_to_download, etag, commit_hash, expected_size, xet_file_data, head_call_error) = ( + _get_metadata_or_catch_error( + repo_id=repo_id, + filename=filename, + repo_type=repo_type, + revision=revision, + endpoint=endpoint, + etag_timeout=_ETAG_RETRY_TIMEOUT, + headers=headers, + token=token, + local_files_only=local_files_only, + storage_folder=storage_folder, + relative_filename=relative_filename, + retry_on_errors=True, + ) + ) + + # If still error, raise + if head_call_error is not None: + _raise_on_head_call_error(head_call_error, force_download, local_files_only) + + # From now on, etag, commit_hash, url and size are not None. + assert etag is not None, "etag must have been retrieved from server" + assert commit_hash is not None, "commit_hash must have been retrieved from server" + assert url_to_download is not None, "file location must have been retrieved from server" + assert expected_size is not None, "expected_size must have been retrieved from server" + blob_path = os.path.join(storage_folder, "blobs", etag) + pointer_path = _get_pointer_path(storage_folder, commit_hash, relative_filename) + + if dry_run: + is_cached = os.path.exists(pointer_path) or os.path.exists(blob_path) + return DryRunFileInfo( + commit_hash=commit_hash, + file_size=expected_size, + filename=filename, + is_cached=is_cached, + local_path=pointer_path, + will_download=force_download or not is_cached, + ) + + os.makedirs(os.path.dirname(blob_path), exist_ok=True) + os.makedirs(os.path.dirname(pointer_path), exist_ok=True) + + # Tag cache_dir so backup tools can skip it (CACHEDIR.TAG standard). + _create_cachedir_tag(Path(cache_dir)) + + # if passed revision is not identical to commit_hash + # then revision has to be a branch name or tag name. + # In that case store a ref. + _cache_commit_hash_for_specific_revision(storage_folder, revision, commit_hash) + + # Prevent parallel downloads of the same file with a lock. + # etag could be duplicated across repos. + # Note: the lock is best-effort to avoid downloading the same file twice. Cache correctness + # does not depend on it: each download writes to a process-unique temporary file that is + # atomically renamed into place (see `_download_to_tmp_and_move`). + lock_path = os.path.join(locks_dir, repo_folder_name(repo_id=repo_id, repo_type=repo_type), f"{etag}.lock") + + # Some Windows versions do not allow for paths longer than 255 characters. + # In this case, we must specify it as an extended path by using the "\\?\" prefix. + if ( + os.name == "nt" + and len(os.path.abspath(lock_path)) > 255 + and not os.path.abspath(lock_path).startswith("\\\\?\\") + ): + lock_path = "\\\\?\\" + os.path.abspath(lock_path) + + if ( + os.name == "nt" + and len(os.path.abspath(blob_path)) > 255 + and not os.path.abspath(blob_path).startswith("\\\\?\\") + ): + blob_path = "\\\\?\\" + os.path.abspath(blob_path) + + Path(lock_path).parent.mkdir(parents=True, exist_ok=True) + + # pointer already exists -> immediate return + if not force_download and os.path.exists(pointer_path): + return pointer_path + + # Blob exists but pointer must be (safely) created -> take the lock + if not force_download and os.path.exists(blob_path): + with WeakFileLock(lock_path): + if not os.path.exists(pointer_path): + _create_symlink(blob_path, pointer_path, new_blob=False) + return pointer_path + + # Local file doesn't exist or etag isn't a match => retrieve file from remote (or cache) + + with WeakFileLock(lock_path): + _download_to_tmp_and_move( + incomplete_path=Path(blob_path + ".incomplete"), + destination_path=Path(blob_path), + url_to_download=url_to_download, + headers=headers, + expected_size=expected_size, + filename=filename, + force_download=force_download, + etag=etag, + xet_file_data=xet_file_data, + tqdm_class=tqdm_class, + ) + if not os.path.exists(pointer_path): + _create_symlink(blob_path, pointer_path, new_blob=True) + + return pointer_path + + +def _hf_hub_download_to_local_dir( + *, + # Destination + local_dir: str | Path, + # File info + repo_id: str, + repo_type: str, + filename: str, + revision: str, + # HTTP info + endpoint: str | None, + etag_timeout: float, + headers: dict[str, str], + token: bool | str | None, + # Additional options + cache_dir: str, + force_download: bool, + local_files_only: bool, + tqdm_class: type[base_tqdm] | None, + dry_run: bool, +) -> str | DryRunFileInfo: + """Download a given file to a local folder, if not already present. + + Method should not be called directly. Please use `hf_hub_download` instead. + """ + # Some Windows versions do not allow for paths longer than 255 characters. + # In this case, we must specify it as an extended path by using the "\\?\" prefix. + if os.name == "nt" and len(os.path.abspath(local_dir)) > 255: + local_dir = "\\\\?\\" + os.path.abspath(local_dir) + local_dir = Path(local_dir) + paths = get_local_download_paths(local_dir=local_dir, filename=filename) + local_metadata = read_download_metadata(local_dir=local_dir, filename=filename) + + # Local file exists + metadata exists + commit_hash matches => return file + if ( + REGEX_COMMIT_HASH.match(revision) + and paths.file_path.is_file() + and local_metadata is not None + and local_metadata.commit_hash == revision + ): + local_file = str(paths.file_path) + if dry_run: + return DryRunFileInfo( + commit_hash=revision, + file_size=os.path.getsize(local_file), + filename=filename, + is_cached=True, + local_path=local_file, + will_download=force_download, + ) + if not force_download: + return local_file + + # Local file doesn't exist or commit_hash doesn't match => we need the etag + # - Xet file => might be cached in /tree listing + # - otherwise => HEAD /resolve call + tree_cache_folder = tree_cache_folder_for_local_dir(str(local_dir)) + (url_to_download, etag, commit_hash, expected_size, xet_file_data, head_call_error) = _get_metadata_or_catch_error( + repo_id=repo_id, + filename=filename, + repo_type=repo_type, + revision=revision, + endpoint=endpoint, + etag_timeout=etag_timeout, + headers=headers, + token=token, + local_files_only=local_files_only, + tree_cache_folder=tree_cache_folder, + ) + + if head_call_error is not None: + # No HEAD call but local file exists => default to local file + if paths.file_path.is_file(): + if dry_run or not force_download: + logger.warning( + f"Couldn't access the Hub to check for update but local file already exists. Defaulting to existing file. (error: {head_call_error})" + ) + local_path = str(paths.file_path) + if dry_run and local_metadata is not None: + return DryRunFileInfo( + commit_hash=local_metadata.commit_hash, + file_size=os.path.getsize(local_path), + filename=filename, + is_cached=True, + local_path=local_path, + will_download=force_download, + ) + if not force_download: + return local_path + elif not force_download: + if isinstance(head_call_error, _DEFAULT_RETRY_ON_EXCEPTIONS) or ( + isinstance(head_call_error, HfHubHTTPError) + and head_call_error.response.status_code in _DEFAULT_RETRY_ON_STATUS_CODES + ): + logger.info("No local file found. Retrying..") + (url_to_download, etag, commit_hash, expected_size, xet_file_data, head_call_error) = ( + _get_metadata_or_catch_error( + repo_id=repo_id, + filename=filename, + repo_type=repo_type, + revision=revision, + endpoint=endpoint, + etag_timeout=_ETAG_RETRY_TIMEOUT, + headers=headers, + token=token, + local_files_only=local_files_only, + retry_on_errors=True, + ) + ) + + # If still error, raise + if head_call_error is not None: + _raise_on_head_call_error(head_call_error, force_download, local_files_only) + + # From now on, etag, commit_hash, url and size are not None. + assert etag is not None, "etag must have been retrieved from server" + assert commit_hash is not None, "commit_hash must have been retrieved from server" + assert url_to_download is not None, "file location must have been retrieved from server" + assert expected_size is not None, "expected_size must have been retrieved from server" + + # Local file exists => check if it's up-to-date + if not force_download and paths.file_path.is_file(): + # etag matches => update metadata and return file + if local_metadata is not None and local_metadata.etag == etag: + write_download_metadata(local_dir=local_dir, filename=filename, commit_hash=commit_hash, etag=etag) + if dry_run: + return DryRunFileInfo( + commit_hash=commit_hash, + file_size=expected_size, + filename=filename, + is_cached=True, + local_path=str(paths.file_path), + will_download=False, + ) + return str(paths.file_path) + + # metadata is outdated + etag is a sha256 + # => means it's an LFS file (large) + # => let's compute local hash and compare + # => if match, update metadata and return file + if local_metadata is None and REGEX_SHA256.match(etag) is not None: + with open(paths.file_path, "rb") as f: + file_hash = sha_fileobj(f).hex() + if file_hash == etag: + write_download_metadata(local_dir=local_dir, filename=filename, commit_hash=commit_hash, etag=etag) + if dry_run: + return DryRunFileInfo( + commit_hash=commit_hash, + file_size=expected_size, + filename=filename, + is_cached=True, + local_path=str(paths.file_path), + will_download=False, + ) + return str(paths.file_path) + + # Local file doesn't exist or etag isn't a match => retrieve file from remote (or cache) + + # If we are lucky enough, the file is already in the cache => copy it + if not force_download: + cached_path = try_to_load_from_cache( + repo_id=repo_id, + filename=filename, + cache_dir=cache_dir, + revision=commit_hash, + repo_type=repo_type, + ) + if isinstance(cached_path, str): + with WeakFileLock(paths.lock_path): + paths.file_path.parent.mkdir(parents=True, exist_ok=True) + shutil.copyfile(cached_path, paths.file_path) + write_download_metadata(local_dir=local_dir, filename=filename, commit_hash=commit_hash, etag=etag) + if dry_run: + return DryRunFileInfo( + commit_hash=commit_hash, + file_size=expected_size, + filename=filename, + is_cached=True, + local_path=str(paths.file_path), + will_download=False, + ) + return str(paths.file_path) + + if dry_run: + is_cached = paths.file_path.is_file() + return DryRunFileInfo( + commit_hash=commit_hash, + file_size=expected_size, + filename=filename, + is_cached=is_cached, + local_path=str(paths.file_path), + will_download=force_download or not is_cached, + ) + + # Otherwise, let's download the file! + with WeakFileLock(paths.lock_path): + paths.file_path.unlink(missing_ok=True) # delete outdated file first + _download_to_tmp_and_move( + incomplete_path=paths.incomplete_path(etag), + destination_path=paths.file_path, + url_to_download=url_to_download, + headers=headers, + expected_size=expected_size, + filename=filename, + force_download=force_download, + etag=etag, + xet_file_data=xet_file_data, + tqdm_class=tqdm_class, + ) + + write_download_metadata(local_dir=local_dir, filename=filename, commit_hash=commit_hash, etag=etag) + return str(paths.file_path) + + +@validate_hf_hub_args +def try_to_load_from_cache( + repo_id: str, + filename: str, + cache_dir: str | Path | None = None, + revision: str | None = None, + repo_type: str | None = None, +) -> str | _CACHED_NO_EXIST_T | None: + """ + Explores the cache to return the latest cached file for a given revision if found. + + This function will not raise any exception if the file in not cached. + + Args: + cache_dir (`str` or `os.PathLike`): + The folder where the cached files lie. + repo_id (`str`): + The ID of the repo on huggingface.co. + filename (`str`): + The filename to look for inside `repo_id`. + revision (`str`, *optional*): + The specific model version to use. Will default to `"main"` if it's not provided and no `commit_hash` is + provided either. + repo_type (`str`, *optional*): + The type of the repository. Will default to `"model"`. + + Returns: + `Optional[str]` or `_CACHED_NO_EXIST`: + Will return `None` if the file was not cached. Otherwise: + - The exact path to the cached file if it's found in the cache + - A special value `_CACHED_NO_EXIST` if the file does not exist at the given commit hash and this fact was + cached. + + Example: + + ```python + from huggingface_hub import try_to_load_from_cache, _CACHED_NO_EXIST + + filepath = try_to_load_from_cache() + if isinstance(filepath, str): + # file exists and is cached + ... + elif filepath is _CACHED_NO_EXIST: + # non-existence of file is cached + ... + else: + # file is not cached + ... + ``` + """ + if revision is None: + revision = "main" + if repo_type is None: + repo_type = "model" + if repo_type not in constants.REPO_TYPES_WITH_KERNEL: + raise ValueError( + f"Invalid repo type: {repo_type}. Accepted repo types are: {str(constants.REPO_TYPES_WITH_KERNEL)}" + ) + if cache_dir is None: + cache_dir = constants.HF_HUB_CACHE + + repo_cache = os.path.join(cache_dir, repo_folder_name(repo_id=repo_id, repo_type=repo_type)) + if not os.path.isdir(repo_cache): + # No cache for this model + return None + + refs_dir = os.path.join(repo_cache, "refs") + snapshots_dir = os.path.join(repo_cache, "snapshots") + no_exist_dir = os.path.join(repo_cache, ".no_exist") + + # Resolve refs (for instance to convert main to the associated commit sha) + if os.path.isdir(refs_dir): + revision_file = os.path.join(refs_dir, revision) + if os.path.isfile(revision_file): + with open(revision_file) as f: + revision = f.read() + + # Check if file is cached as "no_exist" + if os.path.isfile(os.path.join(no_exist_dir, revision, filename)): + return _CACHED_NO_EXIST + + # Check if revision folder exists + if not os.path.exists(snapshots_dir): + return None + cached_shas = os.listdir(snapshots_dir) + if revision not in cached_shas: + # No cache for this revision and we won't try to return a random revision + return None + + # Check if file exists in cache + cached_file = os.path.join(snapshots_dir, revision, filename) + return cached_file if os.path.isfile(cached_file) else None + + +@validate_hf_hub_args +def get_hf_file_metadata( + url: str, + token: bool | str | None = None, + timeout: float | None = constants.HF_HUB_ETAG_TIMEOUT, + library_name: str | None = None, + library_version: str | None = None, + user_agent: dict | str | None = None, + headers: dict[str, str] | None = None, + endpoint: str | None = None, + retry_on_errors: bool = False, +) -> HfFileMetadata: + """Fetch metadata of a file versioned on the Hub for a given url. + + Args: + url (`str`): + File url, for example returned by [`hf_hub_url`]. + token (`str` or `bool`, *optional*): + A token to be used for the download. + - If `True`, the token is read from the HuggingFace config + folder. + - If `False` or `None`, no token is provided. + - If a string, it's used as the authentication token. + timeout (`float`, *optional*, defaults to 10): + How many seconds to wait for the server to send metadata before giving up. + library_name (`str`, *optional*): + The name of the library to which the object corresponds. + library_version (`str`, *optional*): + The version of the library. + user_agent (`dict`, `str`, *optional*): + The user-agent info in the form of a dictionary or a string. + headers (`dict`, *optional*): + Additional headers to be sent with the request. + endpoint (`str`, *optional*): + Endpoint of the Hub. Defaults to . + retry_on_errors (`bool`, *optional*, defaults to `False`): + Whether to retry on errors (429, 5xx, timeout, network errors). + If False, no retry for fast fallback to local cache. + + Returns: + A [`HfFileMetadata`] object containing metadata such as location, etag, size and + commit_hash. + """ + hf_headers = build_hf_headers( + token=token, + library_name=library_name, + library_version=library_version, + user_agent=user_agent, + headers=headers, + ) + hf_headers["Accept-Encoding"] = "identity" # prevent any compression => we want to know the real size of the file + + # Retrieve metadata + response = _httpx_follow_relative_redirects_with_backoff( + method="HEAD", url=url, headers=hf_headers, timeout=timeout, retry_on_errors=retry_on_errors + ) + hf_raise_for_status(response) + + # Return + return HfFileMetadata( + commit_hash=response.headers.get(constants.HUGGINGFACE_HEADER_X_REPO_COMMIT), + # We favor a custom header indicating the etag of the linked resource, and we fall back to the regular etag header. + etag=_normalize_etag( + response.headers.get(constants.HUGGINGFACE_HEADER_X_LINKED_ETAG) or response.headers.get("ETag") + ), + # Either from response headers (if redirected) or defaults to request url + # Do not use directly `url` as we might have followed relative redirects. + location=response.headers.get("Location") or str(response.request.url), # type: ignore + size=_int_or_none( + response.headers.get(constants.HUGGINGFACE_HEADER_X_LINKED_SIZE) or response.headers.get("Content-Length") + ), + xet_file_data=parse_xet_file_data_from_response(response, endpoint=endpoint), # type: ignore + ) + + +def _get_metadata_or_catch_error( + *, + repo_id: str, + filename: str, + repo_type: str, + revision: str, + endpoint: str | None, + etag_timeout: float | None, + headers: dict[str, str], # mutated inplace! + token: bool | str | None, + local_files_only: bool, + relative_filename: str | None = None, # only used to store `.no_exists` in cache + storage_folder: str | None = None, # only used to store `.no_exists` in cache + retry_on_errors: bool = False, + tree_cache_folder: str | None = None, # if set, read the on-disk tree listing to skip the HEAD call +) -> ( + # Either an exception is caught and returned + tuple[None, None, None, None, None, Exception] + | + # Or the metadata is returned as + # `(url_to_download, etag, commit_hash, expected_size, xet_file_data, None)` + tuple[str, str, str, int, XetFileData | None, None] +): + """Get metadata for a file on the Hub, safely handling network issues. + + Returns either the etag, commit_hash and expected size of the file, or the error + raised while fetching the metadata. + + NOTE: This function mutates `headers` inplace! It removes the `authorization` header + if the file is a LFS blob and the domain of the url is different from the + domain of the location (typically an S3 bucket). + """ + if local_files_only: + return ( + None, + None, + None, + None, + None, + OfflineModeIsEnabled( + f"Cannot access file since 'local_files_only=True' as been set. (repo_id: {repo_id}, repo_type: {repo_type}, revision: {revision}, filename: {filename})" + ), + ) + + # Skip the per-file HEAD call when the file metadata can be rebuilt from a tree listing cached on disk. + if tree_cache_folder is not None and REGEX_COMMIT_HASH.match(revision): + tree_metadata = _xet_file_metadata_from_tree_cache( + tree_cache_folder=tree_cache_folder, + repo_id=repo_id, + repo_type=repo_type, + commit_hash=revision, + filename=filename, + endpoint=endpoint, + ) + if tree_metadata is not None: + return tree_metadata + + url = hf_hub_url(repo_id, filename, repo_type=repo_type, revision=revision, endpoint=endpoint) + url_to_download: str = url + etag: str | None = None + commit_hash: str | None = None + expected_size: int | None = None + head_error_call: Exception | None = None + xet_file_data: XetFileData | None = None + + # Try to get metadata from the server. + # Do not raise yet if the file is not found or not accessible. + if not local_files_only: + try: + try: + metadata = get_hf_file_metadata( + url=url, + timeout=etag_timeout, + headers=headers, + token=token, + endpoint=endpoint, + retry_on_errors=retry_on_errors, + ) + except RemoteEntryNotFoundError as http_error: + if storage_folder is not None and relative_filename is not None: + # Cache the non-existence of the file + commit_hash = http_error.response.headers.get(constants.HUGGINGFACE_HEADER_X_REPO_COMMIT) + if commit_hash is not None: + no_exist_file_path = Path(storage_folder) / ".no_exist" / commit_hash / relative_filename + if not no_exist_file_path.exists(): + try: + no_exist_file_path.parent.mkdir(parents=True, exist_ok=True) + no_exist_file_path.touch() + except OSError as e: + logger.error( + f"Could not cache non-existence of file. Will ignore error and continue. Error: {e}" + ) + _cache_commit_hash_for_specific_revision(storage_folder, revision, commit_hash) + raise + + # Commit hash must exist + commit_hash = metadata.commit_hash + if commit_hash is None: + raise FileMetadataError( + "Distant resource does not seem to be on huggingface.co. It is possible that a configuration issue" + " prevents you from downloading resources from https://huggingface.co. Please check your firewall" + " and proxy settings and make sure your SSL certificates are updated." + ) + + # Etag must exist + # If we don't have any of those, raise an error. + etag = metadata.etag + if etag is None: + raise FileMetadataError( + "Distant resource does not have an ETag, we won't be able to reliably ensure reproducibility." + ) + + # Size must exist + expected_size = metadata.size + if expected_size is None: + raise FileMetadataError("Distant resource does not have a Content-Length.") + + xet_file_data = metadata.xet_file_data + + # In case of a redirect, save an extra redirect on the request.get call, + # and ensure we download the exact atomic version even if it changed + # between the HEAD and the GET (unlikely, but hey). + # + # If url domain is different => we are downloading from a CDN => url is signed => don't send auth + # If url domain is the same => redirect due to repo rename AND downloading a regular file => keep auth + if xet_file_data is None and url != metadata.location: + url_to_download = metadata.location + if urlparse(url).netloc != urlparse(metadata.location).netloc: + # Remove authorization header when downloading a LFS blob + headers.pop("authorization", None) + except httpx.ProxyError: + # Actually raise on proxy error + raise + except (httpx.ConnectError, httpx.TimeoutException, OfflineModeIsEnabled) as error: + # Otherwise, our Internet connection is down. + # etag is None + head_error_call = error + except (RevisionNotFoundError, RemoteEntryNotFoundError): + # The repo was found but the revision or entry doesn't exist on the Hub (never existed or got deleted) + raise + except HfHubHTTPError as error: + # Multiple reasons for an http error: + # - Repository is private and invalid/missing token sent + # - Repository is gated and invalid/missing token sent + # - Hub is down (error 500 or 504) + # => let's switch to 'local_files_only=True' to check if the files are already cached. + # (if it's not the case, the error will be re-raised) + head_error_call = error + except FileMetadataError as error: + # Multiple reasons for a FileMetadataError: + # - Wrong network configuration (proxy, firewall, SSL certificates) + # - Inconsistency on the Hub + # => let's switch to 'local_files_only=True' to check if the files are already cached. + # (if it's not the case, the error will be re-raised) + head_error_call = error + + if not (local_files_only or etag is not None or head_error_call is not None): + raise RuntimeError("etag is empty due to uncovered problems") + + return (url_to_download, etag, commit_hash, expected_size, xet_file_data, head_error_call) # type: ignore + + +def _xet_file_metadata_from_tree_cache( + *, + tree_cache_folder: str, + repo_id: str, + repo_type: str, + commit_hash: str, + filename: str, + endpoint: str | None, +) -> tuple[str, str, str, int, XetFileData, None] | None: + """Rebuild the metadata a HEAD call would return, from the on-disk tree listing cache. + + The optimization is intentionally limited to Xet files when Xet is enabled: that's the only case where + skipping the HEAD call pays off, since Xet downloads don't rely on the `/resolve` redirect the HEAD call + would resolve. For regular files (or when Xet is unavailable) we return `None` and let the caller make the + HEAD call as usual. Also returns `None` when the commit's tree listing or the file is not cached. + """ + if not is_xet_available(): + return None + tree_entries = read_tree_cache(tree_cache_folder, commit_hash) + if tree_entries is None: + return None + entry = tree_entries.get(filename) + if entry is None or entry.xet_hash is None or entry.lfs_sha256 is None or entry.lfs_size is None: + return None + + xet_file_data = XetFileData( + file_hash=entry.xet_hash, + refresh_route=xet_connection_info_refresh_url( + token_type=XetTokenType.READ, + repo_id=repo_id, + repo_type=repo_type, + revision=commit_hash, + endpoint=endpoint, + ), + ) + # Mirror the server's HEAD response: ETag/size come from the LFS metadata for LFS-tracked files (which Xet + # files are). + etag = entry.lfs_sha256 + file_size = entry.lfs_size + location = hf_hub_url(repo_id, filename, repo_type=repo_type, revision=commit_hash, endpoint=endpoint) + return (location, etag, commit_hash, file_size, xet_file_data, None) + + +def _raise_on_head_call_error(head_call_error: Exception, force_download: bool, local_files_only: bool) -> NoReturn: + """Raise an appropriate error when the HEAD call failed and we cannot locate a local file.""" + # No head call => we cannot force download. + if force_download: + if local_files_only: + raise ValueError("Cannot pass 'force_download=True' and 'local_files_only=True' at the same time.") + elif isinstance(head_call_error, OfflineModeIsEnabled): + raise ValueError("Cannot pass 'force_download=True' when offline mode is enabled.") from head_call_error + else: + raise ValueError("Force download failed due to the above error.") from head_call_error + + # No head call + couldn't find an appropriate file on disk => raise an error. + if local_files_only: + raise LocalEntryNotFoundError( + "Cannot find the requested files in the disk cache and outgoing traffic has been disabled. To enable" + " hf.co look-ups and downloads online, set 'local_files_only' to False." + ) + elif isinstance(head_call_error, (RepositoryNotFoundError, GatedRepoError)) or ( + isinstance(head_call_error, HfHubHTTPError) and head_call_error.response.status_code == 401 + ): + # Repo not found or gated => let's raise the actual error + # Unauthorized => likely a token issue => let's raise the actual error + raise head_call_error + else: + # Otherwise: most likely a connection issue or Hub downtime => let's warn the user + raise LocalEntryNotFoundError( + "An error happened while trying to locate the file on the Hub and we cannot find the requested files" + " in the local cache. Please check your connection and try again or make sure your Internet connection" + " is on." + ) from head_call_error + + +def _download_to_tmp_and_move( + incomplete_path: Path, + destination_path: Path, + url_to_download: str, + headers: dict[str, str], + expected_size: int | None, + filename: str, + force_download: bool, + etag: str | None, + xet_file_data: XetFileData | None, + tqdm_class: type[base_tqdm] | None = None, +) -> None: + """Download content from a URL to a destination path. + + Internal logic: + - return early if file is already downloaded + - check disk space before downloading + - download content to a process-unique temporary file + - set correct permissions on temporary file + - move the temporary file to the destination path + + Both `incomplete_path` and `destination_path` must be on the same volume to avoid a local copy. + """ + if destination_path.exists() and not force_download: + # Do nothing if already exists (except if force_download=True) + return + + # Download to a process-unique temporary file before moving it in place. A shared + # `.incomplete` file corrupts the cache whenever the surrounding lock is not honored: + # on some filesystems (Lustre, GPFS, some NFS mounts) `flock(2)` silently succeeds for every + # caller and concurrent processes end up appending to the same file. With a unique file per + # process, a broken lock costs only duplicated bandwidth: each process downloads the full + # file and atomically renames it to the final destination. + # See https://github.com/huggingface/huggingface_hub/pull/4228. + tmp_path = incomplete_path.with_name(f"{incomplete_path.stem}.{uuid.uuid4().hex[:8]}.incomplete") + try: + with tmp_path.open("wb") as f: + logger.debug(f"Downloading '{filename}' to '{tmp_path}'") + + if expected_size is not None: # might be None if HTTP header not set correctly + # Check disk space in both tmp and destination path + _check_disk_space(expected_size, tmp_path.parent) + _check_disk_space(expected_size, destination_path.parent) + + if xet_file_data is not None and is_xet_available(): + logger.debug("Xet Storage is enabled for this repo. Downloading file from Xet Storage..") + xet_get( + incomplete_path=tmp_path, + xet_file_data=xet_file_data, + headers=headers, + expected_size=expected_size, + displayed_filename=filename, + tqdm_class=tqdm_class, + ) + else: + if xet_file_data is not None and not constants.HF_HUB_DISABLE_XET: + logger.warning( + "Xet Storage is enabled for this repo, but the 'hf_xet' package is not installed. " + "Falling back to regular HTTP download. " + "For better performance, install the package with: `pip install huggingface_hub[hf_xet]` or `pip install hf_xet`" + ) + + http_get( + url_to_download, + f, + headers=headers, + expected_size=expected_size, + tqdm_class=tqdm_class, + ) + + logger.debug(f"Download complete. Moving file to {destination_path}") + _chmod_and_move(tmp_path, destination_path) + finally: + # No-op on success (file has been moved). On failure, do not keep a partial file around: + # it could not be reused anyway since the temporary name is unique to this download. + tmp_path.unlink(missing_ok=True) + + +def _int_or_none(value: str | None) -> int | None: + try: + return int(value) # type: ignore + except (TypeError, ValueError): + return None + + +def _chmod_and_move(src: Path, dst: Path) -> None: + """Set correct permission before moving a blob from tmp directory to cache dir. + + Do not take into account the `umask` from the process as there is no convenient way + to get it that is thread-safe. + + See: + - About umask: https://docs.python.org/3/library/os.html#os.umask + - Thread-safety: https://stackoverflow.com/a/70343066 + - About solution: https://github.com/huggingface/huggingface_hub/pull/1220#issuecomment-1326211591 + - Fix issue: https://github.com/huggingface/huggingface_hub/issues/1141 + - Fix issue: https://github.com/huggingface/huggingface_hub/issues/1215 + """ + # Get umask by creating a temporary file in the folder containing the incomplete file. + # We know this folder is writable since the incomplete file has just been written there. + # Probing next to `dst` is not always possible: when downloading to a local dir, `dst` is the + # final file location and its parents might not be writable (e.g. read-only root filesystem). + # See https://github.com/huggingface/huggingface_hub/issues/4304. + tmp_file = src.parent / f"tmp_{uuid.uuid4()}" + try: + tmp_file.touch() + cache_dir_mode = Path(tmp_file).stat().st_mode + os.chmod(str(src), stat.S_IMODE(cache_dir_mode)) + except OSError as e: + logger.warning( + f"Could not set the permissions on the file '{src}'. Error: {e}.\nContinuing without setting permissions." + ) + finally: + try: + tmp_file.unlink() + except OSError: + # fails if `tmp_file.touch()` failed => do nothing + # See https://github.com/huggingface/huggingface_hub/issues/2359 + pass + + shutil.move(str(src), str(dst), copy_function=_copy_no_matter_what) + + +def _copy_no_matter_what(src: str, dst: str) -> None: + """Copy file from src to dst. + + If `shutil.copy2` fails, fallback to `shutil.copyfile`. + """ + try: + # Copy file with metadata and permission + # Can fail e.g. if dst is an S3 mount + shutil.copy2(src, dst) + except OSError: + # Copy only file content + shutil.copyfile(src, dst) + + +def _get_pointer_path(storage_folder: str, revision: str, relative_filename: str) -> str: + # Using `os.path.abspath` instead of `Path.resolve()` to avoid resolving symlinks + snapshot_path = os.path.join(storage_folder, "snapshots") + pointer_path = os.path.join(snapshot_path, revision, relative_filename) + if Path(os.path.abspath(snapshot_path)) not in Path(os.path.abspath(pointer_path)).parents: + raise ValueError( + "Invalid pointer path: cannot create pointer path in snapshot folder if" + f" `storage_folder='{storage_folder}'`, `revision='{revision}'` and" + f" `relative_filename='{relative_filename}'`." + ) + return pointer_path diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/hf_api.py b/.venv/lib/python3.13/site-packages/huggingface_hub/hf_api.py new file mode 100644 index 0000000000000000000000000000000000000000..2f948c2c9c31941c741e4d3b9826ce419f68a6fb --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/hf_api.py @@ -0,0 +1,14961 @@ +# Copyright 2019-present, the HuggingFace Inc. team. +# +# 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. +from __future__ import annotations + +import inspect +import itertools +import json +import re +import struct +import time +import warnings +from collections import defaultdict +from collections.abc import Callable, Iterable, Iterator +from concurrent.futures import Future, ThreadPoolExecutor +from dataclasses import asdict, dataclass, field +from datetime import datetime, timezone +from functools import wraps +from itertools import islice +from pathlib import Path +from secrets import token_hex +from typing import TYPE_CHECKING, Any, BinaryIO, Literal, TypeVar, overload +from urllib.parse import quote + +import httpcore +import httpx +from tqdm.auto import tqdm as base_tqdm +from tqdm.contrib.concurrent import thread_map + +from . import constants +from ._buckets import ( + BucketFile, + BucketFileMetadata, + BucketFolder, + BucketInfo, + BucketUrl, + SyncPlan, + _BucketAddFile, + _BucketCopyFile, + _BucketDeleteFile, + _parse_bucket_uri, + sync_bucket_internal, +) +from ._commit_api import ( + DUPLICATE_LFS_BATCH_SIZE, + CommitOperation, + CommitOperationAdd, + CommitOperationCopy, + CommitOperationDelete, + _CopySource, + _fetch_files_to_copy, + _fetch_upload_modes, + _send_commit, + _upload_files, + _warn_on_overwriting_operations, +) +from ._dataset_viewer import DatasetParquetEntry +from ._eval_results import EvalResultEntry, parse_eval_result_entries +from ._inference_endpoints import InferenceEndpoint, InferenceEndpointScalingMetric, InferenceEndpointType +from ._jobs_api import ( + TERMINAL_JOB_STAGES, + JobHardware, + JobHardwareInfo, + JobInfo, + JobSpec, + JobStage, + ScheduledJobInfo, + _create_job_spec, + _derive_job_volume_name, +) +from ._space_api import ( + INTERMEDIATE_SPACE_STAGES, + SpaceHardware, + SpaceRuntime, + SpaceSearchResult, + SpaceSecret, + SpaceStorage, + SpaceTemplate, + SpaceVariable, + Volume, +) +from ._upload_large_folder import upload_large_folder_internal +from ._upload_pipeline import pipelined_upload +from .community import ( + Discussion, + DiscussionComment, + DiscussionStatusChange, + DiscussionTitleChange, + DiscussionWithDetails, + deserialize_event, +) +from .errors import ( + BadRequestError, + EntryNotFoundError, + FileDuplicationError, + GatedRepoError, + HfHubHTTPError, + HfUriError, + LocalTokenNotFoundError, + RemoteEntryNotFoundError, + RepositoryNotFoundError, + RevisionNotFoundError, +) +from .file_download import DryRunFileInfo, HfFileMetadata, get_hf_file_metadata, hf_hub_url +from .repocard_data import DatasetCardData, ModelCardData, SpaceCardData +from .utils import ( + DEFAULT_IGNORE_PATTERNS, + HfUri, + NotASafetensorsRepoError, + SafetensorsFileMetadata, + SafetensorsParsingError, + SafetensorsRepoMetadata, + TensorInfo, + are_progress_bars_disabled, + build_hf_headers, + chunk_iterable, + experimental, + filter_repo_objects, + fix_hf_endpoint_in_url, + get_session, + get_token, + hf_raise_for_status, + http_backoff, + logging, + paginate, + parse_datetime, + parse_hf_uri, + parse_xet_file_data_from_response, + silent_tqdm, + validate_hf_hub_args, +) +from .utils import tqdm as hf_tqdm +from .utils._auth import _get_token_from_environment, _get_token_from_file, _get_token_from_google_colab +from .utils._deprecation import _deprecate_arguments, _deprecate_method +from .utils._http import _httpx_follow_relative_redirects_with_backoff +from .utils._runtime import is_xet_available +from .utils._typing import CallableT +from .utils._verification import collect_local_files, resolve_local_root, verify_maps +from .utils.endpoint_helpers import _is_emission_within_threshold + + +if TYPE_CHECKING: + from .inference._providers import PROVIDER_T + from .utils._verification import FolderVerification + from .utils._xet_progress_reporting import XetUploadProgressReporter + +R = TypeVar("R") # Return type +CollectionItemType_T = Literal["model", "dataset", "space", "paper", "collection", "bucket"] +CollectionSort_T = Literal["lastModified", "trending", "upvotes"] +RepoVisibility_T = Literal["public", "private", "protected"] + +ExpandModelProperty_T = Literal[ + "author", + "baseModels", + "cardData", + "childrenModelCount", + "config", + "createdAt", + "disabled", + "downloads", + "downloadsAllTime", + "evalResults", + "gated", + "gguf", + "inference", + "inferenceProviderMapping", + "lastModified", + "library_name", + "likes", + "mask_token", + "model-index", + "pipeline_tag", + "private", + "resourceGroup", + "safetensors", + "sha", + "siblings", + "spaces", + "tags", + "transformersInfo", + "trendingScore", + "usedStorage", + "widgetData", +] + +ExpandDatasetProperty_T = Literal[ + "author", + "cardData", + "citation", + "createdAt", + "description", + "disabled", + "downloads", + "downloadsAllTime", + "gated", + "lastModified", + "likes", + "mainSize", + "paperswithcode_id", + "private", + "resourceGroup", + "sha", + "siblings", + "tags", + "trendingScore", + "usedStorage", +] + +ExpandSpaceProperty_T = Literal[ + "author", + "cardData", + "createdAt", + "datasets", + "disabled", + "lastModified", + "likes", + "models", + "private", + "resourceGroup", + "runtime", + "sdk", + "sha", + "siblings", + "subdomain", + "tags", + "trendingScore", + "usedStorage", +] + +ModelSort_T = Literal["created_at", "downloads", "last_modified", "likes", "trending_score"] +DatasetSort_T = Literal["created_at", "downloads", "last_modified", "likes", "trending_score"] +SpaceSort_T = Literal["created_at", "last_modified", "likes", "trending_score"] +DailyPapersSort_T = Literal["publishedAt", "trending"] + +REPO_REGIONS = Literal["us", "eu"] + +USERNAME_PLACEHOLDER = "hf_user" +_REGEX_DISCUSSION_URL = re.compile(r".*/discussions/(\d+)$") +_REGEX_HTTP_PROTOCOL = re.compile(r"https?://") + +_CREATE_COMMIT_NO_REPO_ERROR_MESSAGE = ( + "\nNote: Creating a commit assumes that the repo already exists on the" + " Huggingface Hub. Please use `create_repo` if it's not the case." +) +_AUTH_CHECK_NO_REPO_ERROR_MESSAGE = ( + "\nNote: The repository either does not exist or you do not have access rights." + " Please check the repository ID and your access permissions." + " If this is a private repository, ensure that your token is correct." +) +_BUCKET_PATHS_INFO_BATCH_SIZE = 1000 +_BUCKET_BATCH_ADD_CHUNK_SIZE = 1000 +_BUCKET_BATCH_DELETE_CHUNK_SIZE = 1000 + +# Regex used to match special revisions with "/" in them (see #1710) +SPECIAL_REFS_REVISION_REGEX = re.compile( + r""" + (^refs\/convert\/\w+) # `refs/convert/parquet` revisions + | + (^refs\/pr\/\d+) # PR revisions + """, + re.VERBOSE, +) + +logger = logging.get_logger(__name__) + + +def _resolve_repo_visibility( + *, + private: bool | None, + visibility: RepoVisibility_T | None, + repo_type: str | None, +) -> RepoVisibility_T | None: + if private is not None and visibility is not None: + raise ValueError("Received both `private` and `visibility` arguments. Please provide only one of them.") + + if visibility is None: + if private is None: + return None + return "private" if private else "public" + + if visibility == "protected" and repo_type != constants.REPO_TYPE_SPACE: + raise ValueError("Only Spaces can be 'protected'. Please set visibility to 'public' or 'private'.") + return visibility + + +def repo_type_and_id_from_hf_id(hf_id: str, hub_url: str | None = None) -> tuple[str | None, str | None, str]: + """ + Returns the repo type and ID from a huggingface.co URL linking to a + repository + + > [!WARNING] + > Deprecated: prefer [`parse_hf_uri`], which parses both `hf://` URIs and Hugging Face web URLs into a structured [`HfUri`]. + > See https://huggingface.co/docs/huggingface_hub/package_reference/hf_uris for more details. + + Args: + hf_id (`str`): + An URL or ID of a repository on the HF hub. Accepted values are: + + - https://huggingface.co/// + - https://huggingface.co// + - hf://// + - hf:/// + - // + - / + - + hub_url (`str`, *optional*): + The URL of the HuggingFace Hub, defaults to https://huggingface.co + + Returns: + A tuple with three items: repo_type (`str` or `None`), namespace (`str` or + `None`) and repo_id (`str`). + + Raises: + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If URL cannot be parsed. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If `repo_type` is unknown. + """ + input_hf_id = hf_id + + # Get the hub_url (with or without protocol) + full_hub_url = hub_url if hub_url is not None else constants.ENDPOINT + hub_url_without_protocol = _REGEX_HTTP_PROTOCOL.sub("", full_hub_url) + + # Check if hf_id is a URL containing the hub_url (check both with and without protocol) + hf_id_without_protocol = _REGEX_HTTP_PROTOCOL.sub("", hf_id) + is_hf_url = hub_url_without_protocol in hf_id_without_protocol and "@" not in hf_id + + HFFS_PREFIX = "hf://" + if hf_id.startswith(HFFS_PREFIX): # Remove "hf://" prefix if exists + hf_id = hf_id[len(HFFS_PREFIX) :] + + # If it's a URL, strip the endpoint prefix to get the path + if is_hf_url: + # Remove protocol if present + hf_id_normalized = _REGEX_HTTP_PROTOCOL.sub("", hf_id) + + # Remove the hub_url prefix to get the relative path + if hf_id_normalized.startswith(hub_url_without_protocol): + # Strip the hub URL and any leading slashes + hf_id = hf_id_normalized[len(hub_url_without_protocol) :].lstrip("/") + + url_segments = hf_id.split("/") + is_hf_id = len(url_segments) <= 3 + + namespace: str | None + if is_hf_url: + # For URLs, we need to extract repo_type, namespace, repo_id + # Expected format after stripping endpoint: [repo_type]/namespace/repo_id or namespace/repo_id + + if len(url_segments) >= 3: + # Check if first segment is a repo type + if url_segments[0] in constants.REPO_TYPES_MAPPING: + repo_type = constants.REPO_TYPES_MAPPING[url_segments[0]] + namespace = url_segments[1] + repo_id = url_segments[2] + elif url_segments[0] == "buckets": + # Special case for buckets + repo_type = "bucket" + namespace = url_segments[1] + repo_id = url_segments[2] + else: + # First segment is namespace + namespace = url_segments[0] + repo_id = url_segments[1] + repo_type = None + elif len(url_segments) == 2: + namespace = url_segments[0] + repo_id = url_segments[1] + + # Check if namespace is actually a repo type mapping + if namespace in constants.REPO_TYPES_MAPPING: + # Mean canonical dataset or model + repo_type = constants.REPO_TYPES_MAPPING[namespace] + namespace = None + elif namespace == "buckets": + # Special case for buckets + repo_type = "bucket" + namespace = None + else: + repo_type = None + else: + # Single segment + repo_id = url_segments[0] + namespace = None + repo_type = None + elif is_hf_id: + if len(url_segments) == 3: + # Passed // or // + repo_type, namespace, repo_id = url_segments[-3:] + elif len(url_segments) == 2: + if url_segments[0] in constants.REPO_TYPES_MAPPING: + # Passed '' or 'datasets/' for a canonical model or dataset + repo_type = constants.REPO_TYPES_MAPPING[url_segments[0]] + namespace = None + repo_id = hf_id.split("/")[-1] + elif url_segments[0] == "buckets": + # Special case for buckets + repo_type = "bucket" + namespace = None + repo_id = hf_id.split("/")[-1] + else: + # Passed / or / + namespace, repo_id = hf_id.split("/")[-2:] + repo_type = None + else: + # Passed + repo_id = url_segments[0] + namespace, repo_type = None, None + else: + raise ValueError(f"Unable to retrieve user and repo ID from the passed HF ID: {hf_id}") + + # Check if repo type is known (mapping "spaces" => "space" + empty value => `None`) + if repo_type in constants.REPO_TYPES_MAPPING: + repo_type = constants.REPO_TYPES_MAPPING[repo_type] + if repo_type == "": + repo_type = None + if repo_type not in constants.REPO_TYPES_WITH_KERNEL and repo_type != "bucket": + raise ValueError(f"Unknown `repo_type`: '{repo_type}' ('{input_hf_id}')") + + return repo_type, namespace, repo_id + + +@dataclass +class LastCommitInfo(dict): + oid: str + title: str + date: datetime + + def __post_init__(self): # hack to make LastCommitInfo backward compatible + self.update(asdict(self)) + + +@dataclass +class BlobLfsInfo(dict): + size: int + sha256: str + pointer_size: int + + def __post_init__(self): # hack to make BlobLfsInfo backward compatible + self.update(asdict(self)) + + +@dataclass +class BlobSecurityInfo(dict): + safe: bool # duplicate information with "status" field, keeping it for backward compatibility + status: str + av_scan: dict | None + pickle_import_scan: dict | None + + def __post_init__(self): # hack to make BlogSecurityInfo backward compatible + self.update(asdict(self)) + + +@dataclass +class TransformersInfo(dict): + auto_model: str + custom_class: str | None = None + # possible `pipeline_tag` values: https://github.com/huggingface/huggingface.js/blob/3ee32554b8620644a6287e786b2a83bf5caf559c/packages/tasks/src/pipelines.ts#L72 + pipeline_tag: str | None = None + processor: str | None = None + + def __post_init__(self): # hack to make TransformersInfo backward compatible + self.update(asdict(self)) + + +@dataclass +class SafeTensorsInfo(dict): + parameters: dict[str, int] + total: int + + def __post_init__(self): # hack to make SafeTensorsInfo backward compatible + self.update(asdict(self)) + + +@dataclass +class CommitInfo(str): + """Data structure containing information about a newly created commit. + + Returned by any method that creates a commit on the Hub: [`create_commit`], [`upload_file`], [`upload_folder`], + [`delete_file`], [`delete_folder`]. It inherits from `str` for backward compatibility but using methods specific + to `str` is deprecated. + + Attributes: + commit_url (`str`): + Url where to find the commit. + + commit_message (`str`): + The summary (first line) of the commit that has been created. + + commit_description (`str`): + Description of the commit that has been created. Can be empty. + + oid (`str`): + Commit hash id. Example: `"91c54ad1727ee830252e457677f467be0bfd8a57"`. + + pr_url (`str`, *optional*): + Url to the PR that has been created, if any. Populated when `create_pr=True` + is passed. + + pr_revision (`str`, *optional*): + Revision of the PR that has been created, if any. Populated when + `create_pr=True` is passed. Example: `"refs/pr/1"`. + + pr_num (`int`, *optional*): + Number of the PR discussion that has been created, if any. Populated when + `create_pr=True` is passed. Can be passed as `discussion_num` in + [`get_discussion_details`]. Example: `1`. + + repo_url (`RepoUrl`): + Repo URL of the commit containing info like repo_id, repo_type, etc. + """ + + commit_url: str + commit_message: str + commit_description: str + oid: str + _endpoint: str | None = field(default=None, repr=False) + pr_url: str | None = None + + # Computed from `commit_url` in `__post_init__` + repo_url: RepoUrl = field(init=False) + + # Computed from `pr_url` in `__post_init__` + pr_revision: str | None = field(init=False) + pr_num: int | None = field(init=False) + + def __new__(cls, *args, commit_url: str, **kwargs): + return str.__new__(cls, commit_url) + + def __post_init__(self): + """Populate pr-related fields after initialization. + + See https://docs.python.org/3.10/library/dataclasses.html#post-init-processing. + """ + # Repo info + self.repo_url = RepoUrl(self.commit_url.split("/commit/")[0], endpoint=self._endpoint) + + # PR info + if self.pr_url is not None: + self.pr_revision = _parse_revision_from_pr_url(self.pr_url) + self.pr_num = int(self.pr_revision.split("/")[-1]) + else: + self.pr_revision = None + self.pr_num = None + + +@dataclass +class AccessRequest: + """Data structure containing information about a user access request. + + Attributes: + username (`str`): + Username of the user who requested access. + fullname (`str`): + Fullname of the user who requested access. + email (`Optional[str]`): + Email of the user who requested access. + Can only be `None` in the /accepted list if the user was granted access manually. + timestamp (`datetime`): + Timestamp of the request. + status (`Literal["pending", "accepted", "rejected"]`): + Status of the request. Can be one of `["pending", "accepted", "rejected"]`. + fields (`dict[str, Any]`, *optional*): + Additional fields filled by the user in the gate form. + """ + + username: str + fullname: str + email: str | None + timestamp: datetime + status: Literal["pending", "accepted", "rejected"] + + # Additional fields filled by the user in the gate form + fields: dict[str, Any] | None = None + + +@dataclass +class WebhookWatchedItem: + """Data structure containing information about the items watched by a webhook. + + Attributes: + type (`Literal["dataset", "model", "org", "space", "user"]`): + Type of the item to be watched. Can be one of `["dataset", "model", "org", "space", "user"]`. + name (`str`): + Name of the item to be watched. Can be the username, organization name, model name, dataset name or space name. + """ + + type: Literal["dataset", "model", "org", "space", "user"] + name: str + + +@dataclass +class WebhookInfo: + """Data structure containing information about a webhook. + + One of `url` or `job` is specified, but not both. + + Attributes: + id (`str`): + ID of the webhook. + url (`str`, *optional*): + URL of the webhook. + job (`JobSpec`, *optional*): + Specifications of the Job to trigger. + watched (`list[WebhookWatchedItem]`): + List of items watched by the webhook, see [`WebhookWatchedItem`]. + domains (`list[WEBHOOK_DOMAIN_T]`): + List of domains the webhook is watching. Can be one of `["repo", "discussions"]`. + secret (`str`, *optional*): + Secret of the webhook. + disabled (`bool`): + Whether the webhook is disabled or not. + """ + + id: str + url: str | None + job: JobSpec | None + watched: list[WebhookWatchedItem] + domains: list[constants.WEBHOOK_DOMAIN_T] + secret: str | None + disabled: bool + + +class RepoUrl(str): + """Subclass of `str` describing a repo URL on the Hub. + + `RepoUrl` is returned by `HfApi.create_repo`. It inherits from `str` for backward + compatibility. At initialization, the URL is parsed to populate properties: + - endpoint (`str`) + - namespace (`str`) + - repo_name (`str`) + - repo_id (`str`) + - repo_type (`Literal["model", "dataset", "space"]`) + - url (`str`) + + Args: + url (`Any`): + String value of the repo url. + endpoint (`str`, *optional*): + Endpoint of the Hub. Defaults to . + + Example: + ```py + >>> RepoUrl('https://huggingface.co/openai-community/gpt2') + RepoUrl('https://huggingface.co/openai-community/gpt2', endpoint='https://huggingface.co', repo_type='model', repo_id='openai-community/gpt2') + + >>> RepoUrl('https://hub-ci.huggingface.co/datasets/dummy_user/dummy_dataset', endpoint='https://hub-ci.huggingface.co') + RepoUrl('https://hub-ci.huggingface.co/datasets/dummy_user/dummy_dataset', endpoint='https://hub-ci.huggingface.co', repo_type='dataset', repo_id='dummy_user/dummy_dataset') + + >>> RepoUrl('hf://datasets/my-user/my-dataset') + RepoUrl('hf://datasets/my-user/my-dataset', endpoint='https://huggingface.co', repo_type='dataset', repo_id='user/dataset') + + >>> HfApi.create_repo("dummy_model") + RepoUrl('https://huggingface.co/Wauplin/dummy_model', endpoint='https://huggingface.co', repo_type='model', repo_id='Wauplin/dummy_model') + ``` + + Raises: + [`~errors.HfUriError`]: + If the URL cannot be parsed (e.g. canonical single-segment repo, or unknown `repo_type`). + """ + + def __new__(cls, url: Any, endpoint: str | None = None): + url = fix_hf_endpoint_in_url(url, endpoint=endpoint) + return super().__new__(cls, url) + + def __init__(self, url: Any, endpoint: str | None = None) -> None: + super().__init__() + self.endpoint = endpoint or constants.ENDPOINT + + # Parse with the shared 'parse_hf_uri' parser, which handles 'hf://' URIs as well as Hugging + # Face web URLs (including ones on this custom 'endpoint'). If that fails, the input is a bare + # '/' id, which we reparse as an 'hf://' URI. + raw = str(self) + try: + parsed = parse_hf_uri(raw, endpoint=self.endpoint) + except HfUriError: + if "://" in raw: + raise # it was a URL: the original error is authoritative, don't retry as a bare id + parsed = parse_hf_uri(f"{constants.HF_PROTOCOL}{raw}") + + # Populate fields ('parsed.id' is always '/'). + self.namespace, self.repo_name = parsed.id.split("/") + self.repo_id = parsed.id + self.repo_type = parsed.type + self.url = str(self) # just in case it's needed + + def __repr__(self) -> str: + return f"RepoUrl('{self}', endpoint='{self.endpoint}', repo_type='{self.repo_type}', repo_id='{self.repo_id}')" + + +def _resolve_copy_target_path( + src_file_path: str, + src_root_path: str | None, + is_single_file: bool, + destination_path: str, + destination_is_directory: bool, + destination_exists_as_directory: bool, + merge_contents: bool, +) -> str: + basename = src_file_path.rsplit("/", 1)[-1] + if is_single_file: + if destination_path == "": + return basename + if destination_is_directory: + return f"{destination_path.rstrip('/')}/{basename}" + return destination_path + + if src_root_path is None: + rel_path = src_file_path + elif src_file_path.startswith(src_root_path + "/"): + rel_path = src_file_path[len(src_root_path) + 1 :] + elif src_file_path == src_root_path: + rel_path = src_file_path.rsplit("/", 1)[-1] + else: + raise ValueError(f"Unexpected source path while copying folder: '{src_file_path}'.") + + if rel_path == "": + raise ValueError("Cannot copy an empty relative path.") + + # Rsync-style trailing slash on source means "copy contents of" — skip nesting. + # Without trailing slash, match `cp -r` behavior: nest source folder inside + # existing destination directory. Non-existing destination always uses rename semantics. + if destination_exists_as_directory and src_root_path is not None and not merge_contents: + src_dir_basename = src_root_path.rsplit("/", 1)[-1] + rel_path = f"{src_dir_basename}/{rel_path}" + + if destination_path == "": + return rel_path + return f"{destination_path.rstrip('/')}/{rel_path}" + + +@dataclass +class RepoSibling: + """ + Contains basic information about a repo file inside a repo on the Hub. + + > [!TIP] + > All attributes of this class are optional except `rfilename`. This is because only the file names are returned when + > listing repositories on the Hub (with [`list_models`], [`list_datasets`] or [`list_spaces`]). If you need more + > information like file size, blob id or lfs details, you must request them specifically from one repo at a time + > (using [`model_info`], [`dataset_info`] or [`space_info`]) as it adds more constraints on the backend server to + > retrieve these. + + Attributes: + rfilename (str): + file name, relative to the repo root. + size (`int`, *optional*): + The file's size, in bytes. This attribute is defined when `files_metadata` argument of [`repo_info`] is set + to `True`. It's `None` otherwise. + blob_id (`str`, *optional*): + The file's git OID. This attribute is defined when `files_metadata` argument of [`repo_info`] is set to + `True`. It's `None` otherwise. + lfs (`BlobLfsInfo`, *optional*): + The file's LFS metadata. This attribute is defined when`files_metadata` argument of [`repo_info`] is set to + `True` and the file is stored with Git LFS. It's `None` otherwise. + """ + + rfilename: str + size: int | None = None + blob_id: str | None = None + lfs: BlobLfsInfo | None = None + + +@dataclass +class RepoFile: + """ + Contains information about a file on the Hub. + + Attributes: + path (str): + file path relative to the repo root. + size (`int`): + The file's size, in bytes. + blob_id (`str`): + The file's git OID. + lfs (`BlobLfsInfo`, *optional*): + The file's LFS metadata. + xet_hash (`str`, *optional*): + The file's Xet hash. + last_commit (`LastCommitInfo`, *optional*): + The file's last commit metadata. Only defined if [`list_repo_tree`] and [`get_paths_info`] + are called with `expand=True`. + security (`BlobSecurityInfo`, *optional*): + The file's security scan metadata. Only defined if [`list_repo_tree`] and [`get_paths_info`] + are called with `expand=True`. + """ + + path: str + size: int + blob_id: str + lfs: BlobLfsInfo | None = None + xet_hash: str | None = None + last_commit: LastCommitInfo | None = None + security: BlobSecurityInfo | None = None + + def __init__(self, **kwargs): + self.path = kwargs.pop("path") + self.size = kwargs.pop("size") + self.blob_id = kwargs.pop("oid") + lfs = kwargs.pop("lfs", None) + if lfs is not None: + lfs = BlobLfsInfo(size=lfs["size"], sha256=lfs["oid"], pointer_size=lfs["pointerSize"]) + self.lfs = lfs + self.xet_hash = kwargs.pop("xetHash", None) + last_commit = kwargs.pop("lastCommit", None) or kwargs.pop("last_commit", None) + if last_commit is not None: + last_commit = LastCommitInfo( + oid=last_commit["id"], title=last_commit["title"], date=parse_datetime(last_commit["date"]) + ) + self.last_commit = last_commit + security = kwargs.pop("securityFileStatus", None) + if security is not None: + safe = security["status"] == "safe" + security = BlobSecurityInfo( + safe=safe, + status=security["status"], + av_scan=security["avScan"], + pickle_import_scan=security["pickleImportScan"], + ) + self.security = security + + # backwards compatibility + self.rfilename = self.path + self.lastCommit = self.last_commit + + +@dataclass +class RepoFolder: + """ + Contains information about a folder on the Hub. + + Attributes: + path (str): + folder path relative to the repo root. + tree_id (`str`): + The folder's git OID. + last_commit (`LastCommitInfo`, *optional*): + The folder's last commit metadata. Only defined if [`list_repo_tree`] and [`get_paths_info`] + are called with `expand=True`. + """ + + path: str + tree_id: str + last_commit: LastCommitInfo | None = None + + def __init__(self, **kwargs): + self.path = kwargs.pop("path") + self.tree_id = kwargs.pop("oid") + last_commit = kwargs.pop("lastCommit", None) or kwargs.pop("last_commit", None) + if last_commit is not None: + last_commit = LastCommitInfo( + oid=last_commit["id"], title=last_commit["title"], date=parse_datetime(last_commit["date"]) + ) + self.last_commit = last_commit + + +@dataclass +class InferenceProviderMapping: + provider: PROVIDER_T # Provider name + hf_model_id: str # ID of the model on the Hugging Face Hub + provider_id: str # ID of the model on the provider's side + status: Literal["error", "live", "staging"] + task: str + + adapter: str | None = None + adapter_weights_path: str | None = None + type: Literal["single-model", "tag-filter"] | None = None + + def __init__(self, **kwargs): + self.provider = kwargs.pop("provider") + self.hf_model_id = kwargs.pop("hf_model_id") + self.provider_id = kwargs.pop("providerId") + self.status = kwargs.pop("status") + self.task = kwargs.pop("task") + + self.adapter = kwargs.pop("adapter", None) + self.adapter_weights_path = kwargs.pop("adapterWeightsPath", None) + self.type = kwargs.pop("type", None) + self.__dict__.update(**kwargs) + + +@dataclass +class ModelInfo: + """ + Contains information about a model on the Hub. This object is returned by [`model_info`] and [`list_models`]. + + > [!TIP] + > Most attributes of this class are optional. This is because the data returned by the Hub depends on the query made. + > In general, the more specific the query, the more information is returned. On the contrary, when listing models + > using [`list_models`] only a subset of the attributes are returned. + + Attributes: + id (`str`): + ID of model. + author (`str`, *optional*): + Author of the model. + base_models (`list[str]`, *optional*): + List of base models this model is derived from. + card_data (`ModelCardData`, *optional*): + Model Card Metadata as a [`huggingface_hub.repocard_data.ModelCardData`] object. + children_model_count (`int`, *optional*): + Number of children models derived from this model. + config (`dict`, *optional*): + Model configuration. + created_at (`datetime`, *optional*): + Date of creation of the repo on the Hub. Note that the lowest value is `2022-03-02T23:29:04.000Z`, + corresponding to the date when we began to store creation dates. + disabled (`bool`, *optional*): + Is the repo disabled. + downloads (`int`): + Number of downloads of the model over the last 30 days. + downloads_all_time (`int`): + Cumulated number of downloads of the model since its creation. + eval_results (`list[EvalResultEntry]`, *optional*): + Model's evaluation results. + gated (`Literal["auto", "manual", False]`, *optional*): + Is the repo gated. + If so, whether there is manual or automatic approval. + gguf (`dict`, *optional*): + GGUF information of the model. + inference (`Literal["warm"]`, *optional*): + Status of the model on Inference Providers. Warm if the model is served by at least one provider. + inference_provider_mapping (`list[InferenceProviderMapping]`, *optional*): + A list of [`InferenceProviderMapping`] ordered after the user's provider order. + last_modified (`datetime`, *optional*): + Date of last commit to the repo. + library_name (`str`, *optional*): + Library associated with the model. + likes (`int`): + Number of likes of the model. + mask_token (`str`, *optional*): + Mask token used by the model. + model_index (`dict`, *optional*): + Model index for evaluation. + pipeline_tag (`str`, *optional*): + Pipeline tag associated with the model. + private (`bool`): + Is the repo private. + resource_group (`dict`, *optional*): + Resource group information for the model. + safetensors (`SafeTensorsInfo`, *optional*): + Model's safetensors information. + security_repo_status (`dict`, *optional*): + Model's security scan status. + sha (`str`, *optional*): + Repo SHA at this particular revision. + siblings (`list[RepoSibling]`): + List of [`huggingface_hub.hf_api.RepoSibling`] objects that constitute the model. + spaces (`list[str]`, *optional*): + List of spaces using the model. + tags (`list[str]`): + List of tags of the model. Compared to `card_data.tags`, contains extra tags computed by the Hub + (e.g. supported libraries, model's arXiv). + transformers_info (`TransformersInfo`, *optional*): + Transformers-specific info (auto class, processor, etc.) associated with the model. + trending_score (`int`, *optional*): + Trending score of the model. + used_storage (`int`, *optional*): + Size in bytes of the model on the Hub. + widget_data (`Any`, *optional*): + Widget data associated with the model. + """ + + id: str + author: str | None + base_models: list[str] | None + card_data: ModelCardData | None + children_model_count: int | None + config: dict | None + created_at: datetime | None + disabled: bool | None + downloads: int | None + downloads_all_time: int | None + eval_results: list[EvalResultEntry] | None + gated: Literal["auto", "manual", False] | None + gguf: dict | None + inference: Literal["warm"] | None + inference_provider_mapping: list[InferenceProviderMapping] | None + last_modified: datetime | None + library_name: str | None + likes: int | None + mask_token: str | None + model_index: dict | None + pipeline_tag: str | None + private: bool | None + resource_group: dict | None + safetensors: SafeTensorsInfo | None + security_repo_status: dict | None + sha: str | None + siblings: list[RepoSibling] | None + spaces: list[str] | None + tags: list[str] | None + transformers_info: TransformersInfo | None + trending_score: int | None + used_storage: int | None + widget_data: Any | None + + def __init__(self, **kwargs): + self.id = kwargs.pop("id") + self.author = kwargs.pop("author", None) + self.sha = kwargs.pop("sha", None) + last_modified = kwargs.pop("lastModified", None) or kwargs.pop("last_modified", None) + self.last_modified = parse_datetime(last_modified) if last_modified else None + created_at = kwargs.pop("createdAt", None) or kwargs.pop("created_at", None) + self.created_at = parse_datetime(created_at) if created_at else None + self.private = kwargs.pop("private", None) + self.gated = kwargs.pop("gated", None) + self.disabled = kwargs.pop("disabled", None) + self.downloads = kwargs.pop("downloads", None) + self.downloads_all_time = kwargs.pop("downloadsAllTime", None) + self.likes = kwargs.pop("likes", None) + self.library_name = kwargs.pop("library_name", None) + self.gguf = kwargs.pop("gguf", None) + + self.inference = kwargs.pop("inference", None) + + # little hack to simplify Inference Providers logic and make it backward and forward compatible + # right now, API returns a dict on model_info and a list on list_models. Let's harmonize to list. + mapping = kwargs.pop("inferenceProviderMapping", None) + if isinstance(mapping, list): + self.inference_provider_mapping = [ + InferenceProviderMapping(**{**value, "hf_model_id": self.id}) for value in mapping + ] + elif isinstance(mapping, dict): + self.inference_provider_mapping = [ + InferenceProviderMapping(**{**value, "hf_model_id": self.id, "provider": provider}) + for provider, value in mapping.items() + ] + elif mapping is None: + self.inference_provider_mapping = None + else: + raise ValueError( + f"Unexpected type for `inferenceProviderMapping`. Expecting `dict` or `list`. Got {mapping}." + ) + + self.tags = kwargs.pop("tags", None) + self.pipeline_tag = kwargs.pop("pipeline_tag", None) + self.mask_token = kwargs.pop("mask_token", None) + self.trending_score = kwargs.pop("trendingScore", None) + self.used_storage = kwargs.pop("usedStorage", None) + + card_data = kwargs.pop("cardData", None) or kwargs.pop("card_data", None) + self.card_data = ( + ModelCardData(**card_data, ignore_metadata_errors=True) if isinstance(card_data, dict) else card_data + ) + + self.widget_data = kwargs.pop("widgetData", None) + self.model_index = kwargs.pop("model-index", None) or kwargs.pop("model_index", None) + self.config = kwargs.pop("config", None) + transformers_info = kwargs.pop("transformersInfo", None) or kwargs.pop("transformers_info", None) + self.transformers_info = TransformersInfo(**transformers_info) if transformers_info else None + siblings = kwargs.pop("siblings", None) + self.siblings = ( + [ + RepoSibling( + rfilename=sibling["rfilename"], + size=sibling.get("size"), + blob_id=sibling.get("blobId"), + lfs=( + BlobLfsInfo( + size=sibling["lfs"]["size"], + sha256=sibling["lfs"]["sha256"], + pointer_size=sibling["lfs"]["pointerSize"], + ) + if sibling.get("lfs") + else None + ), + ) + for sibling in siblings + ] + if siblings is not None + else None + ) + self.spaces = kwargs.pop("spaces", None) + safetensors = kwargs.pop("safetensors", None) + self.safetensors = ( + SafeTensorsInfo( + parameters=safetensors["parameters"], + total=safetensors["total"], + ) + if safetensors + else None + ) + self.security_repo_status = kwargs.pop("securityRepoStatus", None) + eval_results = kwargs.pop("evalResults", None) + self.eval_results = parse_eval_result_entries(eval_results) if eval_results else None + self.base_models = kwargs.pop("baseModels", None) + self.children_model_count = kwargs.pop("childrenModelCount", None) + self.resource_group = kwargs.pop("resourceGroup", None) + # backwards compatibility + self.lastModified = self.last_modified + self.cardData = self.card_data + self.transformersInfo = self.transformers_info + self.__dict__.update(**kwargs) + + +@dataclass +class DatasetInfo: + """ + Contains information about a dataset on the Hub. This object is returned by [`dataset_info`] and [`list_datasets`]. + + > [!TIP] + > Most attributes of this class are optional. This is because the data returned by the Hub depends on the query made. + > In general, the more specific the query, the more information is returned. On the contrary, when listing datasets + > using [`list_datasets`] only a subset of the attributes are returned. + + Attributes: + id (`str`): + ID of dataset. + author (`str`): + Author of the dataset. + card_data (`DatasetCardData`, *optional*): + Dataset Card Metadata as a [`huggingface_hub.repocard_data.DatasetCardData`] object. + citation (`str`, *optional*): + Citation information for the dataset. + created_at (`datetime`, *optional*): + Date of creation of the repo on the Hub. Note that the lowest value is `2022-03-02T23:29:04.000Z`, + corresponding to the date when we began to store creation dates. + description (`str`, *optional*): + Description of the dataset. + disabled (`bool`, *optional*): + Is the repo disabled. + downloads (`int`): + Number of downloads of the dataset over the last 30 days. + downloads_all_time (`int`): + Cumulated number of downloads of the dataset since its creation. + gated (`Literal["auto", "manual", False]`, *optional*): + Is the repo gated. + If so, whether there is manual or automatic approval. + last_modified (`datetime`, *optional*): + Date of last commit to the repo. + likes (`int`): + Number of likes of the dataset. + main_size (`int`, *optional*): + Size in bytes of the main branch of the dataset. + paperswithcode_id (`str`, *optional*): + Papers with code ID of the dataset. + private (`bool`): + Is the repo private. + resource_group (`dict`, *optional*): + Resource group information for the dataset. + sha (`str`): + Repo SHA at this particular revision. + siblings (`list[RepoSibling]`): + List of [`huggingface_hub.hf_api.RepoSibling`] objects that constitute the dataset. + tags (`list[str]`): + List of tags of the dataset. + trending_score (`int`, *optional*): + Trending score of the dataset. + used_storage (`int`, *optional*): + Size in bytes of the dataset on the Hub. + """ + + id: str + author: str | None + card_data: DatasetCardData | None + citation: str | None + created_at: datetime | None + description: str | None + disabled: bool | None + downloads: int | None + downloads_all_time: int | None + gated: Literal["auto", "manual", False] | None + last_modified: datetime | None + likes: int | None + main_size: int | None + paperswithcode_id: str | None + private: bool | None + resource_group: dict | None + sha: str | None + siblings: list[RepoSibling] | None + tags: list[str] | None + trending_score: int | None + used_storage: int | None + + def __init__(self, **kwargs): + self.id = kwargs.pop("id") + self.author = kwargs.pop("author", None) + self.sha = kwargs.pop("sha", None) + created_at = kwargs.pop("createdAt", None) or kwargs.pop("created_at", None) + self.created_at = parse_datetime(created_at) if created_at else None + last_modified = kwargs.pop("lastModified", None) or kwargs.pop("last_modified", None) + self.last_modified = parse_datetime(last_modified) if last_modified else None + self.private = kwargs.pop("private", None) + self.gated = kwargs.pop("gated", None) + self.disabled = kwargs.pop("disabled", None) + self.downloads = kwargs.pop("downloads", None) + self.downloads_all_time = kwargs.pop("downloadsAllTime", None) + self.likes = kwargs.pop("likes", None) + self.main_size = kwargs.pop("mainSize", None) + self.paperswithcode_id = kwargs.pop("paperswithcode_id", None) + self.tags = kwargs.pop("tags", None) + self.trending_score = kwargs.pop("trendingScore", None) + self.used_storage = kwargs.pop("usedStorage", None) + + card_data = kwargs.pop("cardData", None) or kwargs.pop("card_data", None) + self.card_data = ( + DatasetCardData(**card_data, ignore_metadata_errors=True) if isinstance(card_data, dict) else card_data + ) + siblings = kwargs.pop("siblings", None) + self.siblings = ( + [ + RepoSibling( + rfilename=sibling["rfilename"], + size=sibling.get("size"), + blob_id=sibling.get("blobId"), + lfs=( + BlobLfsInfo( + size=sibling["lfs"]["size"], + sha256=sibling["lfs"]["sha256"], + pointer_size=sibling["lfs"]["pointerSize"], + ) + if sibling.get("lfs") + else None + ), + ) + for sibling in siblings + ] + if siblings is not None + else None + ) + self.citation = kwargs.pop("citation", None) + self.description = kwargs.pop("description", None) + self.resource_group = kwargs.pop("resourceGroup", None) + # backwards compatibility + self.lastModified = self.last_modified + self.cardData = self.card_data + self.__dict__.update(**kwargs) + + +@dataclass +class SpaceInfo: + """ + Contains information about a Space on the Hub. This object is returned by [`space_info`] and [`list_spaces`]. + + > [!TIP] + > Most attributes of this class are optional. This is because the data returned by the Hub depends on the query made. + > In general, the more specific the query, the more information is returned. On the contrary, when listing spaces + > using [`list_spaces`] only a subset of the attributes are returned. + + Attributes: + id (`str`): + ID of the Space. + author (`str`, *optional*): + Author of the Space. + card_data (`SpaceCardData`, *optional*): + Space Card Metadata as a [`huggingface_hub.repocard_data.SpaceCardData`] object. + created_at (`datetime`, *optional*): + Date of creation of the repo on the Hub. Note that the lowest value is `2022-03-02T23:29:04.000Z`, + corresponding to the date when we began to store creation dates. + datasets (`list[str]`, *optional*): + List of datasets used by the Space. + disabled (`bool`, *optional*): + Is the Space disabled. + gated (`Literal["auto", "manual", False]`, *optional*): + Is the repo gated. + If so, whether there is manual or automatic approval. + host (`str`, *optional*): + Host URL of the Space. + last_modified (`datetime`, *optional*): + Date of last commit to the repo. + likes (`int`): + Number of likes of the Space. + models (`list[str]`, *optional*): + List of models used by the Space. + private (`bool`): + Is the repo private. + resource_group (`dict`, *optional*): + Resource group information for the Space. + runtime (`SpaceRuntime`, *optional*): + Space runtime information as a [`huggingface_hub.hf_api.SpaceRuntime`] object. + sdk (`str`, *optional*): + SDK used by the Space. + sha (`str`, *optional*): + Repo SHA at this particular revision. + siblings (`list[RepoSibling]`): + List of [`huggingface_hub.hf_api.RepoSibling`] objects that constitute the Space. + subdomain (`str`, *optional*): + Subdomain of the Space. + tags (`list[str]`): + List of tags of the Space. + trending_score (`int`, *optional*): + Trending score of the Space. + used_storage (`int`, *optional*): + Size in bytes of the Space on the Hub. + """ + + id: str + author: str | None + card_data: SpaceCardData | None + created_at: datetime | None + datasets: list[str] | None + disabled: bool | None + gated: Literal["auto", "manual", False] | None + host: str | None + last_modified: datetime | None + likes: int | None + models: list[str] | None + private: bool | None + resource_group: dict | None + runtime: SpaceRuntime | None + sdk: str | None + sha: str | None + siblings: list[RepoSibling] | None + subdomain: str | None + tags: list[str] | None + trending_score: int | None + used_storage: int | None + + def __init__(self, **kwargs): + self.id = kwargs.pop("id") + self.author = kwargs.pop("author", None) + self.sha = kwargs.pop("sha", None) + created_at = kwargs.pop("createdAt", None) or kwargs.pop("created_at", None) + self.created_at = parse_datetime(created_at) if created_at else None + last_modified = kwargs.pop("lastModified", None) or kwargs.pop("last_modified", None) + self.last_modified = parse_datetime(last_modified) if last_modified else None + self.private = kwargs.pop("private", None) + self.gated = kwargs.pop("gated", None) + self.disabled = kwargs.pop("disabled", None) + self.host = kwargs.pop("host", None) + self.subdomain = kwargs.pop("subdomain", None) + self.likes = kwargs.pop("likes", None) + self.sdk = kwargs.pop("sdk", None) + self.tags = kwargs.pop("tags", None) + self.trending_score = kwargs.pop("trendingScore", None) + self.used_storage = kwargs.pop("usedStorage", None) + card_data = kwargs.pop("cardData", None) or kwargs.pop("card_data", None) + self.card_data = ( + SpaceCardData(**card_data, ignore_metadata_errors=True) if isinstance(card_data, dict) else card_data + ) + siblings = kwargs.pop("siblings", None) + self.siblings = ( + [ + RepoSibling( + rfilename=sibling["rfilename"], + size=sibling.get("size"), + blob_id=sibling.get("blobId"), + lfs=( + BlobLfsInfo( + size=sibling["lfs"]["size"], + sha256=sibling["lfs"]["sha256"], + pointer_size=sibling["lfs"]["pointerSize"], + ) + if sibling.get("lfs") + else None + ), + ) + for sibling in siblings + ] + if siblings is not None + else None + ) + runtime = kwargs.pop("runtime", None) + self.runtime = SpaceRuntime(runtime) if runtime else None + self.models = kwargs.pop("models", None) + self.datasets = kwargs.pop("datasets", None) + self.resource_group = kwargs.pop("resourceGroup", None) + # backwards compatibility + self.lastModified = self.last_modified + self.cardData = self.card_data + self.__dict__.update(**kwargs) + + +@dataclass +class KernelInfo: + """ + Contains information about a kernel repo on the Hub. This object is returned by [`kernel_info`]. + + Attributes: + id (`str`): + ID of the kernel repo. + author (`str`, *optional*): + Author of the kernel repo. + downloads (`int`, *optional*): + Number of downloads of the kernel repo over the last 30 days. + gated (`Literal["auto", "manual", False]`, *optional*): + Is the repo gated. If so, whether there is manual or automatic approval. + last_modified (`datetime`, *optional*): + Date of last commit to the repo. + likes (`int`, *optional*): + Number of likes of the kernel repo. + private (`bool`, *optional*): + Is the repo private. + sha (`str`, *optional*): + Repo SHA at this particular revision. + """ + + id: str + author: str | None + downloads: int | None + gated: Literal["auto", "manual", False] | None + last_modified: datetime | None + likes: int | None + private: bool | None + sha: str | None + + def __init__(self, **kwargs): + self.id = kwargs.pop("id") + self.author = kwargs.pop("author", None) + self.downloads = kwargs.pop("downloads", None) + self.gated = kwargs.pop("gated", None) + last_modified = kwargs.pop("lastModified", None) or kwargs.pop("last_modified", None) + self.last_modified = parse_datetime(last_modified) if last_modified else None + self.likes = kwargs.pop("likes", None) + self.private = kwargs.pop("private", None) + self.sha = kwargs.pop("sha", None) + + # future compatibility + self.__dict__.update(**kwargs) + + +@dataclass +class CollectionItem: + """ + Contains information about an item of a Collection (model, dataset, Space, paper, collection or bucket). + + Attributes: + item_object_id (`str`): + Unique ID of the item in the collection. + item_id (`str`): + ID of the underlying object on the Hub. Can be either a repo_id, a paper id, a collection slug + or a bucket id. + e.g. `"jbilcke-hf/ai-comic-factory"`, `"2307.09288"`, `"celinah/cerebras-function-calling-682607169c35fbfa98b30b9a"`. + item_type (`str`): + Type of the underlying object. Can be one of `"model"`, `"dataset"`, `"space"`, `"paper"`, `"collection"` + or `"bucket"`. + position (`int`): + Position of the item in the collection. + note (`str`, *optional*): + Note associated with the item, as plain text. + """ + + item_object_id: str # id in database + item_id: str # repo_id or paper id + item_type: str + position: int + note: str | None = None + + def __init__( + self, + _id: str, + id: str, + type: CollectionItemType_T, + position: int, + note: dict | None = None, + **kwargs, + ) -> None: + self.item_object_id: str = _id # id in database + self.item_id: str = id # repo_id or paper id + # if the item is a collection, override item_id with the slug + slug = kwargs.get("slug") + if slug is not None: + self.item_id = slug # collection slug + self.item_type: CollectionItemType_T = type + self.position: int = position + note_text = note.get("text") if note is not None else None + self.note = note_text if isinstance(note_text, str) else None + + +@dataclass +class Collection: + """ + Contains information about a Collection on the Hub. + + Attributes: + slug (`str`): + Slug of the collection. E.g. `"TheBloke/recent-models-64f9a55bb3115b4f513ec026"`. + title (`str`): + Title of the collection. E.g. `"Recent models"`. + owner (`str`): + Owner of the collection. E.g. `"TheBloke"`. + items (`list[CollectionItem]`): + List of items in the collection. + last_updated (`datetime`): + Date of the last update of the collection. + position (`int`): + Position of the collection in the list of collections of the owner. + private (`bool`): + Whether the collection is private or not. + theme (`str`): + Theme of the collection. E.g. `"green"`. + upvotes (`int`): + Number of upvotes of the collection. + description (`str`, *optional*): + Description of the collection, as plain text. + url (`str`): + (property) URL of the collection on the Hub. + """ + + slug: str + title: str + owner: str + items: list[CollectionItem] + last_updated: datetime + position: int + private: bool + theme: str + upvotes: int + description: str | None = None + + def __init__(self, **kwargs) -> None: + self.slug = kwargs.pop("slug") + self.title = kwargs.pop("title") + self.owner = kwargs.pop("owner") + self.items = [CollectionItem(**item) for item in kwargs.pop("items")] + self.last_updated = parse_datetime(kwargs.pop("lastUpdated")) + self.position = kwargs.pop("position") + self.private = kwargs.pop("private") + self.theme = kwargs.pop("theme") + self.upvotes = kwargs.pop("upvotes") + self.description = kwargs.pop("description", None) + endpoint = kwargs.pop("endpoint", None) + if endpoint is None: + endpoint = constants.ENDPOINT + self._url = f"{endpoint}/collections/{self.slug}" + + @property + def url(self) -> str: + """Returns the URL of the collection on the Hub.""" + return self._url + + +@dataclass +class GitRefInfo: + """ + Contains information about a git reference for a repo on the Hub. + + Attributes: + name (`str`): + Name of the reference (e.g. tag name or branch name). + ref (`str`): + Full git ref on the Hub (e.g. `"refs/heads/main"` or `"refs/tags/v1.0"`). + target_commit (`str`): + OID of the target commit for the ref (e.g. `"e7da7f221d5bf496a48136c0cd264e630fe9fcc8"`) + """ + + name: str + ref: str + target_commit: str + + +@dataclass +class GitRefs: + """ + Contains information about all git references for a repo on the Hub. + + Object is returned by [`list_repo_refs`]. + + Attributes: + branches (`list[GitRefInfo]`): + A list of [`GitRefInfo`] containing information about branches on the repo. + converts (`list[GitRefInfo]`): + A list of [`GitRefInfo`] containing information about "convert" refs on the repo. + Converts are refs used (internally) to push preprocessed data in Dataset repos. + tags (`list[GitRefInfo]`): + A list of [`GitRefInfo`] containing information about tags on the repo. + pull_requests (`list[GitRefInfo]`, *optional*): + A list of [`GitRefInfo`] containing information about pull requests on the repo. + Only returned if `include_prs=True` is set. + """ + + branches: list[GitRefInfo] + converts: list[GitRefInfo] + tags: list[GitRefInfo] + pull_requests: list[GitRefInfo] | None = None + + +@dataclass +class GitCommitInfo: + """ + Contains information about a git commit for a repo on the Hub. Check out [`list_repo_commits`] for more details. + + Attributes: + commit_id (`str`): + OID of the commit (e.g. `"e7da7f221d5bf496a48136c0cd264e630fe9fcc8"`) + authors (`list[str]`): + List of authors of the commit. + created_at (`datetime`): + Datetime when the commit was created. + title (`str`): + Title of the commit. This is a free-text value entered by the authors. + message (`str`): + Description of the commit. This is a free-text value entered by the authors. + formatted_title (`str`): + Title of the commit formatted as HTML. Only returned if `formatted=True` is set. + formatted_message (`str`): + Description of the commit formatted as HTML. Only returned if `formatted=True` is set. + """ + + commit_id: str + + authors: list[str] + created_at: datetime + title: str + message: str + + formatted_title: str | None + formatted_message: str | None + + +@dataclass +class UserLikes: + """ + Contains information about a user likes on the Hub. + + Attributes: + user (`str`): + Name of the user for which we fetched the likes. + total (`int`): + Total number of likes. + datasets (`list[str]`): + List of datasets liked by the user (as repo_ids). + kernels (`list[str]`): + List of kernels liked by the user (as repo_ids). + models (`list[str]`): + List of models liked by the user (as repo_ids). + spaces (`list[str]`): + List of spaces liked by the user (as repo_ids). + """ + + # Metadata + user: str + total: int + + # User likes + datasets: list[str] + kernels: list[str] + models: list[str] + spaces: list[str] + + +@dataclass +class RepoStorageInfo: + """ + Contains storage information about a repository on the Hub. + + Returned by [`list_user_repos`]. + + Attributes: + id (`str`): + ID of the repo (e.g. `username/repo-name`). + type (`str`): + Type of the repo (`model`, `dataset`, `space`, or `bucket`). + updated_at (`datetime`): + Last update time of the repo. + visibility (`str`): + Visibility of the repo (`public` or `private`). + storage (`int`): + Storage used by the repo in bytes. + storage_percent (`float`): + Percentage of the namespace's total storage used by this repo. + """ + + id: str + type: str + updated_at: datetime + visibility: str + storage: int + storage_percent: float + + def __init__(self, **kwargs: Any) -> None: + self.id = kwargs["id"] + self.type = kwargs["type"] + self.updated_at = parse_datetime(kwargs["updatedAt"]) + self.visibility = kwargs["visibility"] + self.storage = kwargs["storage"] + self.storage_percent = kwargs.get("storagePercent") or 0 + + +@dataclass +class Organization: + """ + Contains information about an organization on the Hub. + + Attributes: + avatar_url (`str`): + URL of the organization's avatar. + name (`str`): + Name of the organization on the Hub (unique). + fullname (`str`): + Organization's full name. + details (`str`, *optional*): + Organization's description. + is_verified (`bool`, *optional*): + Whether the organization is verified. + is_following (`bool`, *optional*): + Whether the authenticated user follows this organization. + num_users (`int`, *optional*): + Number of members in the organization. + num_models (`int`, *optional*): + Number of models owned by the organization. + num_spaces (`int`, *optional*): + Number of Spaces owned by the organization. + num_datasets (`int`, *optional*): + Number of datasets owned by the organization. + num_followers (`int`, *optional*): + Number of followers of the organization. + num_papers (`int`, *optional*): + Number of papers authored by the organization. + plan (`str`, *optional*): + The organization's plan (e.g., "enterprise", "team"). + """ + + avatar_url: str + name: str + fullname: str + details: str | None = None + is_verified: bool | None = None + is_following: bool | None = None + num_users: int | None = None + num_models: int | None = None + num_spaces: int | None = None + num_datasets: int | None = None + num_followers: int | None = None + num_papers: int | None = None + plan: str | None = None + + def __init__(self, **kwargs) -> None: + self.avatar_url = kwargs.pop("avatarUrl", "") + self.name = kwargs.pop("name", "") + self.fullname = kwargs.pop("fullname", "") + self.details = kwargs.pop("details", None) + self.is_verified = kwargs.pop("isVerified", None) + self.is_following = kwargs.pop("isFollowing", None) + self.num_users = kwargs.pop("numUsers", None) + self.num_models = kwargs.pop("numModels", None) + self.num_spaces = kwargs.pop("numSpaces", None) + self.num_datasets = kwargs.pop("numDatasets", None) + self.num_followers = kwargs.pop("numFollowers", None) + self.num_papers = kwargs.pop("numPapers", None) + self.plan = kwargs.pop("plan", None) + + # forward compatibility + self.__dict__.update(**kwargs) + + +@dataclass +class User: + """ + Contains information about a user on the Hub. + + Attributes: + username (`str`): + Name of the user on the Hub (unique). + fullname (`str`): + User's full name. + avatar_url (`str`): + URL of the user's avatar. + details (`str`, *optional*): + User's details. + is_following (`bool`, *optional*): + Whether the authenticated user is following this user. + is_pro (`bool`, *optional*): + Whether the user is a pro user. + num_models (`int`, *optional*): + Number of models created by the user. + num_datasets (`int`, *optional*): + Number of datasets created by the user. + num_spaces (`int`, *optional*): + Number of spaces created by the user. + num_discussions (`int`, *optional*): + Number of discussions initiated by the user. + num_papers (`int`, *optional*): + Number of papers authored by the user. + num_upvotes (`int`, *optional*): + Number of upvotes received by the user. + num_likes (`int`, *optional*): + Number of likes given by the user. + num_following (`int`, *optional*): + Number of users this user is following. + num_followers (`int`, *optional*): + Number of users following this user. + orgs (list of [`Organization`]): + List of organizations the user is part of. + """ + + # Metadata + username: str + fullname: str + avatar_url: str + details: str | None = None + is_following: bool | None = None + is_pro: bool | None = None + num_models: int | None = None + num_datasets: int | None = None + num_spaces: int | None = None + num_discussions: int | None = None + num_papers: int | None = None + num_upvotes: int | None = None + num_likes: int | None = None + num_following: int | None = None + num_followers: int | None = None + orgs: list[Organization] = field(default_factory=list) + + def __init__(self, **kwargs) -> None: + self.username = kwargs.pop("user", "") + self.fullname = kwargs.pop("fullname", "") + self.avatar_url = kwargs.pop("avatarUrl", "") + self.is_following = kwargs.pop("isFollowing", None) + self.is_pro = kwargs.pop("isPro", None) + self.details = kwargs.pop("details", None) + self.num_models = kwargs.pop("numModels", None) + self.num_datasets = kwargs.pop("numDatasets", None) + self.num_spaces = kwargs.pop("numSpaces", None) + self.num_discussions = kwargs.pop("numDiscussions", None) + self.num_papers = kwargs.pop("numPapers", None) + self.num_upvotes = kwargs.pop("numUpvotes", None) + self.num_likes = kwargs.pop("numLikes", None) + self.num_following = kwargs.pop("numFollowing", None) + self.num_followers = kwargs.pop("numFollowers", None) + self.user_type = kwargs.pop("type", None) + self.orgs = [Organization(**org) for org in kwargs.pop("orgs", [])] + + # forward compatibility + self.__dict__.update(**kwargs) + + +@dataclass +class PaperAuthor: + """ + Contains information about a paper author on the Hub. + + Attributes: + name (`str`): + Name of the author. + user (`User`, *optional*): + Information about the author as a [`User`] object. + status (`str`, *optional*): + Status of the author on the Hub. + status_last_changed_at (`datetime`, *optional*): + Date when the status of the author changed. + hidden (`bool`, *optional*): + Whether the author is hidden on the Hub. + """ + + name: str + user: User | None + status: str | None + status_last_changed_at: datetime | None + hidden: bool | None + + def __init__(self, **kwargs) -> None: + self.name = kwargs.pop("name", "") + user = kwargs.pop("user", None) + self.user = User(**user) if user else None + self.status = kwargs.pop("status", None) + status_last_changed_at = kwargs.pop("statusLastChangedAt", None) + self.status_last_changed_at = parse_datetime(status_last_changed_at) if status_last_changed_at else None + self.hidden = kwargs.pop("hidden", None) + + self.__dict__.update(**kwargs) + + +@dataclass +class PaperInfo: + """ + Contains information about a paper on the Hub. + + Attributes: + id (`str`): + arXiv paper ID. + authors (`list[PaperAuthor]`, *optional*): + Authors of the paper. + published_at (`datetime`, *optional*): + Date paper published. + title (`str`, *optional*): + Title of the paper. + summary (`str`, *optional*): + Summary of the paper. + upvotes (`int`, *optional*): + Number of upvotes for the paper on the Hub. + discussion_id (`str`, *optional*): + Discussion ID for the paper on the Hub. + source (`str`, *optional*): + Source of the paper. + comments (`int`, *optional*): + Number of comments for the paper on the Hub. + submitted_at (`datetime`, *optional*): + Date paper appeared in daily papers on the Hub. + submitted_by (`User`, *optional*): + Information about who submitted the daily paper. + ai_summary (`str`, *optional*): + AI summary of the paper. + ai_keywords (`list[str]`, *optional*): + AI keywords of the paper. + organization (`Organization`, *optional*): + Information about the organization associated with the paper. + project_page (`str`, *optional*): + URL of the project page for the paper. + github_repo (`str`, *optional*): + URL of the GitHub repository for the paper. + github_stars (`int`, *optional*): + Number of stars of the GitHub repository for the paper. + linked_models (`list[ModelInfo]`, *optional*): + Models linked to the paper. Only returned by [`paper_info`]. + num_total_models (`int`, *optional*): + Total number of models linked to the paper. Only returned by [`paper_info`]. + linked_datasets (`list[DatasetInfo]`, *optional*): + Datasets linked to the paper. Only returned by [`paper_info`]. + num_total_datasets (`int`, *optional*): + Total number of datasets linked to the paper. Only returned by [`paper_info`]. + linked_spaces (`list[SpaceInfo]`, *optional*): + Spaces linked to the paper. Only returned by [`paper_info`]. + """ + + id: str + authors: list[PaperAuthor] | None + published_at: datetime | None + title: str | None + summary: str | None + upvotes: int | None + discussion_id: str | None + source: str | None + comments: int | None + submitted_at: datetime | None + submitted_by: User | None + ai_summary: str | None + ai_keywords: list[str] | None + organization: Organization | None + project_page: str | None + github_repo: str | None + github_stars: int | None + linked_models: list[ModelInfo] | None + num_total_models: int | None + linked_datasets: list[DatasetInfo] | None + num_total_datasets: int | None + linked_spaces: list[SpaceInfo] | None + + def __init__(self, **kwargs) -> None: + paper = kwargs.pop("paper", {}) + self.id = kwargs.pop("id", None) or paper.pop("id", None) + authors = paper.pop("authors", None) or kwargs.pop("authors", None) + self.authors = [PaperAuthor(**author) for author in authors] if authors else None + published_at = paper.pop("publishedAt", None) or kwargs.pop("publishedAt", None) + self.published_at = parse_datetime(published_at) if published_at else None + self.title = kwargs.pop("title", None) + self.source = kwargs.pop("source", None) + self.summary = paper.pop("summary", None) or kwargs.pop("summary", None) + self.upvotes = paper.pop("upvotes", None) or kwargs.pop("upvotes", None) + self.discussion_id = paper.pop("discussionId", None) or kwargs.pop("discussionId", None) + self.comments = kwargs.pop("numComments", 0) + submitted_at = kwargs.pop("publishedAt", None) or kwargs.pop("submittedOnDailyAt", None) + self.submitted_at = parse_datetime(submitted_at) if submitted_at else None + submitted_by = kwargs.pop("submittedBy", None) or kwargs.pop("submittedOnDailyBy", None) + self.submitted_by = User(**submitted_by) if submitted_by else None + self.ai_summary = kwargs.pop("ai_summary", None) + self.ai_keywords = kwargs.pop("ai_keywords", None) + organization = kwargs.pop("organization", None) + self.organization = Organization(**organization) if organization else None + self.project_page = kwargs.pop("projectPage", None) + self.github_repo = kwargs.pop("githubRepo", None) + self.github_stars = kwargs.pop("githubStars", None) + linked_models = kwargs.pop("linkedModels", None) + self.linked_models = [ModelInfo(**m) for m in linked_models] if linked_models is not None else None + self.num_total_models = kwargs.pop("numTotalModels", None) + linked_datasets = kwargs.pop("linkedDatasets", None) + self.linked_datasets = [DatasetInfo(**d) for d in linked_datasets] if linked_datasets is not None else None + self.num_total_datasets = kwargs.pop("numTotalDatasets", None) + linked_spaces = kwargs.pop("linkedSpaces", None) + self.linked_spaces = [SpaceInfo(**s) for s in linked_spaces] if linked_spaces is not None else None + + # forward compatibility + self.__dict__.update(**kwargs) + + +@dataclass +class LFSFileInfo: + """ + Contains information about a file stored as LFS on a repo on the Hub. + + Used in the context of listing and permanently deleting LFS files from a repo to free-up space. + See [`list_lfs_files`] and [`permanently_delete_lfs_files`] for more details. + + Git LFS files are tracked using SHA-256 object IDs, rather than file paths, to optimize performance + This approach is necessary because a single object can be referenced by multiple paths across different commits, + making it impractical to search and resolve these connections. Check out [our documentation](https://huggingface.co/docs/hub/storage-limits#advanced-track-lfs-file-references) + to learn how to know which filename(s) is(are) associated with each SHA. + + Attributes: + file_oid (`str`): + SHA-256 object ID of the file. This is the identifier to pass when permanently deleting the file. + filename (`str`): + Possible filename for the LFS object. See the note above for more information. + oid (`str`): + OID of the LFS object. + pushed_at (`datetime`): + Date the LFS object was pushed to the repo. + ref (`str`, *optional*): + Ref where the LFS object has been pushed (if any). + size (`int`): + Size of the LFS object. + + Example: + ```py + >>> from huggingface_hub import HfApi + >>> api = HfApi() + >>> lfs_files = api.list_lfs_files("username/my-cool-repo") + + # Filter files files to delete based on a combination of `filename`, `pushed_at`, `ref` or `size`. + # e.g. select only LFS files in the "checkpoints" folder + >>> lfs_files_to_delete = (lfs_file for lfs_file in lfs_files if lfs_file.filename.startswith("checkpoints/")) + + # Permanently delete LFS files + >>> api.permanently_delete_lfs_files("username/my-cool-repo", lfs_files_to_delete) + ``` + """ + + file_oid: str + filename: str + oid: str + pushed_at: datetime + ref: str | None + size: int + + def __init__(self, **kwargs) -> None: + self.file_oid = kwargs.pop("fileOid") + self.filename = kwargs.pop("filename") + self.oid = kwargs.pop("oid") + self.pushed_at = parse_datetime(kwargs.pop("pushedAt")) + self.ref = kwargs.pop("ref", None) + self.size = kwargs.pop("size") + + # forward compatibility + self.__dict__.update(**kwargs) + + +@dataclass +class DatasetLeaderboardEntry: + """Contains information about a single entry in a dataset leaderboard on the Hub. + + A leaderboard ranks models based on their evaluation scores on a given benchmark dataset. + This object is returned by [`get_dataset_leaderboard`]. To get evaluation results for a + specific model across benchmarks, see [`ModelInfo.eval_results`] (via [`model_info`] with + `expand=["evalResults"]`) and [`EvalResultEntry`]. + + Attributes: + rank (`int`): + Rank of the model on the leaderboard (1-indexed). + model_id (`str`): + ID of the model (e.g. `"meta-llama/Llama-3-8b"`). + value (`float`): + Evaluation score value. + filename (`str`): + Name of the result file containing the evaluation data. + verified (`bool`): + Whether the result has been verified. + source (`dict[str, Any]`, *optional*): + Information about the source of the evaluation result. Contains keys like + `"url"`, `"name"`, and `"isExternal"`. Not all entries have a source. + author (`User` or `Organization`): + The model author, parsed based on the `"type"` field in the API response. + pull_request (`int`, *optional*): + Pull request number associated with the leaderboard entry, if any. + notes (`str`, *optional*): + Notes associated with the leaderboard entry, if any. + """ + + rank: int + model_id: str + value: float + filename: str + verified: bool + source: dict[str, Any] | None + author: User | Organization + pull_request: int | None = None + notes: str | None = None + + def __init__(self, **kwargs) -> None: + self.rank = kwargs.pop("rank") + self.model_id = kwargs.pop("modelId") + self.value = kwargs.pop("value") + self.filename = kwargs.pop("filename") + self.verified = kwargs.pop("verified") + self.source = kwargs.pop("source", None) + author_data = dict(kwargs.pop("author")) + author_type = author_data.get("type") + if author_type == "org": + self.author = Organization(**author_data) + else: + author_data["user"] = author_data.pop("name", "") + self.author = User(**author_data) + self.pull_request = kwargs.pop("pullRequest", None) + self.notes = kwargs.pop("notes", None) + + # forward compatibility + self.__dict__.update(**kwargs) + + +def future_compatible(fn: CallableT) -> CallableT: + """Wrap a method of `HfApi` to handle `run_as_future=True`. + + A method flagged as "future_compatible" will be called in a thread if `run_as_future=True` and return a + `concurrent.futures.Future` instance. Otherwise, it will be called normally and return the result. + """ + sig = inspect.signature(fn) + args_params = list(sig.parameters)[1:] # remove "self" from list + + @wraps(fn) + def _inner(self, *args, **kwargs): + # Get `run_as_future` value if provided (default to False) + if "run_as_future" in kwargs: + run_as_future = kwargs["run_as_future"] + kwargs["run_as_future"] = False # avoid recursion error + else: + run_as_future = False + for param, value in zip(args_params, args): + if param == "run_as_future": + run_as_future = value + break + + # Call the function in a thread if `run_as_future=True` + if run_as_future: + return self.run_as_future(fn, self, *args, **kwargs) + + # Otherwise, call the function normally + return fn(self, *args, **kwargs) + + _inner.is_future_compatible = True # type: ignore + return _inner # type: ignore + + +def _get_safetensors_metadata_size(size_bytes: bytes, filename: str, context_msg: str) -> int: + """ + Parse and validate safetensors metadata size from the first 8 bytes. + + This is a shared helper function used by both remote and local safetensors parsing. + + Args: + size_bytes: First 8 bytes of the safetensors file. + filename: Filename for error messages. + context_msg: Additional context for error messages. + + Returns: + The metadata size as an integer. + + Raises: + SafetensorsParsingError: If size_bytes is too short or metadata size exceeds limit. + """ + if len(size_bytes) < 8: + raise SafetensorsParsingError( + f"Failed to parse safetensors header for '{filename}' ({context_msg}): file is too small to be a valid " + "safetensors file." + ) + + metadata_size = struct.unpack(" constants.SAFETENSORS_MAX_HEADER_LENGTH: + raise SafetensorsParsingError( + f"Failed to parse safetensors header for '{filename}' ({context_msg}): safetensors header is too big. " + f"Maximum supported size is {constants.SAFETENSORS_MAX_HEADER_LENGTH} bytes (got {metadata_size})." + ) + + return metadata_size + + +def _parse_safetensors_header(metadata_as_bytes: bytes, filename: str, context_msg: str) -> SafetensorsFileMetadata: + """ + Parse safetensors metadata from raw header bytes. + + This is a shared helper function used by both remote and local safetensors parsing. + + Args: + metadata_as_bytes: Raw bytes of the JSON metadata header (without the 8-byte size prefix). + filename: Filename for error messages. + context_msg: Additional context for error messages (e.g., repo info or local path). + + Returns: + SafetensorsFileMetadata object. + + Raises: + SafetensorsParsingError: If the header cannot be parsed. + """ + # Parse json header + try: + metadata_as_dict = json.loads(metadata_as_bytes.decode(errors="ignore")) + except json.JSONDecodeError as e: + raise SafetensorsParsingError( + f"Failed to parse safetensors header for '{filename}' ({context_msg}): header is not json-encoded string. " + "Please make sure this is a correctly formatted safetensors file." + ) from e + + try: + return SafetensorsFileMetadata( + metadata=metadata_as_dict.get("__metadata__", {}), + tensors={ + key: TensorInfo( + dtype=tensor["dtype"], + shape=tensor["shape"], + data_offsets=tuple(tensor["data_offsets"]), # type: ignore + ) + for key, tensor in metadata_as_dict.items() + if key != "__metadata__" + }, + ) + except (KeyError, IndexError) as e: + raise SafetensorsParsingError( + f"Failed to parse safetensors header for '{filename}' ({context_msg}): header format not recognized. " + "Please make sure this is a correctly formatted safetensors file." + ) from e + + +class HfApi: + """ + Client to interact with the Hugging Face Hub via HTTP. + + The client is initialized with some high-level settings used in all requests + made to the Hub (HF endpoint, authentication, user agents...). Using the `HfApi` + client is preferred but not mandatory as all of its public methods are exposed + directly at the root of `huggingface_hub`. + + Args: + endpoint (`str`, *optional*): + Endpoint of the Hub. Defaults to . + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + library_name (`str`, *optional*): + The name of the library that is making the HTTP request. Will be added to + the user-agent header. Example: `"transformers"`. + library_version (`str`, *optional*): + The version of the library that is making the HTTP request. Will be added + to the user-agent header. Example: `"4.24.0"`. + user_agent (`str`, `dict`, *optional*): + The user agent info in the form of a dictionary or a single string. It will + be completed with information about the installed packages. + headers (`dict`, *optional*): + Additional headers to be sent with each request. Example: `{"X-My-Header": "value"}`. + Headers passed here are taking precedence over the default headers. + """ + + def __init__( + self, + endpoint: str | None = None, + token: str | bool | None = None, + library_name: str | None = None, + library_version: str | None = None, + user_agent: dict | str | None = None, + headers: dict[str, str] | None = None, + ) -> None: + self.endpoint = endpoint if endpoint is not None else constants.ENDPOINT + self.token = token + self.library_name = library_name + self.library_version = library_version + self.user_agent = user_agent + self.headers = headers + self._thread_pool: ThreadPoolExecutor | None = None + + # /whoami-v2 is the only endpoint for which we may want to cache results + self._whoami_cache: dict[str, dict] = {} + + def run_as_future(self, fn: Callable[..., R], *args, **kwargs) -> Future[R]: + """ + Run a method in the background and return a Future instance. + + The main goal is to run methods without blocking the main thread (e.g. to push data during a training). + Background jobs are queued to preserve order but are not ran in parallel. If you need to speed-up your scripts + by parallelizing lots of call to the API, you must setup and use your own [ThreadPoolExecutor](https://docs.python.org/3/library/concurrent.futures.html#threadpoolexecutor). + + Note: Most-used methods like [`upload_file`], [`upload_folder`] and [`create_commit`] have a `run_as_future: bool` + argument to directly call them in the background. This is equivalent to calling `api.run_as_future(...)` on them + but less verbose. + + Args: + fn (`Callable`): + The method to run in the background. + *args, **kwargs: + Arguments with which the method will be called. + + Return: + `Future`: a [Future](https://docs.python.org/3/library/concurrent.futures.html#future-objects) instance to + get the result of the task. + + Example: + ```py + >>> from huggingface_hub import HfApi + >>> api = HfApi() + >>> future = api.run_as_future(api.whoami) # instant + >>> future.done() + False + >>> future.result() # wait until complete and return result + (...) + >>> future.done() + True + ``` + """ + if self._thread_pool is None: + self._thread_pool = ThreadPoolExecutor(max_workers=1) + self._thread_pool + return self._thread_pool.submit(fn, *args, **kwargs) + + @validate_hf_hub_args + def whoami(self, token: bool | str | None = None, *, cache: bool = False) -> dict: + """ + Call HF API to know "whoami". + + If passing `cache=True`, the result will be cached for subsequent calls for the duration of the Python process. This is useful if you plan to call + `whoami` multiple times as this endpoint is heavily rate-limited for security reasons. + + Args: + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + cache (`bool`, *optional*): + Whether to cache the result of the `whoami` call for subsequent calls. + If an error occurs during the first call, it won't be cached. + Defaults to `False`. + """ + # Get the effective token using the helper function get_token + token = self.token if token is None else token + if token is False: + raise ValueError("Cannot use `token=False` with `whoami` method as it requires authentication.") + if token is True or token is None: + token = get_token() + if token is None: + raise LocalTokenNotFoundError( + "Token is required to call the /whoami-v2 endpoint, but no token found. You must provide a token or be logged in to " + "Hugging Face with `hf auth login` or `huggingface_hub.login`. See https://huggingface.co/settings/tokens." + ) + + if cache and (cached_token := self._whoami_cache.get(token)): + return cached_token + + # Call Hub + output = self._inner_whoami(token=token) + + # Cache result and return + if cache: + self._whoami_cache[token] = output + return output + + def _inner_whoami(self, token: str) -> dict: + r = get_session().get( + f"{self.endpoint}/api/whoami-v2", + headers=self._build_hf_headers(token=token), + ) + try: + hf_raise_for_status(r) + except HfHubHTTPError as e: + if e.response.status_code == 401: + error_message = "Invalid user token." + # Check which token is the effective one and generate the error message accordingly + if token == _get_token_from_google_colab(): + error_message += " The token from Google Colab vault is invalid. Please update it from the UI." + elif token == _get_token_from_environment(): + error_message += ( + " The token from HF_TOKEN environment variable is invalid. " + "Note that HF_TOKEN takes precedence over `hf auth login`." + ) + elif token == _get_token_from_file(): + error_message += ( + " The token stored is invalid. Please run `hf auth login --force` to set a new token." + ) + raise HfHubHTTPError(error_message, response=e.response) from e + if e.response.status_code == 429: + error_message = ( + "You've hit the rate limit for the /whoami-v2 endpoint, which is intentionally strict for security reasons." + " If you're calling it often, consider caching the response with `whoami(..., cache=True)`." + ) + raise HfHubHTTPError(error_message, response=e.response) from e + raise + return r.json() + + def get_model_tags(self) -> dict: + """ + List all valid model tags as a nested namespace object + """ + path = f"{self.endpoint}/api/models-tags-by-type" + r = get_session().get(path) + hf_raise_for_status(r) + return r.json() + + def get_dataset_tags(self) -> dict: + """ + List all valid dataset tags as a nested namespace object. + """ + path = f"{self.endpoint}/api/datasets-tags-by-type" + r = get_session().get(path) + hf_raise_for_status(r) + return r.json() + + @_deprecate_arguments(version="2.0", deprecated_args=["model_name"], custom_message="Use `search` instead.") + @validate_hf_hub_args + def list_models( + self, + *, + # Search-query parameter + filter: str | Iterable[str] | None = None, + author: str | None = None, + apps: str | list[str] | None = None, + gated: bool | None = None, + inference: Literal["warm"] | None = None, + inference_provider: Literal["all"] | PROVIDER_T | list[PROVIDER_T] | None = None, + model_name: str | None = None, + trained_dataset: str | list[str] | None = None, + search: str | None = None, + pipeline_tag: str | None = None, + num_parameters: str | None = None, + emissions_thresholds: tuple[float, float] | None = None, + # Sorting and pagination parameters + sort: ModelSort_T | None = None, + limit: int | None = None, + # Additional data to fetch + expand: list[ExpandModelProperty_T] | None = None, + full: bool | None = None, + cardData: bool = False, + fetch_config: bool = False, + token: bool | str | None = None, + ) -> Iterable[ModelInfo]: + """ + List models hosted on the Huggingface Hub, given some filters. + + Args: + filter (`str` or `Iterable[str]`, *optional*): + A string or list of string to filter models on the Hub. + Models can be filtered by library, language, task, tags, and more. + author (`str`, *optional*): + A string which identify the author (user or organization) of the + returned models. + apps (`str` or `List`, *optional*): + A string or list of strings to filter models on the Hub that + support the specified apps. Example values include `"ollama"` or `["ollama", "vllm"]`. + gated (`bool`, *optional*): + A boolean to filter models on the Hub that are gated or not. By default, all models are returned. + If `gated=True` is passed, only gated models are returned. + If `gated=False` is passed, only non-gated models are returned. + inference (`Literal["warm"]`, *optional*): + If "warm", filter models on the Hub currently served by at least one provider. + inference_provider (`Literal["all"]` or `str`, *optional*): + A string to filter models on the Hub that are served by a specific provider. + Pass `"all"` to get all models served by at least one provider. + trained_dataset (`str` or `List`, *optional*): + A string tag or a list of string tags of the trained dataset for a + model on the Hub. + search (`str`, *optional*): + A string that will be contained in the returned model ids. + pipeline_tag (`str`, *optional*): + A string pipeline tag to filter models on the Hub by, such as `summarization`. + num_parameters (`str`, *optional*): + Filter models by parameter count. Accepts the same range syntax as the Hub UI and API, for example + `"min:6B,max:128B"`, `"min:6B"` or `"max:128B"`. + emissions_thresholds (`Tuple`, *optional*): + A tuple of two ints or floats representing a minimum and maximum + carbon footprint to filter the resulting models with in grams. + sort (`ModelSort_T`, *optional*): + The key with which to sort the resulting models. Possible values are "created_at", "downloads", + "last_modified", "likes" and "trending_score". + limit (`int`, *optional*): + The limit on the number of models fetched. Leaving this option + to `None` fetches all models. + expand (`list[ExpandModelProperty_T]`, *optional*): + List properties to return in the response. When used, only the properties in the list will be returned. + This parameter cannot be used if `full`, `cardData` or `fetch_config` are passed. + Possible values are `"author"`, `"cardData"`, `"config"`, `"createdAt"`, `"disabled"`, `"downloads"`, `"downloadsAllTime"`, `"evalResults"`, `"gated"`, `"gguf"`, `"inference"`, `"inferenceProviderMapping"`, `"lastModified"`, `"library_name"`, `"likes"`, `"mask_token"`, `"model-index"`, `"pipeline_tag"`, `"private"`, `"safetensors"`, `"sha"`, `"siblings"`, `"spaces"`, `"tags"`, `"transformersInfo"`, `"trendingScore"`, `"widgetData"`, and `"resourceGroup"`. + full (`bool`, *optional*): + Whether to fetch all model data, including the `last_modified`, + the `sha`, the files and the `tags`. This is set to `True` by + default when using a filter. + cardData (`bool`, *optional*): + Whether to grab the metadata for the model as well. Can contain + useful information such as carbon emissions, metrics, and + datasets trained on. + fetch_config (`bool`, *optional*): + Whether to fetch the model configs as well. This is not included + in `full` due to its size. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + model_name (`str`, *optional*): + (deprecated). Use `search` instead. + + Returns: + `Iterable[ModelInfo]`: an iterable of [`huggingface_hub.hf_api.ModelInfo`] objects. + + Example: + + ```python + >>> from huggingface_hub import HfApi + + >>> api = HfApi() + + # List all models + >>> api.list_models() + + # List text classification models + >>> api.list_models(filter="text-classification") + + # List models from the KerasHub library + >>> api.list_models(filter="keras-hub") + + # List models served by Cohere + >>> api.list_models(inference_provider="cohere") + + # List models with "bert" in their name + >>> api.list_models(search="bert") + + # List models with "bert" in their name and pushed by google + >>> api.list_models(search="bert", author="google") + + # List models with 6B to 128B parameters + >>> api.list_models(num_parameters="min:6B,max:128B", sort="likes") + ``` + """ + if expand and (full or cardData or fetch_config): + raise ValueError("`expand` cannot be used if `full`, `cardData` or `fetch_config` are passed.") + + if emissions_thresholds is not None and not cardData: + raise ValueError("`emissions_thresholds` were passed without setting `cardData=True`.") + + path = f"{self.endpoint}/api/models" + headers = self._build_hf_headers(token=token) + params: dict[str, Any] = {} + + # Build the filter list + filter_list: list[str] = [] + if filter: + filter_list.extend([filter] if isinstance(filter, str) else filter) + if trained_dataset: + datasets = [trained_dataset] if isinstance(trained_dataset, str) else trained_dataset + filter_list.extend(f"dataset:{d}" if not d.startswith("dataset:") else d for d in datasets) + if len(filter_list) > 0: + params["filter"] = filter_list + + # Handle other query params + if author: + params["author"] = author + if apps: + if isinstance(apps, str): + apps = [apps] + params["apps"] = apps + if gated is not None: + params["gated"] = gated + if inference is not None: + params["inference"] = inference + if inference_provider is not None: + params["inference_provider"] = inference_provider + if pipeline_tag: + params["pipeline_tag"] = pipeline_tag + if num_parameters is not None: + params["num_parameters"] = num_parameters + search_list = [] + if model_name: # deprecated + search_list.append(model_name) + if search: + search_list.append(search) + if len(search_list) > 0: + params["search"] = search_list + if sort is not None: + params["sort"] = ( + "lastModified" + if sort == "last_modified" + else "trendingScore" + if sort == "trending_score" + else "createdAt" + if sort == "created_at" + else sort + ) + if limit is not None: + params["limit"] = limit + + # Request additional data + if full: + params["full"] = True + if fetch_config: + params["config"] = True + if cardData: + params["cardData"] = True + if expand: + params["expand"] = expand + + # `items` is a generator + items = paginate(path, params=params, headers=headers) + if limit is not None: + items = islice(items, limit) # Do not iterate over all pages + for item in items: + if "siblings" not in item: + item["siblings"] = None + model_info = ModelInfo(**item) + if emissions_thresholds is None or _is_emission_within_threshold(model_info, *emissions_thresholds): + yield model_info + + @validate_hf_hub_args + def list_datasets( + self, + *, + # Search-query parameter + filter: str | Iterable[str] | None = None, + author: str | None = None, + benchmark: Literal[True] | Literal["official"] | str | None = None, + dataset_name: str | None = None, + gated: bool | None = None, + language_creators: str | list[str] | None = None, + language: str | list[str] | None = None, + multilinguality: str | list[str] | None = None, + size_categories: str | list[str] | None = None, + task_categories: str | list[str] | None = None, + task_ids: str | list[str] | None = None, + search: str | None = None, + # Sorting and pagination parameters + sort: DatasetSort_T | None = None, + limit: int | None = None, + # Additional data to fetch + expand: list[ExpandDatasetProperty_T] | None = None, + full: bool | None = None, + token: bool | str | None = None, + ) -> Iterable[DatasetInfo]: + """ + List datasets hosted on the Huggingface Hub, given some filters. + + Args: + filter (`str` or `Iterable[str]`, *optional*): + A string or list of string to filter datasets on the hub. + author (`str`, *optional*): + A string which identify the author of the returned datasets. + benchmark (`True`, `"official"`, `str`, *optional*): + Filter datasets by benchmark. Can be `True` or `"official"` to return official benchmark datasets. + For future-compatibility, can also be a string representing the benchmark name (currently only "official" is supported). + dataset_name (`str`, *optional*): + A string or list of strings that can be used to identify datasets on + the Hub by its name, such as `SQAC` or `wikineural` + gated (`bool`, *optional*): + A boolean to filter datasets on the Hub that are gated or not. By default, all datasets are returned. + If `gated=True` is passed, only gated datasets are returned. + If `gated=False` is passed, only non-gated datasets are returned. + language_creators (`str` or `List`, *optional*): + A string or list of strings that can be used to identify datasets on + the Hub with how the data was curated, such as `crowdsourced` or + `machine_generated`. + language (`str` or `List`, *optional*): + A string or list of strings representing a two-character language to + filter datasets by on the Hub. + multilinguality (`str` or `List`, *optional*): + A string or list of strings representing a filter for datasets that + contain multiple languages. + size_categories (`str` or `List`, *optional*): + A string or list of strings that can be used to identify datasets on + the Hub by the size of the dataset such as `100K>> from huggingface_hub import HfApi + + >>> api = HfApi() + + # List all datasets + >>> api.list_datasets() + + + # List only the text classification datasets + >>> api.list_datasets(filter="task_categories:text-classification") + + + # List only the datasets in russian for language modeling + >>> api.list_datasets( + ... filter=("language:ru", "task_ids:language-modeling") + ... ) + + # List FiftyOne datasets (identified by the tag "fiftyone" in dataset card) + >>> api.list_datasets(tags="fiftyone") + ``` + + Example usage with the `search` argument: + + ```python + >>> from huggingface_hub import HfApi + + >>> api = HfApi() + + # List all datasets with "text" in their name + >>> api.list_datasets(search="text") + + # List all datasets with "text" in their name made by google + >>> api.list_datasets(search="text", author="google") + ``` + """ + if expand and full: + raise ValueError("`expand` cannot be used if `full` is passed.") + + path = f"{self.endpoint}/api/datasets" + headers = self._build_hf_headers(token=token) + params: dict[str, Any] = {} + + # Build `filter` list + filter_list = [] + if filter is not None: + if isinstance(filter, str): + filter_list.append(filter) + else: + filter_list.extend(filter) + for key, value in ( + ("language_creators", language_creators), + ("language", language), + ("multilinguality", multilinguality), + ("size_categories", size_categories), + ("task_categories", task_categories), + ("task_ids", task_ids), + ): + if value: + if isinstance(value, str): + value = [value] + for value_item in value: + if not value_item.startswith(f"{key}:"): + data = f"{key}:{value_item}" + else: + data = value_item + filter_list.append(data) + if benchmark is not None: + if benchmark is True: # alias for official benchmark + benchmark = "official" + filter_list.append(f"benchmark:{benchmark}") + if len(filter_list) > 0: + params["filter"] = filter_list + + # Handle other query params + if author: + params["author"] = author + if gated is not None: + params["gated"] = gated + search_list = [] + if dataset_name: + search_list.append(dataset_name) + if search: + search_list.append(search) + if len(search_list) > 0: + params["search"] = search_list + if sort is not None: + params["sort"] = ( + "lastModified" + if sort == "last_modified" + else "trendingScore" + if sort == "trending_score" + else "createdAt" + if sort == "created_at" + else sort + ) + if limit is not None: + params["limit"] = limit + + # Request additional data + if expand: + params["expand"] = expand + if full: + params["full"] = True + + items = paginate(path, params=params, headers=headers) + if limit is not None: + items = islice(items, limit) # Do not iterate over all pages + for item in items: + if "siblings" not in item: + item["siblings"] = None + yield DatasetInfo(**item) + + @validate_hf_hub_args + def list_dataset_parquet_files( + self, + repo_id: str, + *, + config: str | None = None, + token: bool | str | None = None, + ) -> list[DatasetParquetEntry]: + """List parquet files available for a dataset on the Hub. + + All datasets hosted on the Hub are auto-converted to Parquet by the + [Dataset Viewer](https://huggingface.co/docs/dataset-viewer/parquet). + This method returns the list of parquet files with their URLs, configs, + splits and sizes. + + Args: + repo_id (`str`): + The dataset repository ID (e.g. `"username/dataset-name"`). + config (`str`, *optional*): + Filter by a specific config/subset name. When provided, only + parquet files for that config are returned. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `list[DatasetParquetEntry]`: a list of [`DatasetParquetEntry`] objects + containing config, split, url and size for each parquet file. + + Example: + ```python + >>> from huggingface_hub import list_dataset_parquet_files + >>> list_dataset_parquet_files("lhoestq/demo1") + >>> entries[0] + DatasetParquetEntry(config='default', split='train', url='https://huggingface.co/...', size=5038) + ``` + """ + if self.endpoint != constants._HF_DEFAULT_ENDPOINT: + raise ValueError( + "The Dataset Viewer is only available on the Hugging Face Hub" + f" (endpoint='{constants._HF_DEFAULT_ENDPOINT}'). It is not supported on" + f" third-party endpoints. (endpoint={self.endpoint})" + ) + + url = f"{constants.DATASETS_SERVER_ENDPOINT}/parquet" + params: dict[str, str] = {"dataset": repo_id} + if config is not None: + params["config"] = config + response = get_session().get(url, params=params, headers=self._build_hf_headers(token=token)) + hf_raise_for_status(response) + payload = response.json() + + return [ + DatasetParquetEntry( + config=file_info["config"], + split=file_info["split"], + url=file_info["url"], + size=file_info["size"], + ) + for file_info in payload.get("parquet_files", []) + ] + + @validate_hf_hub_args + def list_spaces( + self, + *, + # Search-query parameter + filter: str | Iterable[str] | None = None, + author: str | None = None, + search: str | None = None, + datasets: str | Iterable[str] | None = None, + models: str | Iterable[str] | None = None, + linked: bool = False, + # Sorting and pagination parameters + sort: SpaceSort_T | None = None, + limit: int | None = None, + # Additional data to fetch + expand: list[ExpandSpaceProperty_T] | None = None, + full: bool | None = None, + token: bool | str | None = None, + ) -> Iterable[SpaceInfo]: + """ + List spaces hosted on the Huggingface Hub, given some filters. + + Args: + filter (`str` or `Iterable`, *optional*): + A string tag or list of tags that can be used to identify Spaces on the Hub. + author (`str`, *optional*): + A string which identify the author of the returned Spaces. + search (`str`, *optional*): + A string that will be contained in the returned Spaces. + datasets (`str` or `Iterable`, *optional*): + Whether to return Spaces that make use of a dataset. + The name of a specific dataset can be passed as a string. + models (`str` or `Iterable`, *optional*): + Whether to return Spaces that make use of a model. + The name of a specific model can be passed as a string. + linked (`bool`, *optional*): + Whether to return Spaces that make use of either a model or a dataset. + sort (`SpaceSort_T`, *optional*): + The key with which to sort the resulting spaces. Possible values are "created_at", "last_modified", + "likes" and "trending_score". + limit (`int`, *optional*): + The limit on the number of Spaces fetched. Leaving this option + to `None` fetches all Spaces. + expand (`list[ExpandSpaceProperty_T]`, *optional*): + List properties to return in the response. When used, only the properties in the list will be returned. + This parameter cannot be used if `full` is passed. + Possible values are `"author"`, `"cardData"`, `"datasets"`, `"disabled"`, `"lastModified"`, `"createdAt"`, `"likes"`, `"models"`, `"private"`, `"runtime"`, `"sdk"`, `"siblings"`, `"sha"`, `"subdomain"`, `"tags"`, `"trendingScore"`, `"usedStorage"`, and `"resourceGroup"`. + full (`bool`, *optional*): + Whether to fetch all Spaces data, including the `last_modified`, `siblings` + and `card_data` fields. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[SpaceInfo]`: an iterable of [`huggingface_hub.hf_api.SpaceInfo`] objects. + """ + if expand and full: + raise ValueError("`expand` cannot be used if `full` is passed.") + + path = f"{self.endpoint}/api/spaces" + headers = self._build_hf_headers(token=token) + params: dict[str, Any] = {} + if filter is not None: + params["filter"] = filter + if author is not None: + params["author"] = author + if search is not None: + params["search"] = search + if sort is not None: + params["sort"] = ( + "lastModified" + if sort == "last_modified" + else "trendingScore" + if sort == "trending_score" + else "createdAt" + if sort == "created_at" + else sort + ) + if limit is not None: + params["limit"] = limit + if linked: + params["linked"] = True + if datasets is not None: + params["datasets"] = datasets + if models is not None: + params["models"] = models + + # Request additional data + if expand: + params["expand"] = expand + if full: + params["full"] = True + + items = paginate(path, params=params, headers=headers) + if limit is not None: + items = islice(items, limit) # Do not iterate over all pages + for item in items: + if "siblings" not in item: + item["siblings"] = None + yield SpaceInfo(**item) + + @validate_hf_hub_args + def search_spaces( + self, + query: str, + *, + filter: str | Iterable[str] | None = None, + sdk: str | list[str] | None = None, + include_non_running: bool = False, + token: bool | str | None = None, + ) -> Iterable[SpaceSearchResult]: + """Search Spaces on the Hub using semantic search. + + This endpoint uses semantic search (embedding-based) for multi-word queries + and full-text search for single-word queries. + + Args: + query (`str`): + The search query string. + filter (`str` or `Iterable[str]`, *optional*): + A string tag or list of tags to filter by. + sdk (`str` or `list[str]`, *optional*): + Filter by SDK (e.g. `"gradio"`, `"docker"`, `"static"`). + include_non_running (`bool`, *optional*): + Whether to include non-running Spaces in results. Defaults to `False`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[SpaceSearchResult]`: an iterable of [`SpaceSearchResult`] objects. + + Example: + ```python + >>> from huggingface_hub import HfApi + >>> api = HfApi() + >>> results = list(api.search_spaces("generate image")) + >>> results[0].id + 'mrfakename/Z-Image-Turbo' + >>> results[0].ai_category + 'Image Generation' + ``` + """ + path = f"{self.endpoint}/api/spaces/semantic-search" + headers = self._build_hf_headers(token=token) + params: dict[str, Any] = {"q": query} + if filter is not None: + params["filter"] = filter + if sdk is not None: + params["sdk"] = sdk + if include_non_running: + params["includeNonRunning"] = True + + r = get_session().get(path, headers=headers, params=params) + hf_raise_for_status(r) + for item in r.json(): + yield SpaceSearchResult(item) + + @validate_hf_hub_args + def unlike( + self, + repo_id: str, + *, + token: bool | str | None = None, + repo_type: str | None = None, + ) -> None: + """ + Unlike a given repo on the Hub (e.g. remove from favorite list). + + To prevent spam usage, it is not possible to `like` a repository from a script. + + See also [`list_liked_repos`]. + + Args: + repo_id (`str`): + The repository to unlike. Example: `"user/my-cool-model"`. + + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if unliking a dataset or space, `None` or + `"model"` if unliking a model. Default is `None`. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If repository is not found (error 404): wrong repo_id/repo_type, private + but not authenticated or repo does not exist. + + Example: + ```python + >>> from huggingface_hub import list_liked_repos, unlike + >>> "gpt2" in list_liked_repos().models # we assume you have already liked gpt2 + True + >>> unlike("gpt2") + >>> "gpt2" in list_liked_repos().models + False + ``` + """ + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + response = get_session().delete( + url=f"{self.endpoint}/api/{repo_type}s/{repo_id}/like", headers=self._build_hf_headers(token=token) + ) + hf_raise_for_status(response) + + @validate_hf_hub_args + def list_liked_repos( + self, + user: str | None = None, + *, + token: bool | str | None = None, + ) -> UserLikes: + """ + List all public repos liked by a user on huggingface.co. + + This list is public so token is optional. If `user` is not passed, it defaults to + the logged in user. + + See also [`unlike`]. + + Args: + user (`str`, *optional*): + Name of the user for which you want to fetch the likes. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`UserLikes`]: object containing the user name and 3 lists of repo ids (1 for + models, 1 for datasets and 1 for Spaces). + + Raises: + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If `user` is not passed and no token found (either from argument or from machine). + + Example: + ```python + >>> from huggingface_hub import list_liked_repos + + >>> likes = list_liked_repos("julien-c") + + >>> likes.user + "julien-c" + + >>> likes.models + ["osanseviero/streamlit_1.15", "Xhaheen/ChatGPT_HF", ...] + ``` + """ + # User is either provided explicitly or retrieved from current token. + if user is None: + me = self.whoami(token=token) + if me["type"] == "user": + user = me["name"] + else: + raise ValueError( + "Cannot list liked repos. You must provide a 'user' as input or be logged in as a user." + ) + + path = f"{self.endpoint}/api/users/{user}/likes" + headers = self._build_hf_headers(token=token) + + likes = list(paginate(path, params={}, headers=headers)) + # Looping over a list of items similar to: + # { + # 'createdAt': '2021-09-09T21:53:27.000Z', + # 'repo': { + # 'name': 'PaddlePaddle/PaddleOCR', + # 'type': 'space' + # } + # } + # Let's loop 3 times over the received list. Less efficient but more straightforward to read. + return UserLikes( + user=user, + total=len(likes), + kernels=[like["repo"]["name"] for like in likes if like["repo"]["type"] == "kernel"], + models=[like["repo"]["name"] for like in likes if like["repo"]["type"] == "model"], + datasets=[like["repo"]["name"] for like in likes if like["repo"]["type"] == "dataset"], + spaces=[like["repo"]["name"] for like in likes if like["repo"]["type"] == "space"], + ) + + def list_user_repos( + self, + namespace: str | None = None, + *, + token: bool | str | None = None, + ) -> Iterable[RepoStorageInfo]: + """List all repositories (models, datasets, spaces, buckets) for a user or organization with storage info. + + Uses the `/api/settings/repositories` endpoint for the authenticated user or + `/api/organizations/{namespace}/settings/repositories` for an organization. + + Args: + namespace (`str`, *optional*): + Organization name. If not provided, lists repos for the authenticated user. + token (`bool` or `str`, *optional*): + A valid user access token. Defaults to the locally saved token. + + Returns: + `Iterable[RepoStorageInfo]`: An iterable of [`RepoStorageInfo`] objects. + + Example: + ```python + >>> from huggingface_hub import list_user_repos + + >>> repos = list(list_user_repos()) + >>> repos[0] + RepoStorageInfo(id='username/my-model', type='model', ...) + + >>> # List repos from an organization + >>> repos = list(list_user_repos(namespace="my-org")) + ``` + """ + if namespace is not None: + path = f"{self.endpoint}/api/organizations/{namespace}/settings/repositories" + else: + path = f"{self.endpoint}/api/settings/repositories" + headers = self._build_hf_headers(token=token) + for item in paginate(path, params={}, headers=headers): + yield RepoStorageInfo(**item) + + @validate_hf_hub_args + def list_repo_likers( + self, + repo_id: str, + *, + repo_type: str | None = None, + token: bool | str | None = None, + ) -> Iterable[User]: + """ + List all users who liked a given repo on the hugging Face Hub. + + See also [`list_liked_repos`]. + + Args: + repo_id (`str`): + The repository to retrieve . Example: `"user/my-cool-model"`. + + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. Default is + `None`. + + Returns: + `Iterable[User]`: an iterable of [`huggingface_hub.hf_api.User`] objects. + """ + + # Construct the API endpoint + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + path = f"{self.endpoint}/api/{repo_type}s/{repo_id}/likers" + for liker in paginate(path, params={}, headers=self._build_hf_headers(token=token)): + yield User(username=liker["user"], fullname=liker["fullname"], avatar_url=liker["avatarUrl"]) + + @validate_hf_hub_args + def model_info( + self, + repo_id: str, + *, + revision: str | None = None, + timeout: float | None = None, + securityStatus: bool | None = None, + files_metadata: bool = False, + expand: list[ExpandModelProperty_T] | None = None, + token: bool | str | None = None, + ) -> ModelInfo: + """ + Get info on one specific model on huggingface.co + + Model can be private if you pass an acceptable token or are logged in. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + revision (`str`, *optional*): + The revision of the model repository from which to get the + information. + timeout (`float`, *optional*): + Whether to set a timeout for the request to the Hub. + securityStatus (`bool`, *optional*): + Whether to retrieve the security status from the model + repository as well. The security status will be returned in the `security_repo_status` field. + files_metadata (`bool`, *optional*): + Whether or not to retrieve metadata for files in the repository + (size, LFS metadata, etc). Defaults to `False`. + expand (`list[ExpandModelProperty_T]`, *optional*): + List properties to return in the response. When used, only the properties in the list will be returned. + This parameter cannot be used if `securityStatus` or `files_metadata` are passed. + Possible values are `"author"`, `"baseModels"`, `"cardData"`, `"childrenModelCount"`, `"config"`, `"createdAt"`, `"disabled"`, `"downloads"`, `"downloadsAllTime"`, `"evalResults"`, `"gated"`, `"gguf"`, `"inference"`, `"inferenceProviderMapping"`, `"lastModified"`, `"library_name"`, `"likes"`, `"mask_token"`, `"model-index"`, `"pipeline_tag"`, `"private"`, `"safetensors"`, `"sha"`, `"siblings"`, `"spaces"`, `"tags"`, `"transformersInfo"`, `"trendingScore"`, `"widgetData"`, `"usedStorage"`, and `"resourceGroup"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`huggingface_hub.hf_api.ModelInfo`]: The model repository information. + + > [!TIP] + > Raises the following errors: + > + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access. + > - [`~utils.RevisionNotFoundError`] + > If the revision to download from cannot be found. + """ + if expand and (securityStatus or files_metadata): + raise ValueError("`expand` cannot be used if `securityStatus` or `files_metadata` are set.") + + headers = self._build_hf_headers(token=token) + path = ( + f"{self.endpoint}/api/models/{repo_id}" + if revision is None + else (f"{self.endpoint}/api/models/{repo_id}/revision/{quote(revision, safe='')}") + ) + params: dict = {} + if securityStatus: + params["securityStatus"] = True + if files_metadata: + params["blobs"] = True + if expand: + params["expand"] = expand + r = get_session().get(path, headers=headers, timeout=timeout, params=params) + hf_raise_for_status(r) + data = r.json() + return ModelInfo(**data) + + @validate_hf_hub_args + def dataset_info( + self, + repo_id: str, + *, + revision: str | None = None, + timeout: float | None = None, + files_metadata: bool = False, + expand: list[ExpandDatasetProperty_T] | None = None, + token: bool | str | None = None, + ) -> DatasetInfo: + """ + Get info on one specific dataset on huggingface.co. + + Dataset can be private if you pass an acceptable token. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + revision (`str`, *optional*): + The revision of the dataset repository from which to get the + information. + timeout (`float`, *optional*): + Whether to set a timeout for the request to the Hub. + files_metadata (`bool`, *optional*): + Whether or not to retrieve metadata for files in the repository + (size, LFS metadata, etc). Defaults to `False`. + expand (`list[ExpandDatasetProperty_T]`, *optional*): + List properties to return in the response. When used, only the properties in the list will be returned. + This parameter cannot be used if `files_metadata` is passed. + Possible values are `"author"`, `"cardData"`, `"citation"`, `"createdAt"`, `"disabled"`, `"description"`, `"downloads"`, `"downloadsAllTime"`, `"gated"`, `"lastModified"`, `"likes"`, `"mainSize"`, `"paperswithcode_id"`, `"private"`, `"siblings"`, `"sha"`, `"tags"`, `"trendingScore"`, `"usedStorage"`, and `"resourceGroup"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`hf_api.DatasetInfo`]: The dataset repository information. + + > [!TIP] + > Raises the following errors: + > + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access. + > - [`~utils.RevisionNotFoundError`] + > If the revision to download from cannot be found. + """ + if expand and files_metadata: + raise ValueError("`expand` cannot be used if `files_metadata` is set.") + + headers = self._build_hf_headers(token=token) + path = ( + f"{self.endpoint}/api/datasets/{repo_id}" + if revision is None + else (f"{self.endpoint}/api/datasets/{repo_id}/revision/{quote(revision, safe='')}") + ) + params: dict = {} + if files_metadata: + params["blobs"] = True + if expand: + params["expand"] = expand + + r = get_session().get(path, headers=headers, timeout=timeout, params=params) + hf_raise_for_status(r) + data = r.json() + return DatasetInfo(**data) + + @validate_hf_hub_args + def get_dataset_leaderboard( + self, + repo_id: str, + *, + base_model_only: bool | None = None, + token: bool | str | None = None, + timeout: float | None = None, + ) -> list[DatasetLeaderboardEntry]: + """Get the leaderboard for a dataset on the Hub. + + The leaderboard ranks models based on their evaluation scores on the given benchmark + dataset. Not all datasets have leaderboards — only benchmark datasets with evaluation + results submitted to them. This gives a dataset-centric view of scores; for a model-centric + view, use [`model_info`] with `expand=["evalResults"]`. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. For example: `"allenai/olmOCR-bench"`. + base_model_only (`bool` or `None`, *optional*): + By default, the leaderboard only includes models that have no declared `base_model` relation + (i.e. canonical/root repos), matching the Hub's default leaderboard view. Fine-tuned or derivative + repos that declare a parent model are excluded. Pass `base_model_only=False` to disable this filter and + include every submitted result, regardless of whether the model declares a base model relation. + token (`bool` or `str`, *optional*): + A valid user access token. Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + timeout (`float`, *optional*): + Whether to set a timeout for the request to the Hub. + + Returns: + `list[DatasetLeaderboardEntry]`: A list of [`DatasetLeaderboardEntry`] objects representing + the leaderboard entries, sorted by rank. + + > [!TIP] + > Raises the following errors: + > + > - [`~utils.RepositoryNotFoundError`] + > If the repository cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access. + > - [`~utils.HfHubHTTPError`] + > If the dataset does not have a leaderboard. + + Example: + ```python + >>> from huggingface_hub import HfApi + >>> api = HfApi() + >>> leaderboard = api.get_dataset_leaderboard("allenai/olmOCR-bench") + >>> leaderboard[0].model_id + 'datalab-to/chandra-ocr-2' + >>> leaderboard[0].rank + 1 + + # Include fine-tuned / derivative models too + >>> full_leaderboard = api.get_dataset_leaderboard("allenai/olmOCR-bench", base_model_only=False) + ``` + """ + headers = self._build_hf_headers(token=token) + path = f"{self.endpoint}/api/datasets/{repo_id}/leaderboard" + params = {} + if base_model_only is not None: + params["base_model"] = base_model_only + r = get_session().get(path, headers=headers, params=params, timeout=timeout) + hf_raise_for_status(r) + data = r.json() + return [DatasetLeaderboardEntry(**entry) for entry in data] + + @validate_hf_hub_args + def space_info( + self, + repo_id: str, + *, + revision: str | None = None, + timeout: float | None = None, + files_metadata: bool = False, + expand: list[ExpandSpaceProperty_T] | None = None, + token: bool | str | None = None, + ) -> SpaceInfo: + """ + Get info on one specific Space on huggingface.co. + + Space can be private if you pass an acceptable token. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + revision (`str`, *optional*): + The revision of the space repository from which to get the + information. + timeout (`float`, *optional*): + Whether to set a timeout for the request to the Hub. + files_metadata (`bool`, *optional*): + Whether or not to retrieve metadata for files in the repository + (size, LFS metadata, etc). Defaults to `False`. + expand (`list[ExpandSpaceProperty_T]`, *optional*): + List properties to return in the response. When used, only the properties in the list will be returned. + This parameter cannot be used if `full` is passed. + Possible values are `"author"`, `"cardData"`, `"createdAt"`, `"datasets"`, `"disabled"`, `"lastModified"`, `"likes"`, `"models"`, `"private"`, `"runtime"`, `"sdk"`, `"siblings"`, `"sha"`, `"subdomain"`, `"tags"`, `"trendingScore"`, `"usedStorage"`, and `"resourceGroup"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`~hf_api.SpaceInfo`]: The space repository information. + + > [!TIP] + > Raises the following errors: + > + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access. + > - [`~utils.RevisionNotFoundError`] + > If the revision to download from cannot be found. + """ + if expand and files_metadata: + raise ValueError("`expand` cannot be used if `files_metadata` is set.") + + headers = self._build_hf_headers(token=token) + path = ( + f"{self.endpoint}/api/spaces/{repo_id}" + if revision is None + else (f"{self.endpoint}/api/spaces/{repo_id}/revision/{quote(revision, safe='')}") + ) + params: dict = {} + if files_metadata: + params["blobs"] = True + if expand: + params["expand"] = expand + + r = get_session().get(path, headers=headers, timeout=timeout, params=params) + hf_raise_for_status(r) + data = r.json() + return SpaceInfo(**data) + + @validate_hf_hub_args + def kernel_info( + self, + repo_id: str, + *, + revision: str | None = None, + timeout: float | None = None, + token: bool | str | None = None, + ) -> KernelInfo: + """ + Get info on one specific kernel on huggingface.co. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated by a `/`. + revision (`str`, *optional*): + The revision of the kernel repository from which to get the + information. + timeout (`float`, *optional*): + Whether to set a timeout for the request to the Hub. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`~hf_api.ModelInfo`]: The kernel repository information. + """ + headers = self._build_hf_headers(token=token) + path = ( + f"{self.endpoint}/api/kernels/{repo_id}" + if revision is None + else (f"{self.endpoint}/api/kernels/{repo_id}/revision/{quote(revision, safe='')}") + ) + r = get_session().get(path, headers=headers, timeout=timeout) + hf_raise_for_status(r) + data = r.json() + return KernelInfo(**data) + + @validate_hf_hub_args + def repo_info( + self, + repo_id: str, + *, + revision: str | None = None, + repo_type: str | None = None, + timeout: float | None = None, + files_metadata: bool = False, + expand: ExpandModelProperty_T | ExpandDatasetProperty_T | ExpandSpaceProperty_T | None = None, + token: bool | str | None = None, + ) -> ModelInfo | DatasetInfo | SpaceInfo | KernelInfo: + """ + Get the info object for a given repo of a given type. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + revision (`str`, *optional*): + The revision of the repository from which to get the + information. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if getting repository info from a dataset or a space, + `None` or `"model"` if getting repository info from a model. Default is `None`. + timeout (`float`, *optional*): + Whether to set a timeout for the request to the Hub. + expand (`ExpandModelProperty_T` or `ExpandDatasetProperty_T` or `ExpandSpaceProperty_T`, *optional*): + List properties to return in the response. When used, only the properties in the list will be returned. + This parameter cannot be used if `files_metadata` is passed. + For an exhaustive list of available properties, check out [`model_info`], [`dataset_info`] or [`space_info`]. + files_metadata (`bool`, *optional*): + Whether or not to retrieve metadata for files in the repository + (size, LFS metadata, etc). Defaults to `False`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Union[SpaceInfo, DatasetInfo, ModelInfo]`: The repository information, as a + [`huggingface_hub.hf_api.DatasetInfo`], [`huggingface_hub.hf_api.ModelInfo`] + or [`huggingface_hub.hf_api.SpaceInfo`] object. + + > [!TIP] + > Raises the following errors: + > + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access. + > - [`~utils.RevisionNotFoundError`] + > If the revision to download from cannot be found. + """ + match repo_type: + case None | "model": + method = self.model_info + case "dataset": + method = self.dataset_info # type: ignore + case "space": + method = self.space_info # type: ignore + case "kernel": + # No expand/files_metadata for kernels + return self.kernel_info(repo_id, revision=revision, token=token, timeout=timeout) + case _: + raise ValueError("Unsupported repo type.") + return method( + repo_id, + revision=revision, + token=token, + timeout=timeout, + expand=expand, # type: ignore + files_metadata=files_metadata, + ) + + @validate_hf_hub_args + def repo_exists( + self, + repo_id: str, + *, + repo_type: str | None = None, + token: str | bool | None = None, + ) -> bool: + """ + Checks if a repository exists on the Hugging Face Hub. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if getting repository info from a dataset or a space, + `None` or `"model"` if getting repository info from a model. Default is `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + True if the repository exists, False otherwise. + + Examples: + ```py + >>> from huggingface_hub import repo_exists + >>> repo_exists("google/gemma-7b") + True + >>> repo_exists("google/not-a-repo") + False + ``` + """ + try: + self.repo_info(repo_id=repo_id, repo_type=repo_type, token=token) + return True + except GatedRepoError: + return True # we don't have access but it exists + except RepositoryNotFoundError: + return False + + @validate_hf_hub_args + def revision_exists( + self, + repo_id: str, + revision: str, + *, + repo_type: str | None = None, + token: str | bool | None = None, + ) -> bool: + """ + Checks if a specific revision exists on a repo on the Hugging Face Hub. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + revision (`str`): + The revision of the repository to check. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if getting repository info from a dataset or a space, + `None` or `"model"` if getting repository info from a model. Default is `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + True if the repository and the revision exists, False otherwise. + + Examples: + ```py + >>> from huggingface_hub import revision_exists + >>> revision_exists("google/gemma-7b", "float16") + True + >>> revision_exists("google/gemma-7b", "not-a-revision") + False + ``` + """ + try: + self.repo_info(repo_id=repo_id, revision=revision, repo_type=repo_type, token=token) + return True + except RevisionNotFoundError: + return False + except RepositoryNotFoundError: + return False + + @validate_hf_hub_args + def file_exists( + self, + repo_id: str, + filename: str, + *, + repo_type: str | None = None, + revision: str | None = None, + token: str | bool | None = None, + ) -> bool: + """ + Checks if a file exists in a repository on the Hugging Face Hub. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + filename (`str`): + The name of the file to check, for example: + `"config.json"` + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if getting repository info from a dataset or a space, + `None` or `"model"` if getting repository info from a model. Default is `None`. + revision (`str`, *optional*): + The revision of the repository from which to get the information. Defaults to `"main"` branch. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + True if the file exists, False otherwise. + + Examples: + ```py + >>> from huggingface_hub import file_exists + >>> file_exists("bigcode/starcoder", "config.json") + True + >>> file_exists("bigcode/starcoder", "not-a-file") + False + >>> file_exists("bigcode/not-a-repo", "config.json") + False + ``` + """ + url = hf_hub_url( + repo_id=repo_id, repo_type=repo_type, revision=revision, filename=filename, endpoint=self.endpoint + ) + try: + if token is None: + token = self.token + get_hf_file_metadata(url, token=token) + return True + except GatedRepoError: # raise specifically on gated repo + raise + except (RepositoryNotFoundError, RemoteEntryNotFoundError, RevisionNotFoundError): + return False + + @validate_hf_hub_args + def list_repo_files( + self, + repo_id: str, + *, + revision: str | None = None, + repo_type: str | None = None, + token: str | bool | None = None, + ) -> list[str]: + """ + Get the list of files in a given repo. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated by a `/`. + revision (`str`, *optional*): + The revision of the repository from which to get the information. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or space, `None` or `"model"` if uploading to + a model. Default is `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `list[str]`: the list of files in a given repository. + """ + return [ + f.rfilename + for f in self.list_repo_tree( + repo_id=repo_id, recursive=True, revision=revision, repo_type=repo_type, token=token + ) + if isinstance(f, RepoFile) + ] + + @validate_hf_hub_args + def list_repo_tree( + self, + repo_id: str, + path_in_repo: str | None = None, + *, + recursive: bool = False, + expand: bool = False, + revision: str | None = None, + repo_type: str | None = None, + token: str | bool | None = None, + ) -> Iterable[RepoFile | RepoFolder]: + """ + List a repo tree's files and folders and get information about them. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated by a `/`. + path_in_repo (`str`, *optional*): + Relative path of the tree (folder) in the repo, for example: + `"checkpoints/1fec34a/results"`. Will default to the root tree (folder) of the repository. + recursive (`bool`, *optional*, defaults to `False`): + Whether to list tree's files and folders recursively. + expand (`bool`, *optional*, defaults to `False`): + Whether to fetch more information about the tree's files and folders (e.g. last commit and files' security scan results). This + operation is more expensive for the server so only 50 results are returned per page (instead of 1000). + As pagination is implemented in `huggingface_hub`, this is transparent for you except for the time it + takes to get the results. + revision (`str`, *optional*): + The revision of the repository from which to get the tree. Defaults to `"main"` branch. + repo_type (`str`, *optional*): + The type of the repository from which to get the tree (`"model"`, `"dataset"`, `"space"` or `"kernel"`). + Defaults to `"model"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[Union[RepoFile, RepoFolder]]`: + The information about the tree's files and folders, as an iterable of [`RepoFile`] and [`RepoFolder`] objects. The order of the files and folders is + not guaranteed. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If repository is not found (error 404): wrong repo_id/repo_type, private but not authenticated or repo + does not exist. + [`~utils.RevisionNotFoundError`]: + If revision is not found (error 404) on the repo. + [`~utils.RemoteEntryNotFoundError`]: + If the tree (folder) does not exist (error 404) on the repo. + + Examples: + + Get information about a repo's tree. + ```py + >>> from huggingface_hub import list_repo_tree + >>> repo_tree = list_repo_tree("lysandre/arxiv-nlp") + >>> repo_tree + + >>> list(repo_tree) + [ + RepoFile(path='.gitattributes', size=391, blob_id='ae8c63daedbd4206d7d40126955d4e6ab1c80f8f', lfs=None, last_commit=None, security=None), + RepoFile(path='README.md', size=391, blob_id='43bd404b159de6fba7c2f4d3264347668d43af25', lfs=None, last_commit=None, security=None), + RepoFile(path='config.json', size=554, blob_id='2f9618c3a19b9a61add74f70bfb121335aeef666', lfs=None, last_commit=None, security=None), + RepoFile( + path='flax_model.msgpack', size=497764107, blob_id='8095a62ccb4d806da7666fcda07467e2d150218e', + lfs={'size': 497764107, 'sha256': 'd88b0d6a6ff9c3f8151f9d3228f57092aaea997f09af009eefd7373a77b5abb9', 'pointer_size': 134}, last_commit=None, security=None + ), + RepoFile(path='merges.txt', size=456318, blob_id='226b0752cac7789c48f0cb3ec53eda48b7be36cc', lfs=None, last_commit=None, security=None), + RepoFile( + path='pytorch_model.bin', size=548123560, blob_id='64eaa9c526867e404b68f2c5d66fd78e27026523', + lfs={'size': 548123560, 'sha256': '9be78edb5b928eba33aa88f431551348f7466ba9f5ef3daf1d552398722a5436', 'pointer_size': 134}, last_commit=None, security=None + ), + RepoFile(path='vocab.json', size=898669, blob_id='b00361fece0387ca34b4b8b8539ed830d644dbeb', lfs=None, last_commit=None, security=None)] + ] + ``` + + Get even more information about a repo's tree (last commit and files' security scan results) + ```py + >>> from huggingface_hub import list_repo_tree + >>> repo_tree = list_repo_tree("prompthero/openjourney-v4", expand=True) + >>> list(repo_tree) + [ + RepoFolder( + path='feature_extractor', + tree_id='aa536c4ea18073388b5b0bc791057a7296a00398', + last_commit={ + 'oid': '47b62b20b20e06b9de610e840282b7e6c3d51190', + 'title': 'Upload diffusers weights (#48)', + 'date': datetime.datetime(2023, 3, 21, 9, 5, 27, tzinfo=datetime.timezone.utc) + } + ), + RepoFolder( + path='safety_checker', + tree_id='65aef9d787e5557373fdf714d6c34d4fcdd70440', + last_commit={ + 'oid': '47b62b20b20e06b9de610e840282b7e6c3d51190', + 'title': 'Upload diffusers weights (#48)', + 'date': datetime.datetime(2023, 3, 21, 9, 5, 27, tzinfo=datetime.timezone.utc) + } + ), + RepoFile( + path='model_index.json', + size=582, + blob_id='d3d7c1e8c3e78eeb1640b8e2041ee256e24c9ee1', + lfs=None, + last_commit={ + 'oid': 'b195ed2d503f3eb29637050a886d77bd81d35f0e', + 'title': 'Fix deprecation warning by changing `CLIPFeatureExtractor` to `CLIPImageProcessor`. (#54)', + 'date': datetime.datetime(2023, 5, 15, 21, 41, 59, tzinfo=datetime.timezone.utc) + }, + security={ + 'safe': True, + 'av_scan': {'virusFound': False, 'virusNames': None}, + 'pickle_import_scan': None + } + ) + ... + ] + ``` + """ + repo_type = repo_type or constants.REPO_TYPE_MODEL + revision = quote(revision, safe="") if revision is not None else constants.DEFAULT_REVISION + headers = self._build_hf_headers(token=token) + + encoded_path_in_repo = "/" + quote(path_in_repo, safe="") if path_in_repo else "" + tree_url = f"{self.endpoint}/api/{repo_type}s/{repo_id}/tree/{revision}{encoded_path_in_repo}" + for path_info in paginate(path=tree_url, headers=headers, params={"recursive": recursive, "expand": expand}): + yield (RepoFile(**path_info) if path_info["type"] == "file" else RepoFolder(**path_info)) + + @validate_hf_hub_args + def verify_repo_checksums( + self, + repo_id: str, + *, + repo_type: str | None = None, + revision: str | None = None, + local_dir: str | Path | None = None, + cache_dir: str | Path | None = None, + token: str | bool | None = None, + ) -> FolderVerification: + """ + Verify local files for a repo against Hub checksums. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated by a `/`. + repo_type (`str`, *optional*): + The type of the repository from which to get the tree (`"model"`, `"dataset"` or `"space"`. + Defaults to `"model"`. + revision (`str`, *optional*): + The revision of the repository from which to get the tree. Defaults to `"main"` branch. + local_dir (`str` or `Path`, *optional*): + The local directory to verify. + cache_dir (`str` or `Path`, *optional*): + The cache directory to verify. + token (Union[bool, str, None], optional): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`FolderVerification`]: a structured result containing the verification details. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If repository is not found (error 404): wrong repo_id/repo_type, private but not authenticated or repo + does not exist. + [`~utils.RevisionNotFoundError`]: + If revision is not found (error 404) on the repo. + + """ + + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + + if local_dir is not None and cache_dir is not None: + raise ValueError("Pass either `local_dir` or `cache_dir`, not both.") + + root, remote_revision = resolve_local_root( + repo_id=repo_id, + repo_type=repo_type, + revision=revision, + cache_dir=Path(cache_dir) if cache_dir is not None else None, + local_dir=Path(local_dir) if local_dir is not None else None, + ) + local_by_path = collect_local_files(root) + + # get remote entries (only files, not folders) + remote_by_path: dict[str, RepoFile] = {} + for entry in self.list_repo_tree( + repo_id=repo_id, recursive=True, revision=remote_revision, repo_type=repo_type, token=token + ): + if isinstance(entry, RepoFile): + remote_by_path[entry.path] = entry + + return verify_maps( + remote_by_path=remote_by_path, + local_by_path=local_by_path, + revision=remote_revision, + verified_path=root, + ) + + @validate_hf_hub_args + def list_repo_refs( + self, + repo_id: str, + *, + repo_type: str | None = None, + include_pull_requests: bool = False, + token: str | bool | None = None, + ) -> GitRefs: + """ + Get the list of refs of a given repo (both tags and branches). + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + repo_type (`str`, *optional*): + Set to `"dataset"`, `"space"` or `"kernel"` if listing refs from a dataset, a Space or a Kernel, + `None` or `"model"` if listing from a model. Default is `None`. + include_pull_requests (`bool`, *optional*): + Whether to include refs from pull requests in the list. Defaults to `False`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Example: + ```py + >>> from huggingface_hub import HfApi + >>> api = HfApi() + >>> api.list_repo_refs("gpt2") + GitRefs(branches=[GitRefInfo(name='main', ref='refs/heads/main', target_commit='e7da7f221d5bf496a48136c0cd264e630fe9fcc8')], converts=[], tags=[]) + + >>> api.list_repo_refs("bigcode/the-stack", repo_type='dataset') + GitRefs( + branches=[ + GitRefInfo(name='main', ref='refs/heads/main', target_commit='18edc1591d9ce72aa82f56c4431b3c969b210ae3'), + GitRefInfo(name='v1.1.a1', ref='refs/heads/v1.1.a1', target_commit='f9826b862d1567f3822d3d25649b0d6d22ace714') + ], + converts=[], + tags=[ + GitRefInfo(name='v1.0', ref='refs/tags/v1.0', target_commit='c37a8cd1e382064d8aced5e05543c5f7753834da') + ] + ) + ``` + + Returns: + [`GitRefs`]: object containing all information about branches and tags for a + repo on the Hub. + """ + repo_type = repo_type or constants.REPO_TYPE_MODEL + response = get_session().get( + f"{self.endpoint}/api/{repo_type}s/{repo_id}/refs", + headers=self._build_hf_headers(token=token), + params={"include_prs": 1} if include_pull_requests else {}, + ) + hf_raise_for_status(response) + data = response.json() + + def _format_as_git_ref_info(item: dict) -> GitRefInfo: + return GitRefInfo(name=item["name"], ref=item["ref"], target_commit=item["targetCommit"]) + + return GitRefs( + branches=[_format_as_git_ref_info(item) for item in data["branches"]], + converts=[_format_as_git_ref_info(item) for item in data["converts"]], + tags=[_format_as_git_ref_info(item) for item in data["tags"]], + pull_requests=[_format_as_git_ref_info(item) for item in data["pullRequests"]] + if include_pull_requests + else None, + ) + + @validate_hf_hub_args + def list_repo_commits( + self, + repo_id: str, + *, + repo_type: str | None = None, + token: bool | str | None = None, + revision: str | None = None, + formatted: bool = False, + ) -> list[GitCommitInfo]: + """ + Get the list of commits of a given revision for a repo on the Hub. + + Commits are sorted by date (last commit first). + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated by a `/`. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if listing commits from a dataset or a Space, `None` or `"model"` if + listing from a model. Default is `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + revision (`str`, *optional*): + The git revision to commit from. Defaults to the head of the `"main"` branch. + formatted (`bool`): + Whether to return the HTML-formatted title and description of the commits. Defaults to False. + + Example: + ```py + >>> from huggingface_hub import HfApi + >>> api = HfApi() + + # Commits are sorted by date (last commit first) + >>> initial_commit = api.list_repo_commits("gpt2")[-1] + + # Initial commit is always a system commit containing the `.gitattributes` file. + >>> initial_commit + GitCommitInfo( + commit_id='9b865efde13a30c13e0a33e536cf3e4a5a9d71d8', + authors=['system'], + created_at=datetime.datetime(2019, 2, 18, 10, 36, 15, tzinfo=datetime.timezone.utc), + title='initial commit', + message='', + formatted_title=None, + formatted_message=None + ) + + # Create an empty branch by deriving from initial commit + >>> api.create_branch("gpt2", "new_empty_branch", revision=initial_commit.commit_id) + ``` + + Returns: + list[[`GitCommitInfo`]]: list of objects containing information about the commits for a repo on the Hub. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If repository is not found (error 404): wrong repo_id/repo_type, private but not authenticated or repo + does not exist. + [`~utils.RevisionNotFoundError`]: + If revision is not found (error 404) on the repo. + """ + repo_type = repo_type or constants.REPO_TYPE_MODEL + revision = quote(revision, safe="") if revision is not None else constants.DEFAULT_REVISION + + # Paginate over results and return the list of commits. + return [ + GitCommitInfo( + commit_id=item["id"], + authors=[author["user"] for author in item["authors"]], + created_at=parse_datetime(item["date"]), + title=item["title"], + message=item["message"], + formatted_title=item.get("formatted", {}).get("title"), + formatted_message=item.get("formatted", {}).get("message"), + ) + for item in paginate( + f"{self.endpoint}/api/{repo_type}s/{repo_id}/commits/{revision}", + headers=self._build_hf_headers(token=token), + params={"expand[]": "formatted"} if formatted else {}, + ) + ] + + @validate_hf_hub_args + def get_paths_info( + self, + repo_id: str, + paths: list[str] | str, + *, + expand: bool = False, + revision: str | None = None, + repo_type: str | None = None, + token: str | bool | None = None, + ) -> list[RepoFile | RepoFolder]: + """ + Get information about a repo's paths. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated by a `/`. + paths (`Union[list[str], str]`, *optional*): + The paths to get information about. If a path do not exist, it is ignored without raising + an exception. + expand (`bool`, *optional*, defaults to `False`): + Whether to fetch more information about the paths (e.g. last commit and files' security scan results). This + operation is more expensive for the server so only 50 results are returned per page (instead of 1000). + As pagination is implemented in `huggingface_hub`, this is transparent for you except for the time it + takes to get the results. + revision (`str`, *optional*): + The revision of the repository from which to get the information. Defaults to `"main"` branch. + repo_type (`str`, *optional*): + The type of the repository from which to get the information (`"model"`, `"dataset"` or `"space"`. + Defaults to `"model"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `list[Union[RepoFile, RepoFolder]]`: + The information about the paths, as a list of [`RepoFile`] and [`RepoFolder`] objects. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If repository is not found (error 404): wrong repo_id/repo_type, private but not authenticated or repo + does not exist. + [`~utils.RevisionNotFoundError`]: + If revision is not found (error 404) on the repo. + + Example: + ```py + >>> from huggingface_hub import get_paths_info + >>> paths_info = get_paths_info("allenai/c4", ["README.md", "en"], repo_type="dataset") + >>> paths_info + [ + RepoFile(path='README.md', size=2379, blob_id='f84cb4c97182890fc1dbdeaf1a6a468fd27b4fff', lfs=None, last_commit=None, security=None), + RepoFolder(path='en', tree_id='dc943c4c40f53d02b31ced1defa7e5f438d5862e', last_commit=None) + ] + ``` + """ + repo_type = repo_type or constants.REPO_TYPE_MODEL + revision = quote(revision, safe="") if revision is not None else constants.DEFAULT_REVISION + headers = self._build_hf_headers(token=token) + + response = get_session().post( + f"{self.endpoint}/api/{repo_type}s/{repo_id}/paths-info/{revision}", + data={ + "paths": paths if isinstance(paths, list) else [paths], + "expand": expand, + }, + headers=headers, + ) + hf_raise_for_status(response) + paths_info = response.json() + return [ + RepoFile(**path_info) if path_info["type"] == "file" else RepoFolder(**path_info) + for path_info in paths_info + ] + + @validate_hf_hub_args + def super_squash_history( + self, + repo_id: str, + *, + branch: str | None = None, + commit_message: str | None = None, + repo_type: str | None = None, + token: str | bool | None = None, + ) -> None: + """Squash commit history on a branch for a repo on the Hub. + + Squashing the repo history is useful when you know you'll make hundreds of commits and you don't want to + clutter the history. Squashing commits can only be performed from the head of a branch. + + > [!WARNING] + > Once squashed, the commit history cannot be retrieved. This is a non-revertible operation. + + > [!WARNING] + > Once the history of a branch has been squashed, it is not possible to merge it back into another branch since + > their history will have diverged. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated by a `/`. + branch (`str`, *optional*): + The branch to squash. Defaults to the head of the `"main"` branch. + commit_message (`str`, *optional*): + The commit message to use for the squashed commit. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if listing commits from a dataset or a Space, `None` or `"model"` if + listing from a model. Default is `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If repository is not found (error 404): wrong repo_id/repo_type, private but not authenticated or repo + does not exist. + [`~utils.RevisionNotFoundError`]: + If the branch to squash cannot be found. + [`~utils.BadRequestError`]: + If invalid reference for a branch. You cannot squash history on tags. + + Example: + ```py + >>> from huggingface_hub import HfApi + >>> api = HfApi() + + # Create repo + >>> repo_id = api.create_repo("test-squash").repo_id + + # Make a lot of commits. + >>> api.upload_file(repo_id=repo_id, path_in_repo="file.txt", path_or_fileobj=b"content") + >>> api.upload_file(repo_id=repo_id, path_in_repo="lfs.bin", path_or_fileobj=b"content") + >>> api.upload_file(repo_id=repo_id, path_in_repo="file.txt", path_or_fileobj=b"another_content") + + # Squash history + >>> api.super_squash_history(repo_id=repo_id) + ``` + """ + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + if repo_type not in constants.REPO_TYPES: + raise ValueError("Invalid repo type") + if branch is None: + branch = constants.DEFAULT_REVISION + + # Prepare request + url = f"{self.endpoint}/api/{repo_type}s/{repo_id}/super-squash/{quote(branch, safe='')}" + headers = self._build_hf_headers(token=token) + commit_message = commit_message or f"Super-squash branch '{branch}' using huggingface_hub" + + # Super-squash + response = get_session().post(url=url, headers=headers, json={"message": commit_message}) + hf_raise_for_status(response) + + @validate_hf_hub_args + def list_lfs_files( + self, + repo_id: str, + *, + repo_type: str | None = None, + token: bool | str | None = None, + ) -> Iterable[LFSFileInfo]: + """ + List all LFS files in a repo on the Hub. + + This is primarily useful to count how much storage a repo is using and to eventually clean up large files + with [`permanently_delete_lfs_files`]. Note that this would be a permanent action that will affect all commits + referencing this deleted files and that cannot be undone. + + Args: + repo_id (`str`): + The repository for which you are listing LFS files. + repo_type (`str`, *optional*): + Type of repository. Set to `"dataset"` or `"space"` if listing from a dataset or space, `None` or + `"model"` if listing from a model. Default is `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[LFSFileInfo]`: An iterator of [`LFSFileInfo`] objects. + + Example: + ```py + >>> from huggingface_hub import HfApi + >>> api = HfApi() + >>> lfs_files = api.list_lfs_files("username/my-cool-repo") + + # Filter files files to delete based on a combination of `filename`, `pushed_at`, `ref` or `size`. + # e.g. select only LFS files in the "checkpoints" folder + >>> lfs_files_to_delete = (lfs_file for lfs_file in lfs_files if lfs_file.filename.startswith("checkpoints/")) + + # Permanently delete LFS files + >>> api.permanently_delete_lfs_files("username/my-cool-repo", lfs_files_to_delete) + ``` + """ + # Prepare request + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + url = f"{self.endpoint}/api/{repo_type}s/{repo_id}/lfs-files" + headers = self._build_hf_headers(token=token) + + # Paginate over LFS items + for item in paginate(url, params={}, headers=headers): + yield LFSFileInfo(**item) + + @validate_hf_hub_args + def permanently_delete_lfs_files( + self, + repo_id: str, + lfs_files: Iterable[LFSFileInfo], + *, + rewrite_history: bool = True, + repo_type: str | None = None, + token: bool | str | None = None, + ) -> None: + """ + Permanently delete LFS files from a repo on the Hub. + + > [!WARNING] + > This is a permanent action that will affect all commits referencing the deleted files and might corrupt your + > repository. This is a non-revertible operation. Use it only if you know what you are doing. + + Args: + repo_id (`str`): + The repository for which you are listing LFS files. + lfs_files (`Iterable[LFSFileInfo]`): + An iterable of [`LFSFileInfo`] items to permanently delete from the repo. Use [`list_lfs_files`] to list + all LFS files from a repo. + rewrite_history (`bool`, *optional*, default to `True`): + Whether to rewrite repository history to remove file pointers referencing the deleted LFS files (recommended). + repo_type (`str`, *optional*): + Type of repository. Set to `"dataset"` or `"space"` if listing from a dataset or space, `None` or + `"model"` if listing from a model. Default is `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Example: + ```py + >>> from huggingface_hub import HfApi + >>> api = HfApi() + >>> lfs_files = api.list_lfs_files("username/my-cool-repo") + + # Filter files files to delete based on a combination of `filename`, `pushed_at`, `ref` or `size`. + # e.g. select only LFS files in the "checkpoints" folder + >>> lfs_files_to_delete = (lfs_file for lfs_file in lfs_files if lfs_file.filename.startswith("checkpoints/")) + + # Permanently delete LFS files + >>> api.permanently_delete_lfs_files("username/my-cool-repo", lfs_files_to_delete) + ``` + """ + # Prepare request + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + url = f"{self.endpoint}/api/{repo_type}s/{repo_id}/lfs-files/batch" + headers = self._build_hf_headers(token=token) + + # Delete LFS items by batches of 1000 + for batch in chunk_iterable(lfs_files, 1000): + shas = [item.file_oid for item in batch] + if len(shas) == 0: + return + payload = { + "deletions": { + "sha": shas, + "rewriteHistory": rewrite_history, + } + } + response = get_session().post(url, headers=headers, json=payload) + hf_raise_for_status(response) + + def list_space_templates(self, *, token: str | bool | None = None) -> list[SpaceTemplate]: + """List the official Space templates available on the Hub. + + The `repo_id` of a returned template (or its short `name`) can be passed as `space_template` + to [`HfApi.create_repo`] to seed a new Space from that template. + + Args: + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `list[SpaceTemplate]`: The list of available Space templates. + + Example: + ```py + >>> from huggingface_hub import list_space_templates + >>> templates = list_space_templates() + >>> templates[0] + SpaceTemplate(name='Streamlit', repo_id='streamlit/streamlit-template-space', sdk='docker', preferred_private=False) + ``` + """ + r = get_session().get(f"{self.endpoint}/api/spaces/templates", headers=self._build_hf_headers(token=token)) + hf_raise_for_status(r) + return [SpaceTemplate(item) for item in r.json()["templates"]] + + @_deprecate_arguments( + version="2.0", + deprecated_args={"space_storage"}, + custom_message="Use `space_volumes` to mount volumes on a Space.", + ) + @validate_hf_hub_args + def create_repo( + self, + repo_id: str, + *, + token: str | bool | None = None, + private: bool | None = None, + visibility: RepoVisibility_T | None = None, + repo_type: str | None = None, + exist_ok: bool = False, + resource_group_id: str | None = None, + region: REPO_REGIONS | None = None, + space_sdk: str | None = None, + space_hardware: SpaceHardware | None = None, + space_storage: SpaceStorage | None = None, + space_sleep_time: int | None = None, + space_secrets: list[dict[str, str]] | None = None, + space_variables: list[dict[str, str]] | None = None, + space_volumes: list[Volume] | None = None, + space_template: str | None = None, + ) -> RepoUrl: + """Create an empty repo on the HuggingFace Hub. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + private (`bool`, *optional*): + Whether to make the repo private. If `None` (default), the repo will be public unless the organization's default is private. This value is ignored if the repo already exists. Cannot be passed together with `visibility`. + visibility (`Literal["public", "private", "protected"]`, *optional*): + Visibility of the repo. Can be `"public"` or `"private"`, or `"protected"` for Spaces. If `None` + (default), the repo will be public unless the organization's default is private. This value is ignored + if the repo already exists. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. Default is + `None`. + exist_ok (`bool`, *optional*, defaults to `False`): + If `True`, do not raise an error if repo already exists. + resource_group_id (`str`, *optional*): + Resource group in which to create the repo. Resource groups is only available for Enterprise Hub organizations and + allow to define which members of the organization can access the resource. The ID of a resource group + can be found in the URL of the resource's page on the Hub (e.g. `"66670e5163145ca562cb1988"`). + To learn more about resource groups, see https://huggingface.co/docs/hub/en/security-resource-groups. + region (`Literal["us", "eu"]`, *optional*): + Cloud region in which to create the repo. Can be one of `"us"` or `"eu"`. If not specified, the repo will be + created in the default region. Requires Team plan or above. + space_sdk (`str`, *optional*): + Choice of SDK to use if repo_type is "space". Can be "streamlit", "gradio", "docker", or "static". + space_hardware (`SpaceHardware` or `str`, *optional*): + Choice of Hardware if repo_type is "space". See [`SpaceHardware`] for a complete list. + space_storage (`SpaceStorage` or `str`, *optional*): + Choice of persistent storage tier. Example: `"small"`. See [`SpaceStorage`] for a complete list. + space_sleep_time (`int`, *optional*): + Number of seconds of inactivity to wait before a Space is put to sleep. Set to `-1` if you don't want + your Space to sleep (default behavior for upgraded hardware). For free hardware, you can't configure + the sleep time (value is fixed to 48 hours of inactivity). + See https://huggingface.co/docs/hub/spaces-gpus#sleep-time for more details. + space_secrets (`list[dict[str, str]]`, *optional*): + A list of secret keys to set in your Space. Each item is in the form `{"key": ..., "value": ..., "description": ...}` where description is optional. + For more details, see https://huggingface.co/docs/hub/spaces-overview#managing-secrets. + space_variables (`list[dict[str, str]]`, *optional*): + A list of public environment variables to set in your Space. Each item is in the form `{"key": ..., "value": ..., "description": ...}` where description is optional. + For more details, see https://huggingface.co/docs/hub/spaces-overview#managing-secrets-and-environment-variables. + space_volumes (`list[Volume]`, *optional*): + A list of [`Volume`] objects to mount in the Space at creation time. Each volume has a `type` + (`"bucket"`, `"model"`, `"dataset"`, or `"space"`), a `source` (repo or bucket ID), a `mount_path` + (path inside the container), and optional `revision`, `read_only`, and `path` fields. + Only applicable if repo_type is "space". + space_template (`str`, *optional*): + Seed the new Space from an official template. Can be either the template repo id + (e.g. `"SpacesExamples/jupyterlab"`) or its short name (e.g. `"JupyterLab"`). Use + [`HfApi.list_space_templates`] to list available templates. Only applicable if repo_type is + "space". If the template is recommended to be private and visibility is not explicitly set, the Space + is created as private. + + Returns: + [`RepoUrl`]: URL to the newly created repo. Value is a subclass of `str` containing + attributes like `endpoint`, `repo_type` and `repo_id`. + """ + organization, name = repo_id.split("/") if "/" in repo_id else (None, repo_id) + + path = f"{self.endpoint}/api/repos/create" + + if repo_type not in constants.REPO_TYPES_WITH_KERNEL: + raise ValueError("Invalid repo type") + + resolved_visibility = _resolve_repo_visibility(private=private, visibility=visibility, repo_type=repo_type) + + resolved_space_template: str | None = None + if space_template is not None: + if repo_type != constants.REPO_TYPE_SPACE: + raise ValueError(f"space_template can only be used with repo_type 'space'. Got repo_type={repo_type}.") + + # space_template passed => resolve it + all_templates = self.list_space_templates(token=token) + for candidate in all_templates: + if candidate.repo_id == space_template: + template = candidate + break + if candidate.name.lower() == space_template.lower(): + template = candidate + break + else: + raise ValueError( + f"Unknown Space template '{space_template}'. Expected one of {', '.join(sorted(t.name for t in all_templates))}. Use `HfApi.list_space_templates()` to list templates." + ) + + resolved_space_template = template.repo_id + # If the chosen template is recommended to be private and the user did not explicitly set a + # visibility, default to private (mirrors the recommendation shown in the web UI). + if template.preferred_private and private is None and visibility is None: + resolved_visibility = "private" + # space_sdk can be omitted by the user, we set it following server info + if space_sdk is not None and space_sdk != template.sdk: + raise ValueError( + f"space_sdk must match the SDK of the chosen space_template. Got {space_sdk}, expected {template.sdk}." + ) + space_sdk = template.sdk + + payload: dict[str, Any] = {"name": name, "organization": organization} + if resolved_visibility is not None: + payload["visibility"] = resolved_visibility + if repo_type is not None: + payload["type"] = repo_type + if repo_type == "space": + if space_sdk is None: + raise ValueError( + "No space_sdk provided. `create_repo` expects space_sdk to be one" + f" of {constants.SPACES_SDK_TYPES} when repo_type is 'space'`" + ) + if space_sdk not in constants.SPACES_SDK_TYPES: + raise ValueError(f"Invalid space_sdk. Please choose one of {constants.SPACES_SDK_TYPES}.") + payload["sdk"] = space_sdk + if resolved_space_template is not None: + payload["template"] = resolved_space_template + + if space_sdk is not None and repo_type != "space": + warnings.warn("Ignoring provided space_sdk because repo_type is not 'space'.") + + space_args: list[tuple[str, str, Any]] = [ + # input arg, payload key, value + ("space_hardware", "hardware", space_hardware), + ("space_storage", "storageTier", space_storage), + ("space_sleep_time", "sleepTimeSeconds", space_sleep_time), + ("space_secrets", "secrets", space_secrets), + ("space_variables", "variables", space_variables), + ("space_volumes", "volumes", [v.to_dict() for v in space_volumes] if space_volumes else None), + ] + + if repo_type == constants.REPO_TYPE_SPACE: + for _, key, value in space_args: + if value is not None: + payload[key] = value + if space_sleep_time is not None and space_hardware == SpaceHardware.CPU_BASIC: + warnings.warn( + "If your Space runs on the default 'cpu-basic' hardware, it will go to sleep if inactive for more" + " than 48 hours. This value is not configurable. If you don't want your Space to deactivate or if" + " you want to set a custom sleep time, you need to upgrade to a paid Hardware.", + UserWarning, + ) + else: + if provided_space_args := [arg for arg, _, value in space_args if value is not None]: + warnings.warn(f"Ignoring provided {', '.join(provided_space_args)} because repo_type is not 'space'.") + + if resource_group_id is not None: + payload["resourceGroupId"] = resource_group_id + if region is not None: + payload["region"] = region + + headers = self._build_hf_headers(token=token) + while True: + r = get_session().post(path, headers=headers, json=payload) + if r.status_code == 409 and "Cannot create repo: another conflicting operation is in progress" in r.text: + # Since https://github.com/huggingface/moon-landing/pull/7272 (private repo), it is not possible to + # concurrently create repos on the Hub for a same user. This is rarely an issue, except when running + # tests. To avoid any inconvenience, we retry to create the repo for this specific error. + # NOTE: This could have been fixed directly in the tests, but adding it here should fix CIs for all + # dependent libraries. + # NOTE: If a fix is implemented server-side, we should be able to remove this retry mechanism. + logger.debug("Create repo failed due to a concurrency issue. Retrying...") + continue + break + + try: + hf_raise_for_status(r) + except HfHubHTTPError as err: + if exist_ok and err.response.status_code == 409: + # Repo already exists and `exist_ok=True` + pass + elif exist_ok and err.response.status_code in (401, 403): + # 401 -> if JWT token without create repo scope + # 403 -> if no write permission on the namespace + # In both cases, repo might already exist + try: + self.repo_info(repo_id=repo_id, repo_type=repo_type, token=token) + if repo_type is None or repo_type == constants.REPO_TYPE_MODEL: + return RepoUrl(f"{self.endpoint}/{repo_id}") + return RepoUrl(f"{self.endpoint}/{constants.REPO_TYPES_URL_PREFIXES[repo_type]}{repo_id}") + except HfHubHTTPError: + raise err + else: + raise + + d = r.json() + return RepoUrl(d["url"], endpoint=self.endpoint) + + @validate_hf_hub_args + def delete_repo( + self, + repo_id: str, + *, + token: str | bool | None = None, + repo_type: str | None = None, + missing_ok: bool = False, + ) -> None: + """ + Delete a repo from the HuggingFace Hub. CAUTION: this is irreversible. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. + missing_ok (`bool`, *optional*, defaults to `False`): + If `True`, do not raise an error if repo does not exist. + + Raises: + [`~utils.RepositoryNotFoundError`] + If the repository to delete from cannot be found and `missing_ok` is set to False (default). + """ + organization, name = repo_id.split("/") if "/" in repo_id else (None, repo_id) + + path = f"{self.endpoint}/api/repos/delete" + + if repo_type not in constants.REPO_TYPES_WITH_KERNEL: + raise ValueError("Invalid repo type") + + json = {"name": name, "organization": organization} + if repo_type is not None: + json["type"] = repo_type + + headers = self._build_hf_headers(token=token) + r = get_session().request("DELETE", path, headers=headers, json=json) + try: + hf_raise_for_status(r) + except RepositoryNotFoundError: + if not missing_ok: + raise + + @validate_hf_hub_args + def update_repo_settings( + self, + repo_id: str, + *, + gated: Literal["auto", "manual", False] | None = None, + private: bool | None = None, + visibility: RepoVisibility_T | None = None, + token: str | bool | None = None, + repo_type: str | None = None, + ) -> None: + """ + Update the settings of a repository, including gated access and visibility. + + To give more control over how repos are used, the Hub allows repo authors to enable + access requests for their repos, and also to change the visibility of the repo. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated by a /. + gated (`Literal["auto", "manual", False]`, *optional*): + The gated status for the repository. If set to `None` (default), the `gated` setting of the repository won't be updated. + * "auto": The repository is gated, and access requests are automatically approved or denied based on predefined criteria. + * "manual": The repository is gated, and access requests require manual approval. + * False : The repository is not gated, and anyone can access it. + private (`bool`, *optional*): + Whether the repository should be private. Cannot be passed together with `visibility`. + visibility (`Literal["public", "private", "protected"]`, *optional*): + Visibility of the repository. Can be `"public"` or `"private"`, or `"protected"` for Spaces. + token (`Union[str, bool, None]`, *optional*): + A valid user access token (string). Defaults to the locally saved token, + which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass False. + repo_type (`str`, *optional*): + The type of the repository to update settings from (`"model"`, `"dataset"` or `"space"`). + Defaults to `"model"`. + Raises: + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If gated is not one of "auto", "manual", or False. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If repo_type is not one of the values in constants.REPO_TYPES. + [`~utils.HfHubHTTPError`]: + If the request to the Hugging Face Hub API fails. + [`~utils.RepositoryNotFoundError`] + If the repository to download from cannot be found. This may be because it doesn't exist, + or because it is set to `private` and you do not have access. + """ + + if repo_type not in constants.REPO_TYPES: + raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}") + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL # default repo type + + resolved_visibility = _resolve_repo_visibility(private=private, visibility=visibility, repo_type=repo_type) + + # Prepare the JSON payload for the PUT request + payload: dict = {} + + if gated is not None: + if gated not in ["auto", "manual", False]: + raise ValueError(f"Invalid gated status, must be one of 'auto', 'manual', or False. Got '{gated}'.") + payload["gated"] = gated + + if resolved_visibility is not None: + payload["visibility"] = resolved_visibility + + if len(payload) == 0: + raise ValueError("At least one setting must be updated.") + + # Build headers + headers = self._build_hf_headers(token=token) + + r = get_session().put( + url=f"{self.endpoint}/api/{repo_type}s/{repo_id}/settings", + headers=headers, + json=payload, + ) + hf_raise_for_status(r) + + def move_repo( + self, + from_id: str, + to_id: str, + *, + repo_type: str | None = None, + token: str | bool | None = None, + ): + """ + Moving a repository from namespace1/repo_name1 to namespace2/repo_name2 + + Note there are certain limitations. For more information about moving + repositories, please see + https://hf.co/docs/hub/repositories-settings#renaming-or-transferring-a-repo. + + Args: + from_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. Original repository identifier. + to_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. Final repository identifier. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. Default is + `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + > [!TIP] + > Raises the following errors: + > + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access. + """ + if len(from_id.split("/")) != 2: + raise ValueError(f"Invalid repo_id: {from_id}. It should have a namespace (:namespace:/:repo_name:)") + + if len(to_id.split("/")) != 2: + raise ValueError(f"Invalid repo_id: {to_id}. It should have a namespace (:namespace:/:repo_name:)") + + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL # Hub won't accept `None`. + + json = {"fromRepo": from_id, "toRepo": to_id, "type": repo_type} + + path = f"{self.endpoint}/api/repos/move" + headers = self._build_hf_headers(token=token) + r = get_session().post(path, headers=headers, json=json) + try: + hf_raise_for_status(r) + except HfHubHTTPError as e: + e.append_to_message( + "\nFor additional documentation please see" + " https://hf.co/docs/hub/repositories-settings#renaming-or-transferring-a-repo." + ) + raise + + @overload + def create_commit( # type: ignore + self, + repo_id: str, + operations: Iterable[CommitOperation], + *, + commit_message: str, + commit_description: str | None = None, + token: str | bool | None = None, + repo_type: str | None = None, + revision: str | None = None, + create_pr: bool | None = None, + num_threads: int = 5, + parent_commit: str | None = None, + run_as_future: Literal[False] = ..., + _hot_reload: bool | None = None, + ) -> CommitInfo: ... + + @overload + def create_commit( + self, + repo_id: str, + operations: Iterable[CommitOperation], + *, + commit_message: str, + commit_description: str | None = None, + token: str | bool | None = None, + repo_type: str | None = None, + revision: str | None = None, + create_pr: bool | None = None, + num_threads: int = 5, + parent_commit: str | None = None, + run_as_future: Literal[True] = ..., + _hot_reload: bool | None = None, + ) -> Future[CommitInfo]: ... + + @validate_hf_hub_args + @future_compatible + def create_commit( + self, + repo_id: str, + operations: Iterable[CommitOperation], + *, + commit_message: str, + commit_description: str | None = None, + token: str | bool | None = None, + repo_type: str | None = None, + revision: str | None = None, + create_pr: bool | None = None, + num_threads: int = 5, + parent_commit: str | None = None, + run_as_future: bool = False, + _hot_reload: bool | None = None, + ) -> CommitInfo | Future[CommitInfo]: + """ + Creates a commit in the given repo, deleting & uploading files as needed. + + > [!WARNING] + > The input list of `CommitOperation` will be mutated during the commit process. Do not reuse the same objects + > for multiple commits. + + > [!WARNING] + > `create_commit` assumes that the repo already exists on the Hub. If you get a + > Client error 404, please make sure you are authenticated, that your token has the required permissions, + > and that `repo_id` and `repo_type` are set correctly. If repo does not exist, + > create it first using [`~hf_api.create_repo`]. + + > [!WARNING] + > `create_commit` is limited to 25k LFS files and a 1GB payload for regular files. + + Args: + repo_id (`str`): + The repository in which the commit will be created, for example: + `"username/custom_transformers"` + + operations (`Iterable` of [`~hf_api.CommitOperation`]): + An iterable of operations to include in the commit, either: + + - [`~hf_api.CommitOperationAdd`] to upload a file + - [`~hf_api.CommitOperationDelete`] to delete a file + - [`~hf_api.CommitOperationCopy`] to copy a file + + Operation objects will be mutated to include information relative to the upload. Do not reuse the + same objects for multiple commits. + + commit_message (`str`): + The summary (first line) of the commit that will be created. + + commit_description (`str`, *optional*): + The description of the commit that will be created + + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. Default is + `None`. + + revision (`str`, *optional*): + The git revision to commit from. Defaults to the head of the `"main"` branch. + + create_pr (`boolean`, *optional*): + Whether or not to create a Pull Request with that commit. Defaults to `False`. + If `revision` is not set, PR is opened against the `"main"` branch. If + `revision` is set and is a branch, PR is opened against this branch. If + `revision` is set and is not a branch name (example: a commit oid), an + `RevisionNotFoundError` is returned by the server. + + num_threads (`int`, *optional*): + Number of concurrent threads for uploading files. Defaults to 5. + Setting it to 2 means at most 2 files will be uploaded concurrently. + + parent_commit (`str`, *optional*): + The OID / SHA of the parent commit, as a hexadecimal string. + Shorthands (7 first characters) are also supported. If specified and `create_pr` is `False`, + the commit will fail if `revision` does not point to `parent_commit`. If specified and `create_pr` + is `True`, the pull request will be created from `parent_commit`. Specifying `parent_commit` + ensures the repo has not changed before committing the changes, and can be especially useful + if the repo is updated / committed to concurrently. + run_as_future (`bool`, *optional*): + Whether or not to run this method in the background. Background jobs are run sequentially without + blocking the main thread. Passing `run_as_future=True` will return a [Future](https://docs.python.org/3/library/concurrent.futures.html#future-objects) + object. Defaults to `False`. + + Returns: + [`CommitInfo`] or `Future`: + Instance of [`CommitInfo`] containing information about the newly created commit (commit hash, commit + url, pr url, commit message,...). If `run_as_future=True` is passed, returns a Future object which will + contain the result when executed. + + Raises: + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If commit message is empty. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If parent commit is not a valid commit OID. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If a README.md file with an invalid metadata section is committed. In this case, the commit will fail + early, before trying to upload any file. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If `create_pr` is `True` and revision is neither `None` nor `"main"`. + [`~utils.RepositoryNotFoundError`]: + If repository is not found (error 404): wrong repo_id/repo_type, private + but not authenticated or repo does not exist. + """ + if parent_commit is not None and not constants.REGEX_COMMIT_OID.fullmatch(parent_commit): + raise ValueError( + f"`parent_commit` is not a valid commit OID. It must match the following regex: {constants.REGEX_COMMIT_OID}" + ) + + if commit_message is None or len(commit_message) == 0: + raise ValueError("`commit_message` can't be empty, please pass a value.") + + commit_description = commit_description if commit_description is not None else "" + repo_type = repo_type if repo_type is not None else constants.REPO_TYPE_MODEL + if repo_type not in constants.REPO_TYPES: + raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}") + unquoted_revision = revision or constants.DEFAULT_REVISION + revision = quote(unquoted_revision, safe="") + create_pr = create_pr if create_pr is not None else False + _hot_reload = _hot_reload if _hot_reload is not None else False + + headers = self._build_hf_headers(token=token) + + operations = list(operations) + additions = [op for op in operations if isinstance(op, CommitOperationAdd)] + copies = [op for op in operations if isinstance(op, CommitOperationCopy)] + nb_additions = len(additions) + nb_copies = len(copies) + nb_deletions = len(operations) - nb_additions - nb_copies + + for addition in additions: + if addition._is_committed: + raise ValueError( + f"CommitOperationAdd {addition} has already being committed and cannot be reused. Please create a" + " new CommitOperationAdd object if you want to create a new commit." + ) + + if repo_type != "dataset": + for addition in additions: + if addition.path_in_repo.endswith((".arrow", ".parquet")): + warnings.warn( + f"It seems that you are about to commit a data file ({addition.path_in_repo}) to a {repo_type}" + " repository. You are sure this is intended? If you are trying to upload a dataset, please" + " set `repo_type='dataset'` or `--repo-type=dataset` in a CLI." + ) + + logger.debug( + f"About to commit to the hub: {len(additions)} addition(s), {len(copies)} copy(ies) and" + f" {nb_deletions} deletion(s)." + ) + + # If updating a README.md file, make sure the metadata format is valid + # It's better to fail early than to fail after all the files have been uploaded. + for addition in additions: + if addition.path_in_repo == "README.md": + with addition.as_file() as file: + content = file.read().decode() + self._validate_yaml(content, repo_type=repo_type, token=token) + # Skip other additions after `README.md` has been processed + break + + # If updating twice the same file or update then delete a file in a single commit + _warn_on_overwriting_operations(operations) + + self.preupload_lfs_files( + repo_id=repo_id, + additions=additions, + token=token, + repo_type=repo_type, + revision=unquoted_revision, # first-class methods take unquoted revision + create_pr=create_pr, + num_threads=num_threads, + free_memory=False, # do not remove `CommitOperationAdd.path_or_fileobj` on LFS files for "normal" users + ) + + files_to_copy = _fetch_files_to_copy( + copies=copies, + repo_type=repo_type, + repo_id=repo_id, + headers=headers, + revision=unquoted_revision, + endpoint=self.endpoint, + ) + + self._duplicate_lfs_files( + repo_id=repo_id, copies=copies, files_to_copy=files_to_copy, token=token, repo_type=repo_type + ) + + # Remove no-op operations (files that have not changed) + operations_without_no_op = [] + for operation in operations: + if ( + isinstance(operation, CommitOperationAdd) + and operation._remote_oid is not None + and operation._remote_oid == operation._local_oid + ): + # File already exists on the Hub and has not changed: we can skip it. + logger.debug(f"Skipping upload for '{operation.path_in_repo}' as the file has not changed.") + continue + if ( + isinstance(operation, CommitOperationCopy) + and operation._dest_oid is not None + and operation._dest_oid == operation._src_oid + ): + # Source and destination files are identical - skip + logger.debug( + f"Skipping copy for '{operation.src_path_in_repo}' -> '{operation.path_in_repo}' as the content of the source file is the same as the destination file." + ) + continue + operations_without_no_op.append(operation) + if len(operations) != len(operations_without_no_op): + logger.info( + f"Removing {len(operations) - len(operations_without_no_op)} file(s) from commit that have not changed." + ) + + # Return early if empty commit + if len(operations_without_no_op) == 0: + logger.warning("No files have been modified since last commit. Skipping to prevent empty commit.") + + # Get latest commit info + try: + info = self.repo_info(repo_id=repo_id, repo_type=repo_type, revision=unquoted_revision, token=token) + except RepositoryNotFoundError as e: + e.append_to_message(_CREATE_COMMIT_NO_REPO_ERROR_MESSAGE) + raise + + # Return commit info based on latest commit + url_prefix = self.endpoint + if repo_type is not None and repo_type != constants.REPO_TYPE_MODEL: + url_prefix = f"{url_prefix}/{repo_type}s" + return CommitInfo( + commit_url=f"{url_prefix}/{repo_id}/commit/{info.sha}", + commit_message=commit_message, + commit_description=commit_description, + oid=info.sha, # type: ignore + _endpoint=self.endpoint, + ) + + try: + commit_info = _send_commit( + operations=operations_without_no_op, + files_to_copy=files_to_copy, + commit_message=commit_message, + commit_description=commit_description, + repo_type=repo_type, + repo_id=repo_id, + headers=headers, + revision=revision, + endpoint=self.endpoint, + parent_commit=parent_commit, + create_pr=create_pr, + hot_reload=_hot_reload, + ) + except RepositoryNotFoundError as e: + e.append_to_message(_CREATE_COMMIT_NO_REPO_ERROR_MESSAGE) + raise + except RemoteEntryNotFoundError as e: + if nb_deletions > 0 and "A file with this name doesn't exist" in str(e): + e.append_to_message( + "\nMake sure to differentiate file and folder paths in delete" + " operations with a trailing '/' or using `is_folder=True/False`." + ) + raise + + # Mark additions as committed (cannot be reused in another commit) + for addition in additions: + addition._is_committed = True + + return commit_info + + def preupload_lfs_files( + self, + repo_id: str, + additions: Iterable[CommitOperationAdd], + *, + token: str | bool | None = None, + repo_type: str | None = None, + revision: str | None = None, + create_pr: bool | None = None, + num_threads: int = 5, + free_memory: bool = True, + gitignore_content: str | None = None, + ): + """Pre-upload LFS files to S3 in preparation on a future commit. + + This method is useful if you are generating the files to upload on-the-fly and you don't want to store them + in memory before uploading them all at once. + + > [!WARNING] + > This is a power-user method. You shouldn't need to call it directly to make a normal commit. + > Use [`create_commit`] directly instead. + + > [!WARNING] + > Commit operations will be mutated during the process. In particular, the attached `path_or_fileobj` will be + > removed after the upload to save memory (and replaced by an empty `bytes` object). Do not reuse the same + > objects except to pass them to [`create_commit`]. If you don't want to remove the attached content from the + > commit operation object, pass `free_memory=False`. + + Args: + repo_id (`str`): + The repository in which you will commit the files, for example: `"username/custom_transformers"`. + + additions (`Iterable` of [`CommitOperationAdd`]): + The list of files to upload. Warning: the objects in this list will be mutated to include information + relative to the upload. Do not reuse the same objects for multiple commits. + + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + repo_type (`str`, *optional*): + The type of repository to upload to (e.g. `"model"` -default-, `"dataset"` or `"space"`). + + revision (`str`, *optional*): + The git revision to commit from. Defaults to the head of the `"main"` branch. + + create_pr (`boolean`, *optional*): + Whether or not you plan to create a Pull Request with that commit. Defaults to `False`. + + num_threads (`int`, *optional*): + Number of concurrent threads for uploading files. Defaults to 5. + Setting it to 2 means at most 2 files will be uploaded concurrently. + + free_memory (`bool`, *optional*, defaults to `True`): + If `True`, the `path_or_fileobj` attribute of each `CommitOperationAdd` is replaced by an empty + `bytes` object after upload to save memory. Set to `False` if you need to reuse the operation + objects outside of a subsequent [`create_commit`] call. + + gitignore_content (`str`, *optional*): + The content of the `.gitignore` file to know which files should be ignored. The order of priority + is to first check if `gitignore_content` is passed, then check if the `.gitignore` file is present + in the list of files to commit and finally default to the `.gitignore` file already hosted on the Hub + (if any). + + Example: + ```py + >>> from huggingface_hub import CommitOperationAdd, preupload_lfs_files, create_commit, create_repo + + >>> repo_id = create_repo("test_preupload").repo_id + + # Generate and preupload LFS files one by one + >>> operations = [] # List of all `CommitOperationAdd` objects that will be generated + >>> for i in range(5): + ... content = ... # generate binary content + ... addition = CommitOperationAdd(path_in_repo=f"shard_{i}_of_5.bin", path_or_fileobj=content) + ... preupload_lfs_files(repo_id, additions=[addition]) # upload + free memory + ... operations.append(addition) + + # Create commit + >>> create_commit(repo_id, operations=operations, commit_message="Commit all shards") + ``` + """ + repo_type = repo_type if repo_type is not None else constants.REPO_TYPE_MODEL + if repo_type not in constants.REPO_TYPES: + raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}") + revision = quote(revision, safe="") if revision is not None else constants.DEFAULT_REVISION + create_pr = create_pr if create_pr is not None else False + headers = self._build_hf_headers(token=token) + + # Check if a `gitignore` file is being committed to the Hub. + additions = list(additions) + if gitignore_content is None: + for addition in additions: + if addition.path_in_repo == ".gitignore": + with addition.as_file() as f: + gitignore_content = f.read().decode() + break + + # Filter out already uploaded files + new_additions = [addition for addition in additions if not addition._is_uploaded] + + # Check which new files are LFS + # For some items, we might have already fetched the upload mode (in case of upload_large_folder) + additions_no_upload_mode = [addition for addition in new_additions if addition._upload_mode is None] + if len(additions_no_upload_mode) > 0: + try: + _fetch_upload_modes( + additions=additions_no_upload_mode, + repo_type=repo_type, + repo_id=repo_id, + headers=headers, + revision=revision, + endpoint=self.endpoint, + create_pr=create_pr or False, + gitignore_content=gitignore_content, + ) + except RepositoryNotFoundError as e: + e.append_to_message(_CREATE_COMMIT_NO_REPO_ERROR_MESSAGE) + raise + + # Filter out regular files + new_lfs_additions = [addition for addition in new_additions if addition._upload_mode == "lfs"] + + # Filter out files listed in .gitignore + new_lfs_additions_to_upload = [] + for addition in new_lfs_additions: + if addition._should_ignore: + logger.debug(f"Skipping upload for LFS file '{addition.path_in_repo}' (ignored by gitignore file).") + else: + new_lfs_additions_to_upload.append(addition) + if len(new_lfs_additions) != len(new_lfs_additions_to_upload): + logger.info( + f"Skipped upload for {len(new_lfs_additions) - len(new_lfs_additions_to_upload)} LFS file(s) " + "(ignored by gitignore file)." + ) + # If no LFS files remain to upload, keep previous behavior and log explicitly + if len(new_lfs_additions_to_upload) == 0: + logger.debug("No LFS files to upload.") + return + # Prepare upload parameters + upload_kwargs = { + "additions": new_lfs_additions_to_upload, + "repo_type": repo_type, + "repo_id": repo_id, + "headers": headers, + "endpoint": self.endpoint, + # If `create_pr`, we don't want to check user permission on the revision as users with read permission + # should still be able to create PRs even if they don't have write permission on the target branch of the + # PR (i.e. `revision`). + "revision": revision if not create_pr else None, + } + _upload_files( + **upload_kwargs, # type: ignore[arg-type] + num_threads=num_threads, + create_pr=create_pr, + ) + for addition in new_lfs_additions_to_upload: + addition._is_uploaded = True + if free_memory: + addition.path_or_fileobj = b"" + + @validate_hf_hub_args + def _duplicate_lfs_files( + self, + repo_id: str, + copies: Iterable[CommitOperationCopy], + *, + files_to_copy: dict, + token: str | bool | None = None, + repo_type: str | None = None, + ) -> None: + """Duplicate LFS files from source repositories to the destination repository. + + This method is the equivalent of [`preupload_lfs_files`] for cross-repo copy operations. It must be called + before [`create_commit`] to ensure that LFS files from the source repositories are available in the destination + repository before the commit is created. + + Args: + repo_id (`str`): + The destination repository in which you will commit the files, for example: + `"username/custom_transformers"`. + + copies (`Iterable` of [`CommitOperationCopy`]): + The list of copy operations describing which files to duplicate. Only cross-repo copies (where + `src_repo_id` is set) with LFS files will be processed. Warning: the objects in this list will be + mutated to include information relative to the duplication. Do not reuse the same objects for multiple + commits. + + files_to_copy (`dict`): + Pre-fetched file info from [`_fetch_files_to_copy`]. LFS metadata is extracted from this dict instead + of making additional API calls. Keys are `_CopySource` tuples, values are `RepoFile` (for LFS files) + or `bytes` (for regular files). + + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + repo_type (`str`, *optional*): + The type of the destination repository (e.g. `"model"` -default-, `"dataset"` or `"space"`). + """ + repo_type = repo_type if repo_type is not None else constants.REPO_TYPE_MODEL + if repo_type not in constants.REPO_TYPES: + raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}") + headers = self._build_hf_headers(token=token) + + copies = list(copies) + # Filter to cross-repo copies that haven't been duplicated yet + cross_repo_copies = [op for op in copies if op.src_repo_id is not None and not op._is_duplicated] + if not cross_repo_copies: + logger.debug("No cross-repo LFS files to duplicate.") + return + + # The /lfs-files/duplicate endpoint lives on the *source* repo and takes the destination as `target`. + cross_repo_copies.sort(key=lambda op: (op.src_repo_id or "", op.src_repo_type or "", op.src_revision or "")) + + for (src_repo_id, src_repo_type, src_revision), group in itertools.groupby( + cross_repo_copies, key=lambda op: (op.src_repo_id, op.src_repo_type, op.src_revision) + ): + operations = list(group) + + lfs_files: list[dict] = [] + seen_oids: set[str] = set() + + for op in operations: + key = _CopySource(op.src_repo_id, op.src_repo_type, op.src_path_in_repo, op.src_revision) + src_file = files_to_copy.get(key) + if src_file is None or isinstance(src_file, bytes): + continue + if not src_file.lfs: + continue + if not src_file.xet_hash: + raise ValueError( + f"Cannot duplicate LFS file '{src_file.path}' from {src_repo_type}s/{src_repo_id}: file has no xet hash." + f" (file: {src_file})" + ) + oid = src_file.lfs.sha256 + if oid not in seen_oids: + seen_oids.add(oid) + lfs_files.append({"xetHash": src_file.xet_hash, "sha256": oid, "filename": src_file.path}) + + if not lfs_files: + continue + + # Call the duplicate endpoint on the *source* repo, in batches + duplicate_url = f"{self.endpoint}/api/{src_repo_type}s/{src_repo_id}/lfs-files/duplicate" + for batch in chunk_iterable(lfs_files, DUPLICATE_LFS_BATCH_SIZE): + response = get_session().post( + duplicate_url, + headers=headers, + json={"target": {"type": repo_type, "name": repo_id}, "files": list(batch)}, + ) + hf_raise_for_status(response) + data = response.json() + failures = data.get("failed", []) + if failures: + messages = [f" - {f['sha256']}: {f['error']}" for f in failures] + raise FileDuplicationError( + f"Failed to duplicate files from {src_repo_type}s/{src_repo_id} " + f"to {repo_type}s/{repo_id}:\n" + "\n".join(messages) + ) + + for op in cross_repo_copies: + op._is_duplicated = True + + @overload + def upload_file( # type: ignore + self, + *, + path_or_fileobj: str | Path | bytes | BinaryIO, + path_in_repo: str, + repo_id: str, + token: str | bool | None = None, + repo_type: str | None = None, + revision: str | None = None, + commit_message: str | None = None, + commit_description: str | None = None, + create_pr: bool | None = None, + parent_commit: str | None = None, + run_as_future: Literal[False] = ..., + _hot_reload: bool | None = None, + ) -> CommitInfo: ... + + @overload + def upload_file( + self, + *, + path_or_fileobj: str | Path | bytes | BinaryIO, + path_in_repo: str, + repo_id: str, + token: str | bool | None = None, + repo_type: str | None = None, + revision: str | None = None, + commit_message: str | None = None, + commit_description: str | None = None, + create_pr: bool | None = None, + parent_commit: str | None = None, + run_as_future: Literal[True] = ..., + _hot_reload: bool | None = None, + ) -> Future[CommitInfo]: ... + + @validate_hf_hub_args + @future_compatible + def upload_file( + self, + *, + path_or_fileobj: str | Path | bytes | BinaryIO, + path_in_repo: str, + repo_id: str, + token: str | bool | None = None, + repo_type: str | None = None, + revision: str | None = None, + commit_message: str | None = None, + commit_description: str | None = None, + create_pr: bool | None = None, + parent_commit: str | None = None, + run_as_future: bool = False, + _hot_reload: bool | None = None, + ) -> CommitInfo | Future[CommitInfo]: + """ + Upload a local file (up to 50 GB) to the given repo. The upload is done + through a HTTP post request, and doesn't require git or git-lfs to be + installed. + + Args: + path_or_fileobj (`str`, `Path`, `bytes`, or `IO`): + Path to a file on the local machine or binary data stream / + fileobj / buffer. + path_in_repo (`str`): + Relative filepath in the repo, for example: + `"checkpoints/1fec34a/weights.bin"` + repo_id (`str`): + The repository to which the file will be uploaded, for example: + `"username/custom_transformers"` + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. Default is + `None`. + revision (`str`, *optional*): + The git revision to commit from. Defaults to the head of the `"main"` branch. + commit_message (`str`, *optional*): + The summary / title / first line of the generated commit + commit_description (`str` *optional*) + The description of the generated commit + create_pr (`boolean`, *optional*): + Whether or not to create a Pull Request with that commit. Defaults to `False`. + If `revision` is not set, PR is opened against the `"main"` branch. If + `revision` is set and is a branch, PR is opened against this branch. If + `revision` is set and is not a branch name (example: a commit oid), an + `RevisionNotFoundError` is returned by the server. + parent_commit (`str`, *optional*): + The OID / SHA of the parent commit, as a hexadecimal string. Shorthands (7 first characters) are also supported. + If specified and `create_pr` is `False`, the commit will fail if `revision` does not point to `parent_commit`. + If specified and `create_pr` is `True`, the pull request will be created from `parent_commit`. + Specifying `parent_commit` ensures the repo has not changed before committing the changes, and can be + especially useful if the repo is updated / committed to concurrently. + run_as_future (`bool`, *optional*): + Whether or not to run this method in the background. Background jobs are run sequentially without + blocking the main thread. Passing `run_as_future=True` will return a [Future](https://docs.python.org/3/library/concurrent.futures.html#future-objects) + object. Defaults to `False`. + + + Returns: + [`CommitInfo`] or `Future`: + Instance of [`CommitInfo`] containing information about the newly created commit (commit hash, commit + url, pr url, commit message,...). If `run_as_future=True` is passed, returns a Future object which will + contain the result when executed. + > [!TIP] + > Raises the following errors: + > + > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError) + > if the HuggingFace API returned an error + > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > if some parameter value is invalid + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access. + > - [`~utils.RevisionNotFoundError`] + > If the revision to download from cannot be found. + + > [!WARNING] + > `upload_file` assumes that the repo already exists on the Hub. If you get a + > Client error 404, please make sure you are authenticated, that your token has the required permissions, + > and that `repo_id` and `repo_type` are set correctly. If repo does not exist, + > create it first using [`~hf_api.create_repo`]. + + Example: + + ```python + >>> from huggingface_hub import upload_file + + >>> with open("./local/filepath", "rb") as fobj: + ... upload_file( + ... path_or_fileobj=fileobj, + ... path_in_repo="remote/file/path.h5", + ... repo_id="username/my-dataset", + ... repo_type="dataset", + ... token="my_token", + ... ) + + >>> upload_file( + ... path_or_fileobj=".\\\\local\\\\file\\\\path", + ... path_in_repo="remote/file/path.h5", + ... repo_id="username/my-model", + ... token="my_token", + ... ) + + >>> upload_file( + ... path_or_fileobj=".\\\\local\\\\file\\\\path", + ... path_in_repo="remote/file/path.h5", + ... repo_id="username/my-model", + ... token="my_token", + ... create_pr=True, + ... ) + ``` + """ + if repo_type not in constants.REPO_TYPES: + raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}") + + commit_message = ( + commit_message if commit_message is not None else f"Upload {path_in_repo} with huggingface_hub" + ) + operation = CommitOperationAdd( + path_or_fileobj=path_or_fileobj, + path_in_repo=path_in_repo, + ) + + return self.create_commit( + repo_id=repo_id, + repo_type=repo_type, + operations=[operation], + commit_message=commit_message, + commit_description=commit_description, + token=token, + revision=revision, + create_pr=create_pr, + _hot_reload=_hot_reload, + parent_commit=parent_commit, + ) + + @overload + def upload_folder( # type: ignore + self, + *, + repo_id: str, + folder_path: str | Path, + path_in_repo: str | None = None, + commit_message: str | None = None, + commit_description: str | None = None, + token: str | bool | None = None, + repo_type: str | None = None, + revision: str | None = None, + create_pr: bool | None = None, + parent_commit: str | None = None, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + delete_patterns: list[str] | str | None = None, + run_as_future: Literal[False] = ..., + ) -> CommitInfo: ... + + @overload + def upload_folder( # type: ignore + self, + *, + repo_id: str, + folder_path: str | Path, + path_in_repo: str | None = None, + commit_message: str | None = None, + commit_description: str | None = None, + token: str | bool | None = None, + repo_type: str | None = None, + revision: str | None = None, + create_pr: bool | None = None, + parent_commit: str | None = None, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + delete_patterns: list[str] | str | None = None, + run_as_future: Literal[True] = ..., + ) -> Future[CommitInfo]: ... + + @validate_hf_hub_args + @future_compatible + def upload_folder( + self, + *, + repo_id: str, + folder_path: str | Path, + path_in_repo: str | None = None, + commit_message: str | None = None, + commit_description: str | None = None, + token: str | bool | None = None, + repo_type: str | None = None, + revision: str | None = None, + create_pr: bool | None = None, + parent_commit: str | None = None, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + delete_patterns: list[str] | str | None = None, + run_as_future: bool = False, + ) -> CommitInfo | Future[CommitInfo]: + """ + Upload a local folder to the given repo. The upload is done through a HTTP requests, and doesn't require git or + git-lfs to be installed. + + The structure of the folder will be preserved. Files with the same name already present in the repository will + be overwritten. Others will be left untouched. + + Use the `allow_patterns` and `ignore_patterns` arguments to specify which files to upload. These parameters + accept either a single pattern or a list of patterns. Patterns are Standard Wildcards (globbing patterns) as + documented [here](https://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm). If both `allow_patterns` and + `ignore_patterns` are provided, both constraints apply. By default, all files from the folder are uploaded. + + Use the `delete_patterns` argument to specify remote files you want to delete. Input type is the same as for + `allow_patterns` (see above). If `path_in_repo` is also provided, the patterns are matched against paths + relative to this folder. For example, `upload_folder(..., path_in_repo="experiment", delete_patterns="logs/*")` + will delete any remote file under `./experiment/logs/`. Note that the `.gitattributes` file will not be deleted + even if it matches the patterns. + + Any `.git/` folder present in any subdirectory will be ignored. However, please be aware that the `.gitignore` + file is not taken into account. + + When `hf_xet` is installed (the default), files are uploaded through a streamed pipeline: uploads start while + the folder is still being checked against the Hub, files are hashed while being chunked for upload (single + read pass), and large folders are automatically committed in several batches to stay below server limits + (follow-up commits get a ` (part N)` suffix on the commit message). If the upload is interrupted, re-running + the same call resumes it: already-committed files are skipped and already-uploaded data is deduplicated. When + `hf_xet` is not installed, falls back to a single commit created with [`create_commit`]. + + Args: + repo_id (`str`): + The repository to which the file will be uploaded, for example: + `"username/custom_transformers"` + folder_path (`str` or `Path`): + Path to the folder to upload on the local file system + path_in_repo (`str`, *optional*): + Relative path of the directory in the repo, for example: + `"checkpoints/1fec34a/results"`. Will default to the root folder of the repository. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. Default is + `None`. + revision (`str`, *optional*): + The git revision to commit from. Defaults to the head of the `"main"` branch. + commit_message (`str`, *optional*): + The summary / title / first line of the generated commit. Defaults to: + `f"Upload {path_in_repo} with huggingface_hub"` + commit_description (`str` *optional*): + The description of the generated commit + create_pr (`boolean`, *optional*): + Whether or not to create a Pull Request with that commit. Defaults to `False`. The PR is always + opened against the default branch: setting both `create_pr=True` and `revision` raises a + `ValueError`. Note that each call with `create_pr=True` opens a new pull request: to resume an + interrupted upload into the existing PR, re-run with `revision="refs/pr/N"` instead. + parent_commit (`str`, *optional*): + The OID / SHA of the parent commit, as a hexadecimal string. Shorthands (7 first characters) are also supported. + If specified and `create_pr` is `False`, the commit will fail if `revision` does not point to `parent_commit`. + Specifying `parent_commit` ensures the repo has not changed before committing the changes, and can be + especially useful if the repo is updated / committed to concurrently. If the upload is split into + several commits (large folders), `parent_commit` only applies to the first one. + allow_patterns (`list[str]` or `str`, *optional*): + If provided, only files matching at least one pattern are uploaded. + ignore_patterns (`list[str]` or `str`, *optional*): + If provided, files matching any of the patterns are not uploaded. + delete_patterns (`list[str]` or `str`, *optional*): + If provided, remote files matching any of the patterns will be deleted from the repo while committing + new files. This is useful if you don't know which files have already been uploaded. + Note: to avoid discrepancies the `.gitattributes` file is not deleted even if it matches the pattern. + run_as_future (`bool`, *optional*): + Whether or not to run this method in the background. Background jobs are run sequentially without + blocking the main thread. Passing `run_as_future=True` will return a [Future](https://docs.python.org/3/library/concurrent.futures.html#future-objects) + object. Defaults to `False`. + + Returns: + [`CommitInfo`] or `Future`: + Instance of [`CommitInfo`] containing information about the newly created commit (commit hash, commit + url, pr url, commit message,...). If `run_as_future=True` is passed, returns a Future object which will + contain the result when executed. + + > [!TIP] + > Raises the following errors: + > + > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError) + > if the HuggingFace API returned an error + > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > if some parameter value is invalid + + > [!WARNING] + > `upload_folder` assumes that the repo already exists on the Hub. If you get a Client error 404, please make + > sure you are authenticated, that your token has the required permissions, and that `repo_id` and `repo_type` + > are set correctly. If repo does not exist, create it first using [`~hf_api.create_repo`]. + + Example: + + ```python + # Upload checkpoints folder except the log files + >>> upload_folder( + ... folder_path="local/checkpoints", + ... path_in_repo="remote/experiment/checkpoints", + ... repo_id="username/my-dataset", + ... repo_type="datasets", + ... token="my_token", + ... ignore_patterns="**/logs/*.txt", + ... ) + + # Upload checkpoints folder including logs while deleting existing logs from the repo + # Useful if you don't know exactly which log files have already being pushed + >>> upload_folder( + ... folder_path="local/checkpoints", + ... path_in_repo="remote/experiment/checkpoints", + ... repo_id="username/my-dataset", + ... repo_type="datasets", + ... token="my_token", + ... delete_patterns="**/logs/*.txt", + ... ) + + # Upload checkpoints folder while creating a PR + >>> upload_folder( + ... folder_path="local/checkpoints", + ... path_in_repo="remote/experiment/checkpoints", + ... repo_id="username/my-dataset", + ... repo_type="datasets", + ... token="my_token", + ... create_pr=True, + ... ) + ``` + """ + if repo_type not in constants.REPO_TYPES: + raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}") + if create_pr and revision is not None and revision != constants.DEFAULT_REVISION: + raise ValueError( + f"Cannot use `create_pr=True` with `revision='{revision}'`: pull requests created by" + " `upload_folder` are always opened against the default branch. Don't set `revision` when" + " `create_pr=True`." + ) + + # By default, upload folder to the root directory in repo. + if path_in_repo is None: + path_in_repo = "" + + # Do not upload .git folder + if ignore_patterns is None: + ignore_patterns = [] + elif isinstance(ignore_patterns, str): + ignore_patterns = [ignore_patterns] + ignore_patterns += DEFAULT_IGNORE_PATTERNS + + delete_operations = self._prepare_folder_deletions( + repo_id=repo_id, + repo_type=repo_type, + revision=constants.DEFAULT_REVISION if create_pr else revision, + token=token, + path_in_repo=path_in_repo, + delete_patterns=delete_patterns, + ) + add_operations = self._prepare_upload_folder_additions( + folder_path, + path_in_repo, + allow_patterns=allow_patterns, + ignore_patterns=ignore_patterns, + token=token, + repo_type=repo_type, + ) + + # Optimize operations: if some files will be overwritten, we don't need to delete them first + if len(add_operations) > 0: + added_paths = {op.path_in_repo for op in add_operations} + delete_operations = [ + delete_op for delete_op in delete_operations if delete_op.path_in_repo not in added_paths + ] + commit_operations = delete_operations + add_operations + + commit_message = commit_message or "Upload folder using huggingface_hub" + + if is_xet_available(): + # Streamed multi-commit pipeline: uploads and commits overlap, large folders are + # committed in adaptive batches, interrupted uploads resume by re-running. + return pipelined_upload( + self, + repo_id=repo_id, + repo_type=repo_type or constants.REPO_TYPE_MODEL, + add_operations=add_operations, + delete_operations=delete_operations, + commit_message=commit_message, + commit_description=commit_description, + token=token, + revision=revision, + create_pr=create_pr or False, + parent_commit=parent_commit, + ) + + # Legacy single-commit path (hf_xet not installed). + if len(add_operations) > 30: + log = logger.warning if len(add_operations) > 200 else logger.info + log( + "It seems you are trying to upload a large folder at once. This might take some time and then fail if " + "the folder is too large. Installing `hf_xet` (`pip install hf_xet`) enables a more robust, resumable " + "upload that handles large folders in multiple commits." + ) + return self.create_commit( + repo_type=repo_type, + repo_id=repo_id, + operations=commit_operations, + commit_message=commit_message, + commit_description=commit_description, + token=token, + revision=revision, + create_pr=create_pr, + parent_commit=parent_commit, + ) + + @validate_hf_hub_args + def delete_file( + self, + path_in_repo: str, + repo_id: str, + *, + token: str | bool | None = None, + repo_type: str | None = None, + revision: str | None = None, + commit_message: str | None = None, + commit_description: str | None = None, + create_pr: bool | None = None, + parent_commit: str | None = None, + ) -> CommitInfo: + """ + Deletes a file in the given repo. + + Args: + path_in_repo (`str`): + Relative filepath in the repo, for example: + `"checkpoints/1fec34a/weights.bin"` + repo_id (`str`): + The repository from which the file will be deleted, for example: + `"username/custom_transformers"` + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if the file is in a dataset or + space, `None` or `"model"` if in a model. Default is `None`. + revision (`str`, *optional*): + The git revision to commit from. Defaults to the head of the `"main"` branch. + commit_message (`str`, *optional*): + The summary / title / first line of the generated commit. Defaults to + `f"Delete {path_in_repo} with huggingface_hub"`. + commit_description (`str` *optional*) + The description of the generated commit + create_pr (`boolean`, *optional*): + Whether or not to create a Pull Request with that commit. Defaults to `False`. + If `revision` is not set, PR is opened against the `"main"` branch. If + `revision` is set and is a branch, PR is opened against this branch. If + `revision` is set and is not a branch name (example: a commit oid), an + `RevisionNotFoundError` is returned by the server. + parent_commit (`str`, *optional*): + The OID / SHA of the parent commit, as a hexadecimal string. Shorthands (7 first characters) are also supported. + If specified and `create_pr` is `False`, the commit will fail if `revision` does not point to `parent_commit`. + If specified and `create_pr` is `True`, the pull request will be created from `parent_commit`. + Specifying `parent_commit` ensures the repo has not changed before committing the changes, and can be + especially useful if the repo is updated / committed to concurrently. + + + > [!TIP] + > Raises the following errors: + > + > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError) + > if the HuggingFace API returned an error + > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > if some parameter value is invalid + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access. + > - [`~utils.RevisionNotFoundError`] + > If the revision to download from cannot be found. + > - [`~utils.EntryNotFoundError`] + > If the file to download cannot be found. + + """ + commit_message = ( + commit_message if commit_message is not None else f"Delete {path_in_repo} with huggingface_hub" + ) + + operations = [CommitOperationDelete(path_in_repo=path_in_repo)] + + return self.create_commit( + repo_id=repo_id, + repo_type=repo_type, + token=token, + operations=operations, + revision=revision, + commit_message=commit_message, + commit_description=commit_description, + create_pr=create_pr, + parent_commit=parent_commit, + ) + + @validate_hf_hub_args + def delete_files( + self, + repo_id: str, + delete_patterns: list[str], + *, + token: bool | str | None = None, + repo_type: str | None = None, + revision: str | None = None, + commit_message: str | None = None, + commit_description: str | None = None, + create_pr: bool | None = None, + parent_commit: str | None = None, + ) -> CommitInfo: + """ + Delete files from a repository on the Hub. + + If a folder path is provided, the entire folder is deleted as well as + all files it contained. + + Args: + repo_id (`str`): + The repository from which the folder will be deleted, for example: + `"username/custom_transformers"` + delete_patterns (`list[str]`): + List of files or folders to delete. Each string can either be + a file path, a folder path, or a wildcard pattern. Patterns are Standard + Wildcards (globbing patterns) as documented [here](https://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm). + The pattern matching is based on [`fnmatch`](https://docs.python.org/3/library/fnmatch.html). + Note that `fnmatch` matches `*` across path boundaries, unlike traditional Unix shell globbing. + E.g. `["file.txt", "folder/", "data/*.parquet"]` + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + to the stored token. + repo_type (`str`, *optional*): + Type of the repo to delete files from. Can be `"model"`, + `"dataset"` or `"space"`. Defaults to `"model"`. + revision (`str`, *optional*): + The git revision to commit from. Defaults to the head of the `"main"` branch. + commit_message (`str`, *optional*): + The summary (first line) of the generated commit. Defaults to + `f"Delete files using huggingface_hub"`. + commit_description (`str` *optional*) + The description of the generated commit. + create_pr (`boolean`, *optional*): + Whether or not to create a Pull Request with that commit. Defaults to `False`. + If `revision` is not set, PR is opened against the `"main"` branch. If + `revision` is set and is a branch, PR is opened against this branch. If + `revision` is set and is not a branch name (example: a commit oid), an + `RevisionNotFoundError` is returned by the server. + parent_commit (`str`, *optional*): + The OID / SHA of the parent commit, as a hexadecimal string. Shorthands (7 first characters) are also supported. + If specified and `create_pr` is `False`, the commit will fail if `revision` does not point to `parent_commit`. + If specified and `create_pr` is `True`, the pull request will be created from `parent_commit`. + Specifying `parent_commit` ensures the repo has not changed before committing the changes, and can be + especially useful if the repo is updated / committed to concurrently. + """ + operations = self._prepare_folder_deletions( + repo_id=repo_id, repo_type=repo_type, delete_patterns=delete_patterns, path_in_repo="", revision=revision + ) + + if commit_message is None: + commit_message = f"Delete files {' '.join(delete_patterns)} with huggingface_hub" + + return self.create_commit( + repo_id=repo_id, + repo_type=repo_type, + token=token, + operations=operations, + revision=revision, + commit_message=commit_message, + commit_description=commit_description, + create_pr=create_pr, + parent_commit=parent_commit, + ) + + @validate_hf_hub_args + def delete_folder( + self, + path_in_repo: str, + repo_id: str, + *, + token: bool | str | None = None, + repo_type: str | None = None, + revision: str | None = None, + commit_message: str | None = None, + commit_description: str | None = None, + create_pr: bool | None = None, + parent_commit: str | None = None, + ) -> CommitInfo: + """ + Deletes a folder in the given repo. + + Simple wrapper around [`create_commit`] method. + + Args: + path_in_repo (`str`): + Relative folder path in the repo, for example: `"checkpoints/1fec34a"`. + repo_id (`str`): + The repository from which the folder will be deleted, for example: + `"username/custom_transformers"` + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + to the stored token. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if the folder is in a dataset or + space, `None` or `"model"` if in a model. Default is `None`. + revision (`str`, *optional*): + The git revision to commit from. Defaults to the head of the `"main"` branch. + commit_message (`str`, *optional*): + The summary / title / first line of the generated commit. Defaults to + `f"Delete folder {path_in_repo} with huggingface_hub"`. + commit_description (`str` *optional*) + The description of the generated commit. + create_pr (`boolean`, *optional*): + Whether or not to create a Pull Request with that commit. Defaults to `False`. + If `revision` is not set, PR is opened against the `"main"` branch. If + `revision` is set and is a branch, PR is opened against this branch. If + `revision` is set and is not a branch name (example: a commit oid), an + `RevisionNotFoundError` is returned by the server. + parent_commit (`str`, *optional*): + The OID / SHA of the parent commit, as a hexadecimal string. Shorthands (7 first characters) are also supported. + If specified and `create_pr` is `False`, the commit will fail if `revision` does not point to `parent_commit`. + If specified and `create_pr` is `True`, the pull request will be created from `parent_commit`. + Specifying `parent_commit` ensures the repo has not changed before committing the changes, and can be + especially useful if the repo is updated / committed to concurrently. + """ + return self.create_commit( + repo_id=repo_id, + repo_type=repo_type, + token=token, + operations=[CommitOperationDelete(path_in_repo=path_in_repo, is_folder=True)], + revision=revision, + commit_message=( + commit_message if commit_message is not None else f"Delete folder {path_in_repo} with huggingface_hub" + ), + commit_description=commit_description, + create_pr=create_pr, + parent_commit=parent_commit, + ) + + def upload_large_folder( + self, + repo_id: str, + folder_path: str | Path, + *, + repo_type: str, # Repo type is required! + revision: str | None = None, + private: bool | None = None, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + num_workers: int | None = None, + print_report: bool = True, + print_report_every: int = 60, + ) -> None: + """Upload a large folder to the Hub in the most resilient way possible. + + > [!WARNING] + > `upload_large_folder` is deprecated and will be removed in a future release. [`upload_folder`] is now multi-commits + > by default and resilient to interruptions so it is the recommended way to upload large folders. + + Several workers are started to upload files in an optimized way. Before being committed to a repo, files must be + hashed and be pre-uploaded if they are LFS files. Workers will perform these tasks for each file in the folder. + At each step, some metadata information about the upload process is saved in the folder under `.cache/.huggingface/` + to be able to resume the process if interrupted. The whole process might result in several commits. + + Args: + repo_id (`str`): + The repository to which the file will be uploaded. + E.g. `"HuggingFaceTB/smollm-corpus"`. + folder_path (`str` or `Path`): + Path to the folder to upload on the local file system. + repo_type (`str`): + Type of the repository. Must be one of `"model"`, `"dataset"` or `"space"`. + Unlike in all other `HfApi` methods, `repo_type` is explicitly required here. This is to avoid + any mistake when uploading a large folder to the Hub, and therefore prevent from having to re-upload + everything. + revision (`str`, `optional`): + The branch to commit to. If not provided, the `main` branch will be used. + private (`bool`, `optional`): + Whether the repository should be private. + If `None` (default), the repo will be public unless the organization's default is private. + allow_patterns (`list[str]` or `str`, *optional*): + If provided, only files matching at least one pattern are uploaded. + ignore_patterns (`list[str]` or `str`, *optional*): + If provided, files matching any of the patterns are not uploaded. + num_workers (`int`, *optional*): + Number of workers to start. Defaults to half of CPU cores (minimum 1). + A higher number of workers may speed up the process if your machine allows it. However, on machines with a + slower connection, it is recommended to keep the number of workers low to ensure better resumability. + Indeed, partially uploaded files will have to be completely re-uploaded if the process is interrupted. + print_report (`bool`, *optional*): + Whether to print a report of the upload progress. Defaults to True. + Report is printed to `sys.stdout` every X seconds (60 by defaults) and overwrites the previous report. + print_report_every (`int`, *optional*): + Frequency at which the report is printed. Defaults to 60 seconds. + + > [!TIP] + > A few things to keep in mind: + > - Repository limits still apply: https://huggingface.co/docs/hub/repositories-recommendations + > - Do not start several processes in parallel. + > - You can interrupt and resume the process at any time. + > - Do not upload the same folder to several repositories. If you need to do so, you must delete the local `.cache/.huggingface/` folder first. + + > [!WARNING] + > While being much more robust to upload large folders, `upload_large_folder` is more limited than [`upload_folder`] feature-wise. In practice: + > - you cannot set a custom `path_in_repo`. If you want to upload to a subfolder, you need to set the proper structure locally. + > - you cannot set a custom `commit_message` and `commit_description` since multiple commits are created. + > - you cannot delete from the repo while uploading. Please make a separate commit first. + > - you cannot create a PR directly. Please create a PR first (from the UI or using [`create_pull_request`]) and then commit to it by passing `revision`. + + **Technical details:** + + `upload_large_folder` process is as follow: + 1. (Check parameters and setup.) + 2. Create repo if missing. + 3. List local files to upload. + 4. Run validation checks and display warnings if repository limits might be exceeded: + - Warns if the total number of files exceeds 100k (recommended limit). + - Warns if any folder contains more than 10k files (recommended limit). + - Warns about files larger than 20GB (recommended) or 50GB (hard limit). + 5. Start workers. Workers can perform the following tasks: + - Hash a file. + - Get upload mode (regular or LFS) for a list of files. + - Pre-upload an LFS file. + - Commit a bunch of files. + Once a worker finishes a task, it will move on to the next task based on the priority list (see below) until + all files are uploaded and committed. + 6. While workers are up, regularly print a report to sys.stdout. + + Order of priority: + 1. Commit if more than 5 minutes since last commit attempt (and at least 1 file). + 2. Commit if at least 150 files are ready to commit. + 3. Get upload mode if at least 10 files have been hashed. + 4. Pre-upload LFS file if at least 1 file and no worker is pre-uploading. + 5. Hash file if at least 1 file and no worker is hashing. + 6. Get upload mode if at least 1 file and no worker is getting upload mode. + 7. Pre-upload LFS file if at least 1 file. + 8. Hash file if at least 1 file to hash. + 9. Get upload mode if at least 1 file to get upload mode. + 10. Commit if at least 1 file to commit and at least 1 min since last commit attempt. + 11. Commit if at least 1 file to commit and all other queues are empty. + + Special rules: + - Only one worker can commit at a time. + - If no tasks are available, the worker waits for 10 seconds before checking again. + """ + warnings.warn( + "\n" + "================================================================================\n" + "`upload_large_folder` is DEPRECATED and will be removed in a future release.\n" + "\n" + "Use `upload_folder` instead:\n" + "\n" + f' api.upload_folder(repo_id="{repo_id}", repo_type="{repo_type}", folder_path="{folder_path}")\n' + "================================================================================\n", + FutureWarning, + stacklevel=2, + ) + return upload_large_folder_internal( + self, + repo_id=repo_id, + folder_path=folder_path, + repo_type=repo_type, + revision=revision, + private=private, + allow_patterns=allow_patterns, + ignore_patterns=ignore_patterns, + num_workers=num_workers, + print_report=print_report, + print_report_every=print_report_every, + ) + + @validate_hf_hub_args + def get_hf_file_metadata( + self, + *, + url: str, + token: bool | str | None = None, + timeout: float | None = constants.HF_HUB_ETAG_TIMEOUT, + ) -> HfFileMetadata: + """Fetch metadata of a file versioned on the Hub for a given url. + + Args: + url (`str`): + File url, for example returned by [`hf_hub_url`]. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + timeout (`float`, *optional*, defaults to 10): + How many seconds to wait for the server to send metadata before giving up. + + Returns: + A [`HfFileMetadata`] object containing metadata such as location, etag, size and commit_hash. + """ + if token is None: + # Cannot do `token = token or self.token` as token can be `False`. + token = self.token + + return get_hf_file_metadata( + url=url, + token=token, + timeout=timeout, + library_name=self.library_name, + library_version=self.library_version, + user_agent=self.user_agent, + endpoint=self.endpoint, + ) + + @overload + def hf_hub_download( + self, + repo_id: str, + filename: str, + *, + subfolder: str | None = None, + repo_type: str | None = None, + revision: str | None = None, + cache_dir: str | Path | None = None, + local_dir: str | Path | None = None, + force_download: bool = False, + etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT, + token: bool | str | None = None, + local_files_only: bool = False, + tqdm_class: type[base_tqdm] | None = None, + dry_run: Literal[False] = False, + ) -> str: ... + + @overload + def hf_hub_download( + self, + repo_id: str, + filename: str, + *, + subfolder: str | None = None, + repo_type: str | None = None, + revision: str | None = None, + cache_dir: str | Path | None = None, + local_dir: str | Path | None = None, + force_download: bool = False, + etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT, + token: bool | str | None = None, + local_files_only: bool = False, + tqdm_class: type[base_tqdm] | None = None, + dry_run: Literal[True], + ) -> DryRunFileInfo: ... + + @validate_hf_hub_args + def hf_hub_download( + self, + repo_id: str, + filename: str, + *, + subfolder: str | None = None, + repo_type: str | None = None, + revision: str | None = None, + cache_dir: str | Path | None = None, + local_dir: str | Path | None = None, + force_download: bool = False, + etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT, + token: bool | str | None = None, + local_files_only: bool = False, + tqdm_class: type[base_tqdm] | None = None, + dry_run: bool = False, + ) -> str | DryRunFileInfo: + """Download a given file if it's not already present in the local cache. + + The new cache file layout looks like this: + - The cache directory contains one subfolder per repo_id (namespaced by repo type) + - inside each repo folder: + - refs is a list of the latest known revision => commit_hash pairs + - blobs contains the actual file blobs (identified by their git-sha or sha256, depending on + whether they're LFS files or not) + - snapshots contains one subfolder per commit, each "commit" contains the subset of the files + that have been resolved at that particular commit. Each filename is a symlink to the blob + at that particular commit. + + ``` + [ 96] . + └── [ 160] models--julien-c--EsperBERTo-small + ├── [ 160] blobs + │ ├── [321M] 403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd + │ ├── [ 398] 7cb18dc9bafbfcf74629a4b760af1b160957a83e + │ └── [1.4K] d7edf6bd2a681fb0175f7735299831ee1b22b812 + ├── [ 96] refs + │ └── [ 40] main + └── [ 128] snapshots + ├── [ 128] 2439f60ef33a0d46d85da5001d52aeda5b00ce9f + │ ├── [ 52] README.md -> ../../blobs/d7edf6bd2a681fb0175f7735299831ee1b22b812 + │ └── [ 76] pytorch_model.bin -> ../../blobs/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd + └── [ 128] bbc77c8132af1cc5cf678da3f1ddf2de43606d48 + ├── [ 52] README.md -> ../../blobs/7cb18dc9bafbfcf74629a4b760af1b160957a83e + └── [ 76] pytorch_model.bin -> ../../blobs/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd + ``` + + If `local_dir` is provided, the file structure from the repo will be replicated in this location. When using this + option, the `cache_dir` will not be used and a `.cache/huggingface/` folder will be created at the root of `local_dir` + to store some metadata related to the downloaded files. While this mechanism is not as robust as the main + cache-system, it's optimized for regularly pulling the latest version of a repository. + + Args: + repo_id (`str`): + A user or an organization name and a repo name separated by a `/`. + filename (`str`): + The name of the file in the repo. + subfolder (`str`, *optional*): + An optional value corresponding to a folder inside the repository. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if downloading from a dataset or space, + `None` or `"model"` if downloading from a model. Default is `None`. + revision (`str`, *optional*): + An optional Git revision id which can be a branch name, a tag, or a + commit hash. + cache_dir (`str`, `Path`, *optional*): + Path to the folder where cached files are stored. + local_dir (`str` or `Path`, *optional*): + If provided, the downloaded file will be placed under this directory. + force_download (`bool`, *optional*, defaults to `False`): + Whether the file should be downloaded even if it already exists in + the local cache. + etag_timeout (`float`, *optional*, defaults to `10`): + When fetching ETag, how many seconds to wait for the server to send + data before giving up which is passed to `httpx.request`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + local_files_only (`bool`, *optional*, defaults to `False`): + If `True`, avoid downloading the file and return the path to the + local cached file if it exists. + tqdm_class (`tqdm`, *optional*): + If provided, overwrites the default behavior for the progress bar. Passed + argument must inherit from `tqdm.auto.tqdm` or at least mimic its behavior. + Defaults to the custom HF progress bar that can be disabled by setting + `HF_HUB_DISABLE_PROGRESS_BARS` environment variable. + dry_run (`bool`, *optional*, defaults to `False`): + If `True`, perform a dry run without actually downloading the file. Returns a + [`DryRunFileInfo`] object containing information about what would be downloaded. + + Returns: + `str` or [`DryRunFileInfo`]: + - If `dry_run=False`: Local path of file or if networking is off, last version of file cached on disk. + - If `dry_run=True`: A [`DryRunFileInfo`] object containing download information. + + Raises: + [`~utils.RepositoryNotFoundError`] + If the repository to download from cannot be found. This may be because it doesn't exist, + or because it is set to `private` and you do not have access. + [`~utils.RevisionNotFoundError`] + If the revision to download from cannot be found. + [`~utils.RemoteEntryNotFoundError`] + If the file to download cannot be found. + [`~utils.LocalEntryNotFoundError`] + If network is disabled or unavailable and file is not found in cache. + [`EnvironmentError`](https://docs.python.org/3/library/exceptions.html#EnvironmentError) + If `token=True` but the token cannot be found. + [`OSError`](https://docs.python.org/3/library/exceptions.html#OSError) + If ETag cannot be determined. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If some parameter value is invalid. + """ + from .file_download import hf_hub_download + + if token is None: + # Cannot do `token = token or self.token` as token can be `False`. + token = self.token + + return hf_hub_download( + repo_id=repo_id, + filename=filename, + subfolder=subfolder, + repo_type=repo_type, + revision=revision, + endpoint=self.endpoint, + library_name=self.library_name, + library_version=self.library_version, + cache_dir=cache_dir, + local_dir=local_dir, + user_agent=self.user_agent, + force_download=force_download, + etag_timeout=etag_timeout, + token=token, + headers=self.headers, + local_files_only=local_files_only, + tqdm_class=tqdm_class, + dry_run=dry_run, + ) + + @overload + def snapshot_download( + self, + repo_id: str, + *, + repo_type: str | None = None, + revision: str | None = None, + cache_dir: str | Path | None = None, + local_dir: str | Path | None = None, + etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT, + force_download: bool = False, + token: bool | str | None = None, + local_files_only: bool = False, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + max_workers: int = 8, + tqdm_class: type[base_tqdm] | None = None, + dry_run: Literal[False] = False, + ) -> str: ... + + @overload + def snapshot_download( + self, + repo_id: str, + *, + repo_type: str | None = None, + revision: str | None = None, + cache_dir: str | Path | None = None, + local_dir: str | Path | None = None, + etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT, + force_download: bool = False, + token: bool | str | None = None, + local_files_only: bool = False, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + max_workers: int = 8, + tqdm_class: type[base_tqdm] | None = None, + dry_run: Literal[True], + ) -> list[DryRunFileInfo]: ... + + @validate_hf_hub_args + def snapshot_download( + self, + repo_id: str, + *, + repo_type: str | None = None, + revision: str | None = None, + cache_dir: str | Path | None = None, + local_dir: str | Path | None = None, + etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT, + force_download: bool = False, + token: bool | str | None = None, + local_files_only: bool = False, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + max_workers: int = 8, + tqdm_class: type[base_tqdm] | None = None, + dry_run: bool = False, + ) -> str | list[DryRunFileInfo]: + """Download repo files. + + Download a whole snapshot of a repo's files at the specified revision. This is useful when you want all files from + a repo, because you don't know which ones you will need a priori. All files are nested inside a folder in order + to keep their actual filename relative to that folder. You can also filter which files to download using + `allow_patterns` and `ignore_patterns`. + + If `local_dir` is provided, the file structure from the repo will be replicated in this location. When using this + option, the `cache_dir` will not be used and a `.cache/huggingface/` folder will be created at the root of `local_dir` + to store some metadata related to the downloaded files.While this mechanism is not as robust as the main + cache-system, it's optimized for regularly pulling the latest version of a repository. + + An alternative would be to clone the repo but this requires git and git-lfs to be installed and properly + configured. It is also not possible to filter which files to download when cloning a repository using git. + + Args: + repo_id (`str`): + A user or an organization name and a repo name separated by a `/`. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if downloading from a dataset or space, + `None` or `"model"` if downloading from a model. Default is `None`. + revision (`str`, *optional*): + An optional Git revision id which can be a branch name, a tag, or a + commit hash. + cache_dir (`str`, `Path`, *optional*): + Path to the folder where cached files are stored. + local_dir (`str` or `Path`, *optional*): + If provided, the downloaded files will be placed under this directory. + etag_timeout (`float`, *optional*, defaults to `10`): + When fetching ETag, how many seconds to wait for the server to send + data before giving up which is passed to `httpx.request`. + force_download (`bool`, *optional*, defaults to `False`): + Whether the file should be downloaded even if it already exists in the local cache. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + local_files_only (`bool`, *optional*, defaults to `False`): + If `True`, avoid downloading the file and return the path to the + local cached file if it exists. + allow_patterns (`list[str]` or `str`, *optional*): + If provided, only files matching at least one pattern are downloaded. + ignore_patterns (`list[str]` or `str`, *optional*): + If provided, files matching any of the patterns are not downloaded. + max_workers (`int`, *optional*): + Number of concurrent threads to download files (1 thread = 1 file download). + Defaults to 8. + tqdm_class (`tqdm`, *optional*): + If provided, overwrites the default behavior for the progress bar. Passed + argument must inherit from `tqdm.auto.tqdm` or at least mimic its behavior. + Note that the `tqdm_class` is not passed to each individual download. + Defaults to the custom HF progress bar that can be disabled by setting + `HF_HUB_DISABLE_PROGRESS_BARS` environment variable. + dry_run (`bool`, *optional*, defaults to `False`): + If `True`, perform a dry run without actually downloading the files. Returns a list of + [`DryRunFileInfo`] objects containing information about what would be downloaded. + + Returns: + `str` or list of [`DryRunFileInfo`]: + - If `dry_run=False`: Folder path of the repo snapshot. + - If `dry_run=True`: A list of [`DryRunFileInfo`] objects containing download information. + + Raises: + [`~utils.RepositoryNotFoundError`] + If the repository to download from cannot be found. This may be because it doesn't exist, + or because it is set to `private` and you do not have access. + [`~utils.RevisionNotFoundError`] + If the revision to download from cannot be found. + [`EnvironmentError`](https://docs.python.org/3/library/exceptions.html#EnvironmentError) + If `token=True` and the token cannot be found. + [`OSError`](https://docs.python.org/3/library/exceptions.html#OSError) if + ETag cannot be determined. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + if some parameter value is invalid. + """ + from ._snapshot_download import snapshot_download + + if token is None: + # Cannot do `token = token or self.token` as token can be `False`. + token = self.token + + return snapshot_download( + repo_id=repo_id, + repo_type=repo_type, + revision=revision, + endpoint=self.endpoint, + cache_dir=cache_dir, + local_dir=local_dir, + library_name=self.library_name, + library_version=self.library_version, + user_agent=self.user_agent, + etag_timeout=etag_timeout, + force_download=force_download, + token=token, + local_files_only=local_files_only, + allow_patterns=allow_patterns, + ignore_patterns=ignore_patterns, + max_workers=max_workers, + tqdm_class=tqdm_class, + headers=self.headers, + dry_run=dry_run, + ) + + def get_safetensors_metadata( + self, + repo_id: str, + *, + repo_type: str | None = None, + revision: str | None = None, + token: bool | str | None = None, + ) -> SafetensorsRepoMetadata: + """ + Parse metadata for a safetensors repo on the Hub. + + We first check if the repo has a single safetensors file or a sharded safetensors repo. If it's a single + safetensors file, we parse the metadata from this file. If it's a sharded safetensors repo, we parse the + metadata from the index file and then parse the metadata from each shard. + + To parse metadata from a single safetensors file, use [`parse_safetensors_file_metadata`]. + + For more details regarding the safetensors format, check out https://huggingface.co/docs/safetensors/index#format. + + Args: + repo_id (`str`): + A user or an organization name and a repo name separated by a `/`. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if the file is in a dataset or space, `None` or `"model"` if in a + model. Default is `None`. + revision (`str`, *optional*): + The git revision to fetch the file from. Can be a branch name, a tag, or a commit hash. Defaults to the + head of the `"main"` branch. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`SafetensorsRepoMetadata`]: information related to safetensors repo. + + Raises: + [`NotASafetensorsRepoError`] + If the repo is not a safetensors repo i.e. doesn't have either a + `model.safetensors` or a `model.safetensors.index.json` file. + [`SafetensorsParsingError`] + If a safetensors file header couldn't be parsed correctly. + + Example: + ```py + # Parse repo with single weights file + >>> metadata = get_safetensors_metadata("bigscience/bloomz-560m") + >>> metadata + SafetensorsRepoMetadata( + metadata=None, + sharded=False, + weight_map={'h.0.input_layernorm.bias': 'model.safetensors', ...}, + files_metadata={'model.safetensors': SafetensorsFileMetadata(...)} + ) + >>> metadata.files_metadata["model.safetensors"].metadata + {'format': 'pt'} + + # Parse repo with sharded model + >>> metadata = get_safetensors_metadata("bigscience/bloom") + Parse safetensors files: 100%|██████████████████████████████████████████| 72/72 [00:12<00:00, 5.78it/s] + >>> metadata + SafetensorsRepoMetadata(metadata={'total_size': 352494542848}, sharded=True, weight_map={...}, files_metadata={...}) + >>> len(metadata.files_metadata) + 72 # All safetensors files have been fetched + + # Parse repo with sharded model + >>> get_safetensors_metadata("runwayml/stable-diffusion-v1-5") + NotASafetensorsRepoError: 'runwayml/stable-diffusion-v1-5' is not a safetensors repo. Couldn't find 'model.safetensors.index.json' or 'model.safetensors' files. + ``` + """ + if self.file_exists( # Single safetensors file => non-sharded model + repo_id=repo_id, + filename=constants.SAFETENSORS_SINGLE_FILE, + repo_type=repo_type, + revision=revision, + token=token, + ): + file_metadata = self.parse_safetensors_file_metadata( + repo_id=repo_id, + filename=constants.SAFETENSORS_SINGLE_FILE, + repo_type=repo_type, + revision=revision, + token=token, + ) + return SafetensorsRepoMetadata( + metadata=None, + sharded=False, + weight_map={ + tensor_name: constants.SAFETENSORS_SINGLE_FILE for tensor_name in file_metadata.tensors.keys() + }, + files_metadata={constants.SAFETENSORS_SINGLE_FILE: file_metadata}, + ) + elif self.file_exists( # Multiple safetensors files => sharded with index + repo_id=repo_id, + filename=constants.SAFETENSORS_INDEX_FILE, + repo_type=repo_type, + revision=revision, + token=token, + ): + # Fetch index + index_file = self.hf_hub_download( + repo_id=repo_id, + filename=constants.SAFETENSORS_INDEX_FILE, + repo_type=repo_type, + revision=revision, + token=token, + ) + with open(index_file) as f: + index = json.load(f) + + weight_map = index.get("weight_map", {}) + + # Fetch metadata per shard + files_metadata = {} + + def _parse(filename: str) -> None: + files_metadata[filename] = self.parse_safetensors_file_metadata( + repo_id=repo_id, filename=filename, repo_type=repo_type, revision=revision, token=token + ) + + thread_map( + _parse, + set(weight_map.values()), + desc="Parse safetensors files", + tqdm_class=hf_tqdm, + ) + + return SafetensorsRepoMetadata( + metadata=index.get("metadata", None), + sharded=True, + weight_map=weight_map, + files_metadata=files_metadata, + ) + else: + # Not a safetensors repo + raise NotASafetensorsRepoError( + f"'{repo_id}' is not a safetensors repo. Couldn't find '{constants.SAFETENSORS_INDEX_FILE}' or '{constants.SAFETENSORS_SINGLE_FILE}' files." + ) + + def parse_safetensors_file_metadata( + self, + repo_id: str, + filename: str, + *, + repo_type: str | None = None, + revision: str | None = None, + token: bool | str | None = None, + ) -> SafetensorsFileMetadata: + """ + Parse metadata from a safetensors file on the Hub. + + To parse metadata from all safetensors files in a repo at once, use [`get_safetensors_metadata`]. + + For more details regarding the safetensors format, check out https://huggingface.co/docs/safetensors/index#format. + + Args: + repo_id (`str`): + A user or an organization name and a repo name separated by a `/`. + filename (`str`): + The name of the file in the repo. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if the file is in a dataset or space, `None` or `"model"` if in a + model. Default is `None`. + revision (`str`, *optional*): + The git revision to fetch the file from. Can be a branch name, a tag, or a commit hash. Defaults to the + head of the `"main"` branch. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`SafetensorsFileMetadata`]: information related to a safetensors file. + + Raises: + [`NotASafetensorsRepoError`]: + If the repo is not a safetensors repo i.e. doesn't have either a + `model.safetensors` or a `model.safetensors.index.json` file. + [`SafetensorsParsingError`]: + If a safetensors file header couldn't be parsed correctly. + """ + url = hf_hub_url( + repo_id=repo_id, filename=filename, repo_type=repo_type, revision=revision, endpoint=self.endpoint + ) + _headers = self._build_hf_headers(token=token) + + context_msg = f"repo '{repo_id}', revision '{revision or constants.DEFAULT_REVISION}'" + + # 1. Fetch first 100kb + # Empirically, 97% of safetensors files have a metadata size < 100kb (over the top 1000 models on the Hub). + # We assume fetching 100kb is faster than making 2 GET requests. Therefore we always fetch the first 100kb to + # avoid the 2nd GET in most cases. + # See https://github.com/huggingface/huggingface_hub/pull/1855#discussion_r1404286419. + response = get_session().get(url, headers={**_headers, "range": "bytes=0-100000"}) + hf_raise_for_status(response) + + # 2. Parse and validate metadata size using shared helper + metadata_size = _get_safetensors_metadata_size(response.content[:8], filename, context_msg) + + # 3.a. Get metadata from payload + if metadata_size <= 100000: + metadata_as_bytes = response.content[8 : 8 + metadata_size] + else: # 3.b. Request full metadata + response = get_session().get(url, headers={**_headers, "range": f"bytes=8-{metadata_size + 7}"}) + hf_raise_for_status(response) + metadata_as_bytes = response.content + + # 4. Parse json header using shared helper + return _parse_safetensors_header(metadata_as_bytes, filename, context_msg) + + @validate_hf_hub_args + def create_branch( + self, + repo_id: str, + *, + branch: str, + revision: str | None = None, + token: bool | str | None = None, + repo_type: str | None = None, + exist_ok: bool = False, + ) -> None: + """ + Create a new branch for a repo on the Hub, starting from the specified revision (defaults to `main`). + To find a revision suiting your needs, you can use [`list_repo_refs`] or [`list_repo_commits`]. + + Args: + repo_id (`str`): + The repository in which the branch will be created. + Example: `"user/my-cool-model"`. + + branch (`str`): + The name of the branch to create. + + revision (`str`, *optional*): + The git revision to create the branch from. It can be a branch name or + the OID/SHA of a commit, as a hexadecimal string. Defaults to the head + of the `"main"` branch. + + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if creating a branch on a dataset or + space, `None` or `"model"` if tagging a model. Default is `None`. + + exist_ok (`bool`, *optional*, defaults to `False`): + If `True`, do not raise an error if branch already exists. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If repository is not found (error 404): wrong repo_id/repo_type, private + but not authenticated or repo does not exist. + [`~utils.BadRequestError`]: + If invalid reference for a branch. Ex: `refs/pr/5` or 'refs/foo/bar'. + [`~utils.HfHubHTTPError`]: + If the branch already exists on the repo (error 409) and `exist_ok` is + set to `False`. + """ + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + branch = quote(branch, safe="") + + # Prepare request + branch_url = f"{self.endpoint}/api/{repo_type}s/{repo_id}/branch/{branch}" + headers = self._build_hf_headers(token=token) + payload = {} + if revision is not None: + payload["startingPoint"] = revision + + # Create branch + response = get_session().post(url=branch_url, headers=headers, json=payload) + try: + hf_raise_for_status(response) + except HfHubHTTPError as e: + if exist_ok and e.response.status_code == 409: + return + elif exist_ok and e.response.status_code == 403: + # No write permission on the namespace but branch might already exist + try: + refs = self.list_repo_refs(repo_id=repo_id, repo_type=repo_type, token=token) + for branch_ref in refs.branches: + if branch_ref.name == branch: + return # Branch already exists => do not raise + except HfHubHTTPError: + pass # We raise the original error if the branch does not exist + raise + + @validate_hf_hub_args + def delete_branch( + self, + repo_id: str, + *, + branch: str, + token: bool | str | None = None, + repo_type: str | None = None, + ) -> None: + """ + Delete a branch from a repo on the Hub. + + Args: + repo_id (`str`): + The repository in which a branch will be deleted. + Example: `"user/my-cool-model"`. + + branch (`str`): + The name of the branch to delete. + + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if creating a branch on a dataset or + space, `None` or `"model"` if tagging a model. Default is `None`. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If repository is not found (error 404): wrong repo_id/repo_type, private + but not authenticated or repo does not exist. + [`~utils.HfHubHTTPError`]: + If trying to delete a protected branch. Ex: `main` cannot be deleted. + [`~utils.HfHubHTTPError`]: + If trying to delete a branch that does not exist. + + """ + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + branch = quote(branch, safe="") + + # Prepare request + branch_url = f"{self.endpoint}/api/{repo_type}s/{repo_id}/branch/{branch}" + headers = self._build_hf_headers(token=token) + + # Delete branch + response = get_session().delete(url=branch_url, headers=headers) + hf_raise_for_status(response) + + @validate_hf_hub_args + def create_tag( + self, + repo_id: str, + *, + tag: str, + tag_message: str | None = None, + revision: str | None = None, + token: bool | str | None = None, + repo_type: str | None = None, + exist_ok: bool = False, + ) -> None: + """ + Tag a given commit of a repo on the Hub. + + Args: + repo_id (`str`): + The repository in which a commit will be tagged. + Example: `"user/my-cool-model"`. + + tag (`str`): + The name of the tag to create. + + tag_message (`str`, *optional*): + The description of the tag to create. + + revision (`str`, *optional*): + The git revision to tag. It can be a branch name or the OID/SHA of a + commit, as a hexadecimal string. Shorthands (7 first characters) are + also supported. Defaults to the head of the `"main"` branch. + + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if tagging a dataset or + space, `None` or `"model"` if tagging a model. Default is + `None`. + + exist_ok (`bool`, *optional*, defaults to `False`): + If `True`, do not raise an error if tag already exists. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If repository is not found (error 404): wrong repo_id/repo_type, private + but not authenticated or repo does not exist. + [`~utils.RevisionNotFoundError`]: + If revision is not found (error 404) on the repo. + [`~utils.HfHubHTTPError`]: + If the branch already exists on the repo (error 409) and `exist_ok` is + set to `False`. + """ + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + revision = quote(revision, safe="") if revision is not None else constants.DEFAULT_REVISION + + # Prepare request + tag_url = f"{self.endpoint}/api/{repo_type}s/{repo_id}/tag/{revision}" + headers = self._build_hf_headers(token=token) + payload = {"tag": tag} + if tag_message is not None: + payload["message"] = tag_message + + # Tag + response = get_session().post(url=tag_url, headers=headers, json=payload) + try: + hf_raise_for_status(response) + except HfHubHTTPError as e: + if not (e.response.status_code == 409 and exist_ok): + raise + + @validate_hf_hub_args + def delete_tag( + self, + repo_id: str, + *, + tag: str, + token: bool | str | None = None, + repo_type: str | None = None, + ) -> None: + """ + Delete a tag from a repo on the Hub. + + Args: + repo_id (`str`): + The repository in which a tag will be deleted. + Example: `"user/my-cool-model"`. + + tag (`str`): + The name of the tag to delete. + + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if tagging a dataset or space, `None` or + `"model"` if tagging a model. Default is `None`. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If repository is not found (error 404): wrong repo_id/repo_type, private + but not authenticated or repo does not exist. + [`~utils.RevisionNotFoundError`]: + If tag is not found. + """ + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + tag = quote(tag, safe="") + + # Prepare request + tag_url = f"{self.endpoint}/api/{repo_type}s/{repo_id}/tag/{tag}" + headers = self._build_hf_headers(token=token) + + # Un-tag + response = get_session().delete(url=tag_url, headers=headers) + hf_raise_for_status(response) + + @validate_hf_hub_args + def get_full_repo_name( + self, + model_id: str, + *, + organization: str | None = None, + token: bool | str | None = None, + ): + """ + Returns the repository name for a given model ID and optional + organization. + + Args: + model_id (`str`): + The name of the model. + organization (`str`, *optional*): + If passed, the repository name will be in the organization + namespace instead of the user namespace. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `str`: The repository name in the user's namespace + ({username}/{model_id}) if no organization is passed, and under the + organization namespace ({organization}/{model_id}) otherwise. + """ + if organization is None: + if "/" in model_id: + username = model_id.split("/")[0] + else: + username = self.whoami(token=token)["name"] # type: ignore + return f"{username}/{model_id}" + else: + return f"{organization}/{model_id}" + + @validate_hf_hub_args + def get_repo_discussions( + self, + repo_id: str, + *, + author: str | None = None, + discussion_type: constants.DiscussionTypeFilter | None = None, + discussion_status: constants.DiscussionStatusFilter | None = None, + repo_type: str | None = None, + token: bool | str | None = None, + ) -> Iterator[Discussion]: + """ + Fetches Discussions and Pull Requests for the given repo. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + author (`str`, *optional*): + Pass a value to filter by discussion author. `None` means no filter. + Default is `None`. + discussion_type (`str`, *optional*): + Set to `"pull_request"` to fetch only pull requests, `"discussion"` + to fetch only discussions. Set to `"all"` or `None` to fetch both. + Default is `None`. + discussion_status (`str`, *optional*): + Set to `"open"` (respectively `"closed"`) to fetch only open + (respectively closed) discussions. Set to `"all"` or `None` + to fetch both. + Default is `None`. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if fetching from a dataset or + space, `None` or `"model"` if fetching from a model. Default is + `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterator[Discussion]`: An iterator of [`Discussion`] objects. + + Example: + Collecting all discussions of a repo in a list: + + ```python + >>> from huggingface_hub import get_repo_discussions + >>> discussions_list = list(get_repo_discussions(repo_id="bert-base-uncased")) + ``` + + Iterating over discussions of a repo: + + ```python + >>> from huggingface_hub import get_repo_discussions + >>> for discussion in get_repo_discussions(repo_id="bert-base-uncased"): + ... print(discussion.num, discussion.title) + ``` + """ + if repo_type not in constants.REPO_TYPES: + raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}") + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + if discussion_type is not None and discussion_type not in constants.DISCUSSION_TYPES: + raise ValueError(f"Invalid discussion_type, must be one of {constants.DISCUSSION_TYPES}") + if discussion_status is not None and discussion_status not in constants.DISCUSSION_STATUS: + raise ValueError(f"Invalid discussion_status, must be one of {constants.DISCUSSION_STATUS}") + + headers = self._build_hf_headers(token=token) + path = f"{self.endpoint}/api/{repo_type}s/{repo_id}/discussions" + + params: dict[str, str | int] = {} + if discussion_type is not None: + params["type"] = discussion_type + if discussion_status is not None: + params["status"] = discussion_status + if author is not None: + params["author"] = author + + def _fetch_discussion_page(page_index: int): + params["p"] = page_index + resp = get_session().get(path, headers=headers, params=params) + hf_raise_for_status(resp) + paginated_discussions = resp.json() + total = paginated_discussions["count"] + start = paginated_discussions["start"] + discussions = paginated_discussions["discussions"] + has_next = (start + len(discussions)) < total + return discussions, has_next + + has_next, page_index = True, 0 + + while has_next: + discussions, has_next = _fetch_discussion_page(page_index=page_index) + for discussion in discussions: + yield Discussion( + title=discussion["title"], + num=discussion["num"], + author=discussion.get("author", {}).get("name", "deleted"), + created_at=parse_datetime(discussion["createdAt"]), + status=discussion["status"], + repo_id=discussion["repo"]["name"], + repo_type=discussion["repo"]["type"], + is_pull_request=discussion["isPullRequest"], + endpoint=self.endpoint, + ) + page_index = page_index + 1 + + @validate_hf_hub_args + def get_discussion_details( + self, + repo_id: str, + discussion_num: int, + *, + repo_type: str | None = None, + token: bool | str | None = None, + ) -> DiscussionWithDetails: + """Fetches a Discussion's / Pull Request 's details from the Hub. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + discussion_num (`int`): + The number of the Discussion or Pull Request . Must be a strictly positive integer. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. Default is + `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: [`DiscussionWithDetails`] + + > [!TIP] + > Raises the following errors: + > + > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError) + > if the HuggingFace API returned an error + > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > if some parameter value is invalid + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access. + """ + if not isinstance(discussion_num, int) or discussion_num <= 0: + raise ValueError("Invalid discussion_num, must be a positive integer") + if repo_type not in constants.REPO_TYPES: + raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}") + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + + path = f"{self.endpoint}/api/{repo_type}s/{repo_id}/discussions/{discussion_num}" + headers = self._build_hf_headers(token=token) + resp = get_session().get(path, params={"diff": "1"}, headers=headers) + hf_raise_for_status(resp) + + discussion_details = resp.json() + is_pull_request = discussion_details["isPullRequest"] + + target_branch = discussion_details["changes"]["base"] if is_pull_request else None + conflicting_files = discussion_details["filesWithConflicts"] if is_pull_request else None + merge_commit_oid = discussion_details["changes"].get("mergeCommitId", None) if is_pull_request else None + + return DiscussionWithDetails( + title=discussion_details["title"], + num=discussion_details["num"], + author=discussion_details.get("author", {}).get("name", "deleted"), + created_at=parse_datetime(discussion_details["createdAt"]), + status=discussion_details["status"], + repo_id=discussion_details["repo"]["name"], + repo_type=discussion_details["repo"]["type"], + is_pull_request=discussion_details["isPullRequest"], + events=[deserialize_event(evt) for evt in discussion_details["events"]], + conflicting_files=conflicting_files, + target_branch=target_branch, + merge_commit_oid=merge_commit_oid, + diff=discussion_details.get("diff"), + endpoint=self.endpoint, + ) + + @validate_hf_hub_args + def create_discussion( + self, + repo_id: str, + title: str, + *, + token: bool | str | None = None, + description: str | None = None, + repo_type: str | None = None, + pull_request: bool = False, + ) -> DiscussionWithDetails: + """Creates a Discussion or Pull Request. + + Pull Requests created programmatically will be in `"draft"` status. + + Creating a Pull Request with changes can also be done at once with [`HfApi.create_commit`]. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + title (`str`): + The title of the discussion. It can be up to 200 characters long, + and must be at least 3 characters long. Leading and trailing whitespaces + will be stripped. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + description (`str`, *optional*): + An optional description for the Pull Request. + Defaults to `"Discussion opened with the huggingface_hub Python library"` + pull_request (`bool`, *optional*): + Whether to create a Pull Request or discussion. If `True`, creates a Pull Request. + If `False`, creates a discussion. Defaults to `False`. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. Default is + `None`. + + Returns: [`DiscussionWithDetails`] + + > [!TIP] + > Raises the following errors: + > + > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError) + > if the HuggingFace API returned an error + > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > if some parameter value is invalid + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access.""" + if repo_type not in constants.REPO_TYPES: + raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}") + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + + if description is not None: + description = description.strip() + description = ( + description + if description + else ( + f"{'Pull Request' if pull_request else 'Discussion'} opened with the" + " [huggingface_hub Python" + " library](https://huggingface.co/docs/huggingface_hub)" + ) + ) + + headers = self._build_hf_headers(token=token) + resp = get_session().post( + f"{self.endpoint}/api/{repo_type}s/{repo_id}/discussions", + json={ + "title": title.strip(), + "description": description, + "pullRequest": pull_request, + }, + headers=headers, + ) + hf_raise_for_status(resp) + num = resp.json()["num"] + return self.get_discussion_details( + repo_id=repo_id, + repo_type=repo_type, + discussion_num=num, + token=token, + ) + + @validate_hf_hub_args + def create_pull_request( + self, + repo_id: str, + title: str, + *, + token: bool | str | None = None, + description: str | None = None, + repo_type: str | None = None, + ) -> DiscussionWithDetails: + """Creates a Pull Request . Pull Requests created programmatically will be in `"draft"` status. + + Creating a Pull Request with changes can also be done at once with [`HfApi.create_commit`]; + + This is a wrapper around [`HfApi.create_discussion`]. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + title (`str`): + The title of the discussion. It can be up to 200 characters long, + and must be at least 3 characters long. Leading and trailing whitespaces + will be stripped. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + description (`str`, *optional*): + An optional description for the Pull Request. + Defaults to `"Discussion opened with the huggingface_hub Python library"` + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. Default is + `None`. + + Returns: [`DiscussionWithDetails`] + + > [!TIP] + > Raises the following errors: + > + > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError) + > if the HuggingFace API returned an error + > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > if some parameter value is invalid + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access.""" + return self.create_discussion( + repo_id=repo_id, + title=title, + token=token, + description=description, + repo_type=repo_type, + pull_request=True, + ) + + def _post_discussion_changes( + self, + *, + repo_id: str, + discussion_num: int, + resource: str, + body: dict | None = None, + token: bool | str | None = None, + repo_type: str | None = None, + ) -> httpx.Response: + """Internal utility to POST changes to a Discussion or Pull Request""" + if not isinstance(discussion_num, int) or discussion_num <= 0: + raise ValueError("Invalid discussion_num, must be a positive integer") + if repo_type not in constants.REPO_TYPES: + raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}") + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + repo_id = f"{repo_type}s/{repo_id}" + + path = f"{self.endpoint}/api/{repo_id}/discussions/{discussion_num}/{resource}" + + headers = self._build_hf_headers(token=token) + resp = get_session().post(path, headers=headers, json=body) + hf_raise_for_status(resp) + return resp + + @validate_hf_hub_args + def comment_discussion( + self, + repo_id: str, + discussion_num: int, + comment: str, + *, + token: bool | str | None = None, + repo_type: str | None = None, + ) -> DiscussionComment: + """Creates a new comment on the given Discussion. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + discussion_num (`int`): + The number of the Discussion or Pull Request . Must be a strictly positive integer. + comment (`str`): + The content of the comment to create. Comments support markdown formatting. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. Default is + `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`DiscussionComment`]: the newly created comment + + + Examples: + ```python + + >>> comment = \"\"\" + ... Hello @otheruser! + ... + ... # This is a title + ... + ... **This is bold**, *this is italic* and ~this is strikethrough~ + ... And [this](http://url) is a link + ... \"\"\" + + >>> HfApi().comment_discussion( + ... repo_id="username/repo_name", + ... discussion_num=34 + ... comment=comment + ... ) + # DiscussionComment(id='deadbeef0000000', type='comment', ...) + + ``` + + > [!TIP] + > Raises the following errors: + > + > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError) + > if the HuggingFace API returned an error + > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > if some parameter value is invalid + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access. + """ + resp = self._post_discussion_changes( + repo_id=repo_id, + repo_type=repo_type, + discussion_num=discussion_num, + token=token, + resource="comment", + body={"comment": comment}, + ) + return deserialize_event(resp.json()["newMessage"]) # type: ignore + + @validate_hf_hub_args + def rename_discussion( + self, + repo_id: str, + discussion_num: int, + new_title: str, + *, + token: bool | str | None = None, + repo_type: str | None = None, + ) -> DiscussionTitleChange: + """Renames a Discussion. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + discussion_num (`int`): + The number of the Discussion or Pull Request . Must be a strictly positive integer. + new_title (`str`): + The new title for the discussion + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. Default is + `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`DiscussionTitleChange`]: the title change event + + + Examples: + ```python + >>> new_title = "New title, fixing a typo" + >>> HfApi().rename_discussion( + ... repo_id="username/repo_name", + ... discussion_num=34 + ... new_title=new_title + ... ) + # DiscussionTitleChange(id='deadbeef0000000', type='title-change', ...) + + ``` + + > [!TIP] + > Raises the following errors: + > + > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError) + > if the HuggingFace API returned an error + > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > if some parameter value is invalid + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access. + """ + resp = self._post_discussion_changes( + repo_id=repo_id, + repo_type=repo_type, + discussion_num=discussion_num, + token=token, + resource="title", + body={"title": new_title}, + ) + return deserialize_event(resp.json()["newTitle"]) # type: ignore + + @validate_hf_hub_args + def change_discussion_status( + self, + repo_id: str, + discussion_num: int, + new_status: Literal["open", "closed"], + *, + token: bool | str | None = None, + comment: str | None = None, + repo_type: str | None = None, + ) -> DiscussionStatusChange: + """Closes or re-opens a Discussion or Pull Request. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + discussion_num (`int`): + The number of the Discussion or Pull Request . Must be a strictly positive integer. + new_status (`str`): + The new status for the discussion, either `"open"` or `"closed"`. + comment (`str`, *optional*): + An optional comment to post with the status change. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. Default is + `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`DiscussionStatusChange`]: the status change event + + + Examples: + ```python + >>> new_title = "New title, fixing a typo" + >>> HfApi().rename_discussion( + ... repo_id="username/repo_name", + ... discussion_num=34 + ... new_title=new_title + ... ) + # DiscussionStatusChange(id='deadbeef0000000', type='status-change', ...) + + ``` + + > [!TIP] + > Raises the following errors: + > + > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError) + > if the HuggingFace API returned an error + > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > if some parameter value is invalid + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access. + """ + if new_status not in ["open", "closed"]: + raise ValueError("Invalid status, valid statuses are: 'open' and 'closed'") + body: dict[str, str] = {"status": new_status} + if comment and comment.strip(): + body["comment"] = comment.strip() + resp = self._post_discussion_changes( + repo_id=repo_id, + repo_type=repo_type, + discussion_num=discussion_num, + token=token, + resource="status", + body=body, + ) + return deserialize_event(resp.json()["newStatus"]) # type: ignore + + @validate_hf_hub_args + def merge_pull_request( + self, + repo_id: str, + discussion_num: int, + *, + token: bool | str | None = None, + comment: str | None = None, + repo_type: str | None = None, + ): + """Merges a Pull Request. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + discussion_num (`int`): + The number of the Discussion or Pull Request . Must be a strictly positive integer. + comment (`str`, *optional*): + An optional comment to post with the status change. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. Default is + `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`DiscussionStatusChange`]: the status change event + + > [!TIP] + > Raises the following errors: + > + > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError) + > if the HuggingFace API returned an error + > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > if some parameter value is invalid + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access. + """ + self._post_discussion_changes( + repo_id=repo_id, + repo_type=repo_type, + discussion_num=discussion_num, + token=token, + resource="merge", + body={"comment": comment.strip()} if comment and comment.strip() else None, + ) + + @validate_hf_hub_args + def edit_discussion_comment( + self, + repo_id: str, + discussion_num: int, + comment_id: str, + new_content: str, + *, + token: bool | str | None = None, + repo_type: str | None = None, + ) -> DiscussionComment: + """Edits a comment on a Discussion / Pull Request. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + discussion_num (`int`): + The number of the Discussion or Pull Request . Must be a strictly positive integer. + comment_id (`str`): + The ID of the comment to edit. + new_content (`str`): + The new content of the comment. Comments support markdown formatting. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. Default is + `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`DiscussionComment`]: the edited comment + + > [!TIP] + > Raises the following errors: + > + > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError) + > if the HuggingFace API returned an error + > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > if some parameter value is invalid + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access. + """ + resp = self._post_discussion_changes( + repo_id=repo_id, + repo_type=repo_type, + discussion_num=discussion_num, + token=token, + resource=f"comment/{comment_id.lower()}/edit", + body={"content": new_content}, + ) + return deserialize_event(resp.json()["updatedComment"]) # type: ignore + + @validate_hf_hub_args + def hide_discussion_comment( + self, + repo_id: str, + discussion_num: int, + comment_id: str, + *, + token: bool | str | None = None, + repo_type: str | None = None, + ) -> DiscussionComment: + """Hides a comment on a Discussion / Pull Request. + + > [!WARNING] + > Hidden comments' content cannot be retrieved anymore. Hiding a comment is irreversible. + + Args: + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + discussion_num (`int`): + The number of the Discussion or Pull Request . Must be a strictly positive integer. + comment_id (`str`): + The ID of the comment to edit. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if uploading to a dataset or + space, `None` or `"model"` if uploading to a model. Default is + `None`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`DiscussionComment`]: the hidden comment + + > [!TIP] + > Raises the following errors: + > + > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError) + > if the HuggingFace API returned an error + > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > if some parameter value is invalid + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it doesn't exist, + > or because it is set to `private` and you do not have access. + """ + warnings.warn( + "Hidden comments' content cannot be retrieved anymore. Hiding a comment is irreversible.", + UserWarning, + ) + resp = self._post_discussion_changes( + repo_id=repo_id, + repo_type=repo_type, + discussion_num=discussion_num, + token=token, + resource=f"comment/{comment_id.lower()}/hide", + ) + return deserialize_event(resp.json()["updatedComment"]) # type: ignore + + @validate_hf_hub_args + def add_space_secret( + self, + repo_id: str, + key: str, + value: str, + *, + description: str | None = None, + token: bool | str | None = None, + ) -> None: + """Adds or updates a secret in a Space. + + Secrets allow to set secret keys or tokens to a Space without hardcoding them. + For more details, see https://huggingface.co/docs/hub/spaces-overview#managing-secrets. + + Args: + repo_id (`str`): + ID of the repo to update. Example: `"bigcode/in-the-stack"`. + key (`str`): + Secret key. Example: `"GITHUB_API_KEY"` + value (`str`): + Secret value. Example: `"your_github_api_key"`. + description (`str`, *optional*): + Secret description. Example: `"Github API key to access the Github API"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + """ + payload = {"key": key, "value": value} + if description is not None: + payload["description"] = description + r = get_session().post( + f"{self.endpoint}/api/spaces/{repo_id}/secrets", + headers=self._build_hf_headers(token=token), + json=payload, + ) + hf_raise_for_status(r) + + @validate_hf_hub_args + def delete_space_secret(self, repo_id: str, key: str, *, token: bool | str | None = None) -> None: + """Deletes a secret from a Space. + + Secrets allow to set secret keys or tokens to a Space without hardcoding them. + For more details, see https://huggingface.co/docs/hub/spaces-overview#managing-secrets. + + Args: + repo_id (`str`): + ID of the repo to update. Example: `"bigcode/in-the-stack"`. + key (`str`): + Secret key. Example: `"GITHUB_API_KEY"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + """ + r = get_session().request( + "DELETE", + f"{self.endpoint}/api/spaces/{repo_id}/secrets", + headers=self._build_hf_headers(token=token), + json={"key": key}, + ) + hf_raise_for_status(r) + + @validate_hf_hub_args + def get_space_secrets(self, repo_id: str, *, token: bool | str | None = None) -> dict[str, SpaceSecret]: + """Gets all secrets from a Space. + + Secret values are write-only and cannot be read back. Only the key, description, and last update time + are returned. + + Secrets allow to set secret keys or tokens to a Space without hardcoding them. + For more details, see https://huggingface.co/docs/hub/spaces-overview#managing-secrets. + + Args: + repo_id (`str`): + ID of the repo to query. Example: `"bigcode/in-the-stack"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `dict[str, SpaceSecret]`: Dictionary of [`SpaceSecret`] objects keyed by secret name. + + Example: + ```python + >>> from huggingface_hub import HfApi + >>> api = HfApi() + >>> api.get_space_secrets("username/my-space") + {'HF_TOKEN': SpaceSecret(key='HF_TOKEN', description='...', updated_at=datetime.datetime(...))} + ``` + """ + r = get_session().get( + f"{self.endpoint}/api/spaces/{repo_id}/secrets", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(r) + return {k: SpaceSecret(k, v) for k, v in r.json().items()} + + @validate_hf_hub_args + def get_space_variables(self, repo_id: str, *, token: bool | str | None = None) -> dict[str, SpaceVariable]: + """Gets all variables from a Space. + + Variables allow to set environment variables to a Space without hardcoding them. + For more details, see https://huggingface.co/docs/hub/spaces-overview#managing-secrets-and-environment-variables + + Args: + repo_id (`str`): + ID of the repo to query. Example: `"bigcode/in-the-stack"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + """ + r = get_session().get( + f"{self.endpoint}/api/spaces/{repo_id}/variables", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(r) + return {k: SpaceVariable(k, v) for k, v in r.json().items()} + + @validate_hf_hub_args + def add_space_variable( + self, + repo_id: str, + key: str, + value: str, + *, + description: str | None = None, + token: bool | str | None = None, + ) -> dict[str, SpaceVariable]: + """Adds or updates a variable in a Space. + + Variables allow to set environment variables to a Space without hardcoding them. + For more details, see https://huggingface.co/docs/hub/spaces-overview#managing-secrets-and-environment-variables + + Args: + repo_id (`str`): + ID of the repo to update. Example: `"bigcode/in-the-stack"`. + key (`str`): + Variable key. Example: `"MODEL_REPO_ID"` + value (`str`): + Variable value. Example: `"the_model_repo_id"`. + description (`str`): + Description of the variable. Example: `"Model Repo ID of the implemented model"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + """ + payload = {"key": key, "value": value} + if description is not None: + payload["description"] = description + r = get_session().post( + f"{self.endpoint}/api/spaces/{repo_id}/variables", + headers=self._build_hf_headers(token=token), + json=payload, + ) + hf_raise_for_status(r) + return {k: SpaceVariable(k, v) for k, v in r.json().items()} + + @validate_hf_hub_args + def delete_space_variable( + self, repo_id: str, key: str, *, token: bool | str | None = None + ) -> dict[str, SpaceVariable]: + """Deletes a variable from a Space. + + Variables allow to set environment variables to a Space without hardcoding them. + For more details, see https://huggingface.co/docs/hub/spaces-overview#managing-secrets-and-environment-variables + + Args: + repo_id (`str`): + ID of the repo to update. Example: `"bigcode/in-the-stack"`. + key (`str`): + Variable key. Example: `"MODEL_REPO_ID"` + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + """ + r = get_session().request( + "DELETE", + f"{self.endpoint}/api/spaces/{repo_id}/variables", + headers=self._build_hf_headers(token=token), + json={"key": key}, + ) + hf_raise_for_status(r) + return {k: SpaceVariable(k, v) for k, v in r.json().items()} + + @validate_hf_hub_args + def get_space_runtime(self, repo_id: str, *, token: bool | str | None = None) -> SpaceRuntime: + """Gets runtime information about a Space. + + Args: + repo_id (`str`): + ID of the repo to update. Example: `"bigcode/in-the-stack"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + Returns: + [`SpaceRuntime`]: Runtime information about a Space including Space stage and hardware. + """ + r = get_session().get( + f"{self.endpoint}/api/spaces/{repo_id}/runtime", headers=self._build_hf_headers(token=token) + ) + hf_raise_for_status(r) + return SpaceRuntime(r.json()) + + def list_spaces_hardware(self, token: bool | str | None = None) -> list[JobHardwareInfo]: + """List available hardware options for Spaces. + + Returns: + `list[JobHardwareInfo]`: A list of available hardware configurations. + + Example: + + ```python + >>> from huggingface_hub import list_spaces_hardware + >>> hardware_list = list_spaces_hardware() + >>> hardware_list[0] + JobHardwareInfo(name='cpu-basic', pretty_name='CPU Basic', cpu='2 vCPU', ram='16 GB', ...) + >>> hardware_list[0].name + 'cpu-basic' + ``` + """ + response = get_session().get( + f"{self.endpoint}/api/spaces/hardware", headers=self._build_hf_headers(token=token) + ) + hf_raise_for_status(response) + return [JobHardwareInfo(**hardware) for hardware in response.json()] + + @validate_hf_hub_args + def request_space_hardware( + self, + repo_id: str, + hardware: SpaceHardware, + *, + token: bool | str | None = None, + sleep_time: int | None = None, + ) -> SpaceRuntime: + """Request new hardware for a Space. + + Args: + repo_id (`str`): + ID of the repo to update. Example: `"bigcode/in-the-stack"`. + hardware (`str` or [`SpaceHardware`]): + Hardware on which to run the Space. Example: `"t4-medium"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + sleep_time (`int`, *optional*): + Number of seconds of inactivity to wait before a Space is put to sleep. Set to `-1` if you don't want + your Space to sleep (default behavior for upgraded hardware). For free hardware, you can't configure + the sleep time (value is fixed to 48 hours of inactivity). + See https://huggingface.co/docs/hub/spaces-gpus#sleep-time for more details. + Returns: + [`SpaceRuntime`]: Runtime information about a Space including Space stage and hardware. + + > [!TIP] + > It is also possible to request hardware directly when creating the Space repo! See [`create_repo`] for details. + """ + if sleep_time is not None and hardware == SpaceHardware.CPU_BASIC: + warnings.warn( + "If your Space runs on the default 'cpu-basic' hardware, it will go to sleep if inactive for more" + " than 48 hours. This value is not configurable. If you don't want your Space to deactivate or if" + " you want to set a custom sleep time, you need to upgrade to a paid Hardware.", + UserWarning, + ) + payload: dict[str, Any] = {"flavor": hardware} + if sleep_time is not None: + payload["sleepTimeSeconds"] = sleep_time + r = get_session().post( + f"{self.endpoint}/api/spaces/{repo_id}/hardware", + headers=self._build_hf_headers(token=token), + json=payload, + ) + hf_raise_for_status(r) + return SpaceRuntime(r.json()) + + @validate_hf_hub_args + def set_space_sleep_time(self, repo_id: str, sleep_time: int, *, token: bool | str | None = None) -> SpaceRuntime: + """Set a custom sleep time for a Space running on upgraded hardware.. + + Your Space will go to sleep after X seconds of inactivity. You are not billed when your Space is in "sleep" + mode. If a new visitor lands on your Space, it will "wake it up". Only upgraded hardware can have a + configurable sleep time. To know more about the sleep stage, please refer to + https://huggingface.co/docs/hub/spaces-gpus#sleep-time. + + Args: + repo_id (`str`): + ID of the repo to update. Example: `"bigcode/in-the-stack"`. + sleep_time (`int`, *optional*): + Number of seconds of inactivity to wait before a Space is put to sleep. Set to `-1` if you don't want + your Space to pause (default behavior for upgraded hardware). For free hardware, you can't configure + the sleep time (value is fixed to 48 hours of inactivity). + See https://huggingface.co/docs/hub/spaces-gpus#sleep-time for more details. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + Returns: + [`SpaceRuntime`]: Runtime information about a Space including Space stage and hardware. + + > [!TIP] + > It is also possible to set a custom sleep time when requesting hardware with [`request_space_hardware`]. + """ + r = get_session().post( + f"{self.endpoint}/api/spaces/{repo_id}/sleeptime", + headers=self._build_hf_headers(token=token), + json={"seconds": sleep_time}, + ) + hf_raise_for_status(r) + runtime = SpaceRuntime(r.json()) + + hardware = runtime.requested_hardware or runtime.hardware + if hardware == SpaceHardware.CPU_BASIC: + warnings.warn( + "If your Space runs on the default 'cpu-basic' hardware, it will go to sleep if inactive for more" + " than 48 hours. This value is not configurable. If you don't want your Space to deactivate or if" + " you want to set a custom sleep time, you need to upgrade to a paid Hardware.", + UserWarning, + ) + return runtime + + @validate_hf_hub_args + def pause_space(self, repo_id: str, *, token: bool | str | None = None) -> SpaceRuntime: + """Pause your Space. + + A paused Space stops executing until manually restarted by its owner. This is different from the sleeping + state in which free Spaces go after 48h of inactivity. Paused time is not billed to your account, no matter the + hardware you've selected. To restart your Space, use [`restart_space`] and go to your Space settings page. + + For more details, please visit [the docs](https://huggingface.co/docs/hub/spaces-gpus#pause). + + Args: + repo_id (`str`): + ID of the Space to pause. Example: `"Salesforce/BLIP2"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`SpaceRuntime`]: Runtime information about your Space including `stage=PAUSED` and requested hardware. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If your Space is not found (error 404). Most probably wrong repo_id or your space is private but you + are not authenticated. + [`~utils.HfHubHTTPError`]: + 403 Forbidden: only the owner of a Space can pause it. If you want to manage a Space that you don't + own, either ask the owner by opening a Discussion or duplicate the Space. + [`~utils.BadRequestError`]: + If your Space is a static Space. Static Spaces are always running and never billed. If you want to hide + a static Space, you can set it to private. + """ + r = get_session().post( + f"{self.endpoint}/api/spaces/{repo_id}/pause", headers=self._build_hf_headers(token=token) + ) + hf_raise_for_status(r) + return SpaceRuntime(r.json()) + + @validate_hf_hub_args + def enable_space_dev_mode(self, repo_id: str, *, token: bool | str | None = None) -> SpaceRuntime: + """Enable dev mode on a Space. + + Spaces Dev Mode eases the debugging of your application and makes iterating on Spaces faster by allowing you + to restart your application without stopping the Space container itself. This feature is available as part of + a PRO or Team & Enterprise plan. See https://huggingface.co/docs/hub/spaces-dev-mode for more details. + + Args: + repo_id (`str`): + ID of the Space to enable dev mode. Example: `"Salesforce/BLIP2"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`SpaceRuntime`]: Runtime information about your Space. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If your Space is not found (error 404). Most probably wrong repo_id or your space is private but you + are not authenticated. + [`~utils.HfHubHTTPError`]: + 403 Forbidden: only the owner of a Space can set dev mode. If you want to handle a Space that you don't + own, either ask the owner by opening a Discussion or duplicate the Space. + [`~utils.BadRequestError`]: + If your Space is a static Space. Static Spaces are always running and never billed. If you want to hide + a static Space, you can set it to private. + """ + r = get_session().post( + f"{self.endpoint}/api/spaces/{repo_id}/dev-mode", + headers=self._build_hf_headers(token=token), + json={"enabled": True}, + ) + hf_raise_for_status(r) + return SpaceRuntime(r.json()) + + @validate_hf_hub_args + def disable_space_dev_mode( + self, + repo_id: str, + *, + token: bool | str | None = None, + ) -> SpaceRuntime: + """Disable dev mode on a Space. + + Spaces Dev Mode eases the debugging of your application and makes iterating on Spaces faster by allowing you + to restart your application without stopping the Space container itself. This feature is available as part of + a PRO or Team & Enterprise plan. See https://huggingface.co/docs/hub/spaces-dev-mode for more details. + + Args: + repo_id (`str`): + ID of the Space to disable dev mode. Example: `"Salesforce/BLIP2"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`SpaceRuntime`]: Runtime information about your Space. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If your Space is not found (error 404). Most probably wrong repo_id or your space is private but you + are not authenticated. + [`~utils.HfHubHTTPError`]: + 403 Forbidden: only the owner of a Space can set dev mode. If you want to handle a Space that you don't + own, either ask the owner by opening a Discussion or duplicate the Space. + [`~utils.BadRequestError`]: + If your Space is a static Space. Static Spaces are always running and never billed. If you want to hide + a static Space, you can set it to private. + """ + r = get_session().post( + f"{self.endpoint}/api/spaces/{repo_id}/dev-mode", + headers=self._build_hf_headers(token=token), + json={"enabled": False}, + ) + hf_raise_for_status(r) + return SpaceRuntime(r.json()) + + @validate_hf_hub_args + def restart_space( + self, repo_id: str, *, token: bool | str | None = None, factory_reboot: bool = False + ) -> SpaceRuntime: + """Restart your Space. + + This is the only way to programmatically restart a Space if you've put it on Pause (see [`pause_space`]). You + must be the owner of the Space to restart it. If you are using an upgraded hardware, your account will be + billed as soon as the Space is restarted. You can trigger a restart no matter the current state of a Space. + + For more details, please visit [the docs](https://huggingface.co/docs/hub/spaces-gpus#pause). + + Args: + repo_id (`str`): + ID of the Space to restart. Example: `"Salesforce/BLIP2"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + factory_reboot (`bool`, *optional*): + If `True`, the Space will be rebuilt from scratch without caching any requirements. + + Returns: + [`SpaceRuntime`]: Runtime information about your Space. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If your Space is not found (error 404). Most probably wrong repo_id or your space is private but you + are not authenticated. + [`~utils.HfHubHTTPError`]: + 403 Forbidden: only the owner of a Space can restart it. If you want to restart a Space that you don't + own, either ask the owner by opening a Discussion or duplicate the Space. + [`~utils.BadRequestError`]: + If your Space is a static Space. Static Spaces are always running and never billed. If you want to hide + a static Space, you can set it to private. + """ + params = {} + if factory_reboot: + params["factory"] = "true" + r = get_session().post( + f"{self.endpoint}/api/spaces/{repo_id}/restart", headers=self._build_hf_headers(token=token), params=params + ) + hf_raise_for_status(r) + return SpaceRuntime(r.json()) + + def _stream_sse_events( + self, + *, + url: str, + log_label: str, + timeout: int, + follow: bool, + token: bool | str | None = None, + skip_previous_events_on_retry: bool = True, + tolerated_status_codes: tuple[int, ...] = (), + tolerated_exception_types: tuple[type[Exception], ...] = (), + on_iteration_end: Callable[[], bool] | None = None, + params: dict[str, Any] | None = None, + ) -> Iterable[dict[str, Any]]: + # Shared SSE streaming loop with retry/backoff and event-index dedup. + # Used by Spaces logs and Jobs logs/metrics. Two retry styles: + # - on_iteration_end is None: retries are the only backstop (Spaces). + # - on_iteration_end is set: it polls authoritative state after every + # failed iteration; ReadTimeouts/tolerated errors fall through to it + # instead of consuming retries (Jobs). + nb_tries = 0 + max_retries = 5 if follow else 0 + min_wait_time = 1 + max_wait_time = 10 + sleep_time = 0 + start_event_idx = 0 + error_to_retry: Exception | None = None + while True: + if error_to_retry is not None: + logger.warning(f"'{error_to_retry}' thrown while requesting {log_label}") + logger.warning(f"Retrying in {sleep_time}s [Retry {nb_tries}/{max_retries}].") + error_to_retry = None + time.sleep(sleep_time) + try: + with get_session().stream( + "GET", + url, + headers=self._build_hf_headers(token=token), + timeout=timeout, + params=params, + ) as response: + if response.status_code == 200: + event_idx = -1 + for line in response.iter_lines(): + if line and line.startswith("data: {"): + event_idx += 1 + if event_idx >= start_event_idx: + if skip_previous_events_on_retry: + start_event_idx += 1 + yield json.loads(line[len("data: ") :]) + break + elif response.status_code not in tolerated_status_codes: + hf_raise_for_status(response) + except HfHubHTTPError: + # Permanent HTTP error (404/403/...). Never retry — fail fast. + raise + except httpx.DecodingError: + # Response ended prematurely. + break + except KeyboardInterrupt: + break + except (httpx.HTTPError, httpcore.TimeoutException) as err: + is_no_new_line_timeout = isinstance(err, (httpx.ReadTimeout, httpcore.ReadTimeout)) + if is_no_new_line_timeout and not follow: + break # no-follow: timeout means the buffer is drained + if on_iteration_end is not None: + # Authoritative-state mode: ReadTimeouts and tolerated errors + # fall through to the post-iteration check without consuming + # retries. Note: ReadTimeout is handled here regardless of + # `tolerated_exception_types` — entries in that tuple only + # fire for non-timeout errors. + if is_no_new_line_timeout or type(err) in tolerated_exception_types: + pass + elif nb_tries >= max_retries: + raise + else: + nb_tries += 1 + sleep_time = min(max_wait_time, max(min_wait_time, sleep_time * 2)) + error_to_retry = err + else: + # Retry-only mode: every error in follow mode burns a retry. + if nb_tries >= max_retries: + if is_no_new_line_timeout: + break # follow mode, silent stream, retries exhausted: give up + raise + nb_tries += 1 + sleep_time = min(max_wait_time, max(min_wait_time, sleep_time * 2)) + error_to_retry = err + # Drop params after the first attempt: the start_event_idx dedup + # requires a stable replay prefix, which `tail` would break. + params = None + if on_iteration_end is not None and on_iteration_end(): + break + + def _fetch_space_logs_sse( + self, + *, + repo_id: str, + build: bool, + timeout: int, + follow: bool, + token: bool | str | None = None, + ) -> Iterable[dict[str, Any]]: + log_type = "build" if build else "run" + yield from self._stream_sse_events( + url=f"{self.endpoint}/api/spaces/{repo_id}/logs/{log_type}", + log_label=f"spaces /logs/{log_type} for repo_id={repo_id!r}", + timeout=timeout, + follow=follow, + token=token, + ) + + @validate_hf_hub_args + def fetch_space_logs( + self, + repo_id: str, + *, + build: bool = False, + follow: bool = False, + token: bool | str | None = None, + ) -> Iterable[str]: + """Fetch the run or build logs of a Space on the Hub. + + Useful for debugging a Space that is failing to build or crashing at runtime, + especially from a script or agentic workflow where reading logs in a browser + is not an option. + + Args: + repo_id (`str`): + ID of the Space. Example: `"bigcode/in-the-stack"`. + build (`bool`, *optional*, defaults to `False`): + If `True`, fetch the container build logs (useful when a Space is stuck + in `BUILD_ERROR`). If `False` (default), fetch the run logs, i.e. the + stdout/stderr of the running application. + follow (`bool`, *optional*, defaults to `False`): + If `True`, stream logs in real-time (blocking) until the server closes + the stream or `KeyboardInterrupt` is raised. If `False` (default), fetch + only the currently buffered logs and return immediately (non-blocking, + like `docker logs`). + token (`bool` or `str`, *optional*): + A valid user access token. Defaults to the locally saved token, which is + the recommended authentication method. Set to `False` to disable + authentication. See + https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Returns: + `Iterable[str]`: A generator yielding log lines as they become available. + + Example: + + ```python + >>> from huggingface_hub import fetch_space_logs + >>> # Non-blocking: print currently available run logs and exit. + >>> for line in fetch_space_logs("username/my-space"): + ... print(line, end="") + + >>> # Debug a build failure: + >>> for line in fetch_space_logs("username/my-space", build=True): + ... print(line, end="") + + >>> # Stream run logs until the server closes the stream. + >>> for line in fetch_space_logs("username/my-space", follow=True): + ... print(line, end="") + ``` + """ + # - Spaces /logs/{run|build} is SSE with `data: {"data": "...", "timestamp": "..."}` events. + # - Keep-alive messages are sent as empty `data:` events (skipped by the `data: {` filter). + # - In no-follow mode we use a short read timeout to drain the buffer and return. + timeout = 120 if follow else 5 + for event in self._fetch_space_logs_sse( + repo_id=repo_id, + build=build, + timeout=timeout, + follow=follow, + token=token, + ): + yield event["data"] + + @validate_hf_hub_args + def wait_for_space( + self, + repo_id: str, + *, + timeout: float | None = None, + poll_interval: float = 1.0, + token: bool | str | None = None, + ) -> SpaceRuntime: + """Wait until a Space reaches a terminal stage (not building/starting). + + Polls [`get_space_runtime`] every `poll_interval` seconds until the Space's stage + is no longer intermediate (`BUILDING`, `RUNNING_BUILDING`, `APP_STARTING`, + `RUNNING_APP_STARTING`). Returns the final [`SpaceRuntime`] in all cases — check + `runtime.stage` to act on the outcome (e.g. `RUNNING` vs `BUILD_ERROR`). + + Args: + repo_id (`str`): + ID of the Space to wait for. Example: `"username/my-space"`. + timeout (`float`, *optional*): + Maximum time to wait in seconds. If `None`, waits indefinitely. + poll_interval (`float`, *optional*): + Seconds between status checks. Defaults to 1s. + token (`bool` or `str`, *optional*): + A valid user access token. Defaults to the locally saved token, which is the + recommended authentication method. Set to `False` to disable authentication. + See https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Returns: + [`SpaceRuntime`]: The final runtime information once the Space reaches a terminal stage. + + Raises: + `TimeoutError`: + If the Space has not reached a terminal stage after `timeout` seconds. + + Example: + + ```python + >>> from huggingface_hub import restart_space, wait_for_space + >>> restart_space("username/my-space") + >>> runtime = wait_for_space("username/my-space") + >>> runtime.stage + 'RUNNING' + ``` + """ + if timeout is not None and timeout < 0: + raise ValueError("`timeout` cannot be negative.") + if poll_interval <= 0: + raise ValueError("`poll_interval` must be positive.") + + deadline = None if timeout is None else time.monotonic() + timeout + while True: + runtime = self.get_space_runtime(repo_id, token=token) + if runtime.stage not in INTERMEDIATE_SPACE_STAGES: + return runtime + remaining = None if deadline is None else deadline - time.monotonic() + if remaining is not None and remaining <= 0: + raise TimeoutError(f"Space '{repo_id}' is still in stage '{runtime.stage}' after {timeout} seconds.") + time.sleep(poll_interval if remaining is None else min(poll_interval, remaining)) + + @_deprecate_arguments( + version="2.0", + deprecated_args={"space_storage"}, + custom_message="Use `space_volumes` to mount volumes on a Space.", + ) + @validate_hf_hub_args + def duplicate_repo( + self, + from_id: str, + to_id: str | None = None, + *, + repo_type: str | None = None, + private: bool | None = None, + visibility: RepoVisibility_T | None = None, + token: bool | str | None = None, + exist_ok: bool = False, + space_hardware: SpaceHardware | None = None, + space_storage: SpaceStorage | None = None, + space_sleep_time: int | None = None, + space_secrets: list[dict[str, str]] | None = None, + space_variables: list[dict[str, str]] | None = None, + space_volumes: list[Volume] | None = None, + ) -> RepoUrl: + """Duplicate a repo on the Hub (model, dataset, or Space). + + This performs a server-side copy that preserves full git history and LFS objects + without requiring a local download/upload round-trip. + + Args: + from_id (`str`): + ID of the repo to duplicate. Example: `"openai/gdpval"`. + to_id (`str`, *optional*): + ID of the new repo. Example: `"myorg/my-gdpval"`. If not provided, the new + repo will have the same name as the original repo, but in your account. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if duplicating a dataset or Space, + `None` or `"model"` if duplicating a model. Default is `None`. + private (`bool`, *optional*): + Whether the new repo should be private or not. Defaults to the same + privacy as the original repo. Cannot be passed together with `visibility`. + visibility (`Literal["public", "private", "protected"]`, *optional*): + Visibility of the new repo. Can be `"public"` or `"private"`, or `"protected"` for Spaces. Defaults + to the same visibility as the original repo. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + exist_ok (`bool`, *optional*, defaults to `False`): + If `True`, do not raise an error if repo already exists. + space_hardware (`SpaceHardware` or `str`, *optional*): + Choice of Hardware if repo_type is "space". Example: `"t4-medium"`. See + [`SpaceHardware`] for a complete list. + space_storage (`SpaceStorage` or `str`, *optional*): + Choice of persistent storage tier if repo_type is "space". Example: + `"small"`. See [`SpaceStorage`] for a complete list. + space_sleep_time (`int`, *optional*): + Number of seconds of inactivity to wait before a Space is put to sleep. + Set to `-1` if you don't want your Space to sleep (default behavior for + upgraded hardware). For free hardware, you can't configure the sleep time + (value is fixed to 48 hours of inactivity). Only applicable if repo_type is "space". + See https://huggingface.co/docs/hub/spaces-gpus#sleep-time for more details. + space_secrets (`list[dict[str, str]]`, *optional*): + A list of secret keys to set in your Space. Each item is in the form + `{"key": ..., "value": ..., "description": ...}` where description is optional. + Only applicable if repo_type is "space". + For more details, see https://huggingface.co/docs/hub/spaces-overview#managing-secrets. + space_variables (`list[dict[str, str]]`, *optional*): + A list of public environment variables to set in your Space. Each item is in + the form `{"key": ..., "value": ..., "description": ...}` where description + is optional. Only applicable if repo_type is "space". + For more details, see https://huggingface.co/docs/hub/spaces-overview#managing-secrets-and-environment-variables. + space_volumes (`list[Volume]`, *optional*): + A list of [`Volume`] objects to mount in the Space at duplication time. Each volume has a `type` + (`"bucket"`, `"model"`, `"dataset"`, or `"space"`), a `source` (repo or bucket ID), a `mount_path` + (path inside the container), and optional `revision`, `read_only`, and `path` fields. + Only applicable if repo_type is "space". + + Returns: + [`RepoUrl`]: URL to the newly created repo. Value is a subclass of `str` containing + attributes like `endpoint`, `repo_type` and `repo_id`. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If one of `from_id` or `to_id` cannot be found. This may be because it doesn't exist, + or because it is set to `private` and you do not have access. + [`HfHubHTTPError`]: + If the HuggingFace API returned an error + + Example: + ```python + >>> from huggingface_hub import duplicate_repo + + # Duplicate a model to your account + >>> duplicate_repo("google/gemma-7b") + RepoUrl('https://huggingface.co/nateraw/gemma-7b',...) + + # Duplicate a dataset with a custom name + >>> duplicate_repo("openai/gdpval", to_id="myorg/my-gdpval", repo_type="dataset") + RepoUrl('https://huggingface.co/datasets/myorg/my-gdpval',...) + + # Duplicate a Space with custom hardware + >>> duplicate_repo("multimodalart/dreambooth-training", repo_type="space", space_hardware="t4-medium") + RepoUrl('https://huggingface.co/spaces/nateraw/dreambooth-training',...) + ``` + """ + if repo_type not in constants.REPO_TYPES: + raise ValueError("Invalid repo type") + + resolved_visibility = _resolve_repo_visibility(private=private, visibility=visibility, repo_type=repo_type) + + # Map repo_type to API path segment + api_prefix = { + None: "models", + constants.REPO_TYPE_MODEL: "models", + constants.REPO_TYPE_DATASET: "datasets", + constants.REPO_TYPE_SPACE: "spaces", + }[repo_type] + + # Resolve the target namespace + name. When 'to_id' is provided we take the name from it, + # otherwise we reuse the source name. Both may be a URL, an 'hf://' URI, or a bare id, so we + # try 'parse_hf_uri' first and fall back to a plain split ('/', or just + # '' for 'to_id'). A missing namespace defaults to the caller's account. + to_namespace: str | None = None + if to_id is not None: + try: + to_namespace, to_repo_name = parse_hf_uri(to_id).id.split("/") + except HfUriError: + namespace_and_name = to_id.rsplit("/", 1) + to_namespace = namespace_and_name[0] if len(namespace_and_name) == 2 else None + to_repo_name = namespace_and_name[-1] + else: + try: + to_repo_name = parse_hf_uri(from_id).id.split("/")[1] + except HfUriError: + to_repo_name = from_id.rsplit("/", 1)[-1] + if to_namespace is None: + to_namespace = self.whoami(token)["name"] + + payload: dict[str, Any] = {"repository": f"{to_namespace}/{to_repo_name}"} + + if resolved_visibility is not None: + payload["visibility"] = resolved_visibility + + # Space-specific options + space_args: list[tuple[str, str, Any]] = [ + # input arg, payload key, value + ("space_hardware", "hardware", space_hardware), + ("space_storage", "storageTier", space_storage), + ("space_sleep_time", "sleepTimeSeconds", space_sleep_time), + ("space_secrets", "secrets", space_secrets), + ("space_variables", "variables", space_variables), + ("space_volumes", "volumes", [v.to_dict() for v in space_volumes] if space_volumes else None), + ] + + if repo_type == "space": + for _, key, value in space_args: + if value is not None: + payload[key] = value + if space_sleep_time is not None and space_hardware == SpaceHardware.CPU_BASIC: + warnings.warn( + "If your Space runs on the default 'cpu-basic' hardware, it will go to sleep if inactive for more" + " than 48 hours. This value is not configurable. If you don't want your Space to deactivate or if" + " you want to set a custom sleep time, you need to upgrade to a paid Hardware.", + UserWarning, + ) + else: + if provided_space_args := [arg for arg, _, value in space_args if value is not None]: + warnings.warn(f"Ignoring provided {', '.join(provided_space_args)} because repo_type is not 'space'.") + + r = get_session().post( + f"{self.endpoint}/api/{api_prefix}/{from_id}/duplicate", + headers=self._build_hf_headers(token=token), + json=payload, + ) + + try: + hf_raise_for_status(r) + except HfHubHTTPError as err: + if exist_ok and err.response.status_code == 409: + pass + else: + raise + + return RepoUrl(r.json()["url"], endpoint=self.endpoint) + + @_deprecate_method(version="2.0", message="Use `duplicate_repo` instead.") + @validate_hf_hub_args + def duplicate_space( + self, + from_id: str, + to_id: str | None = None, + *, + private: bool | None = None, + visibility: RepoVisibility_T | None = None, + token: bool | str | None = None, + exist_ok: bool = False, + hardware: SpaceHardware | None = None, + storage: SpaceStorage | None = None, + sleep_time: int | None = None, + secrets: list[dict[str, str]] | None = None, + variables: list[dict[str, str]] | None = None, + ) -> RepoUrl: + """Duplicate a Space. + + Programmatically duplicate a Space. The new Space will be created in your account and will be in the same state + as the original Space (running or paused). You can duplicate a Space no matter the current state of a Space. + + Args: + from_id (`str`): + ID of the Space to duplicate. Example: `"pharma/CLIP-Interrogator"`. + to_id (`str`, *optional*): + ID of the new Space. Example: `"dog/CLIP-Interrogator"`. If not provided, the new Space will have the same + name as the original Space, but in your account. + private (`bool`, *optional*): + Whether the new Space should be private or not. Defaults to the same privacy as the original Space. Cannot be passed together with `visibility`. + visibility (`Literal["public", "private", "protected"]`, *optional*): + Visibility of the new Space. Can be `"public"`, `"private"`, or `"protected"`. Defaults to the same + visibility as the original Space. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + exist_ok (`bool`, *optional*, defaults to `False`): + If `True`, do not raise an error if repo already exists. + hardware (`SpaceHardware` or `str`, *optional*): + Choice of Hardware. Example: `"t4-medium"`. See [`SpaceHardware`] for a complete list. + storage (`SpaceStorage` or `str`, *optional*): + Choice of persistent storage tier. Example: `"small"`. See [`SpaceStorage`] for a complete list. + sleep_time (`int`, *optional*): + Number of seconds of inactivity to wait before a Space is put to sleep. Set to `-1` if you don't want + your Space to sleep (default behavior for upgraded hardware). For free hardware, you can't configure + the sleep time (value is fixed to 48 hours of inactivity). + See https://huggingface.co/docs/hub/spaces-gpus#sleep-time for more details. + secrets (`list[dict[str, str]]`, *optional*): + A list of secret keys to set in your Space. Each item is in the form `{"key": ..., "value": ..., "description": ...}` where description is optional. + For more details, see https://huggingface.co/docs/hub/spaces-overview#managing-secrets. + variables (`list[dict[str, str]]`, *optional*): + A list of public environment variables to set in your Space. Each item is in the form `{"key": ..., "value": ..., "description": ...}` where description is optional. + For more details, see https://huggingface.co/docs/hub/spaces-overview#managing-secrets-and-environment-variables. + + Returns: + [`RepoUrl`]: URL to the newly created repo. Value is a subclass of `str` containing + attributes like `endpoint`, `repo_type` and `repo_id`. + + Raises: + [`~utils.RepositoryNotFoundError`]: + If one of `from_id` or `to_id` cannot be found. This may be because it doesn't exist, + or because it is set to `private` and you do not have access. + [`HfHubHTTPError`]: + If the HuggingFace API returned an error + + Example: + ```python + >>> from huggingface_hub import duplicate_space + + # Duplicate a Space to your account + >>> duplicate_space("multimodalart/dreambooth-training") + RepoUrl('https://huggingface.co/spaces/nateraw/dreambooth-training',...) + + # Can set custom destination id and visibility flag. + >>> duplicate_space("multimodalart/dreambooth-training", to_id="my-dreambooth", visibility="private") + RepoUrl('https://huggingface.co/spaces/nateraw/my-dreambooth',...) + ``` + + > [!WARNING] + > `duplicate_space` is deprecated and will be removed in version 2.0. Use [`~HfApi.duplicate_repo`] instead. + """ + kwargs: dict[str, Any] = {} + if to_id is not None: + kwargs["to_id"] = to_id + return self.duplicate_repo( + from_id=from_id, + repo_type="space", + private=private, + visibility=visibility, + token=token, + exist_ok=exist_ok, + space_hardware=hardware, + space_storage=storage, + space_sleep_time=sleep_time, + space_secrets=secrets, + space_variables=variables, + **kwargs, + ) + + @_deprecate_method(version="2.0", message="Use `set_space_volumes` instead.") + @validate_hf_hub_args + def request_space_storage( + self, + repo_id: str, + storage: SpaceStorage, + *, + token: bool | str | None = None, + ) -> SpaceRuntime: + """Request persistent storage for a Space. + + > [!WARNING] + > `request_space_storage` is deprecated and will be removed in version 2.0. Use [`set_space_volumes`] instead. + + Args: + repo_id (`str`): + ID of the Space to update. Example: `"open-llm-leaderboard/open_llm_leaderboard"`. + storage (`str` or [`SpaceStorage`]): + Storage tier. Either 'small', 'medium', or 'large'. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + Returns: + [`SpaceRuntime`]: Runtime information about a Space including Space stage and hardware. + """ + payload: dict[str, SpaceStorage] = {"tier": storage} + r = get_session().post( + f"{self.endpoint}/api/spaces/{repo_id}/storage", + headers=self._build_hf_headers(token=token), + json=payload, + ) + hf_raise_for_status(r) + return SpaceRuntime(r.json()) + + @_deprecate_method(version="2.0", message="Use `delete_space_volumes` instead.") + @validate_hf_hub_args + def delete_space_storage( + self, + repo_id: str, + *, + token: bool | str | None = None, + ) -> SpaceRuntime: + """Delete persistent storage for a Space. + + > [!WARNING] + > `delete_space_storage` is deprecated and will be removed in version 2.0. Use [`delete_space_volumes`] instead. + + Args: + repo_id (`str`): + ID of the Space to update. Example: `"open-llm-leaderboard/open_llm_leaderboard"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + Returns: + [`SpaceRuntime`]: Runtime information about a Space including Space stage and hardware. + Raises: + [`BadRequestError`] + If space has no persistent storage. + """ + r = get_session().delete( + f"{self.endpoint}/api/spaces/{repo_id}/storage", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(r) + return SpaceRuntime(r.json()) + + @validate_hf_hub_args + def set_space_volumes( + self, + repo_id: str, + volumes: list[Volume], + *, + token: bool | str | None = None, + ) -> None: + """Set volumes for a Space. + + Sets (or replaces) the list of volumes mounted in the Space. Each volume gives the Space's container access + to a Hub resource (model, dataset, or storage bucket). + + Args: + repo_id (`str`): + ID of the Space to update. Example: `"username/my-space"`. + volumes (`list[Volume]`): + List of [`Volume`] objects to mount. Each volume has a `type` (`"bucket"`, `"model"`, `"dataset"`, or + `"space"`), a `source` (repo or bucket ID), a `mount_path` (path inside the container), and optional + `revision`, `read_only`, and `path` fields. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Raises: + [`BadRequestError`]: + If the Space is a static Space (volumes are not supported on static Spaces). + + Example: + ```python + >>> from huggingface_hub import HfApi, Volume + >>> api = HfApi() + >>> api.set_space_volumes( + ... "username/my-space", + ... volumes=[ + ... Volume(type="model", source="username/my-model", mount_path="/models", read_only=True), + ... Volume(type="bucket", source="username/my-bucket", mount_path="/data"), + ... ], + ... ) + ``` + """ + payload = {"volumes": [vol.to_dict() for vol in volumes]} + r = get_session().put( + f"{self.endpoint}/api/spaces/{repo_id}/volumes", + headers=self._build_hf_headers(token=token), + json=payload, + ) + hf_raise_for_status(r) + + @validate_hf_hub_args + def delete_space_volumes( + self, + repo_id: str, + *, + token: bool | str | None = None, + ) -> None: + """Remove all volumes from a Space. + + Args: + repo_id (`str`): + ID of the Space to update. Example: `"username/my-space"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Raises: + [`BadRequestError`]: + If the Space has no volumes attached. + + Example: + ```python + >>> from huggingface_hub import HfApi + >>> api = HfApi() + >>> api.delete_space_volumes("username/my-space") + ``` + """ + r = get_session().delete( + f"{self.endpoint}/api/spaces/{repo_id}/volumes", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(r) + + ####################### + # Inference Endpoints # + ####################### + + def list_inference_endpoints( + self, namespace: str | None = None, *, token: bool | str | None = None + ) -> list[InferenceEndpoint]: + """Lists all inference endpoints for the given namespace. + + Args: + namespace (`str`, *optional*): + The namespace to list endpoints for. Defaults to the current user. Set to `"*"` to list all endpoints + from all namespaces (i.e. personal namespace and all orgs the user belongs to). + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + list[`InferenceEndpoint`]: A list of all inference endpoints for the given namespace. + + Example: + ```python + >>> from huggingface_hub import HfApi + >>> api = HfApi() + >>> api.list_inference_endpoints() + [InferenceEndpoint(name='my-endpoint', ...), ...] + ``` + """ + # Special case: list all endpoints for all namespaces the user has access to + if namespace == "*": + user = self.whoami(token=token) + + # List personal endpoints first + endpoints: list[InferenceEndpoint] = list_inference_endpoints(namespace=self._get_namespace(token=token)) + + # Then list endpoints for all orgs the user belongs to and ignore 401 errors (no billing or no access) + for org in user.get("orgs", []): + try: + endpoints += list_inference_endpoints(namespace=org["name"], token=token) + except HfHubHTTPError as error: + if error.response.status_code == 401: # Either no billing or user don't have access) + logger.debug("Cannot list Inference Endpoints for org '%s': %s", org["name"], error) + pass + + return endpoints + + # Normal case: list endpoints for a specific namespace + namespace = namespace or self._get_namespace(token=token) + + response = get_session().get( + f"{constants.INFERENCE_ENDPOINTS_ENDPOINT}/endpoint/{namespace}", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + + return [ + InferenceEndpoint.from_raw(endpoint, namespace=namespace, token=token) + for endpoint in response.json()["items"] + ] + + def create_inference_endpoint( + self, + name: str, + *, + repository: str, + framework: str, + accelerator: str, + instance_size: str, + instance_type: str, + region: str, + vendor: str, + account_id: str | None = None, + min_replica: int = 1, + max_replica: int = 1, + scaling_metric: InferenceEndpointScalingMetric | None = None, + scaling_threshold: float | None = None, + scale_to_zero_timeout: int | None = None, + revision: str | None = None, + task: str | None = None, + custom_image: dict | None = None, + container_command: list[str] | None = None, + container_args: list[str] | None = None, + env: dict[str, str] | None = None, + secrets: dict[str, str] | None = None, + type: InferenceEndpointType | str = InferenceEndpointType.AUTHENTICATED, + domain: str | None = None, + path: str | None = None, + cache_http_responses: bool | None = None, + tags: list[str] | None = None, + namespace: str | None = None, + token: bool | str | None = None, + ) -> InferenceEndpoint: + """Create a new Inference Endpoint. + + Args: + name (`str`): + The unique name for the new Inference Endpoint. + repository (`str`): + The name of the model repository associated with the Inference Endpoint (e.g. `"gpt2"`). + framework (`str`): + The machine learning framework used for the model (e.g. `"custom"`). + accelerator (`str`): + The hardware accelerator to be used for inference (e.g. `"cpu"`). + instance_size (`str`): + The size or type of the instance to be used for hosting the model (e.g. `"x4"`). + instance_type (`str`): + The cloud instance type where the Inference Endpoint will be deployed (e.g. `"intel-icl"`). + region (`str`): + The cloud region in which the Inference Endpoint will be created (e.g. `"us-east-1"`). + vendor (`str`): + The cloud provider or vendor where the Inference Endpoint will be hosted (e.g. `"aws"`). + account_id (`str`, *optional*): + The account ID used to link a VPC to a private Inference Endpoint (if applicable). + min_replica (`int`, *optional*): + The minimum number of replicas (instances) to keep running for the Inference Endpoint. To enable + scaling to zero, set this value to 0 and adjust `scale_to_zero_timeout` accordingly. Defaults to 1. + max_replica (`int`, *optional*): + The maximum number of replicas (instances) to scale to for the Inference Endpoint. Defaults to 1. + scaling_metric (`str` or [`InferenceEndpointScalingMetric `], *optional*): + The metric reference for scaling. Either "pendingRequests" or "hardwareUsage" when provided. Defaults to + None (meaning: let the HF Endpoints service specify the metric). + scaling_threshold (`float`, *optional*): + The scaling metric threshold used to trigger a scale up. Ignored when scaling metric is not provided. + Defaults to None (meaning: let the HF Endpoints service specify the threshold). + scale_to_zero_timeout (`int`, *optional*): + The duration in minutes before an inactive endpoint is scaled to zero, or no scaling to zero if + set to None and `min_replica` is not 0. Defaults to None. + revision (`str`, *optional*): + The specific model revision to deploy on the Inference Endpoint (e.g. `"6c0e6080953db56375760c0471a8c5f2929baf11"`). + task (`str`, *optional*): + The task on which to deploy the model (e.g. `"text-classification"`). + custom_image (`dict`, *optional*): + A custom Docker image to use for the Inference Endpoint. This is useful if you want to deploy an + Inference Endpoint running on the `text-generation-inference` (TGI) framework or a custom container + (see examples). + container_command (`list[str]`, *optional*): + Override the container entrypoint command (maps to `model.command` in the API payload). Typically + used together with `custom_image`. + container_args (`list[str]`, *optional*): + Arguments appended to the container entrypoint (maps to `model.args` in the API payload). Typically + used together with `custom_image` to pass runtime flags to the container. + env (`dict[str, str]`, *optional*): + Non-secret environment variables to inject in the container environment. + secrets (`dict[str, str]`, *optional*): + Secret values to inject in the container environment. + type ([`InferenceEndpointType]`, *optional*): + The type of the Inference Endpoint, which can be `"authenticated"` (default), `"public"` or + `"private"`. `"protected"` is deprecated in favor of `"authenticated"` and will be removed in a + future release. + domain (`str`, *optional*): + The custom domain for the Inference Endpoint deployment, if setup the inference endpoint will be available at this domain (e.g. `"my-new-domain.cool-website.woof"`). + path (`str`, *optional*): + The custom path to the deployed model, should start with a `/` (e.g. `"/models/google-bert/bert-base-uncased"`). + cache_http_responses (`bool`, *optional*): + Whether to cache HTTP responses from the Inference Endpoint. Defaults to `False`. + tags (`list[str]`, *optional*): + A list of tags to associate with the Inference Endpoint. + namespace (`str`, *optional*): + The namespace where the Inference Endpoint will be created. Defaults to the current user's namespace. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`InferenceEndpoint`]: information about the updated Inference Endpoint. + + Example: + ```python + >>> from huggingface_hub import HfApi + >>> api = HfApi() + >>> endpoint = api.create_inference_endpoint( + ... "my-endpoint-name", + ... repository="gpt2", + ... framework="pytorch", + ... task="text-generation", + ... accelerator="cpu", + ... vendor="aws", + ... region="us-east-1", + ... type="authenticated", + ... instance_size="x2", + ... instance_type="intel-icl", + ... ) + >>> endpoint + InferenceEndpoint(name='my-endpoint-name', status="pending",...) + + # Run inference on the endpoint + >>> endpoint.client.text_generation(...) + "..." + ``` + + ```python + # Start an Inference Endpoint running Zephyr-7b-beta on TGI + >>> from huggingface_hub import HfApi + >>> api = HfApi() + >>> endpoint = api.create_inference_endpoint( + ... "aws-zephyr-7b-beta-0486", + ... repository="HuggingFaceH4/zephyr-7b-beta", + ... framework="pytorch", + ... task="text-generation", + ... accelerator="gpu", + ... vendor="aws", + ... region="us-east-1", + ... type="authenticated", + ... instance_size="x1", + ... instance_type="nvidia-a10g", + ... env={ + ... "MAX_BATCH_PREFILL_TOKENS": "2048", + ... "MAX_INPUT_LENGTH": "1024", + ... "MAX_TOTAL_TOKENS": "1512", + ... "MODEL_ID": "/repository" + ... }, + ... custom_image={ + ... "healthRoute": "/health", + ... "url": "ghcr.io/huggingface/text-generation-inference:1.1.0", + ... }, + ... secrets={"MY_SECRET_KEY": "secret_value"}, + ... tags=["dev", "text-generation"], + ... ) + ``` + + ```python + # Start an Inference Endpoint running ProsusAI/finbert while scaling to zero in 15 minutes + >>> from huggingface_hub import HfApi + >>> api = HfApi() + >>> endpoint = api.create_inference_endpoint( + ... "finbert-classifier", + ... repository="ProsusAI/finbert", + ... framework="pytorch", + ... task="text-classification", + ... min_replica=0, + ... scale_to_zero_timeout=15, + ... accelerator="cpu", + ... vendor="aws", + ... region="us-east-1", + ... type="authenticated", + ... instance_size="x2", + ... instance_type="intel-icl", + ... ) + >>> endpoint.wait(timeout=300) + # Run inference on the endpoint + >>> endpoint.client.text_generation(...) + TextClassificationOutputElement(label='positive', score=0.8983615040779114) + ``` + + """ + namespace = namespace or self._get_namespace(token=token) + + if type == InferenceEndpointType.PROTECTED: + warnings.warn( + "`type='protected'` is deprecated and will be removed in a future release. " + "Use `type='authenticated'` instead.", + FutureWarning, + ) + + if custom_image is not None: + image = ( + custom_image + if next(iter(custom_image)) in constants.INFERENCE_ENDPOINT_IMAGE_KEYS + else {"custom": custom_image} + ) + else: + image = {"huggingface": {}} + + payload: dict = { + "accountId": account_id, + "compute": { + "accelerator": accelerator, + "instanceSize": instance_size, + "instanceType": instance_type, + "scaling": { + "maxReplica": max_replica, + "minReplica": min_replica, + "scaleToZeroTimeout": scale_to_zero_timeout, + }, + }, + "model": { + "framework": framework, + "repository": repository, + "revision": revision, + "task": task, + "image": image, + }, + "name": name, + "provider": { + "region": region, + "vendor": vendor, + }, + "type": type, + } + if scaling_metric: + payload["compute"]["scaling"]["measure"] = {scaling_metric: scaling_threshold} # type: ignore + model_payload: dict[str, Any] = payload["model"] + if container_command is not None: + model_payload["command"] = container_command + if container_args is not None: + model_payload["args"] = container_args + if env: + payload["model"]["env"] = env + if secrets: + payload["model"]["secrets"] = secrets + if domain is not None or path is not None: + payload["route"] = {} + if domain is not None: + payload["route"]["domain"] = domain + if path is not None: + payload["route"]["path"] = path + if cache_http_responses is not None: + payload["cacheHttpResponses"] = cache_http_responses + if tags is not None: + payload["tags"] = tags + + response = get_session().post( + f"{constants.INFERENCE_ENDPOINTS_ENDPOINT}/endpoint/{namespace}", + headers=self._build_hf_headers(token=token), + json=payload, + ) + hf_raise_for_status(response) + + return InferenceEndpoint.from_raw(response.json(), namespace=namespace, token=token) + + @experimental + @validate_hf_hub_args + def create_inference_endpoint_from_catalog( + self, + repo_id: str, + *, + name: str | None = None, + accelerator: Literal["cpu", "gpu", "neuron"] | str | None = None, + token: bool | str | None = None, + namespace: str | None = None, + ) -> InferenceEndpoint: + """Create a new Inference Endpoint from a model in the Hugging Face Inference Catalog. + + The goal of the Inference Catalog is to provide a curated list of models that are optimized for inference + and for which default configurations have been tested. See https://endpoints.huggingface.co/catalog for a list + of available models in the catalog. + + Args: + repo_id (`str`): + The ID of the model in the catalog to deploy as an Inference Endpoint. + name (`str`, *optional*): + The unique name for the new Inference Endpoint. If not provided, a random name will be generated. + accelerator (`str`, *optional*): + The hardware accelerator to be used for inference. Possible values include `"cpu"`, `"gpu"`, and + `"neuron"`. If not provided, the server will use a default appropriate for the model. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + namespace (`str`, *optional*): + The namespace where the Inference Endpoint will be created. Defaults to the current user's namespace. + + Returns: + [`InferenceEndpoint`]: information about the new Inference Endpoint. + + > [!WARNING] + > `create_inference_endpoint_from_catalog` is experimental. Its API is subject to change in the future. Please provide feedback + > if you have any suggestions or requests. + """ + token = token or self.token or get_token() + payload: dict = { + "namespace": namespace or self._get_namespace(token=token), + "repoId": repo_id, + } + if name is not None: + payload["endpointName"] = name + if accelerator is not None: + payload["accelerator"] = accelerator + + response = get_session().post( + f"{constants.INFERENCE_CATALOG_ENDPOINT}/deploy", + headers=self._build_hf_headers(token=token), + json=payload, + ) + hf_raise_for_status(response) + data = response.json()["endpoint"] + return InferenceEndpoint.from_raw(data, namespace=data["name"], token=token) + + @experimental + @validate_hf_hub_args + def list_inference_catalog(self, *, token: bool | str | None = None) -> list[str]: + """List models available in the Hugging Face Inference Catalog. + + The goal of the Inference Catalog is to provide a curated list of models that are optimized for inference + and for which default configurations have been tested. See https://endpoints.huggingface.co/catalog for a list + of available models in the catalog. + + Use [`create_inference_endpoint_from_catalog`] to deploy a model from the catalog. + + Args: + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + + Returns: + List[`str`]: A list of model IDs available in the catalog. + > [!WARNING] + > `list_inference_catalog` is experimental. Its API is subject to change in the future. Please provide feedback + > if you have any suggestions or requests. + """ + response = get_session().get( + f"{constants.INFERENCE_CATALOG_ENDPOINT}/repo-list", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + return response.json()["models"] + + def get_inference_endpoint( + self, name: str, *, namespace: str | None = None, token: bool | str | None = None + ) -> InferenceEndpoint: + """Get information about an Inference Endpoint. + + Args: + name (`str`): + The name of the Inference Endpoint to retrieve information about. + namespace (`str`, *optional*): + The namespace in which the Inference Endpoint is located. Defaults to the current user. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`InferenceEndpoint`]: information about the requested Inference Endpoint. + + Example: + ```python + >>> from huggingface_hub import HfApi + >>> api = HfApi() + >>> endpoint = api.get_inference_endpoint("my-text-to-image") + >>> endpoint + InferenceEndpoint(name='my-text-to-image', ...) + + # Get status + >>> endpoint.status + 'running' + >>> endpoint.url + 'https://my-text-to-image.region.vendor.endpoints.huggingface.cloud' + + # Run inference + >>> endpoint.client.text_to_image(...) + ``` + """ + namespace = namespace or self._get_namespace(token=token) + + response = get_session().get( + f"{constants.INFERENCE_ENDPOINTS_ENDPOINT}/endpoint/{namespace}/{name}", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + + return InferenceEndpoint.from_raw(response.json(), namespace=namespace, token=token) + + def update_inference_endpoint( + self, + name: str, + *, + # Compute update + accelerator: str | None = None, + instance_size: str | None = None, + instance_type: str | None = None, + min_replica: int | None = None, + max_replica: int | None = None, + scale_to_zero_timeout: int | None = None, + scaling_metric: InferenceEndpointScalingMetric | None = None, + scaling_threshold: float | None = None, + # Model update + repository: str | None = None, + framework: str | None = None, + revision: str | None = None, + task: str | None = None, + custom_image: dict | None = None, + env: dict[str, str] | None = None, + secrets: dict[str, str] | None = None, + # Route update + domain: str | None = None, + path: str | None = None, + # Other + cache_http_responses: bool | None = None, + tags: list[str] | None = None, + namespace: str | None = None, + token: bool | str | None = None, + ) -> InferenceEndpoint: + """Update an Inference Endpoint. + + This method allows the update of either the compute configuration, the deployed model, the route, or any combination. + All arguments are optional but at least one must be provided. + + For convenience, you can also update an Inference Endpoint using [`InferenceEndpoint.update`]. + + Args: + name (`str`): + The name of the Inference Endpoint to update. + + accelerator (`str`, *optional*): + The hardware accelerator to be used for inference (e.g. `"cpu"`). + instance_size (`str`, *optional*): + The size or type of the instance to be used for hosting the model (e.g. `"x4"`). + instance_type (`str`, *optional*): + The cloud instance type where the Inference Endpoint will be deployed (e.g. `"intel-icl"`). + min_replica (`int`, *optional*): + The minimum number of replicas (instances) to keep running for the Inference Endpoint. + max_replica (`int`, *optional*): + The maximum number of replicas (instances) to scale to for the Inference Endpoint. + scale_to_zero_timeout (`int`, *optional*): + The duration in minutes before an inactive endpoint is scaled to zero. + scaling_metric (`str` or [`InferenceEndpointScalingMetric `], *optional*): + The metric reference for scaling. Either "pendingRequests" or "hardwareUsage" when provided. + Defaults to None. + scaling_threshold (`float`, *optional*): + The scaling metric threshold used to trigger a scale up. Ignored when scaling metric is not provided. + Defaults to None. + repository (`str`, *optional*): + The name of the model repository associated with the Inference Endpoint (e.g. `"gpt2"`). + framework (`str`, *optional*): + The machine learning framework used for the model (e.g. `"custom"`). + revision (`str`, *optional*): + The specific model revision to deploy on the Inference Endpoint (e.g. `"6c0e6080953db56375760c0471a8c5f2929baf11"`). + task (`str`, *optional*): + The task on which to deploy the model (e.g. `"text-classification"`). + custom_image (`dict`, *optional*): + A custom Docker image to use for the Inference Endpoint. This is useful if you want to deploy an + Inference Endpoint running on the `text-generation-inference` (TGI) framework (see examples). + env (`dict[str, str]`, *optional*): + Non-secret environment variables to inject in the container environment + secrets (`dict[str, str]`, *optional*): + Secret values to inject in the container environment. + + domain (`str`, *optional*): + The custom domain for the Inference Endpoint deployment, if setup the inference endpoint will be available at this domain (e.g. `"my-new-domain.cool-website.woof"`). + path (`str`, *optional*): + The custom path to the deployed model, should start with a `/` (e.g. `"/models/google-bert/bert-base-uncased"`). + + cache_http_responses (`bool`, *optional*): + Whether to cache HTTP responses from the Inference Endpoint. + tags (`list[str]`, *optional*): + A list of tags to associate with the Inference Endpoint. + + namespace (`str`, *optional*): + The namespace where the Inference Endpoint will be updated. Defaults to the current user's namespace. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`InferenceEndpoint`]: information about the updated Inference Endpoint. + """ + namespace = namespace or self._get_namespace(token=token) + + # Populate only the fields that are not None + payload: dict = defaultdict(lambda: defaultdict(dict)) + if accelerator is not None: + payload["compute"]["accelerator"] = accelerator + if instance_size is not None: + payload["compute"]["instanceSize"] = instance_size + if instance_type is not None: + payload["compute"]["instanceType"] = instance_type + if max_replica is not None: + payload["compute"]["scaling"]["maxReplica"] = max_replica + if min_replica is not None: + payload["compute"]["scaling"]["minReplica"] = min_replica + if scale_to_zero_timeout is not None: + payload["compute"]["scaling"]["scaleToZeroTimeout"] = scale_to_zero_timeout + if scaling_metric: + payload["compute"]["scaling"]["measure"] = {scaling_metric: scaling_threshold} + if repository is not None: + payload["model"]["repository"] = repository + if framework is not None: + payload["model"]["framework"] = framework + if revision is not None: + payload["model"]["revision"] = revision + if task is not None: + payload["model"]["task"] = task + if custom_image is not None: + payload["model"]["image"] = {"custom": custom_image} + if env is not None: + payload["model"]["env"] = env + if secrets is not None: + payload["model"]["secrets"] = secrets + if domain is not None: + payload["route"]["domain"] = domain + if path is not None: + payload["route"]["path"] = path + if cache_http_responses is not None: + payload["cacheHttpResponses"] = cache_http_responses + if tags is not None: + payload["tags"] = tags + + response = get_session().put( + f"{constants.INFERENCE_ENDPOINTS_ENDPOINT}/endpoint/{namespace}/{name}", + headers=self._build_hf_headers(token=token), + json=payload, + ) + hf_raise_for_status(response) + + return InferenceEndpoint.from_raw(response.json(), namespace=namespace, token=token) + + def delete_inference_endpoint( + self, name: str, *, namespace: str | None = None, token: bool | str | None = None + ) -> None: + """Delete an Inference Endpoint. + + This operation is not reversible. If you don't want to be charged for an Inference Endpoint, it is preferable + to pause it with [`pause_inference_endpoint`] or scale it to zero with [`scale_to_zero_inference_endpoint`]. + + For convenience, you can also delete an Inference Endpoint using [`InferenceEndpoint.delete`]. + + Args: + name (`str`): + The name of the Inference Endpoint to delete. + namespace (`str`, *optional*): + The namespace in which the Inference Endpoint is located. Defaults to the current user. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + """ + namespace = namespace or self._get_namespace(token=token) + response = get_session().delete( + f"{constants.INFERENCE_ENDPOINTS_ENDPOINT}/endpoint/{namespace}/{name}", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + + def pause_inference_endpoint( + self, name: str, *, namespace: str | None = None, token: bool | str | None = None + ) -> InferenceEndpoint: + """Pause an Inference Endpoint. + + A paused Inference Endpoint will not be charged. It can be resumed at any time using [`resume_inference_endpoint`]. + This is different than scaling the Inference Endpoint to zero with [`scale_to_zero_inference_endpoint`], which + would be automatically restarted when a request is made to it. + + For convenience, you can also pause an Inference Endpoint using [`pause_inference_endpoint`]. + + Args: + name (`str`): + The name of the Inference Endpoint to pause. + namespace (`str`, *optional*): + The namespace in which the Inference Endpoint is located. Defaults to the current user. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`InferenceEndpoint`]: information about the paused Inference Endpoint. + """ + namespace = namespace or self._get_namespace(token=token) + + response = get_session().post( + f"{constants.INFERENCE_ENDPOINTS_ENDPOINT}/endpoint/{namespace}/{name}/pause", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + + return InferenceEndpoint.from_raw(response.json(), namespace=namespace, token=token) + + def resume_inference_endpoint( + self, + name: str, + *, + namespace: str | None = None, + running_ok: bool = True, + token: bool | str | None = None, + ) -> InferenceEndpoint: + """Resume an Inference Endpoint. + + For convenience, you can also resume an Inference Endpoint using [`InferenceEndpoint.resume`]. + + Args: + name (`str`): + The name of the Inference Endpoint to resume. + namespace (`str`, *optional*): + The namespace in which the Inference Endpoint is located. Defaults to the current user. + running_ok (`bool`, *optional*): + If `True`, the method will not raise an error if the Inference Endpoint is already running. Defaults to + `True`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`InferenceEndpoint`]: information about the resumed Inference Endpoint. + """ + namespace = namespace or self._get_namespace(token=token) + + response = get_session().post( + f"{constants.INFERENCE_ENDPOINTS_ENDPOINT}/endpoint/{namespace}/{name}/resume", + headers=self._build_hf_headers(token=token), + ) + try: + hf_raise_for_status(response) + except HfHubHTTPError as error: + # If already running (and it's ok), then fetch current status and return + if running_ok and error.response.status_code == 400 and "already running" in error.response.text: + return self.get_inference_endpoint(name, namespace=namespace, token=token) + # Otherwise, raise the error + raise + + return InferenceEndpoint.from_raw(response.json(), namespace=namespace, token=token) + + def scale_to_zero_inference_endpoint( + self, name: str, *, namespace: str | None = None, token: bool | str | None = None + ) -> InferenceEndpoint: + """Scale Inference Endpoint to zero. + + An Inference Endpoint scaled to zero will not be charged. It will be resume on the next request to it, with a + cold start delay. This is different than pausing the Inference Endpoint with [`pause_inference_endpoint`], which + would require a manual resume with [`resume_inference_endpoint`]. + + For convenience, you can also scale an Inference Endpoint to zero using [`InferenceEndpoint.scale_to_zero`]. + + Args: + name (`str`): + The name of the Inference Endpoint to scale to zero. + namespace (`str`, *optional*): + The namespace in which the Inference Endpoint is located. Defaults to the current user. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`InferenceEndpoint`]: information about the scaled-to-zero Inference Endpoint. + """ + namespace = namespace or self._get_namespace(token=token) + + response = get_session().post( + f"{constants.INFERENCE_ENDPOINTS_ENDPOINT}/endpoint/{namespace}/{name}/scale-to-zero", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + + return InferenceEndpoint.from_raw(response.json(), namespace=namespace, token=token) + + def _get_namespace(self, token: bool | str | None = None) -> str: + """Get the default namespace for the current user.""" + me = self.whoami(token=token) + if me["type"] == "user": + return me["name"] + else: + raise ValueError( + "Cannot determine default namespace. You must provide a 'namespace' as input or be logged in as a" + " user." + ) + + ######################## + # Collection Endpoints # + ######################## + @validate_hf_hub_args + def list_collections( + self, + *, + owner: list[str] | str | None = None, + item: list[str] | str | None = None, + sort: CollectionSort_T | None = None, + limit: int | None = None, + token: bool | str | None = None, + ) -> Iterable[Collection]: + """List collections on the Huggingface Hub, given some filters. + + > [!WARNING] + > When listing collections, the item list per collection is truncated to 4 items maximum. To retrieve all items + > from a collection, you must use [`get_collection`]. + + Args: + owner (`list[str]` or `str`, *optional*): + Filter by owner's username. + item (`list[str]` or `str`, *optional*): + Filter collections containing a particular items. Example: `"models/teknium/OpenHermes-2.5-Mistral-7B"`, `"datasets/squad"` or `"papers/2311.12983"`. + sort (`Literal["lastModified", "trending", "upvotes"]`, *optional*): + Sort collections by last modified, trending or upvotes. + limit (`int`, *optional*): + Maximum number of collections to be returned. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[Collection]`: an iterable of [`Collection`] objects. + """ + # Construct the API endpoint + path = f"{self.endpoint}/api/collections" + headers = self._build_hf_headers(token=token) + params: dict = {} + if owner is not None: + params.update({"owner": owner}) + if item is not None: + params.update({"item": item}) + if sort is not None: + params.update({"sort": sort}) + if limit is not None: + params.update({"limit": limit}) + + # Paginate over the results until limit is reached + items = paginate(path, headers=headers, params=params) + if limit is not None: + items = islice(items, limit) # Do not iterate over all pages + + # Parse as Collection and return + for position, collection_data in enumerate(items): + yield Collection(position=position, **collection_data) + + def get_collection(self, collection_slug: str, *, token: bool | str | None = None) -> Collection: + """Gets information about a Collection on the Hub. + + Args: + collection_slug (`str`): + Slug of the collection of the Hub. Example: `"TheBloke/recent-models-64f9a55bb3115b4f513ec026"`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: [`Collection`] + + Example: + + ```py + >>> from huggingface_hub import get_collection + >>> collection = get_collection("TheBloke/recent-models-64f9a55bb3115b4f513ec026") + >>> collection.title + 'Recent models' + >>> len(collection.items) + 37 + >>> collection.items[0] + CollectionItem( + item_object_id='651446103cd773a050bf64c2', + item_id='TheBloke/U-Amethyst-20B-AWQ', + item_type='model', + position=88, + note=None + ) + ``` + """ + r = get_session().get( + f"{self.endpoint}/api/collections/{collection_slug}", headers=self._build_hf_headers(token=token) + ) + hf_raise_for_status(r) + return Collection(**{**r.json(), "endpoint": self.endpoint}) + + def create_collection( + self, + title: str, + *, + namespace: str | None = None, + description: str | None = None, + private: bool = False, + exists_ok: bool = False, + token: bool | str | None = None, + ) -> Collection: + """Create a new Collection on the Hub. + + Args: + title (`str`): + Title of the collection to create. Example: `"Recent models"`. + namespace (`str`, *optional*): + Namespace of the collection to create (username or org). Will default to the owner name. + description (`str`, *optional*): + Description of the collection to create. + private (`bool`, *optional*): + Whether the collection should be private or not. Defaults to `False` (i.e. public collection). + exists_ok (`bool`, *optional*): + If `True`, do not raise an error if collection already exists. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: [`Collection`] + + Example: + + ```py + >>> from huggingface_hub import create_collection + >>> collection = create_collection( + ... title="ICCV 2023", + ... description="Portfolio of models, papers and demos I presented at ICCV 2023", + ... ) + >>> collection.slug + "username/iccv-2023-64f9a55bb3115b4f513ec026" + ``` + """ + if namespace is None: + namespace = self.whoami(token)["name"] + + payload = { + "title": title, + "namespace": namespace, + "private": private, + } + if description is not None: + payload["description"] = description + + r = get_session().post( + f"{self.endpoint}/api/collections", headers=self._build_hf_headers(token=token), json=payload + ) + try: + hf_raise_for_status(r) + except HfHubHTTPError as err: + if exists_ok and err.response.status_code == 409: + # Collection already exists and `exists_ok=True` + slug = r.json()["slug"] + return self.get_collection(slug, token=token) + else: + raise + return Collection(**{**r.json(), "endpoint": self.endpoint}) + + def update_collection_metadata( + self, + collection_slug: str, + *, + title: str | None = None, + description: str | None = None, + position: int | None = None, + private: bool | None = None, + theme: str | None = None, + token: bool | str | None = None, + ) -> Collection: + """Update metadata of a collection on the Hub. + + All arguments are optional. Only provided metadata will be updated. + + Args: + collection_slug (`str`): + Slug of the collection to update. Example: `"TheBloke/recent-models-64f9a55bb3115b4f513ec026"`. + title (`str`): + Title of the collection to update. + description (`str`, *optional*): + Description of the collection to update. + position (`int`, *optional*): + New position of the collection in the list of collections of the user. + private (`bool`, *optional*): + Whether the collection should be private or not. + theme (`str`, *optional*): + Theme of the collection on the Hub. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: [`Collection`] + + Example: + + ```py + >>> from huggingface_hub import update_collection_metadata + >>> collection = update_collection_metadata( + ... collection_slug="username/iccv-2023-64f9a55bb3115b4f513ec026", + ... title="ICCV Oct. 2023" + ... description="Portfolio of models, datasets, papers and demos I presented at ICCV Oct. 2023", + ... private=False, + ... theme="pink", + ... ) + >>> collection.slug + "username/iccv-oct-2023-64f9a55bb3115b4f513ec026" + # ^collection slug got updated but not the trailing ID + ``` + """ + payload = { + "position": position, + "private": private, + "theme": theme, + "title": title, + "description": description, + } + r = get_session().patch( + f"{self.endpoint}/api/collections/{collection_slug}", + headers=self._build_hf_headers(token=token), + # Only send not-none values to the API + json={key: value for key, value in payload.items() if value is not None}, + ) + hf_raise_for_status(r) + return Collection(**{**r.json()["data"], "endpoint": self.endpoint}) + + def delete_collection( + self, collection_slug: str, *, missing_ok: bool = False, token: bool | str | None = None + ) -> None: + """Delete a collection on the Hub. + + Args: + collection_slug (`str`): + Slug of the collection to delete. Example: `"TheBloke/recent-models-64f9a55bb3115b4f513ec026"`. + missing_ok (`bool`, *optional*): + If `True`, do not raise an error if the collection doesn't exist. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Example: + + ```py + >>> from huggingface_hub import delete_collection + >>> collection = delete_collection("username/useless-collection-64f9a55bb3115b4f513ec026", missing_ok=True) + ``` + + > [!WARNING] + > This is a non-revertible action. A deleted collection cannot be restored. + """ + r = get_session().delete( + f"{self.endpoint}/api/collections/{collection_slug}", headers=self._build_hf_headers(token=token) + ) + try: + hf_raise_for_status(r) + except HfHubHTTPError as err: + if missing_ok and err.response.status_code == 404: + # Collection doesn't exist and `missing_ok=True` + return + else: + raise + + def add_collection_item( + self, + collection_slug: str, + item_id: str, + item_type: CollectionItemType_T, + *, + note: str | None = None, + exists_ok: bool = False, + token: bool | str | None = None, + ) -> Collection: + """Add an item to a collection on the Hub. + + Args: + collection_slug (`str`): + Slug of the collection to update. Example: `"TheBloke/recent-models-64f9a55bb3115b4f513ec026"`. + item_id (`str`): + Id of the item to add to the collection. Use the repo_id for repos/spaces/datasets, + the paper id for papers, the slug of another collection (e.g. `"moonshotai/kimi-k2"`) + or a bucket id (e.g. `"namespace/bucket-name"`). + item_type (`str`): + Type of the item to add. Can be one of `"model"`, `"dataset"`, `"space"`, `"paper"`, `"collection"` + or `"bucket"`. + note (`str`, *optional*): + A note to attach to the item in the collection. The maximum size for a note is 500 characters. + exists_ok (`bool`, *optional*): + If `True`, do not raise an error if item already exists. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: [`Collection`] + + Raises: + [`HfHubHTTPError`]: + HTTP 403 if you only have read-only access to the repo. This can be the case if you don't have `write` + or `admin` role in the organization the repo belongs to or if you passed a `read` token. + [`HfHubHTTPError`]: + HTTP 404 if the item you try to add to the collection does not exist on the Hub. + [`HfHubHTTPError`]: + HTTP 409 if the item you try to add to the collection is already in the collection (and exists_ok=False) + + Example: + + ```py + >>> from huggingface_hub import add_collection_item + >>> collection = add_collection_item( + ... collection_slug="davanstrien/climate-64f99dc2a5067f6b65531bab", + ... item_id="pierre-loic/climate-news-articles", + ... item_type="dataset" + ... ) + >>> collection.items[-1].item_id + "pierre-loic/climate-news-articles" + # ^item got added to the collection on last position + + # Add item with a note + >>> add_collection_item( + ... collection_slug="davanstrien/climate-64f99dc2a5067f6b65531bab", + ... item_id="datasets/climate_fever", + ... item_type="dataset" + ... note="This dataset adopts the FEVER methodology that consists of 1,535 real-world claims regarding climate-change collected on the internet." + ... ) + (...) + ``` + """ + payload: dict[str, Any] = {"item": {"id": item_id, "type": item_type}} + if note is not None: + payload["note"] = note + r = get_session().post( + f"{self.endpoint}/api/collections/{collection_slug}/items", + headers=self._build_hf_headers(token=token), + json=payload, + ) + try: + hf_raise_for_status(r) + except HfHubHTTPError as err: + if exists_ok and err.response.status_code == 409: + # Item already exists and `exists_ok=True` + return self.get_collection(collection_slug, token=token) + else: + raise + return Collection(**{**r.json(), "endpoint": self.endpoint}) + + def update_collection_item( + self, + collection_slug: str, + item_object_id: str, + *, + note: str | None = None, + position: int | None = None, + token: bool | str | None = None, + ) -> None: + """Update an item in a collection. + + Args: + collection_slug (`str`): + Slug of the collection to update. Example: `"TheBloke/recent-models-64f9a55bb3115b4f513ec026"`. + item_object_id (`str`): + ID of the item in the collection. This is not the id of the item on the Hub (repo_id or paper id). + It must be retrieved from a [`CollectionItem`] object. Example: `collection.items[0].item_object_id`. + note (`str`, *optional*): + A note to attach to the item in the collection. The maximum size for a note is 500 characters. + position (`int`, *optional*): + New position of the item in the collection. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Example: + + ```py + >>> from huggingface_hub import get_collection, update_collection_item + + # Get collection first + >>> collection = get_collection("TheBloke/recent-models-64f9a55bb3115b4f513ec026") + + # Update item based on its ID (add note + update position) + >>> update_collection_item( + ... collection_slug="TheBloke/recent-models-64f9a55bb3115b4f513ec026", + ... item_object_id=collection.items[-1].item_object_id, + ... note="Newly updated model!" + ... position=0, + ... ) + ``` + """ + payload = {"position": position, "note": note} + r = get_session().patch( + f"{self.endpoint}/api/collections/{collection_slug}/items/{item_object_id}", + headers=self._build_hf_headers(token=token), + # Only send not-none values to the API + json={key: value for key, value in payload.items() if value is not None}, + ) + hf_raise_for_status(r) + + def delete_collection_item( + self, + collection_slug: str, + item_object_id: str, + *, + missing_ok: bool = False, + token: bool | str | None = None, + ) -> None: + """Delete an item from a collection. + + Args: + collection_slug (`str`): + Slug of the collection to update. Example: `"TheBloke/recent-models-64f9a55bb3115b4f513ec026"`. + item_object_id (`str`): + ID of the item in the collection. This is not the id of the item on the Hub (repo_id or paper id). + It must be retrieved from a [`CollectionItem`] object. Example: `collection.items[0].item_object_id`. + missing_ok (`bool`, *optional*): + If `True`, do not raise an error if the item doesn't exist. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Example: + + ```py + >>> from huggingface_hub import get_collection, delete_collection_item + + # Get collection first + >>> collection = get_collection("TheBloke/recent-models-64f9a55bb3115b4f513ec026") + + # Delete item based on its ID + >>> delete_collection_item( + ... collection_slug="TheBloke/recent-models-64f9a55bb3115b4f513ec026", + ... item_object_id=collection.items[-1].item_object_id, + ... ) + ``` + """ + r = get_session().delete( + f"{self.endpoint}/api/collections/{collection_slug}/items/{item_object_id}", + headers=self._build_hf_headers(token=token), + ) + try: + hf_raise_for_status(r) + except HfHubHTTPError as err: + if missing_ok and err.response.status_code == 404: + # Item already deleted and `missing_ok=True` + return + else: + raise + + ########################## + # Manage access requests # + ########################## + + @validate_hf_hub_args + def list_pending_access_requests( + self, repo_id: str, *, repo_type: str | None = None, token: bool | str | None = None + ) -> Iterable[AccessRequest]: + """ + Get pending access requests for a given gated repo. + + A pending request means the user has requested access to the repo but the request has not been processed yet. + If the approval mode is automatic, this list should be empty. Pending requests can be accepted or rejected + using [`accept_access_request`] and [`reject_access_request`]. + + For more info about gated repos, see https://huggingface.co/docs/hub/models-gated. + + Args: + repo_id (`str`): + The id of the repo to get access requests for. + repo_type (`str`, *optional*): + The type of the repo to get access requests for. Must be one of `model`, `dataset` or `space`. + Defaults to `model`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[AccessRequest]`: An iterable of [`AccessRequest`] objects. Each time contains a `username`, `email`, + `status` and `timestamp` attribute. If the gated repo has a custom form, the `fields` attribute will + be populated with user's answers. + + Raises: + [`HfHubHTTPError`]: + HTTP 400 if the repo is not gated. + [`HfHubHTTPError`]: + HTTP 403 if you only have read-only access to the repo. This can be the case if you don't have `write` + or `admin` role in the organization the repo belongs to or if you passed a `read` token. + + Example: + ```py + >>> from huggingface_hub import list_pending_access_requests, accept_access_request + + # List pending requests + >>> requests = list(list_pending_access_requests("meta-llama/Llama-2-7b")) + >>> len(requests) + 411 + >>> requests[0] + [ + AccessRequest( + username='clem', + fullname='Clem 🤗', + email='***', + timestamp=datetime.datetime(2023, 11, 23, 18, 4, 53, 828000, tzinfo=datetime.timezone.utc), + status='pending', + fields=None, + ), + ... + ] + + # Accept Clem's request + >>> accept_access_request("meta-llama/Llama-2-7b", "clem") + ``` + """ + yield from self._list_access_requests(repo_id, "pending", repo_type=repo_type, token=token) + + @validate_hf_hub_args + def list_accepted_access_requests( + self, repo_id: str, *, repo_type: str | None = None, token: bool | str | None = None + ) -> Iterable[AccessRequest]: + """ + Get accepted access requests for a given gated repo. + + An accepted request means the user has requested access to the repo and the request has been accepted. The user + can download any file of the repo. If the approval mode is automatic, this list should contains by default all + requests. Accepted requests can be cancelled or rejected at any time using [`cancel_access_request`] and + [`reject_access_request`]. A cancelled request will go back to the pending list while a rejected request will + go to the rejected list. In both cases, the user will lose access to the repo. + + For more info about gated repos, see https://huggingface.co/docs/hub/models-gated. + + Args: + repo_id (`str`): + The id of the repo to get access requests for. + repo_type (`str`, *optional*): + The type of the repo to get access requests for. Must be one of `model`, `dataset` or `space`. + Defaults to `model`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[AccessRequest]`: An iterable of [`AccessRequest`] objects. Each time contains a `username`, `email`, + `status` and `timestamp` attribute. If the gated repo has a custom form, the `fields` attribute will + be populated with user's answers. + + Raises: + [`HfHubHTTPError`]: + HTTP 400 if the repo is not gated. + [`HfHubHTTPError`]: + HTTP 403 if you only have read-only access to the repo. This can be the case if you don't have `write` + or `admin` role in the organization the repo belongs to or if you passed a `read` token. + + Example: + ```py + >>> from huggingface_hub import list_accepted_access_requests + + >>> requests = list(list_accepted_access_requests("meta-llama/Llama-2-7b")) + >>> len(requests) + 411 + >>> requests[0] + [ + AccessRequest( + username='clem', + fullname='Clem 🤗', + email='***', + timestamp=datetime.datetime(2023, 11, 23, 18, 4, 53, 828000, tzinfo=datetime.timezone.utc), + status='accepted', + fields=None, + ), + ... + ] + ``` + """ + yield from self._list_access_requests(repo_id, "accepted", repo_type=repo_type, token=token) + + @validate_hf_hub_args + def list_rejected_access_requests( + self, repo_id: str, *, repo_type: str | None = None, token: bool | str | None = None + ) -> Iterable[AccessRequest]: + """ + Get rejected access requests for a given gated repo. + + A rejected request means the user has requested access to the repo and the request has been explicitly rejected + by a repo owner (either you or another user from your organization). The user cannot download any file of the + repo. Rejected requests can be accepted or cancelled at any time using [`accept_access_request`] and + [`cancel_access_request`]. A cancelled request will go back to the pending list while an accepted request will + go to the accepted list. + + For more info about gated repos, see https://huggingface.co/docs/hub/models-gated. + + Args: + repo_id (`str`): + The id of the repo to get access requests for. + repo_type (`str`, *optional*): + The type of the repo to get access requests for. Must be one of `model`, `dataset` or `space`. + Defaults to `model`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[AccessRequest]`: An iterable of [`AccessRequest`] objects. Each time contains a `username`, `email`, + `status` and `timestamp` attribute. If the gated repo has a custom form, the `fields` attribute will + be populated with user's answers. + + Raises: + [`HfHubHTTPError`]: + HTTP 400 if the repo is not gated. + [`HfHubHTTPError`]: + HTTP 403 if you only have read-only access to the repo. This can be the case if you don't have `write` + or `admin` role in the organization the repo belongs to or if you passed a `read` token. + + Example: + ```py + >>> from huggingface_hub import list_rejected_access_requests + + >>> requests = list(list_rejected_access_requests("meta-llama/Llama-2-7b")) + >>> len(requests) + 411 + >>> requests[0] + [ + AccessRequest( + username='clem', + fullname='Clem 🤗', + email='***', + timestamp=datetime.datetime(2023, 11, 23, 18, 4, 53, 828000, tzinfo=datetime.timezone.utc), + status='rejected', + fields=None, + ), + ... + ] + ``` + """ + yield from self._list_access_requests(repo_id, "rejected", repo_type=repo_type, token=token) + + def _list_access_requests( + self, + repo_id: str, + status: Literal["accepted", "rejected", "pending"], + repo_type: str | None = None, + token: bool | str | None = None, + ) -> Iterable[AccessRequest]: + if repo_type not in constants.REPO_TYPES: + raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}") + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + + for request in paginate( + f"{constants.ENDPOINT}/api/{repo_type}s/{repo_id}/user-access-request/{status}", + params={}, + headers=self._build_hf_headers(token=token), + ): + yield AccessRequest( + username=request["user"]["user"], + fullname=request["user"]["fullname"], + email=request["user"].get("email"), + status=request["status"], + timestamp=parse_datetime(request["timestamp"]), + fields=request.get("fields"), # only if custom fields in form + ) + + @validate_hf_hub_args + def cancel_access_request( + self, repo_id: str, user: str, *, repo_type: str | None = None, token: bool | str | None = None + ) -> None: + """ + Cancel an access request from a user for a given gated repo. + + A cancelled request will go back to the pending list and the user will lose access to the repo. + + For more info about gated repos, see https://huggingface.co/docs/hub/models-gated. + + Args: + repo_id (`str`): + The id of the repo to cancel access request for. + user (`str`): + The username of the user which access request should be cancelled. + repo_type (`str`, *optional*): + The type of the repo to cancel access request for. Must be one of `model`, `dataset` or `space`. + Defaults to `model`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Raises: + [`HfHubHTTPError`]: + HTTP 400 if the repo is not gated. + [`HfHubHTTPError`]: + HTTP 403 if you only have read-only access to the repo. This can be the case if you don't have `write` + or `admin` role in the organization the repo belongs to or if you passed a `read` token. + [`HfHubHTTPError`]: + HTTP 404 if the user does not exist on the Hub. + [`HfHubHTTPError`]: + HTTP 404 if the user access request cannot be found. + [`HfHubHTTPError`]: + HTTP 404 if the user access request is already in the pending list. + """ + self._handle_access_request(repo_id, user, "pending", repo_type=repo_type, token=token) + + @validate_hf_hub_args + def accept_access_request( + self, repo_id: str, user: str, *, repo_type: str | None = None, token: bool | str | None = None + ) -> None: + """ + Accept an access request from a user for a given gated repo. + + Once the request is accepted, the user will be able to download any file of the repo and access the community + tab. If the approval mode is automatic, you don't have to accept requests manually. An accepted request can be + cancelled or rejected at any time using [`cancel_access_request`] and [`reject_access_request`]. + + For more info about gated repos, see https://huggingface.co/docs/hub/models-gated. + + Args: + repo_id (`str`): + The id of the repo to accept access request for. + user (`str`): + The username of the user which access request should be accepted. + repo_type (`str`, *optional*): + The type of the repo to accept access request for. Must be one of `model`, `dataset` or `space`. + Defaults to `model`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Raises: + [`HfHubHTTPError`]: + HTTP 400 if the repo is not gated. + [`HfHubHTTPError`]: + HTTP 403 if you only have read-only access to the repo. This can be the case if you don't have `write` + or `admin` role in the organization the repo belongs to or if you passed a `read` token. + [`HfHubHTTPError`]: + HTTP 404 if the user does not exist on the Hub. + [`HfHubHTTPError`]: + HTTP 404 if the user access request cannot be found. + [`HfHubHTTPError`]: + HTTP 404 if the user access request is already in the accepted list. + """ + self._handle_access_request(repo_id, user, "accepted", repo_type=repo_type, token=token) + + @validate_hf_hub_args + def reject_access_request( + self, + repo_id: str, + user: str, + *, + repo_type: str | None = None, + rejection_reason: str | None, + token: bool | str | None = None, + ) -> None: + """ + Reject an access request from a user for a given gated repo. + + A rejected request will go to the rejected list. The user cannot download any file of the repo. Rejected + requests can be accepted or cancelled at any time using [`accept_access_request`] and [`cancel_access_request`]. + A cancelled request will go back to the pending list while an accepted request will go to the accepted list. + + For more info about gated repos, see https://huggingface.co/docs/hub/models-gated. + + Args: + repo_id (`str`): + The id of the repo to reject access request for. + user (`str`): + The username of the user which access request should be rejected. + repo_type (`str`, *optional*): + The type of the repo to reject access request for. Must be one of `model`, `dataset` or `space`. + Defaults to `model`. + rejection_reason (`str`, *optional*): + Optional rejection reason that will be visible to the user (max 200 characters). + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Raises: + [`HfHubHTTPError`]: + HTTP 400 if the repo is not gated. + [`HfHubHTTPError`]: + HTTP 403 if you only have read-only access to the repo. This can be the case if you don't have `write` + or `admin` role in the organization the repo belongs to or if you passed a `read` token. + [`HfHubHTTPError`]: + HTTP 404 if the user does not exist on the Hub. + [`HfHubHTTPError`]: + HTTP 404 if the user access request cannot be found. + [`HfHubHTTPError`]: + HTTP 404 if the user access request is already in the rejected list. + """ + self._handle_access_request( + repo_id, user, "rejected", repo_type=repo_type, rejection_reason=rejection_reason, token=token + ) + + @validate_hf_hub_args + def _handle_access_request( + self, + repo_id: str, + user: str, + status: Literal["accepted", "rejected", "pending"], + repo_type: str | None = None, + rejection_reason: str | None = None, + token: bool | str | None = None, + ) -> None: + if repo_type not in constants.REPO_TYPES: + raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}") + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + + payload = {"user": user, "status": status} + + if rejection_reason is not None: + if status != "rejected": + raise ValueError("`rejection_reason` can only be passed when rejecting an access request.") + payload["rejectionReason"] = rejection_reason + + response = get_session().post( + f"{constants.ENDPOINT}/api/{repo_type}s/{repo_id}/user-access-request/handle", + headers=self._build_hf_headers(token=token), + json=payload, + ) + hf_raise_for_status(response) + + @validate_hf_hub_args + def grant_access( + self, repo_id: str, user: str, *, repo_type: str | None = None, token: bool | str | None = None + ) -> None: + """ + Grant access to a user for a given gated repo. + + Granting access don't require for the user to send an access request by themselves. The user is automatically + added to the accepted list meaning they can download the files You can revoke the granted access at any time + using [`cancel_access_request`] or [`reject_access_request`]. + + For more info about gated repos, see https://huggingface.co/docs/hub/models-gated. + + Args: + repo_id (`str`): + The id of the repo to grant access to. + user (`str`): + The username of the user to grant access. + repo_type (`str`, *optional*): + The type of the repo to grant access to. Must be one of `model`, `dataset` or `space`. + Defaults to `model`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Raises: + [`HfHubHTTPError`]: + HTTP 400 if the repo is not gated. + [`HfHubHTTPError`]: + HTTP 400 if the user already has access to the repo. + [`HfHubHTTPError`]: + HTTP 403 if you only have read-only access to the repo. This can be the case if you don't have `write` + or `admin` role in the organization the repo belongs to or if you passed a `read` token. + [`HfHubHTTPError`]: + HTTP 404 if the user does not exist on the Hub. + """ + if repo_type not in constants.REPO_TYPES: + raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}") + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + + response = get_session().post( + f"{constants.ENDPOINT}/api/{repo_type}s/{repo_id}/user-access-request/grant", + headers=self._build_hf_headers(token=token), + json={"user": user}, + ) + hf_raise_for_status(response) + return response.json() + + ################### + # Manage webhooks # + ################### + + @validate_hf_hub_args + def get_webhook(self, webhook_id: str, *, token: bool | str | None = None) -> WebhookInfo: + """Get a webhook by its id. + + Args: + webhook_id (`str`): + The unique identifier of the webhook to get. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved token, which is the recommended + method for authentication (see https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`WebhookInfo`]: + Info about the webhook. + + Example: + ```python + >>> from huggingface_hub import get_webhook + >>> webhook = get_webhook("654bbbc16f2ec14d77f109cc") + >>> print(webhook) + WebhookInfo( + id="654bbbc16f2ec14d77f109cc", + job=None, + watched=[WebhookWatchedItem(type="user", name="julien-c"), WebhookWatchedItem(type="org", name="HuggingFaceH4")], + url="https://webhook.site/a2176e82-5720-43ee-9e06-f91cb4c91548", + secret="my-secret", + domains=["repo", "discussion"], + disabled=False, + ) + ``` + """ + response = get_session().get( + f"{constants.ENDPOINT}/api/settings/webhooks/{webhook_id}", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + webhook_data = response.json()["webhook"] + + watched_items = [WebhookWatchedItem(type=item["type"], name=item["name"]) for item in webhook_data["watched"]] + + webhook = WebhookInfo( + id=webhook_data["id"], + url=webhook_data.get("url"), + job=JobSpec(**webhook_data["job"]) if webhook_data.get("job") else None, + watched=watched_items, + domains=webhook_data["domains"], + secret=webhook_data.get("secret"), + disabled=webhook_data["disabled"], + ) + + return webhook + + @validate_hf_hub_args + def list_webhooks(self, *, token: bool | str | None = None) -> list[WebhookInfo]: + """List all configured webhooks. + + Args: + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved token, which is the recommended + method for authentication (see https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `list[WebhookInfo]`: + List of webhook info objects. + + Example: + ```python + >>> from huggingface_hub import list_webhooks + >>> webhooks = list_webhooks() + >>> len(webhooks) + 2 + >>> webhooks[0] + WebhookInfo( + id="654bbbc16f2ec14d77f109cc", + watched=[WebhookWatchedItem(type="user", name="julien-c"), WebhookWatchedItem(type="org", name="HuggingFaceH4")], + url="https://webhook.site/a2176e82-5720-43ee-9e06-f91cb4c91548", + secret="my-secret", + domains=["repo", "discussion"], + disabled=False, + ) + ``` + """ + response = get_session().get( + f"{constants.ENDPOINT}/api/settings/webhooks", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + webhooks_data = response.json() + + return [ + WebhookInfo( + id=webhook["id"], + url=webhook.get("url"), + job=JobSpec(**webhook["job"]) if webhook.get("job") else None, + watched=[WebhookWatchedItem(type=item["type"], name=item["name"]) for item in webhook["watched"]], + domains=webhook["domains"], + secret=webhook.get("secret"), + disabled=webhook["disabled"], + ) + for webhook in webhooks_data + ] + + @validate_hf_hub_args + def create_webhook( + self, + *, + url: str | None = None, + job_id: str | None = None, + watched: list[dict | WebhookWatchedItem], + domains: list[constants.WEBHOOK_DOMAIN_T] | None = None, + secret: str | None = None, + token: bool | str | None = None, + ) -> WebhookInfo: + """Create a new webhook. + + The webhook can either send a payload to a URL, or trigger a Job to run on Hugging Face infrastructure. + This function should be called with one of `url` or `job_id`, but not both. + + Args: + url (`str`): + URL to send the payload to. + job_id (`str`): + ID of the source Job to trigger with the webhook payload in the environment variable WEBHOOK_PAYLOAD. + Additional environment variables are available for convenience: WEBHOOK_REPO_ID, WEBHOOK_REPO_TYPE and WEBHOOK_SECRET. + watched (`list[WebhookWatchedItem]`): + List of [`WebhookWatchedItem`] to be watched by the webhook. It can be users, orgs, models, datasets or spaces. + Watched items can also be provided as plain dictionaries. + domains (`list[Literal["repo", "discussion"]]`, optional): + List of domains to watch. It can be "repo", "discussion" or both. + secret (`str`, optional): + A secret to sign the payload with. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved token, which is the recommended + method for authentication (see https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`WebhookInfo`]: + Info about the newly created webhook. + + Example: + + Create a webhook that sends a payload to a URL + ```python + >>> from huggingface_hub import create_webhook + >>> payload = create_webhook( + ... watched=[{"type": "user", "name": "julien-c"}, {"type": "org", "name": "HuggingFaceH4"}], + ... url="https://webhook.site/a2176e82-5720-43ee-9e06-f91cb4c91548", + ... domains=["repo", "discussion"], + ... secret="my-secret", + ... ) + >>> print(payload) + WebhookInfo( + id="654bbbc16f2ec14d77f109cc", + url="https://webhook.site/a2176e82-5720-43ee-9e06-f91cb4c91548", + job=None, + watched=[WebhookWatchedItem(type="user", name="julien-c"), WebhookWatchedItem(type="org", name="HuggingFaceH4")], + domains=["repo", "discussion"], + secret="my-secret", + disabled=False, + ) + ``` + + Run a Job and then create a webhook that triggers this Job + ```python + >>> from huggingface_hub import create_webhook, run_job + >>> job = run_job( + ... image="ubuntu", + ... command=["bash", "-c", r"echo An event occurred in $WEBHOOK_REPO_ID: $WEBHOOK_PAYLOAD"], + ... ) + >>> payload = create_webhook( + ... watched=[{"type": "user", "name": "julien-c"}, {"type": "org", "name": "HuggingFaceH4"}], + ... job_id=job.id, + ... domains=["repo", "discussion"], + ... secret="my-secret", + ... ) + >>> print(payload) + WebhookInfo( + id="654bbbc16f2ec14d77f109cc", + url=None, + job=JobSpec( + docker_image='ubuntu', + space_id=None, + command=['bash', '-c', 'echo An event occurred in $WEBHOOK_REPO_ID: $WEBHOOK_PAYLOAD'], + arguments=[], + environment={}, + secrets=[], + flavor='cpu-basic', + timeout=None, + tags=None, + arch=None + ), + watched=[WebhookWatchedItem(type="user", name="julien-c"), WebhookWatchedItem(type="org", name="HuggingFaceH4")], + domains=["repo", "discussion"], + secret="my-secret", + disabled=False, + ) + ``` + """ + watched_dicts = [asdict(item) if isinstance(item, WebhookWatchedItem) else item for item in watched] + + post_webhooks_json: dict = {"watched": watched_dicts} + if domains is not None: + post_webhooks_json["domains"] = domains + if secret is not None: + post_webhooks_json["secret"] = secret + if url is not None and job_id is not None: + raise ValueError("Set `url` or `job_id` but not both.") + elif url is not None: + post_webhooks_json["url"] = url + elif job_id is not None: + post_webhooks_json["jobSourceId"] = job_id + else: + raise ValueError("Missing argument for webhook: `url` or `job_id`.") + + response = get_session().post( + f"{constants.ENDPOINT}/api/settings/webhooks", + json=post_webhooks_json, + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + webhook_data = response.json()["webhook"] + watched_items = [WebhookWatchedItem(type=item["type"], name=item["name"]) for item in webhook_data["watched"]] + + webhook = WebhookInfo( + id=webhook_data["id"], + url=webhook_data.get("url"), + job=JobSpec(**webhook_data["job"]) if webhook_data.get("job") else None, + watched=watched_items, + domains=webhook_data["domains"], + secret=webhook_data.get("secret"), + disabled=webhook_data["disabled"], + ) + + return webhook + + @validate_hf_hub_args + def update_webhook( + self, + webhook_id: str, + *, + url: str | None = None, + watched: list[dict | WebhookWatchedItem] | None = None, + domains: list[constants.WEBHOOK_DOMAIN_T] | None = None, + secret: str | None = None, + token: bool | str | None = None, + ) -> WebhookInfo: + """Update an existing webhook. + + Args: + webhook_id (`str`): + The unique identifier of the webhook to be updated. + url (`str`, optional): + The URL to which the payload will be sent. + watched (`list[WebhookWatchedItem]`, optional): + List of items to watch. It can be users, orgs, models, datasets, or spaces. + Refer to [`WebhookWatchedItem`] for more details. Watched items can also be provided as plain dictionaries. + domains (`list[Literal["repo", "discussion"]]`, optional): + The domains to watch. This can include "repo", "discussion", or both. + secret (`str`, optional): + A secret to sign the payload with, providing an additional layer of security. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved token, which is the recommended + method for authentication (see https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`WebhookInfo`]: + Info about the updated webhook. + + Example: + ```python + >>> from huggingface_hub import update_webhook + >>> updated_payload = update_webhook( + ... webhook_id="654bbbc16f2ec14d77f109cc", + ... url="https://new.webhook.site/a2176e82-5720-43ee-9e06-f91cb4c91548", + ... watched=[{"type": "user", "name": "julien-c"}, {"type": "org", "name": "HuggingFaceH4"}], + ... domains=["repo"], + ... secret="my-secret", + ... ) + >>> print(updated_payload) + WebhookInfo( + id="654bbbc16f2ec14d77f109cc", + job=None, + url="https://new.webhook.site/a2176e82-5720-43ee-9e06-f91cb4c91548", + watched=[WebhookWatchedItem(type="user", name="julien-c"), WebhookWatchedItem(type="org", name="HuggingFaceH4")], + domains=["repo"], + secret="my-secret", + disabled=False, + ``` + """ + if watched is None: + watched = [] + watched_dicts = [asdict(item) if isinstance(item, WebhookWatchedItem) else item for item in watched] + + update_json: dict = {"watched": watched_dicts} + if url is not None: + update_json["url"] = url + if domains is not None: + update_json["domains"] = domains + if secret is not None: + update_json["secret"] = secret + + response = get_session().post( + f"{constants.ENDPOINT}/api/settings/webhooks/{webhook_id}", + json=update_json, + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + webhook_data = response.json()["webhook"] + + watched_items = [WebhookWatchedItem(type=item["type"], name=item["name"]) for item in webhook_data["watched"]] + + webhook = WebhookInfo( + id=webhook_data["id"], + url=webhook_data.get("url"), + job=JobSpec(**webhook_data["job"]) if webhook_data.get("job") else None, + watched=watched_items, + domains=webhook_data["domains"], + secret=webhook_data.get("secret"), + disabled=webhook_data["disabled"], + ) + + return webhook + + @validate_hf_hub_args + def enable_webhook(self, webhook_id: str, *, token: bool | str | None = None) -> WebhookInfo: + """Enable a webhook (makes it "active"). + + Args: + webhook_id (`str`): + The unique identifier of the webhook to enable. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved token, which is the recommended + method for authentication (see https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`WebhookInfo`]: + Info about the enabled webhook. + + Example: + ```python + >>> from huggingface_hub import enable_webhook + >>> enabled_webhook = enable_webhook("654bbbc16f2ec14d77f109cc") + >>> enabled_webhook + WebhookInfo( + id="654bbbc16f2ec14d77f109cc", + job=None, + url="https://webhook.site/a2176e82-5720-43ee-9e06-f91cb4c91548", + watched=[WebhookWatchedItem(type="user", name="julien-c"), WebhookWatchedItem(type="org", name="HuggingFaceH4")], + domains=["repo", "discussion"], + secret="my-secret", + disabled=False, + ) + ``` + """ + response = get_session().post( + f"{constants.ENDPOINT}/api/settings/webhooks/{webhook_id}/enable", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + webhook_data = response.json()["webhook"] + + watched_items = [WebhookWatchedItem(type=item["type"], name=item["name"]) for item in webhook_data["watched"]] + + webhook = WebhookInfo( + id=webhook_data["id"], + url=webhook_data.get("url"), + job=JobSpec(**webhook_data["job"]) if webhook_data.get("job") else None, + watched=watched_items, + domains=webhook_data["domains"], + secret=webhook_data.get("secret"), + disabled=webhook_data["disabled"], + ) + + return webhook + + @validate_hf_hub_args + def disable_webhook(self, webhook_id: str, *, token: bool | str | None = None) -> WebhookInfo: + """Disable a webhook (makes it "disabled"). + + Args: + webhook_id (`str`): + The unique identifier of the webhook to disable. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved token, which is the recommended + method for authentication (see https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`WebhookInfo`]: + Info about the disabled webhook. + + Example: + ```python + >>> from huggingface_hub import disable_webhook + >>> disabled_webhook = disable_webhook("654bbbc16f2ec14d77f109cc") + >>> disabled_webhook + WebhookInfo( + id="654bbbc16f2ec14d77f109cc", + url="https://webhook.site/a2176e82-5720-43ee-9e06-f91cb4c91548", + jon=None, + watched=[WebhookWatchedItem(type="user", name="julien-c"), WebhookWatchedItem(type="org", name="HuggingFaceH4")], + domains=["repo", "discussion"], + secret="my-secret", + disabled=True, + ) + ``` + """ + response = get_session().post( + f"{constants.ENDPOINT}/api/settings/webhooks/{webhook_id}/disable", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + webhook_data = response.json()["webhook"] + + watched_items = [WebhookWatchedItem(type=item["type"], name=item["name"]) for item in webhook_data["watched"]] + + webhook = WebhookInfo( + id=webhook_data["id"], + url=webhook_data.get("url"), + job=JobSpec(**webhook_data["job"]) if webhook_data.get("job") else None, + watched=watched_items, + domains=webhook_data["domains"], + secret=webhook_data.get("secret"), + disabled=webhook_data["disabled"], + ) + + return webhook + + @validate_hf_hub_args + def delete_webhook(self, webhook_id: str, *, token: bool | str | None = None) -> None: + """Delete a webhook. + + Args: + webhook_id (`str`): + The unique identifier of the webhook to delete. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved token, which is the recommended + method for authentication (see https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `None` + + Example: + ```python + >>> from huggingface_hub import delete_webhook + >>> delete_webhook("654bbbc16f2ec14d77f109cc") + ``` + """ + response = get_session().delete( + f"{constants.ENDPOINT}/api/settings/webhooks/{webhook_id}", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + + ############# + # Internals # + ############# + + def _build_hf_headers( + self, + token: bool | str | None = None, + library_name: str | None = None, + library_version: str | None = None, + user_agent: dict | str | None = None, + ) -> dict[str, str]: + """ + Alias for [`build_hf_headers`] that uses the token from [`HfApi`] client + when `token` is not provided. + """ + if token is None: + # Cannot do `token = token or self.token` as token can be `False`. + token = self.token + return build_hf_headers( + token=token, + library_name=library_name or self.library_name, + library_version=library_version or self.library_version, + user_agent=user_agent or self.user_agent, + headers=self.headers, + ) + + def _prepare_folder_deletions( + self, + repo_id: str, + repo_type: str | None, + revision: str | None, + path_in_repo: str, + delete_patterns: list[str] | str | None, + token: bool | str | None = None, + ) -> list[CommitOperationDelete]: + """Generate the list of Delete operations for a commit to delete files from a repo. + + List remote files and match them against the `delete_patterns` constraints. Returns a list of [`CommitOperationDelete`] + with the matching items. + + Note: `.gitattributes` file is essential to make a repo work properly on the Hub. This file will always be + kept even if it matches the `delete_patterns` constraints. + """ + if delete_patterns is None: + # If no delete patterns, no need to list and filter remote files + return [] + + # List remote files + filenames = self.list_repo_files(repo_id=repo_id, revision=revision, repo_type=repo_type, token=token) + + # Compute relative path in repo + if path_in_repo and path_in_repo not in (".", "./"): + path_in_repo = path_in_repo.strip("/") + "/" # harmonize + relpath_to_abspath = { + file[len(path_in_repo) :]: file for file in filenames if file.startswith(path_in_repo) + } + else: + relpath_to_abspath = {file: file for file in filenames} + + # Apply filter on relative paths and return + return [ + CommitOperationDelete(path_in_repo=relpath_to_abspath[relpath], is_folder=False) + for relpath in filter_repo_objects(relpath_to_abspath.keys(), allow_patterns=delete_patterns) + if relpath_to_abspath[relpath] != ".gitattributes" + ] + + def _prepare_upload_folder_additions( + self, + folder_path: str | Path, + path_in_repo: str, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + repo_type: str | None = None, + token: bool | str | None = None, + ) -> list[CommitOperationAdd]: + """Generate the list of Add operations for a commit to upload a folder. + + Files not matching the `allow_patterns` (allowlist) and `ignore_patterns` (denylist) + constraints are discarded. + """ + + folder_path = Path(folder_path).expanduser().resolve() + if not folder_path.is_dir(): + raise ValueError(f"Provided path: '{folder_path}' is not a directory") + + # List files from folder + relpath_to_abspath = { + path.relative_to(folder_path).as_posix(): path + for path in sorted(folder_path.glob("**/*")) # sorted to be deterministic + if path.is_file() + } + + # Filter files + # Patterns are applied on the path relative to `folder_path`. `path_in_repo` is prefixed after the filtering. + filtered_repo_objects = list( + filter_repo_objects( + relpath_to_abspath.keys(), allow_patterns=allow_patterns, ignore_patterns=ignore_patterns + ) + ) + + prefix = f"{path_in_repo.strip('/')}/" if path_in_repo else "" + + # If updating a README.md file, make sure the metadata format is valid + # It's better to fail early than to fail after all the files have been hashed. + if "README.md" in filtered_repo_objects: + self._validate_yaml( + content=relpath_to_abspath["README.md"].read_text(encoding="utf8"), + repo_type=repo_type, + token=token, + ) + return [ + CommitOperationAdd( + path_or_fileobj=relpath_to_abspath[relpath], # absolute path on disk + path_in_repo=prefix + relpath, # "absolute" path in repo + ) + for relpath in filtered_repo_objects + ] + + def _validate_yaml(self, content: str, *, repo_type: str | None = None, token: bool | str | None = None): + """ + Validate YAML from `README.md`, used before file hashing and upload. + + Args: + content (`str`): + Content of `README.md` to validate. + repo_type (`str`, *optional*): + The type of the repo to grant access to. Must be one of `model`, `dataset` or `space`. + Defaults to `model`. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Raises: + - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + if YAML is invalid + """ + repo_type = repo_type if repo_type is not None else constants.REPO_TYPE_MODEL + headers = self._build_hf_headers(token=token) + + response = get_session().post( + f"{self.endpoint}/api/validate-yaml", + json={"content": content, "repoType": repo_type}, + headers=headers, + ) + # Handle warnings (example: empty metadata) + response_content = response.json() + message = "\n".join([f"- {warning.get('message')}" for warning in response_content.get("warnings", [])]) + if message: + warnings.warn(f"Warnings while validating metadata in README.md:\n{message}") + + # Raise on errors + try: + hf_raise_for_status(response) + except BadRequestError as e: + errors = response_content.get("errors", []) + message = "\n".join([f"- {error.get('message')}" for error in errors]) + raise ValueError(f"Invalid metadata in README.md.\n{message}") from e + + def get_user_overview(self, username: str, token: bool | str | None = None) -> User: + """ + Get an overview of a user on the Hub. + + Args: + username (`str`): + Username of the user to get an overview of. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `User`: A [`User`] object with the user's overview. + + Raises: + [`HfHubHTTPError`]: + HTTP 404 If the user does not exist on the Hub. + """ + r = get_session().get( + f"{constants.ENDPOINT}/api/users/{username}/overview", headers=self._build_hf_headers(token=token) + ) + hf_raise_for_status(r) + return User(**r.json()) + + @validate_hf_hub_args + def get_organization_overview(self, organization: str, token: bool | str | None = None) -> Organization: + """ + Get an overview of an organization on the Hub. + + Args: + organization (`str`): + Name of the organization to get an overview of. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved token, which is the recommended method + for authentication (see https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Organization`: An [`Organization`] object with the organization's overview. + + Raises: + [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError): + HTTP 404 If the organization does not exist on the Hub. + """ + r = get_session().get( + f"{constants.ENDPOINT}/api/organizations/{organization}/overview", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(r) + return Organization(**r.json()) + + @validate_hf_hub_args + def list_organization_followers(self, organization: str, token: bool | str | None = None) -> Iterable[User]: + """ + List followers of an organization on the Hub. + + Args: + organization (`str`): + Name of the organization to get the followers of. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[User]`: A list of [`User`] objects with the followers of the organization. + + Raises: + [`HfHubHTTPError`]: + HTTP 404 If the organization does not exist on the Hub. + + """ + for follower in paginate( + path=f"{constants.ENDPOINT}/api/organizations/{organization}/followers", + params={}, + headers=self._build_hf_headers(token=token), + ): + yield User(**follower) + + def list_organization_members(self, organization: str, token: bool | str | None = None) -> Iterable[User]: + """ + List of members of an organization on the Hub. + + Args: + organization (`str`): + Name of the organization to get the members of. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[User]`: A list of [`User`] objects with the members of the organization. + + Raises: + [`HfHubHTTPError`]: + HTTP 404 If the organization does not exist on the Hub. + + """ + for member in paginate( + path=f"{constants.ENDPOINT}/api/organizations/{organization}/members", + params={}, + headers=self._build_hf_headers(token=token), + ): + yield User(**member) + + def list_user_followers(self, username: str, token: bool | str | None = None) -> Iterable[User]: + """ + Get the list of followers of a user on the Hub. + + Args: + username (`str`): + Username of the user to get the followers of. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[User]`: A list of [`User`] objects with the followers of the user. + + Raises: + [`HfHubHTTPError`]: + HTTP 404 If the user does not exist on the Hub. + + """ + for follower in paginate( + path=f"{constants.ENDPOINT}/api/users/{username}/followers", + params={}, + headers=self._build_hf_headers(token=token), + ): + yield User(**follower) + + def list_user_following(self, username: str, token: bool | str | None = None) -> Iterable[User]: + """ + Get the list of users followed by a user on the Hub. + + Args: + username (`str`): + Username of the user to get the users followed by. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[User]`: A list of [`User`] objects with the users followed by the user. + + Raises: + [`HfHubHTTPError`]: + HTTP 404 If the user does not exist on the Hub. + + """ + for followed_user in paginate( + path=f"{constants.ENDPOINT}/api/users/{username}/following", + params={}, + headers=self._build_hf_headers(token=token), + ): + yield User(**followed_user) + + def list_papers( + self, + *, + query: str | None = None, + limit: int | None = None, + token: bool | str | None = None, + ) -> Iterable[PaperInfo]: + """ + List daily papers on the Hugging Face Hub given a search query. + + Args: + query (`str`, *optional*): + A search query string to find papers. + If provided, returns papers that match the query. + limit (`int`, *optional*): + The maximum number of papers to return. + token (Union[bool, str, None], *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[PaperInfo]`: an iterable of [`huggingface_hub.hf_api.PaperInfo`] objects. + + Example: + + ```python + >>> from huggingface_hub import HfApi + + >>> api = HfApi() + + # List all papers with "attention" in their title + >>> api.list_papers(query="attention") + ``` + """ + path = f"{self.endpoint}/api/papers/search" + params: dict[str, Any] = {} + if query: + params["q"] = query + if limit is not None: + params["limit"] = limit + r = get_session().get( + path, + params=params, + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(r) + for paper in r.json(): + yield PaperInfo(**paper) + + def paper_info(self, id: str) -> PaperInfo: + """ + Get information for a paper on the Hub. + + Args: + id (`str`, **optional**): + ArXiv id of the paper. + + Returns: + `PaperInfo`: A `PaperInfo` object. + + Raises: + [`HfHubHTTPError`]: + HTTP 404 If the paper does not exist on the Hub. + """ + path = f"{self.endpoint}/api/papers/{id}" + r = get_session().get(path) + hf_raise_for_status(r) + return PaperInfo(**r.json()) + + def read_paper(self, id: str) -> str: + """ + Get the markdown content of a paper page on the Hub. + + Args: + id (`str`): + ArXiv id of the paper. + + Returns: + `str`: The paper page content as markdown. + + Raises: + [`HfHubHTTPError`]: + HTTP 404 If the paper does not exist on the Hub. + """ + path = f"{self.endpoint}/papers/{id}.md" + r = get_session().get(path) + hf_raise_for_status(r) + return r.text + + def list_daily_papers( + self, + *, + date: str | None = None, + token: bool | str | None = None, + week: str | None = None, + month: str | None = None, + submitter: str | None = None, + sort: DailyPapersSort_T | None = None, + p: int | None = None, + limit: int | None = None, + ) -> Iterable[PaperInfo]: + """ + List the daily papers published on a given date on the Hugging Face Hub. + + Args: + date (`str`, *optional*): + Date in ISO format (YYYY-MM-DD) for which to fetch daily papers. + Defaults to most recent ones. + token (Union[bool, str, None], *optional*): + A valid user access token (string). Defaults to the locally saved + token. To disable authentication, pass `False`. + week (`str`, *optional*): + Week in ISO format (YYYY-Www) for which to fetch daily papers. Example, `2025-W09`. + month (`str`, *optional*): + Month in ISO format (YYYY-MM) for which to fetch daily papers. Example, `2025-02`. + submitter (`str`, *optional*): + Username of the submitter to filter daily papers. + sort (`Literal["publishedAt", "trending"]`, *optional*): + Sort order for the daily papers. Can be either by `publishedAt` or by `trending`. + Defaults to `"publishedAt"` + p (`int`, *optional*): + Page number for pagination. Defaults to 0. + limit (`int`, *optional*): + Limit of papers to fetch. Defaults to 50. + + Returns: + `Iterable[PaperInfo]`: an iterable of [`huggingface_hub.hf_api.PaperInfo`] objects. + + Example: + + ```python + >>> from huggingface_hub import HfApi + + >>> api = HfApi() + >>> list(api.list_daily_papers(date="2025-10-29")) + ``` + """ + path = f"{self.endpoint}/api/daily_papers" + + params = { + k: v + for k, v in { + "p": p, + "limit": limit, + "sort": sort, + "date": date, + "week": week, + "month": month, + "submitter": submitter, + }.items() + if v is not None + } + + r = get_session().get(path, params=params, headers=self._build_hf_headers(token=token)) + hf_raise_for_status(r) + for paper in r.json(): + yield PaperInfo(**paper) + + def auth_check( + self, + repo_id: str, + *, + repo_type: str | None = None, + token: bool | str | None = None, + write: bool = False, + ) -> None: + """ + Check if the provided user token has access to a specific repository on the Hugging Face Hub. + + This method verifies whether the user, authenticated via the provided token, has access to the specified + repository. If the repository is not found or if the user lacks the required permissions to access it, + the method raises an appropriate exception. + + Args: + repo_id (`str`): + The repository to check for access. Format should be `"user/repo_name"`. + Example: `"user/my-cool-model"`. + + repo_type (`str`, *optional*): + The type of the repository. Should be one of `"model"`, `"dataset"`, or `"space"`. + If not specified, the default is `"model"`. + + token (`Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + write (`bool`, *optional*): + If `True`, checks whether the user has content write permission on the repository. + If `False` (default), only checks for read access. + + Raises: + [`~utils.RepositoryNotFoundError`]: + Raised if the repository does not exist, is private, or the user does not have access. This can + occur if the `repo_id` or `repo_type` is incorrect or if the repository is private but the user + is not authenticated. + + [`~utils.GatedRepoError`]: + Raised if the repository exists but is gated and the user is not authorized to access it. + + Example: + Check if the user has access to a repository: + + ```python + >>> from huggingface_hub import auth_check + >>> from huggingface_hub.utils import GatedRepoError, RepositoryNotFoundError + + try: + auth_check("user/my-cool-model") + except GatedRepoError: + # Handle gated repository error + print("You do not have permission to access this gated repository.") + except RepositoryNotFoundError: + # Handle repository not found error + print("The repository was not found or you do not have access.") + ``` + + In this example: + - If the user has access, the method completes successfully. + - If the repository is gated or does not exist, appropriate exceptions are raised, allowing the user + to handle them accordingly. + """ + headers = self._build_hf_headers(token=token) + if repo_type is None: + repo_type = constants.REPO_TYPE_MODEL + if repo_type not in constants.REPO_TYPES: + raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}") + path = f"{self.endpoint}/api/{repo_type}s/{repo_id}/auth-check" + if write: + path = f"{path}/write" + r = get_session().get(path, headers=headers) + hf_raise_for_status(r) + + def run_job( + self, + *, + image: str, + command: list[str], + env: dict[str, Any] | None = None, + secrets: dict[str, Any] | None = None, + flavor: JobHardware | str | None = None, + timeout: int | float | str | None = None, + labels: dict[str, str] | None = None, + volumes: list[Volume] | None = None, + expose: list[int] | None = None, + ssh: bool = False, + namespace: str | None = None, + token: bool | str | None = None, + ) -> JobInfo: + """ + Run compute Jobs on Hugging Face infrastructure. + + Args: + image (`str`): + The Docker image to use. + Examples: `"ubuntu"`, `"python:3.12"`, `"pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel"`. + Example with an image from a Space: `"hf.co/spaces/lhoestq/duckdb"`. + + command (`list[str]`): + The command to run. Example: `["echo", "hello"]`. + + env (`dict[str, Any]`, *optional*): + Defines the environment variables for the Job. + + secrets (`dict[str, Any]`, *optional*): + Defines the secret environment variables for the Job. + + flavor (`str`, *optional*): + Flavor for the hardware. See [`JobHardware`] for possible values. + Defaults to `"cpu-basic"`. + + timeout (`Union[int, float, str]`, *optional*): + Max duration for the Job: int with s (seconds, default), m (minutes), h (hours) or d (days). + Example: `300` or `"5m"` for 5 minutes. + + labels (`dict[str, str]`, *optional*): + Labels to attach to the job (key-value pairs). + + volumes (`list[Volume]`, *optional*): + Hugging Face Buckets or Repos to mount as volumes in the job container. + Each volume is a [`Volume`] with `type` (`"bucket"`, `"model"`, `"dataset"`, or `"space"`), + `source` (e.g. `"username/my-bucket"`), and `mount_path` (e.g. `"/data"`). + + expose (`list[int]`, *optional*): + Container ports to expose through the jobs proxy. Each listed port is reachable + on the public jobs domain (e.g. `https://--8000.hf.jobs`). Access always + requires an HF token with read access to the job's namespace. + + ssh (`bool`, *optional*): + If True, the job's container is reachable over SSH at the URL given by `job.status.ssh_url` + (e.g. `ssh @ssh.hf.jobs`, or `hf jobs ssh ` from the CLI). Connecting requires + write access to the job's namespace and an SSH public key registered on the Hub + (https://huggingface.co/settings/keys). Defaults to False. + + namespace (`str`, *optional*): + The namespace where the Job will be created. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Example: + Run your first Job: + + ```python + >>> from huggingface_hub import run_job + >>> run_job(image="python:3.12", command=["python", "-c" ,"print('Hello from HF compute!')"]) + ``` + + Run a GPU Job: + + ```python + >>> from huggingface_hub import run_job + >>> image = "pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel" + >>> command = ["python", "-c", "import torch; print(f"This code ran with the following GPU: {torch.cuda.get_device_name()}")"] + >>> run_job(image=image, command=command, flavor="a10g-small") + ``` + + Run a Job with volumes: + + ```python + >>> from huggingface_hub import Volume, run_job + >>> dataset_volume = Volume(type="dataset", source="HuggingFaceFW/fineweb", mount_path="/data") + >>> output_bucket_volume = Volume(type="bucket", source="username/my-bucket", mount_path="/output") + >>> image = "duckdb/duckdb" + >>> command = ["duckdb", "-c", "COPY (SELECT * FROM '/data/**/*.parquet' LIMIT 5) TO '/output/first-rows.parquet'"] + >>> run_job(image=image, command=command, volumes=[dataset_volume, output_bucket_volume]) + ``` + + """ + if namespace is None: + namespace = self.whoami(token=token)["name"] + job_spec = _create_job_spec( + image=image, + command=command, + env=env, + secrets=secrets, + flavor=flavor, + timeout=timeout, + labels=labels, + volumes=volumes, + expose=expose, + ssh=ssh, + ) + response = get_session().post( + f"{self.endpoint}/api/jobs/{namespace}", + json=job_spec, + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + job_info = response.json() + return JobInfo(**job_info, endpoint=self.endpoint) + + def _fetch_running_job_sse( + self, + *, + job_id: str, + route: str, + timeout: int, + skip_previous_events_on_retry: bool, + tolerated_status_codes: tuple[int, ...] = (), + tolerated_exception_types: tuple[type[Exception], ...] = (), + follow: bool = True, + namespace: str | None = None, + token: bool | str | None = None, + params: dict[str, Any] | None = None, + ) -> Iterable[dict[str, Any]]: + if namespace is None: + namespace = self.whoami(token=token)["name"] + + def has_job_finished() -> bool: + # We don't use http_backoff: this is the authoritative check that + # decides whether to keep streaming. + job_status_response = get_session().get( + f"{self.endpoint}/api/jobs/{namespace}/{job_id}", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(job_status_response) + job_status = job_status_response.json() + return "status" in job_status and job_status["status"]["stage"] not in ("RUNNING", "UPDATING") + + yield from self._stream_sse_events( + url=f"{self.endpoint}/api/jobs/{namespace}/{job_id}/{route}", + log_label=f"jobs /{route} for {job_id=}", + timeout=timeout, + follow=follow, + token=token, + skip_previous_events_on_retry=skip_previous_events_on_retry, + tolerated_status_codes=tolerated_status_codes, + tolerated_exception_types=tolerated_exception_types, + on_iteration_end=has_job_finished, + params=params, + ) + + def fetch_job_logs( + self, + *, + job_id: str, + namespace: str | None = None, + follow: bool = False, + tail: int | None = None, + token: bool | str | None = None, + ) -> Iterable[str]: + """ + Fetch all the logs from a compute Job on Hugging Face infrastructure. + + Args: + job_id (`str`): + ID of the Job. + + namespace (`str`, *optional*): + The namespace where the Job is running. Defaults to the current user's namespace. + + follow (`bool`, *optional*): + If `True`, stream logs in real-time until the job completes (blocking). + If `False` (default), fetch only the currently available logs and return immediately (non-blocking). + + tail (`int`, *optional*): + Maximum number of lines to return from the logs. When combined with `follow=True`, + starts from the last N lines and continues streaming new logs. When `follow=False`, + returns only the last N lines from currently available logs. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Example: + + ```python + >>> from huggingface_hub import fetch_job_logs, run_job + >>> job = run_job(image="python:3.12", command=["python", "-c" ,"print('Hello from HF compute!')"]) + >>> for log in fetch_job_logs(job_id=job.id): + ... print(log) + Hello from HF compute! + + >>> # Non-blocking: fetch only currently available logs + >>> for log in fetch_job_logs(job_id=job.id, follow=False): + ... print(log) + + >>> # Stream logs starting from the last 100 lines + >>> for log in fetch_job_logs(job_id=job.id, follow=True, tail=100): + ... print(log) + ``` + """ + # - We need to retry because sometimes the /logs doesn't return logs when the job just started. + # (for example it can return only two lines: one for "Job started" and one empty line) + # - Timeouts can happen in case of build errors + # - ChunkedEncodingError can happen in case of stopped logging in the middle of streaming + # - Infinite empty log stream can happen in case of build error + # (the logs stream is infinite and empty except for the Job started message) + # - there is a ": keep-alive" every 30 seconds + + seconds_between_keep_alive = 30 + # When not following, use a short timeout: the server replays historical logs + # quickly, then pauses waiting for new events (~30s keep-alive). 5 seconds is + # enough to receive all buffered logs. + timeout = 4 * seconds_between_keep_alive if follow else 5 + params = {"tail": tail} if tail is not None else None + for event in self._fetch_running_job_sse( + job_id=job_id, + route="logs", + timeout=timeout, + skip_previous_events_on_retry=True, + follow=follow, + namespace=namespace, + token=token, + params=params, + ): + # timestamp = event["timestamp"] + if not event["data"].startswith("===== Job started"): + log = event["data"] + yield log + + def fetch_job_metrics( + self, + *, + job_id: str, + namespace: str | None = None, + token: bool | str | None = None, + ) -> Iterable[dict[str, Any]]: + """ + Fetch all the live metrics from a compute Job on Hugging Face infrastructure. + + Args: + job_id (`str`): + ID of the Job. + + namespace (`str`, *optional*): + The namespace where the Job is running. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Example: + + ```python + >>> from huggingface_hub import fetch_job_metrics, run_job + >>> job = run_job(image="python:3.12", command=["python", "-c" ,"print('Hello from HF compute!')"], flavor="a10g-small") + >>> for metrics in fetch_job_metrics(job_id=job.id): + ... print(metrics) + { + "cpu_usage_pct": 0, + "cpu_millicores": 3500, + "memory_used_bytes": 1306624, + "memory_total_bytes": 15032385536, + "rx_bps": 0, + "tx_bps": 0, + "gpus": { + "882fa930": { + "utilization": 0, + "memory_used_bytes": 0, + "memory_total_bytes": 22836000000 + } + }, + "replica": "57vr7" + } + ``` + """ + # - there is one "metric" event every second, like this: + # event: metric + # data: {"cpu_usage_pct":0,"cpu_millicores":3500,"memory_used_bytes":1417216,"memory_total_bytes":15032385536,"rx_bps":0,"tx_bps":0,"gpus":{"d901cd7f":{"utilization":0,"memory_used_bytes":0,"memory_total_bytes":22836000000}},"replica":"j6qz9"} + # - the stream doesn't end when the job finishes, so we rely on timeouts (httpx.NetworkError with Timeout as cause) + # - httpx.ReadTimeout can happen if the job is marked as running but the hardware is not available yet, that we can ignore + # - it returns an internal error 500 if the job has already finished, we simply ignore it + # - ChunkedEncodingError can happen in case of stopped logging in the middle of streaming + # - there is a ": keep-alive" every 30 seconds + seconds_between_events = 1 + yield from self._fetch_running_job_sse( + job_id=job_id, + route="metrics", + timeout=10 * seconds_between_events, + skip_previous_events_on_retry=False, + tolerated_status_codes=(500,), + namespace=namespace, + token=token, + ) + + def list_jobs( + self, + *, + status: list[JobStage | str] | JobStage | str | None = None, + labels: dict[str, str] | None = None, + timeout: int | None = None, + namespace: str | None = None, + token: bool | str | None = None, + ) -> Iterable[JobInfo]: + """ + List compute Jobs on Hugging Face infrastructure. + + Args: + status (`JobStage`, `str` or `list`, *optional*): + Only return Jobs with the given status(es), e.g. `"RUNNING"` or `[JobStage.RUNNING, JobStage.SCHEDULING]`. + See [`JobStage`] for possible values. + + labels (`dict[str, str]`, *optional*): + Only return Jobs that have all the given `key=value` labels, e.g. `{"env": "prod", "team": "ml"}`. + + timeout (`float`, *optional*): + Whether to set a timeout for the request to the Hub. + + namespace (`str`, *optional*): + The namespace from where it lists the jobs. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Returns: + `Iterable[JobInfo]`: an iterable of [`JobInfo`] objects. + """ + if namespace is None: + namespace = whoami(token=token)["name"] + params: list[tuple[str, Any]] = [] + if status is not None: + statuses = [status] if isinstance(status, (str, JobStage)) else status + params.extend(("stage", (s.value if isinstance(s, JobStage) else str(s)).upper()) for s in statuses) + if labels is not None: + params.extend(("label", f"{key}={value}") for key, value in labels.items()) + + path = f"{self.endpoint}/api/jobs/{namespace}" + headers = self._build_hf_headers(token=token) + for job_info in paginate(path, params=params, headers=headers, timeout=timeout): + yield JobInfo(**job_info, endpoint=self.endpoint) + + def list_jobs_hardware(self, token: bool | str | None = None) -> list[JobHardwareInfo]: + """ + List available hardware options for Jobs on Hugging Face infrastructure. + + Returns: + `list[JobHardwareInfo]`: A list of available hardware configurations. + + Example: + + ```python + >>> from huggingface_hub import HfApi + >>> api = HfApi() + >>> hardware_list = api.list_jobs_hardware() + >>> hardware_list[0] + JobHardwareInfo(name='cpu-basic', pretty_name='CPU Basic', cpu='2 vCPU', ram='16 GB', ephemeral_storage='20 GB', accelerator=None, unit_cost_micro_usd=167, unit_cost_usd=0.000167, unit_label='minute') + >>> hardware_list[0].name + 'cpu-basic' + + # Filter GPU options + >>> gpu_hardware = [hw for hw in hardware_list if hw.accelerator is not None] + >>> gpu_hardware[0].accelerator.model + 'T4' + ``` + """ + response = get_session().get(f"{self.endpoint}/api/jobs/hardware", headers=self._build_hf_headers(token=token)) + hf_raise_for_status(response) + return [JobHardwareInfo(**hardware) for hardware in response.json()] + + def inspect_job( + self, + *, + job_id: str, + namespace: str | None = None, + token: bool | str | None = None, + ) -> JobInfo: + """ + Inspect a compute Job on Hugging Face infrastructure. + + Args: + job_id (`str`): + ID of the Job. + + namespace (`str`, *optional*): + The namespace where the Job is running. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Example: + + ```python + >>> from huggingface_hub import inspect_job, run_job + >>> job = run_job(image="python:3.12", command=["python", "-c" ,"print('Hello from HF compute!')"]) + >>> inspect_job(job.id) + JobInfo( + id='68780d00bbe36d38803f645f', + created_at=datetime.datetime(2025, 7, 16, 20, 35, 12, 808000, tzinfo=datetime.timezone.utc), + docker_image='python:3.12', + space_id=None, + command=['python', '-c', "print('Hello from HF compute!')"], + arguments=[], + environment={}, + secrets={}, + flavor='cpu-basic', + status=JobStatus(stage='RUNNING', message=None) + ) + ``` + """ + if namespace is None: + namespace = self.whoami(token=token)["name"] + response = get_session().get( + f"{self.endpoint}/api/jobs/{namespace}/{job_id}", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + return JobInfo(**response.json(), endpoint=self.endpoint) + + @overload + def wait_for_job( + self, + job_id: str, + *, + timeout: float | None = None, + poll_interval: float = 1.0, + stages: list[JobStage] | None = None, + namespace: str | None = None, + token: bool | str | None = None, + ) -> JobInfo: ... + + @overload + def wait_for_job( + self, + job_id: list[str], + *, + timeout: float | None = None, + poll_interval: float = 1.0, + stages: list[JobStage] | None = None, + namespace: str | None = None, + token: bool | str | None = None, + ) -> list[JobInfo]: ... + + def wait_for_job( + self, + job_id: str | list[str], + *, + timeout: float | None = None, + poll_interval: float = 1.0, + stages: list[JobStage] | None = None, + namespace: str | None = None, + token: bool | str | None = None, + ) -> JobInfo | list[JobInfo]: + """ + Wait until one or more compute Jobs on Hugging Face infrastructure reach a given stage. + + Each Job status is polled (with [`inspect_job`]) every `poll_interval` seconds until its stage is one + of `stages` (terminal stages by default: `"COMPLETED"`, `"CANCELED"`, `"ERROR"` or `"DELETED"`). The + final [`JobInfo`] is returned in all cases: a failed or canceled Job does **not** raise an exception — + check `job.status.stage` to act on the outcome. + + Terminal stages always stop the wait, even when not listed in `stages`. This avoids waiting forever for + a stage the Job will never reach (e.g. waiting for `"RUNNING"` on a Job that fails during scheduling). + + Args: + job_id (`str` or `list[str]`): + ID of the Job, or a list of Job IDs to wait for. If a list is passed, a list of [`JobInfo`] + is returned (in the same order). + + timeout (`float`, *optional*): + The maximum time to wait for the Job(s) to finish, in seconds. If `None`, will wait + indefinitely. + + poll_interval (`float`, *optional*): + The time to wait between each status check, in seconds. Defaults to 1s. + + stages (`list[JobStage]`, *optional*): + The stages to wait for. Defaults to the terminal stages (`"COMPLETED"`, `"CANCELED"`, + `"ERROR"`, `"DELETED"`). Pass e.g. `[JobStage.RUNNING]` to wait for the Job to start running. + Terminal stages always stop the wait regardless of this value. + + namespace (`str`, *optional*): + The namespace where the Job(s) are running. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Returns: + [`JobInfo`] or `list[JobInfo]`: the final Job info(s). + + Raises: + `TimeoutError`: + If at least one Job has not reached one of the target stages after `timeout` seconds. + + Example: + + ```python + >>> from huggingface_hub import run_job, wait_for_job + >>> job = run_job(image="python:3.12", command=["python", "-c", "print('Hello from HF compute!')"]) + >>> wait_for_job(job_id=job.id).status.stage + 'COMPLETED' + ``` + """ + if timeout is not None and timeout < 0: + raise ValueError("`timeout` cannot be negative.") + if poll_interval <= 0: + raise ValueError("`poll_interval` must be positive.") + + # Terminal stages always stop the wait, so a Job that never reaches the target stage doesn't hang. + target_stages = set(stages) | set(TERMINAL_JOB_STAGES) if stages else set(TERMINAL_JOB_STAGES) + + if namespace is None: + namespace = self.whoami(token=token)["name"] + deadline = None if timeout is None else time.monotonic() + timeout + + def _wait_single(single_job_id: str) -> JobInfo: + while True: + job = self.inspect_job(job_id=single_job_id, namespace=namespace, token=token) + if job.status.stage in target_stages: + return job + remaining = None if deadline is None else deadline - time.monotonic() + if remaining is not None and remaining <= 0: + raise TimeoutError( + f"Job '{single_job_id}' is still in stage '{job.status.stage}' after {timeout} seconds." + ) + time.sleep(poll_interval if remaining is None else min(poll_interval, remaining)) + + if isinstance(job_id, str): + return _wait_single(job_id) + return [_wait_single(single_job_id) for single_job_id in job_id] + + def cancel_job( + self, + *, + job_id: str, + namespace: str | None = None, + token: bool | str | None = None, + ) -> None: + """ + Cancel a compute Job on Hugging Face infrastructure. + + Args: + job_id (`str`): + ID of the Job. + + namespace (`str`, *optional*): + The namespace where the Job is running. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + """ + if namespace is None: + namespace = self.whoami(token=token)["name"] + response = get_session().post( + f"{self.endpoint}/api/jobs/{namespace}/{job_id}/cancel", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + + def update_job_labels( + self, + *, + job_id: str, + labels: dict[str, str], + namespace: str | None = None, + token: bool | str | None = None, + ) -> JobInfo: + """ + Update labels of an existing Job. + + Replaces all existing user-provided labels with the new labels. + + Args: + job_id (`str`): + ID of the Job. + + labels (`dict[str, str]`): + New labels to set on the job. Replaces all existing labels. + Both keys and values must be max 100 characters and contain only + alphanumeric characters, dots, dashes, and underscores. + + namespace (`str`, *optional*): + The namespace where the Job is running. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Returns: + [`JobInfo`]: The updated Job info. + """ + if namespace is None: + namespace = self.whoami(token=token)["name"] + response = get_session().put( + f"{self.endpoint}/api/jobs/{namespace}/{job_id}/labels", + headers=self._build_hf_headers(token=token), + json={"labels": labels}, + ) + hf_raise_for_status(response) + return JobInfo(**response.json(), endpoint=self.endpoint) + + @experimental + def run_uv_job( + self, + script: str, + *, + script_args: list[str] | None = None, + dependencies: list[str] | None = None, + python: str | None = None, + image: str | None = None, + env: dict[str, Any] | None = None, + secrets: dict[str, Any] | None = None, + flavor: JobHardware | str | None = None, + timeout: int | float | str | None = None, + labels: dict[str, str] | None = None, + volumes: list[Volume] | None = None, + expose: list[int] | None = None, + ssh: bool = False, + namespace: str | None = None, + token: bool | str | None = None, + ) -> JobInfo: + """ + Run a UV script Job on Hugging Face infrastructure. + + Args: + script (`str`): + Path or URL of the UV script, or a command. + + script_args (`list[str]`, *optional*) + Arguments to pass to the script or command. + + dependencies (`list[str]`, *optional*) + Dependencies to use to run the UV script. + + python (`str`, *optional*) + Use a specific Python version. Default is 3.12. + + image (`str`, *optional*, defaults to "ghcr.io/astral-sh/uv:python3.12-bookworm"): + Use a custom Docker image with `uv` installed. + + env (`dict[str, Any]`, *optional*): + Defines the environment variables for the Job. + + secrets (`dict[str, Any]`, *optional*): + Defines the secret environment variables for the Job. + + flavor (`str`, *optional*): + Flavor for the hardware. See [`JobHardware`] for possible values. + Defaults to `"cpu-basic"`. + + timeout (`Union[int, float, str]`, *optional*): + Max duration for the Job: int with s (seconds, default), m (minutes), h (hours) or d (days). + Example: `300` or `"5m"` for 5 minutes. + + labels (`dict[str, str]`, *optional*): + Labels to attach to the job (key-value pairs). + + volumes (`list[Volume]`, *optional*): + Hugging Face Buckets or Repos to mount as volumes in the job container. + Each volume is a [`Volume`] with `type` (`"bucket"`, `"model"`, `"dataset"`, or `"space"`), + `source` (e.g. `"username/my-bucket"`), and `mount_path` (e.g. `"/data"`). + + expose (`list[int]`, *optional*): + Container ports to expose through the jobs proxy. Each listed port is reachable + on the public jobs domain (e.g. `https://--8000.hf.jobs`). Access always + requires an HF token with read access to the job's namespace. + + ssh (`bool`, *optional*): + If True, the job's container is reachable over SSH at the URL given by `job.status.ssh_url` + (e.g. `ssh @ssh.hf.jobs`, or `hf jobs ssh ` from the CLI). Connecting requires + write access to the job's namespace and an SSH public key registered on the Hub + (https://huggingface.co/settings/keys). Defaults to False. + + namespace (`str`, *optional*): + The namespace where the Job will be created. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Example: + + Run a script from a URL: + + ```python + >>> from huggingface_hub import run_uv_job + >>> script = "https://raw.githubusercontent.com/huggingface/trl/refs/heads/main/trl/scripts/sft.py" + >>> script_args = ["--model_name_or_path", "Qwen/Qwen2-0.5B", "--dataset_name", "trl-lib/Capybara", "--push_to_hub"] + >>> run_uv_job(script, script_args=script_args, dependencies=["trl"], flavor="a10g-small") + ``` + + Run a local script: + + ```python + >>> from huggingface_hub import run_uv_job + >>> script = "my_sft.py" + >>> script_args = ["--model_name_or_path", "Qwen/Qwen2-0.5B", "--dataset_name", "trl-lib/Capybara", "--push_to_hub"] + >>> run_uv_job(script, script_args=script_args, dependencies=["trl"], flavor="a10g-small") + ``` + + Run a command: + + ```python + >>> from huggingface_hub import run_uv_job + >>> script = "lighteval" + >>> script_args= ["endpoint", "inference-providers", "model_name=openai/gpt-oss-20b,provider=auto", "lighteval|gsm8k|0|0"] + >>> run_uv_job(script, script_args=script_args, dependencies=["lighteval"], flavor="a10g-small") + ``` + + Mount volumes, e.g. to save model checkpoints during training: + + ```python + >>> from huggingface_hub import Volume, run_uv_job + >>> script = "my_sft.py" + >>> script_args = ["--output_dir", "/training-outputs/training-v3-final", ...] + >>> checkpoints_bucket = Volume(type="bucket", source="username/my-bucket", mount_path="/training-outputs") + >>> run_uv_job(script, script_args=script_args, volumes=[checkpoints_bucket]) + ``` + """ + image = image or "ghcr.io/astral-sh/uv:python3.12-bookworm" + env = env or {} + secrets = secrets or {} + + # Build command + command, env, secrets, extra_volumes = self._create_uv_command_env_and_secrets( + script=script, + script_args=script_args, + dependencies=dependencies, + python=python, + env=env, + secrets=secrets, + namespace=namespace, + token=token, + volumes=volumes, + ) + if extra_volumes: + volumes = (volumes or []) + extra_volumes + # Create RunCommand args + return self.run_job( + image=image, + command=command, + env=env, + secrets=secrets, + flavor=flavor, + timeout=timeout, + labels=labels, + volumes=volumes, + expose=expose, + ssh=ssh, + namespace=namespace, + token=token, + ) + + def create_scheduled_job( + self, + *, + image: str, + command: list[str], + schedule: str, + suspend: bool | None = None, + concurrency: bool | None = None, + env: dict[str, Any] | None = None, + secrets: dict[str, Any] | None = None, + flavor: JobHardware | str | None = None, + timeout: int | float | str | None = None, + labels: dict[str, str] | None = None, + volumes: list[Volume] | None = None, + expose: list[int] | None = None, + namespace: str | None = None, + token: bool | str | None = None, + ) -> ScheduledJobInfo: + """ + Create scheduled compute Jobs on Hugging Face infrastructure. + + Args: + image (`str`): + The Docker image to use. + Examples: `"ubuntu"`, `"python:3.12"`, `"pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel"`. + Example with an image from a Space: `"hf.co/spaces/lhoestq/duckdb"`. + + command (`list[str]`): + The command to run. Example: `["echo", "hello"]`. + + schedule (`str`): + One of "@annually", "@yearly", "@monthly", "@weekly", "@daily", "@hourly", or a + CRON schedule expression (e.g., '0 9 * * 1' for 9 AM every Monday). + + suspend (`bool`, *optional*): + If True, the scheduled Job is suspended (paused). Defaults to False. + + concurrency (`bool`, *optional*): + If True, multiple instances of this Job can run concurrently. Defaults to False. + + env (`dict[str, Any]`, *optional*): + Defines the environment variables for the Job. + + secrets (`dict[str, Any]`, *optional*): + Defines the secret environment variables for the Job. + + flavor (`str`, *optional*): + Flavor for the hardware. See [`JobHardware`] for possible values. + Defaults to `"cpu-basic"`. + + timeout (`Union[int, float, str]`, *optional*): + Max duration for the Job: int with s (seconds, default), m (minutes), h (hours) or d (days). + Example: `300` or `"5m"` for 5 minutes. + + labels (`dict[str, str]`, *optional*): + Labels to attach to the job (key-value pairs). + + volumes (`list[Volume]`, *optional*): + Hugging Face Buckets or Repos to mount as volumes in the job container. + Each volume is a [`Volume`] with `type` (`"bucket"`, `"model"`, `"dataset"`, or `"space"`), + `source` (e.g. `"username/my-bucket"`), and `mount_path` (e.g. `"/data"`). + + expose (`list[int]`, *optional*): + Container ports to expose through the jobs proxy. Each listed port is reachable + on the public jobs domain (e.g. `https://--8000.hf.jobs`). Access always + requires an HF token with read access to the job's namespace. + + namespace (`str`, *optional*): + The namespace where the Job will be created. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Example: + Create your first scheduled Job: + + ```python + >>> from huggingface_hub import create_scheduled_job + >>> create_scheduled_job(image="python:3.12", command=["python", "-c" ,"print('Hello from HF compute!')"], schedule="@hourly") + ``` + + Use a CRON schedule expression: + + ```python + >>> from huggingface_hub import create_scheduled_job + >>> create_scheduled_job(image="python:3.12", command=["python", "-c" ,"print('this runs every 5min')"], schedule="*/5 * * * *") + ``` + + Create a scheduled GPU Job: + + ```python + >>> from huggingface_hub import create_scheduled_job + >>> image = "pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel" + >>> command = ["python", "-c", "import torch; print(f"This code ran with the following GPU: {torch.cuda.get_device_name()}")"] + >>> create_scheduled_job(image, command, flavor="a10g-small", schedule="@hourly") + ``` + + """ + if namespace is None: + namespace = self.whoami(token=token)["name"] + + # prepare payload to send to HF Jobs API + job_spec = _create_job_spec( + image=image, + command=command, + env=env, + secrets=secrets, + flavor=flavor, + timeout=timeout, + labels=labels, + volumes=volumes, + expose=expose, + ) + input_json: dict[str, Any] = { + "jobSpec": job_spec, + "schedule": schedule, + } + if concurrency is not None: + input_json["concurrency"] = concurrency + if suspend is not None: + input_json["suspend"] = suspend + response = get_session().post( + f"{self.endpoint}/api/scheduled-jobs/{namespace}", + json=input_json, + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + scheduled_job_info = response.json() + return ScheduledJobInfo(**scheduled_job_info) + + def list_scheduled_jobs( + self, + *, + timeout: int | None = None, + namespace: str | None = None, + token: bool | str | None = None, + ) -> list[ScheduledJobInfo]: + """ + List scheduled compute Jobs on Hugging Face infrastructure. + + Args: + timeout (`float`, *optional*): + Whether to set a timeout for the request to the Hub. + + namespace (`str`, *optional*): + The namespace from where it lists the jobs. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + """ + if namespace is None: + namespace = self.whoami(token=token)["name"] + response = get_session().get( + f"{self.endpoint}/api/scheduled-jobs/{namespace}", + headers=self._build_hf_headers(token=token), + timeout=timeout, + ) + hf_raise_for_status(response) + return [ScheduledJobInfo(**scheduled_job_info) for scheduled_job_info in response.json()] + + def inspect_scheduled_job( + self, + *, + scheduled_job_id: str, + namespace: str | None = None, + token: bool | str | None = None, + ) -> ScheduledJobInfo: + """ + Inspect a scheduled compute Job on Hugging Face infrastructure. + + Args: + scheduled_job_id (`str`): + ID of the scheduled Job. + + namespace (`str`, *optional*): + The namespace where the scheduled Job is. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Example: + + ```python + >>> from huggingface_hub import inspect_job, create_scheduled_job + >>> scheduled_job = create_scheduled_job(image="python:3.12", command=["python", "-c" ,"print('Hello from HF compute!')"], schedule="@hourly") + >>> inspect_scheduled_job(scheduled_job.id) + ``` + """ + if namespace is None: + namespace = self.whoami(token=token)["name"] + response = get_session().get( + f"{self.endpoint}/api/scheduled-jobs/{namespace}/{scheduled_job_id}", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + return ScheduledJobInfo(**response.json()) + + def delete_scheduled_job( + self, + *, + scheduled_job_id: str, + namespace: str | None = None, + token: bool | str | None = None, + ) -> None: + """ + Delete a scheduled compute Job on Hugging Face infrastructure. + + Args: + scheduled_job_id (`str`): + ID of the scheduled Job. + + namespace (`str`, *optional*): + The namespace where the scheduled Job is. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + """ + if namespace is None: + namespace = self.whoami(token=token)["name"] + response = get_session().delete( + f"{self.endpoint}/api/scheduled-jobs/{namespace}/{scheduled_job_id}", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + + def suspend_scheduled_job( + self, + *, + scheduled_job_id: str, + namespace: str | None = None, + token: bool | str | None = None, + ) -> None: + """ + Suspend (pause) a scheduled compute Job on Hugging Face infrastructure. + + Args: + scheduled_job_id (`str`): + ID of the scheduled Job. + + namespace (`str`, *optional*): + The namespace where the scheduled Job is. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + """ + if namespace is None: + namespace = self.whoami(token=token)["name"] + response = get_session().post( + f"{self.endpoint}/api/scheduled-jobs/{namespace}/{scheduled_job_id}/suspend", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + + def resume_scheduled_job( + self, + *, + scheduled_job_id: str, + namespace: str | None = None, + token: bool | str | None = None, + ) -> None: + """ + Resume (unpause) a scheduled compute Job on Hugging Face infrastructure. + + Args: + scheduled_job_id (`str`): + ID of the scheduled Job. + + namespace (`str`, *optional*): + The namespace where the scheduled Job is. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + """ + if namespace is None: + namespace = self.whoami(token=token)["name"] + response = get_session().post( + f"{self.endpoint}/api/scheduled-jobs/{namespace}/{scheduled_job_id}/resume", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + + def trigger_scheduled_job( + self, + *, + scheduled_job_id: str, + namespace: str | None = None, + token: bool | str | None = None, + ) -> JobInfo: + """ + Trigger a scheduled Job to run immediately. + + This triggers one immediate run of the scheduled job's spec. It does **not** modify the schedule + and does **not** affect the next scheduled run. If an instance is already running and the scheduled + job does not allow concurrent runs, the request is rejected (HTTP 409). + + Args: + scheduled_job_id (`str`): + ID of the scheduled Job. + + namespace (`str`, *optional*): + The namespace where the scheduled Job is. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Returns: + [`JobInfo`]: Info about the triggered run. + + Raises: + [`~utils.HfHubHTTPError`]: + HTTP 409 if another instance is already running and `concurrency` is disabled on the scheduled job. + """ + if namespace is None: + namespace = self.whoami(token=token)["name"] + response = get_session().post( + f"{self.endpoint}/api/scheduled-jobs/{namespace}/{scheduled_job_id}/run", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + return JobInfo(**response.json(), endpoint=self.endpoint) + + def update_scheduled_job_labels( + self, + *, + scheduled_job_id: str, + labels: dict[str, str], + namespace: str | None = None, + token: bool | str | None = None, + ) -> ScheduledJobInfo: + """ + Update labels of an existing scheduled Job. + + Replaces all existing user-provided labels with the new labels. + + Args: + scheduled_job_id (`str`): + ID of the scheduled Job. + + labels (`dict[str, str]`): + New labels to set on the scheduled job. Replaces all existing labels. + Both keys and values must be max 100 characters and contain only + alphanumeric characters, dots, dashes, and underscores. + + namespace (`str`, *optional*): + The namespace where the scheduled Job is. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Returns: + [`ScheduledJobInfo`]: The updated scheduled Job info. + """ + if namespace is None: + namespace = self.whoami(token=token)["name"] + response = get_session().put( + f"{self.endpoint}/api/scheduled-jobs/{namespace}/{scheduled_job_id}/labels", + headers=self._build_hf_headers(token=token), + json={"labels": labels}, + ) + hf_raise_for_status(response) + return ScheduledJobInfo(**response.json()) + + @experimental + def create_scheduled_uv_job( + self, + script: str, + *, + script_args: list[str] | None = None, + schedule: str, + suspend: bool | None = None, + concurrency: bool | None = None, + dependencies: list[str] | None = None, + python: str | None = None, + image: str | None = None, + env: dict[str, Any] | None = None, + secrets: dict[str, Any] | None = None, + flavor: JobHardware | str | None = None, + timeout: int | float | str | None = None, + labels: dict[str, str] | None = None, + volumes: list[Volume] | None = None, + expose: list[int] | None = None, + namespace: str | None = None, + token: bool | str | None = None, + ) -> ScheduledJobInfo: + """ + Run a UV script Job on Hugging Face infrastructure. + + Args: + script (`str`): + Path or URL of the UV script, or a command. + + script_args (`list[str]`, *optional*) + Arguments to pass to the script, or a command. + + schedule (`str`): + One of "@annually", "@yearly", "@monthly", "@weekly", "@daily", "@hourly", or a + CRON schedule expression (e.g., '0 9 * * 1' for 9 AM every Monday). + + suspend (`bool`, *optional*): + If True, the scheduled Job is suspended (paused). Defaults to False. + + concurrency (`bool`, *optional*): + If True, multiple instances of this Job can run concurrently. Defaults to False. + + dependencies (`list[str]`, *optional*) + Dependencies to use to run the UV script. + + python (`str`, *optional*) + Use a specific Python version. Default is 3.12. + + image (`str`, *optional*, defaults to "ghcr.io/astral-sh/uv:python3.12-bookworm"): + Use a custom Docker image with `uv` installed. + + env (`dict[str, Any]`, *optional*): + Defines the environment variables for the Job. + + secrets (`dict[str, Any]`, *optional*): + Defines the secret environment variables for the Job. + + flavor (`str`, *optional*): + Flavor for the hardware. See [`JobHardware`] for possible values. + Defaults to `"cpu-basic"`. + + timeout (`Union[int, float, str]`, *optional*): + Max duration for the Job: int with s (seconds, default), m (minutes), h (hours) or d (days). + Example: `300` or `"5m"` for 5 minutes. + + labels (`dict[str, str]`, *optional*): + Labels to attach to the job (key-value pairs). + + volumes (`list[Volume]`, *optional*): + Hugging Face Buckets or Repos to mount as volumes in the job container. + Each volume is a [`Volume`] with `type` (`"bucket"`, `"model"`, `"dataset"`, or `"space"`), + `source` (e.g. `"username/my-bucket"`), and `mount_path` (e.g. `"/data"`). + + expose (`list[int]`, *optional*): + Container ports to expose through the jobs proxy. Each listed port is reachable + on the public jobs domain (e.g. `https://--8000.hf.jobs`). Access always + requires an HF token with read access to the job's namespace. + + namespace (`str`, *optional*): + The namespace where the Job will be created. Defaults to the current user's namespace. + + token `(Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Example: + + Schedule a script from a URL: + + ```python + >>> from huggingface_hub import create_scheduled_uv_job + >>> script = "https://raw.githubusercontent.com/huggingface/trl/refs/heads/main/trl/scripts/sft.py" + >>> script_args = ["--model_name_or_path", "Qwen/Qwen2-0.5B", "--dataset_name", "trl-lib/Capybara", "--push_to_hub"] + >>> create_scheduled_uv_job(script, script_args=script_args, dependencies=["trl"], flavor="a10g-small", schedule="@weekly") + ``` + + Schedule a local script: + + ```python + >>> from huggingface_hub import create_scheduled_uv_job + >>> script = "my_sft.py" + >>> script_args = ["--model_name_or_path", "Qwen/Qwen2-0.5B", "--dataset_name", "trl-lib/Capybara", "--push_to_hub"] + >>> create_scheduled_uv_job(script, script_args=script_args, dependencies=["trl"], flavor="a10g-small", schedule="@weekly") + ``` + + Schedule a command: + + ```python + >>> from huggingface_hub import create_scheduled_uv_job + >>> script = "lighteval" + >>> script_args= ["endpoint", "inference-providers", "model_name=openai/gpt-oss-20b,provider=auto", "lighteval|gsm8k|0|0"] + >>> create_scheduled_uv_job(script, script_args=script_args, dependencies=["lighteval"], flavor="a10g-small", schedule="@weekly") + ``` + """ + image = image or "ghcr.io/astral-sh/uv:python3.12-bookworm" + # Build command + command, env, secrets, extra_volumes = self._create_uv_command_env_and_secrets( + script=script, + script_args=script_args, + dependencies=dependencies, + python=python, + env=env, + secrets=secrets, + namespace=namespace, + token=token, + volumes=volumes, + ) + if extra_volumes: + volumes = (volumes or []) + extra_volumes + # Create RunCommand args + return self.create_scheduled_job( + image=image, + command=command, + schedule=schedule, + suspend=suspend, + concurrency=concurrency, + env=env, + secrets=secrets, + flavor=flavor, + timeout=timeout, + labels=labels, + volumes=volumes, + expose=expose, + namespace=namespace, + token=token, + ) + + def _create_uv_command_env_and_secrets( + self, + *, + script: str, + script_args: list[str] | None, + dependencies: list[str] | None, + python: str | None, + env: dict[str, Any] | None, + secrets: dict[str, Any] | None, + namespace: str | None, + token: bool | str | None, + volumes: list[Volume] | None = None, + ) -> tuple[list[str], dict[str, Any], dict[str, Any], list[Volume]]: + env = env or {} + secrets = secrets or {} + + # Build command + uv_args = [] + if dependencies: + for dependency in dependencies: + uv_args += ["--with", dependency] + if python: + uv_args += ["--python", python] + script_args = script_args or [] + + if namespace is None: + namespace = self.whoami(token=token)["name"] + + # Find the local files to pass to the job + local_files_to_include = {candidate for candidate in [script] + script_args if Path(candidate).is_file()} + # Fail early for missing scripts or config files + missing_local_files = { + candidate + for candidate in [script] + script_args + if not Path(candidate).is_file() + and Path(candidate).suffix in [".py", ".sh", ".yaml", ".yml", ".toml"] + and not candidate.startswith("https://") + and not candidate.startswith("http://") + } + if missing_local_files: + raise FileNotFoundError(", ".join(missing_local_files)) + + if len(local_files_to_include) == 0: + # Direct URL execution or command - no upload needed + command = ["uv", "run"] + uv_args + [script] + script_args + return command, env, secrets, [] + + # Find appropriate remote file names + remote_to_local_file_names: dict[str, str] = {} + for local_file_to_include in local_files_to_include: + local_file_path = Path(local_file_to_include) + # Sanitize spaces for predictable remote paths + remote_file_path = Path(local_file_path.name.replace(" ", "_")) + if remote_file_path.name in remote_to_local_file_names: + for i in itertools.count(): + remote_file_name = remote_file_path.with_stem(remote_file_path.stem + f"({i})").name + if remote_file_name not in remote_to_local_file_names: + remote_to_local_file_names[remote_file_name] = local_file_to_include + break + else: + remote_to_local_file_names[remote_file_path.name] = local_file_to_include + local_to_remote_file_names = { + local_file_to_include: remote_file_name + for remote_file_name, local_file_to_include in remote_to_local_file_names.items() + } + + # Local files are shipped to the job via a bucket mounted at /data. + existing_mount_paths = {v.mount_path for v in (volumes or [])} + if constants.HF_JOBS_ARTIFACTS_MOUNT_PATH in existing_mount_paths: + raise ValueError( + f"Mount path {constants.HF_JOBS_ARTIFACTS_MOUNT_PATH!r} is reserved for Jobs artifacts when running local scripts. Mount your volume at a different path." + ) + + extra_volumes = self._upload_scripts_to_bucket( + namespace=namespace, + remote_to_local_file_names=remote_to_local_file_names, + token=token, + ) + # Rewrite script and script_args to reference the mounted path. The bucket + # volume is scoped to the per-job subfolder (via `Volume.path`), so the job + # container sees the uploaded files directly at the mount root. + mount_path = constants.HF_JOBS_ARTIFACTS_MOUNT_PATH + if script in local_to_remote_file_names: + script = f"{mount_path}/{local_to_remote_file_names[script]}" + script_args = [ + f"{mount_path}/{local_to_remote_file_names[arg]}" if arg in local_to_remote_file_names else arg + for arg in script_args + ] + command = ["uv", "run"] + uv_args + [script] + script_args + return command, env, secrets, extra_volumes + + def _upload_scripts_to_bucket( + self, + *, + namespace: str, + remote_to_local_file_names: dict[str, str], + token: bool | str | None, + ) -> list[Volume]: + """Upload script files to a per-job subfolder in the artifacts bucket. + + Creates a bucket `/jobs-artifacts` (if it doesn't exist) and uploads + each script to `{timestamp}-{random}/{remote_name}` inside it. Returns a + [`Volume`] scoped to that bucket subfolder. Volume is in read-write mode so the Job can save data back to this bucket. + """ + bucket_id = f"{namespace}/{constants.HF_JOBS_ARTIFACTS_BUCKET_NAME}" + subfolder_id = f"{datetime.now(timezone.utc).strftime('%Y%m%dT%H%M%S')}-{token_hex(3)}" + + bucket_url = self.create_bucket(bucket_id=bucket_id, exist_ok=True, token=token, private=True) + + add_ops: list[tuple[str | Path | bytes, str]] = [ + (Path(local_path), f"{subfolder_id}/{remote_name}") + for remote_name, local_path in remote_to_local_file_names.items() + ] + self.batch_bucket_files(bucket_id=bucket_id, add=add_ops, token=token) + print(f"Your script and Job artifacts will be saved in this bucket: {bucket_url.url}") + + volume = Volume( + type="bucket", + source=bucket_id, + mount_path=constants.HF_JOBS_ARTIFACTS_MOUNT_PATH, + path=subfolder_id, + read_only=False, + ) + return [volume] + + def sync_job_volume( + self, + source: str | Path, + mount_path: str, + *, + remote_name: str | None = None, + read_only: bool = True, + namespace: str | None = None, + token: bool | str | None = None, + ) -> Volume: + """Sync a local directory to a bucket and return a [`Volume`] ready to mount in a Job. + + Files are uploaded to a subfolder of the `{namespace}/jobs-artifacts` bucket (auto-created as + private; a warning is emitted if it already exists and is public) using the same sync logic + as [`sync_bucket`]: re-syncing the same directory only + uploads new or modified files. By default the subfolder name is derived from the directory + path and the machine's hostname, so repeated calls from the same directory reuse the same + remote folder. Pass `remote_name` to use a fixed name instead. + + Note that the data is *copied* to the bucket, not mounted live: changes made locally after + the sync are not visible to the Job (re-run `sync_job_volume` to update), and the volume is + mounted read-only by default. To retrieve data written by a Job to a read-write volume, sync + the bucket folder back with [`sync_bucket`]. If the source directory is empty (e.g. an output + directory), a placeholder `.keep` file is uploaded so the volume can still be mounted. + + Args: + source (`str` or `Path`): + Path to a local directory to sync. + mount_path (`str`): + Mount path inside the Job container, e.g. `"/inputs"`. Must start with `/`. + remote_name (`str`, *optional*): + Name of the bucket subfolder to sync to. Defaults to a `{dirname}-{hash}` name derived + from the source path and the machine's hostname. + read_only (`bool`, *optional*, defaults to `True`): + Mount the volume read-only in the Job. Pass `False` to let the Job write back to the + bucket folder (e.g. to retrieve outputs with [`sync_bucket`] afterwards). + namespace (`str`, *optional*): + The namespace owning the `jobs-artifacts` bucket. Defaults to the current user's + namespace. Use the same namespace as the Job that will mount the volume. + token (`Union[bool, str, None]`, *optional*): + A valid user access token. If not provided, the locally saved token will be used, which is the + recommended authentication method. Set to `False` to disable authentication. + Refer to: https://huggingface.co/docs/huggingface_hub/quick-start#authentication. + + Returns: + [`Volume`]: A bucket volume scoped to the synced subfolder, to pass in the `volumes` list + of [`run_job`], [`run_uv_job`], [`create_scheduled_job`] or [`create_scheduled_uv_job`]. + + Example: + ```python + >>> from huggingface_hub import run_uv_job, sync_job_volume + + # Upload ./training-data once, then run multiple jobs against it + >>> volume = sync_job_volume("./training-data", "/data") + >>> run_uv_job("train.py", script_args=["--learning-rate", "0.01"], volumes=[volume]) + >>> run_uv_job("train.py", script_args=["--learning-rate", "0.05"], volumes=[volume]) + + # Read-write volume to retrieve outputs after the job completes + >>> volume = sync_job_volume("./outputs", "/outputs", read_only=False) + >>> job = run_uv_job("process.py", volumes=[volume]) + ``` + """ + if not mount_path.startswith("/"): + raise ValueError( + f"Mount path must be an absolute path inside the container (e.g. '/data'), got {mount_path!r}." + ) + source_path = Path(source).expanduser() + if not source_path.is_dir(): + raise ValueError(f"Source must be an existing local directory: '{source}'.") + + if namespace is None: + namespace = self.whoami(token=token)["name"] + bucket_id = f"{namespace}/{constants.HF_JOBS_ARTIFACTS_BUCKET_NAME}" + folder = remote_name or _derive_job_volume_name(source_path) + + # The jobs-artifacts bucket holds user scripts and data, so it must be private. A new bucket + # is created private here; if it already exists we cannot change its visibility, so warn when + # it is public instead of silently uploading the data to a publicly accessible bucket. + self.create_bucket(bucket_id=bucket_id, exist_ok=True, private=True, token=token) + if not self.bucket_info(bucket_id=bucket_id, token=token).private: + warnings.warn( + f"Bucket '{bucket_id}' already exists and is public: data synced for the Job will be " + f"publicly accessible. Make it private from {self.endpoint}/buckets/{bucket_id}.", + UserWarning, + ) + self.sync_bucket(str(source_path), f"hf://buckets/{bucket_id}/{folder}", token=token) + if not any(path.is_file() for path in source_path.rglob("*")): + # A folder cannot be empty in a bucket, and mounting a non-existent folder fails the Job. + # Upload a placeholder file so an empty directory (e.g. an output dir) can still be mounted. + self.batch_bucket_files(bucket_id, add=[(b"", f"{folder}/.keep")], token=token) + + return Volume(type="bucket", source=bucket_id, mount_path=mount_path, path=folder, read_only=read_only) + + @validate_hf_hub_args + def create_bucket( + self, + bucket_id: str, + *, + private: bool | None = None, + resource_group_id: str | None = None, + region: REPO_REGIONS | None = None, + exist_ok: bool = False, + token: bool | str | None = None, + ) -> BucketUrl: + """Create a bucket on the Hub. + + Args: + bucket_id (`str`): + A namespace (user or an organization) and a bucket name separated by a `/`. + If no namespace is provided, the bucket will be created in the current user's namespace. + private (`bool`, *optional*): + Whether to make the bucket private. If `None` (default), the bucket will be public unless the + organization's default is private. + resource_group_id (`str`, *optional*): + Resource group in which to create the bucket. Resource groups are only available for Enterprise Hub + organizations and allow to define which members of the organization can access the resource. The ID + of a resource group can be found in the URL of the resource's page on the Hub + (e.g. `"66670e5163145ca562cb1988"`). To learn more about resource groups, see + https://huggingface.co/docs/hub/en/security-resource-groups. + region (`Literal["us", "eu"]`, *optional*): + Cloud region in which to create the bucket. Can be one of `"us"` or `"eu"`. If not specified, the bucket will be + created in the default region. Requires Team plan or above. + exist_ok (`bool`, *optional*, defaults to `False`): + If `True`, do not raise an error if the bucket already exists. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`BucketUrl`]: URL to the newly created bucket containing + attributes like `endpoint`, `namespace`, and `bucket_id`. + + Example: + ```python + >>> from huggingface_hub import create_bucket + + >>> url = create_bucket(bucket_id="my-bucket") + >>> url.bucket_id + 'user/my-bucket' + >>> url.url + 'https://huggingface.co/buckets/user/my-bucket' + >>> url.uri.to_uri() + 'hf://buckets/user/my-bucket' + + >>> create_bucket(bucket_id="my-bucket", private=True, exist_ok=True) + BucketUrl(...) + + >>> create_bucket(bucket_id="my-bucket", region="us") + BucketUrl(...) + ``` + """ + payload: dict[str, Any] = {} + if private is not None: + payload["private"] = private + if resource_group_id is not None: + payload["resourceGroupId"] = resource_group_id + if region is not None: + payload["region"] = region + + if "/" not in bucket_id: + namespace, name = "me", bucket_id # "me" namespace refers to the current user + else: + parsed = _parse_bucket_uri(bucket_id) + if parsed.path_in_repo: + raise ValueError(f"Invalid bucket ID: {bucket_id}") + namespace, name = parsed.id.split("/") + + response = get_session().post( + f"{self.endpoint}/api/buckets/{namespace}/{name}", + headers=self._build_hf_headers(token=token), + json=payload, + ) + try: + hf_raise_for_status(response) + except HfHubHTTPError as err: + if exist_ok and err.response.status_code == 409: + # Bucket already exists and `exist_ok=True` + pass + elif exist_ok and err.response.status_code in (401, 403): + # 401 -> if JWT token without create bucket scope + # 403 -> if no write permission on the namespace + # In both cases, bucket might already exist + try: + self.bucket_info(bucket_id=bucket_id, token=token) + return BucketUrl(f"{self.endpoint}/buckets/{bucket_id}", endpoint=self.endpoint) + except HfHubHTTPError: + raise err + else: + raise + return BucketUrl(response.json()["url"], endpoint=self.endpoint) + + @validate_hf_hub_args + def bucket_info( + self, + bucket_id: str, + *, + token: bool | str | None = None, + ) -> BucketInfo: + """Get information about a specific bucket on the Hub. + + Args: + bucket_id (`str`): + The ID of the bucket (e.g. `"username/my-bucket"`). + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`BucketInfo`]: The bucket information. + + Raises: + [`~errors.BucketNotFoundError`]: If the bucket cannot be found. This may be because it doesn't exist, + or because it is set to `private` and you do not have access. + + Example: + ```python + >>> from huggingface_hub import bucket_info + >>> info = bucket_info(bucket_id="Wauplin/first-bucket") + >>> info.id + 'Wauplin/first-bucket' + >>> info.private + False + >>> info.created_at + datetime.datetime(2026, 2, 6, 17, 37, 57, tzinfo=datetime.timezone.utc) + >>> info.size + 551879671 + >>> info.total_files + 12 + ``` + """ + response = get_session().get( + f"{self.endpoint}/api/buckets/{bucket_id}", + headers=self._build_hf_headers(token=token), + ) + hf_raise_for_status(response) + return BucketInfo(**response.json()) + + @validate_hf_hub_args + def list_buckets( + self, + namespace: str | None = None, + *, + search: str | None = None, + token: bool | str | None = None, + ) -> Iterable[BucketInfo]: + """List buckets on the Hub under a certain namespace. + + Args: + namespace (`str`, *optional*): + List buckets under this namespace (user or organization). Defaults to listing user's buckets. + search (`str`, *optional*): + A search string to filter bucket names. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[BucketInfo]`: An iterable of [`BucketInfo`] objects. + + Example: + ```python + >>> from huggingface_hub import list_buckets + >>> for bucket in list_buckets(): # lists buckets in the user's namespace + ... print(bucket) + + >>> for bucket in list_buckets(namespace="huggingface"): # lists buckets in the "huggingface" organization + ... print(bucket) + + >>> for bucket in list_buckets(search="my-prefix"): # filter buckets by name + ... print(bucket) + ``` + """ + if namespace is None: + namespace = "me" + params: dict[str, Any] = {} + if search is not None: + params["search"] = search + for item in paginate( + f"{self.endpoint}/api/buckets/{namespace}", params=params, headers=self._build_hf_headers(token=token) + ): + yield BucketInfo(**item) + + @validate_hf_hub_args + def delete_bucket( + self, + bucket_id: str, + *, + missing_ok: bool = False, + token: bool | str | None = None, + ) -> None: + """Delete a bucket from the Hub. + + Args: + bucket_id (`str`): + The ID of the bucket (e.g. `"username/my-bucket"`). + missing_ok (`bool`, *optional*, defaults to `False`): + If `True`, do not raise an error if the bucket does not exist. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Raises: + [`~errors.BucketNotFoundError`]: If the bucket cannot be found and `missing_ok` is set to `False` (default). + + Example: + ```python + >>> from huggingface_hub import delete_bucket + >>> delete_bucket(bucket_id="Wauplin/first-bucket") + >>> delete_bucket(bucket_id="Wauplin/first-bucket", missing_ok=True) + ``` + """ + response = get_session().delete( + f"{self.endpoint}/api/buckets/{bucket_id}", + headers=self._build_hf_headers(token=token), + ) + + try: + hf_raise_for_status(response) + except HfHubHTTPError as e: + if e.response.status_code != 404 or not missing_ok: + raise + + @validate_hf_hub_args + def move_bucket( + self, + from_id: str, + to_id: str, + *, + token: bool | str | None = None, + ) -> None: + """Move a bucket from "namespace1/repo_name1" to "namespace2/repo_name2" + + Note there are certain limitations. For more information about moving + repositories, please see + https://hf.co/docs/hub/repositories-settings#renaming-or-transferring-a-repo. + + Args: + from_id (`str`): + A namespace (user or an organization) and a bucket name separated + by a `/`. Original bucket identifier (e.g. `"username/my-bucket"`). + to_id (`str`): + A namespace (user or an organization) and a bucket name separated + by a `/`. Final bucket identifier (e.g. `"username/new-bucket-name"` + or `"organization/my-bucket"`). + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Raises: + [`~errors.BucketNotFoundError`]: + If the source bucket cannot be found. This may be because it doesn't exist, + or because it is set to `private` and you do not have access. + + Example: + ```python + >>> from huggingface_hub import move_bucket + + >>> # Rename a bucket within the same namespace + >>> move_bucket(from_id="username/old-name", to_id="username/new-name") + + >>> # Transfer a bucket to an organization + >>> move_bucket(from_id="username/my-bucket", to_id="my-org/my-bucket") + ``` + """ + if len(from_id.split("/")) != 2: + raise ValueError(f"Invalid repo_id: {from_id}. It should have a namespace (:namespace:/:repo_name:)") + + if len(to_id.split("/")) != 2: + raise ValueError(f"Invalid repo_id: {to_id}. It should have a namespace (:namespace:/:repo_name:)") + + json_payload = {"fromRepo": from_id, "toRepo": to_id, "type": "bucket"} + + path = f"{self.endpoint}/api/repos/move" + headers = self._build_hf_headers(token=token) + response = get_session().post(path, headers=headers, json=json_payload) + hf_raise_for_status(response) + + @validate_hf_hub_args + def list_bucket_tree( + self, + bucket_id: str, + prefix: str | None = None, + *, + recursive: bool | None = None, + token: str | bool | None = None, + ) -> Iterable[BucketFile | BucketFolder]: + """List files in a bucket. + + Args: + bucket_id (`str`): + The ID of the bucket (e.g. `"username/my-bucket"`). + prefix (`str`, *optional*): + Filter results to files whose path starts with this prefix. + recursive (`bool`, *optional*): + If `True`, list files recursively. If `False` (default), list files and directories only at root. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[Union[BucketFile, BucketFolder]]`: An iterable of [`BucketFile`] and [`BucketFolder`] objects + containing file and directory information (path, etc.). + + Example: + ```python + >>> from huggingface_hub import list_bucket_tree + >>> for file_info in list_bucket_tree(bucket_id="username/my-bucket"): + ... print(file_info.path) + + >>> # Filter by prefix + >>> for file_info in list_bucket_tree(bucket_id="username/my-bucket", prefix="models/"): + ... print(file_info.path) + ``` + """ + encoded_prefix = "/" + quote(prefix, safe="") if prefix else "" + params = {} + if recursive is not None: + params["recursive"] = recursive + for item in paginate( + path=f"{self.endpoint}/api/buckets/{bucket_id}/tree{encoded_prefix}", + headers=self._build_hf_headers(token=token), + params=params, + ): + if item["type"] == "file": + yield BucketFile(**item) + elif item["type"] == "directory": + yield BucketFolder(**item) + + @validate_hf_hub_args + def get_bucket_paths_info( + self, + bucket_id: str, + paths: Iterable[str], + *, + token: str | bool | None = None, + ) -> Iterable[BucketFile]: + """ + Get information about a bucket's paths. + + Calls are made in batches of 1000 paths. Results are yielded as they are received. + + Args: + bucket_id (`str`): + The ID of the bucket (e.g. `"username/my-bucket"`). + paths (`Iterable[str]`): + The paths to get information about. If a path does not exist, it is ignored without raising an exception. + Only file paths are supported. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + `Iterable[BucketFile]`: + The information about the paths, as an iterable of [`BucketFile`] objects. + + Example: + ```py + >>> from huggingface_hub import get_bucket_paths_info + >>> paths_info = get_bucket_paths_info("username/my-bucket", ["file.txt", "checkpoints/model.safetensors"]) + >>> for info in paths_info: + ... print(info) + BucketFile(type='file', path='file.txt', size=2379, xet_hash='96e637d9665bd35477b1908a23f2e254edfba0618dbd2d62f90a6baee7d139cf', mtime=datetime.datetime(2024, 9, 25, 15, 31, 2, 346000, tzinfo=datetime.timezone.utc)) + BucketFile(type='file', path='checkpoints/model.safetensors', size=2408828, xet_hash='3ed0e9fefe788ddd61d1e26eba67057e9740a064b009256fbafadf6bb95785ca', mtime=datetime.datetime(2024, 9, 25, 15, 31, 2, 346000, tzinfo=datetime.timezone.utc)) + ``` + """ + headers = self._build_hf_headers(token=token) + + for batch in chunk_iterable(paths, chunk_size=_BUCKET_PATHS_INFO_BATCH_SIZE): + response = http_backoff( + "POST", + f"{self.endpoint}/api/buckets/{bucket_id}/paths-info", + json={"paths": list(batch)}, + headers=headers, + ) + hf_raise_for_status(response) + for path_info in response.json(): + yield BucketFile(**path_info) + + @validate_hf_hub_args + def copy_files(self, source: str, destination: str, *, token: str | bool | None = None) -> None: + """Copy files between locations on the Hub. + + Copy files from a bucket or repository (model, dataset, space) to a bucket or another repository. + Both individual files and entire folders are supported. + + When copying folders, a trailing `/` on the source path uses rsync-style semantics: copy the *contents* + of the folder into the destination, without nesting the source folder itself. Without a trailing `/`, + the source folder is nested inside the destination (like `cp -r`). + + When copying from a repository to a bucket, `.gitattributes` files are automatically excluded since they + are git-specific metadata and not relevant in a bucket context. + + Repo-to-repo copies use [`CommitOperationCopy`] under the hood and create a commit on the destination + repository. Bucket-to-repo copies are not supported. + + > [!WARNING] + > Server-side copies only work within the same [storage region](https://huggingface.co/docs/hub/storage-regions). + + Args: + source (`str`): + Source location as an `hf://` URI. Can be a bucket path (e.g. `"hf://buckets/my-bucket/path/to/file"`) + or a repo path (e.g. `"hf://username/my-model/weights.bin"`, `"hf://datasets/username/my-dataset/data/"`). + destination (`str`): + Destination location as an `hf://` URI pointing to a bucket (e.g. `"hf://buckets/my-bucket/target/path"`) + or a repository (e.g. `"hf://username/my-model/target/path"`). + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Raises: + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError): + If source/destination URIs are invalid or if copying from a bucket to a repo. + + Example: + ```python + >>> from huggingface_hub import copy_files + + # Copy a single file between buckets + >>> copy_files("hf://buckets/my-bucket/data.bin", "hf://buckets/other-bucket/data.bin") + + # Copy a folder into another bucket (nests: backup/models/...) + >>> copy_files("hf://buckets/my-bucket/models", "hf://buckets/other-bucket/backup/") + + # Copy folder contents (trailing /): files go directly into backup/ + >>> copy_files("hf://buckets/my-bucket/models/", "hf://buckets/other-bucket/backup/") + + # Copy a file from a model repo to a bucket + >>> copy_files("hf://username/my-model/model.safetensors", "hf://buckets/my-bucket/") + + # Copy an entire dataset to a bucket + >>> copy_files("hf://datasets/username/my-dataset/", "hf://buckets/my-bucket/datasets/") + + # Copy files between repositories + >>> copy_files("hf://username/source-model/", "hf://username/dest-model/") + + # Copy a file from one repo to another + >>> copy_files("hf://username/source-model/config.json", "hf://username/dest-model/config.json") + ``` + """ + source_uri = parse_hf_uri(source) + destination_uri = parse_hf_uri(destination) + + # Rsync-style trailing slash on source: "copy contents of" instead of "copy directory into". + # Check before parsing strips the slash. + merge_contents = source.endswith("/") + + if destination_uri.is_repo: + if source_uri.is_bucket: + raise ValueError("Bucket-to-repo copy is not supported.") + self._copy_to_repo(source_uri, destination_uri, merge_contents, source, destination, token=token) + else: + self._copy_to_bucket(source_uri, destination_uri, merge_contents, source, destination, token=token) + + def _copy_to_bucket( + self, + source: HfUri, + destination: HfUri, + merge_contents: bool, + source_str: str, + destination_str: str, + *, + token: str | bool | None = None, + ) -> None: + destination_bucket_id = destination.id + destination_path = destination.path_in_repo + destination_is_directory = False + destination_exists_as_directory = False + + if destination_path == "": + destination_is_directory = True + destination_exists_as_directory = True + else: + dest_path_info = list(self.get_bucket_paths_info(destination_bucket_id, [destination_path], token=token)) + if dest_path_info: + destination_is_directory = False + else: + destination_exists_as_directory = any( + self.list_bucket_tree(destination_bucket_id, prefix=destination_path, recursive=False, token=token) + ) + destination_is_directory = destination_exists_as_directory or destination_str.endswith("/") + + all_adds: list[tuple[str, str]] = [] + all_copies: list[_BucketCopyFile] = [] + pending_downloads: list[tuple[str, str]] = [] + + def _resolve_target_path(src_file_path: str, src_root_path: str | None, is_single_file: bool) -> str: + return _resolve_copy_target_path( + src_file_path, + src_root_path, + is_single_file, + destination_path, + destination_is_directory, + destination_exists_as_directory, + merge_contents, + ) + + def _build_copy_op( + target_path: str, xet_hash: str, size: int, source_repo_type: str, source_repo_id: str + ) -> _BucketCopyFile: + """Server-side copy by xet hash — no data transfer needed.""" + return _BucketCopyFile( + destination=target_path, + xet_hash=xet_hash, + source_repo_type=source_repo_type, + source_repo_id=source_repo_id, + size=size, + ) + + def _add_repo_file(file: RepoFile, target_path: str) -> None: + if file.xet_hash is not None: + all_copies.append(_build_copy_op(target_path, file.xet_hash, file.size, source.type, source.id)) + else: + pending_downloads.append((file.path, target_path)) + + if source.is_bucket: + source_path = source.path_in_repo + source_path_info = list(self.get_bucket_paths_info(source.id, [source_path], token=token)) + + if source_path_info: + source_file = source_path_info[0] + target_path = _resolve_target_path(source_file.path, None, is_single_file=True) + all_copies.append( + _build_copy_op(target_path, source_file.xet_hash, source_file.size, "bucket", source.id) + ) + else: + for item in self.list_bucket_tree(source.id, prefix=source_path or None, recursive=True, token=token): + if not isinstance(item, BucketFile): + continue + if source_path and not (item.path == source_path or item.path.startswith(source_path + "/")): + continue + target_path = _resolve_target_path(item.path, source_path or None, is_single_file=False) + all_copies.append(_build_copy_op(target_path, item.xet_hash, item.size, "bucket", source.id)) + else: + for file, target_path in self._iter_repo_files_for_copy( + source, + destination_path, + destination_is_directory, + destination_exists_as_directory, + merge_contents, + token=token, + ): + # Skip .gitattributes files (git-specific metadata, not relevant in a bucket) + if file.path.rsplit("/", 1)[-1] == ".gitattributes": + continue + _add_repo_file(file, target_path) + + if not all_copies and not all_adds and not pending_downloads: + if source.is_bucket: + raise EntryNotFoundError(f"No files found at '{source_str}' in bucket '{source.id}'.") + else: + raise EntryNotFoundError(f"No files found at '{source_str}' in {source.type} '{source.id}'.") + + if pending_downloads: + + def _download_and_collect(item: tuple[str, str]) -> None: + file_path, target_path = item + local_path = self.hf_hub_download( + repo_id=source.id, + repo_type=source.type, + filename=file_path, + revision=source.revision, + token=token, + tqdm_class=silent_tqdm, # type: ignore + ) + all_adds.append((local_path, target_path)) + + thread_map(_download_and_collect, pending_downloads, desc="Downloading text files for copy") + + # Send copies first (no upload needed), then adds (may need upload) + if all_copies: + for copy_chunk in chunk_iterable(all_copies, chunk_size=_BUCKET_BATCH_ADD_CHUNK_SIZE): + self._batch_bucket_files(destination_bucket_id, copy=list(copy_chunk), token=token) + if all_adds: + for add_chunk in chunk_iterable(all_adds, chunk_size=_BUCKET_BATCH_ADD_CHUNK_SIZE): + self._batch_bucket_files(destination_bucket_id, add=list(add_chunk), token=token) + + def _iter_repo_files_for_copy( + self, + source: HfUri, + destination_path: str, + destination_is_directory: bool, + destination_exists_as_directory: bool, + merge_contents: bool, + *, + token: str | bool | None = None, + ) -> Iterable[tuple[RepoFile, str]]: + """Yield (file, target_path) pairs from a repo source, with target paths resolved.""" + source_path = source.path_in_repo + source_repo_path_info: list[RepoFile | RepoFolder] = [] + if source_path != "": + source_repo_path_info = self.get_paths_info( + repo_id=source.id, + paths=[source_path], + repo_type=source.type, + revision=source.revision, + token=token, + ) + + def _resolve(src_file_path: str, src_root_path: str | None, is_single_file: bool) -> str: + return _resolve_copy_target_path( + src_file_path, + src_root_path, + is_single_file, + destination_path, + destination_is_directory, + destination_exists_as_directory, + merge_contents, + ) + + if len(source_repo_path_info) == 1 and isinstance(source_repo_path_info[0], RepoFile): + file = source_repo_path_info[0] + yield file, _resolve(file.path, None, is_single_file=True) + else: + for repo_item in self.list_repo_tree( + repo_id=source.id, + path_in_repo=source_path, + recursive=True, + repo_type=source.type, + revision=source.revision, + token=token, + ): + if not isinstance(repo_item, RepoFile): + continue + yield repo_item, _resolve(repo_item.path, source_path or None, is_single_file=False) + + def _copy_to_repo( + self, + source: HfUri, + destination: HfUri, + merge_contents: bool, + source_str: str, + destination_str: str, + *, + token: str | bool | None = None, + ) -> None: + destination_path = destination.path_in_repo + destination_is_directory = False + destination_exists_as_directory = False + + if destination_path == "": + destination_is_directory = True + destination_exists_as_directory = True + else: + dest_path_info = self.get_paths_info( + repo_id=destination.id, + paths=[destination_path], + repo_type=destination.type, + revision=destination.revision, + token=token, + ) + if len(dest_path_info) == 1 and isinstance(dest_path_info[0], RepoFile): + destination_is_directory = False + elif len(dest_path_info) == 1 and isinstance(dest_path_info[0], RepoFolder): + destination_is_directory = True + destination_exists_as_directory = True + else: + try: + destination_exists_as_directory = any( + self.list_repo_tree( + repo_id=destination.id, + path_in_repo=destination_path, + repo_type=destination.type, + revision=destination.revision, + token=token, + ) + ) + except RemoteEntryNotFoundError: + destination_exists_as_directory = False + destination_is_directory = destination_exists_as_directory or destination_str.endswith("/") + + is_same_repo = source.id == destination.id and source.type == destination.type + + commit_ops: list[CommitOperationCopy] = [ + CommitOperationCopy( + src_path_in_repo=file.path, + path_in_repo=target, + src_revision=source.revision, + src_repo_id=None if is_same_repo else source.id, + src_repo_type=None if is_same_repo else source.type, + ) + for file, target in self._iter_repo_files_for_copy( + source, + destination_path, + destination_is_directory, + destination_exists_as_directory, + merge_contents, + token=token, + ) + ] + + if not commit_ops: + raise EntryNotFoundError(f"No files found at '{source_str}' in {source.type} '{source.id}'.") + + self.create_commit( + repo_id=destination.id, + repo_type=destination.type, + revision=destination.revision, + operations=commit_ops, + commit_message=f"Copy files from {source.type}s/{source.id}", + token=token, + ) + + @validate_hf_hub_args + def batch_bucket_files( + self, + bucket_id: str, + *, + add: list[tuple[str | Path | bytes, str]] | None = None, + copy: list[tuple[str, str, str, str]] | None = None, + delete: list[str] | None = None, + token: str | bool | None = None, + ): + """Add, copy, and/or delete files in a bucket. + + This is a non-transactional operation. If an error occurs in the process, some files may have been uploaded, + copied, or deleted while others haven't. + + Args: + bucket_id (`str`): + The ID of the bucket (e.g. `"username/my-bucket"`). + add (`list` of `tuple`, *optional*): + Files to upload. Each element is a `(source, destination)` tuple where `source` is a path to a local + file (`str` or `Path`) or raw `bytes` content, and `destination` is the path in the bucket. + copy (`list` of `tuple`, *optional*): + Files to copy by xet hash. Each element is a `(source_repo_type, source_repo_id, xet_hash, + destination)` tuple where: + - `source_repo_type` is the type of the source repository: `"model"`, `"dataset"`, `"space"`, or + `"bucket"`. + - `source_repo_id` is the ID of the source repository or bucket (e.g. `"username/my-model"`). + - `xet_hash` is the xet hash of the file to copy. + - `destination` is the destination path in the bucket. + This is a server-side operation — no data is downloaded or re-uploaded. + delete (`list` of `str`, *optional*): + Paths of files to delete from the bucket. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Example: + ```python + >>> from huggingface_hub import batch_bucket_files + + # Upload files + >>> batch_bucket_files( + ... "username/my-bucket", + ... add=[ + ... ("./model.safetensors", "models/model.safetensors"), + ... (b'{{"key": "value"}}', "config.json"), + ... ], + ... ) + + # Copy xet files from another bucket or repo (server-side, no data transfer) + >>> batch_bucket_files( + ... "username/my-bucket", + ... copy=[ + ... ("bucket", "username/source-bucket", "", "models/model.safetensors"), + ... ("model", "username/my-model", "", "models/config.safetensors"), + ... ], + ... ) + + # Delete files + >>> batch_bucket_files("username/my-bucket", delete=["old-model.bin"]) + + # Upload and delete in one batch + >>> batch_bucket_files( + ... "username/my-bucket", + ... add=[("./new.txt", "new.txt")], + ... delete=["old.txt"], + ... ) + ``` + """ + add = add or [] + copy = copy or [] + delete = delete or [] + + # Small batch: do everything in one call + if len(add) + len(copy) + len(delete) <= _BUCKET_BATCH_ADD_CHUNK_SIZE: + self._batch_bucket_files(bucket_id, add=add, copy=copy, delete=delete, token=token) # type: ignore + return + + # Large batch: chunk copies first (no upload), then adds, then deletes + from .utils._xet_progress_reporting import XetUploadProgressReporter + + if add and not are_progress_bars_disabled(): + progress = XetUploadProgressReporter(total_files=len(add)) + else: + progress = None + + try: + for copy_chunk in chunk_iterable(copy, chunk_size=_BUCKET_BATCH_ADD_CHUNK_SIZE): + self._batch_bucket_files(bucket_id, copy=list(copy_chunk), token=token) + + for add_chunk in chunk_iterable(add, chunk_size=_BUCKET_BATCH_ADD_CHUNK_SIZE): + self._batch_bucket_files(bucket_id, add=list(add_chunk), token=token, _progress=progress) + + for delete_chunk in chunk_iterable(delete, chunk_size=_BUCKET_BATCH_DELETE_CHUNK_SIZE): + self._batch_bucket_files(bucket_id, delete=list(delete_chunk), token=token) + finally: + if progress is not None: + progress.close() + + return + + def _batch_bucket_files( + self, + bucket_id: str, + *, + add: list[tuple[str | Path | bytes, str] | _BucketAddFile] | None = None, + copy: list[tuple[str, str, str, str] | _BucketCopyFile] | None = None, + delete: list[str | _BucketDeleteFile] | None = None, + token: str | bool | None = None, + _progress: XetUploadProgressReporter | None = None, + ): + """Internal method: process a single batch of bucket file operations (upload to XET + call /batch).""" + # Convert public API inputs to internal operation objects + operations: list[_BucketAddFile | _BucketCopyFile | _BucketDeleteFile] = [] + if add: + for add_item in add: + if isinstance(add_item, _BucketAddFile): + operations.append(add_item) + else: + source, destination = add_item + operations.append(_BucketAddFile(source=source, destination=destination)) + if copy: + for copy_item in copy: + if isinstance(copy_item, _BucketCopyFile): + operations.append(copy_item) + else: + source_repo_type, source_repo_id, xet_hash, destination = copy_item + operations.append( + _BucketCopyFile( + destination=destination, + xet_hash=xet_hash, + source_repo_type=source_repo_type, + source_repo_id=source_repo_id, + ) + ) + if delete: + for delete_item in delete: + if isinstance(delete_item, _BucketDeleteFile): + operations.append(delete_item) + else: + operations.append(_BucketDeleteFile(path=delete_item)) + + if not operations: + return + + from hf_xet import SKIP_SHA256 + + from .utils._xet import ( + XetTokenType, + abort_xet_session, + get_xet_session, + xet_connection_info_refresh_url, + xet_headers_without_auth, + ) + from .utils._xet_progress_reporting import XetUploadProgressReporter + + headers = self._build_hf_headers(token=token) + + add_operations = [op for op in operations if isinstance(op, _BucketAddFile)] + add_operations_to_upload = [op for op in add_operations if op.xet_hash is None] + add_bytes_operations = [op for op in add_operations if isinstance(op.source, bytes)] + add_path_operations = [op for op in add_operations if not isinstance(op.source, bytes)] + + if len(add_operations_to_upload) > 0: + refresh_url = xet_connection_info_refresh_url( + token_type=XetTokenType.WRITE, + repo_id=bucket_id, + repo_type="bucket", + endpoint=self.endpoint, + ) + xet_headers = xet_headers_without_auth(headers) + + owns_progress = _progress is None + if _progress is not None: + progress = _progress + progress.reset_for_next_commit() + progress_callback = progress.update_progress + elif not are_progress_bars_disabled(): + progress = XetUploadProgressReporter() + progress_callback = progress.update_progress + else: + progress, progress_callback = None, None + + session = get_xet_session() + + try: + with session.new_upload_commit( + token_refresh_url=refresh_url, + token_refresh_headers=headers, + custom_headers=xet_headers, + progress_callback=progress_callback, + ) as commit: + handles = [] + for op in add_path_operations: + if op.xet_hash is None: + handles.append((commit.start_upload_file(str(op.source), sha256=SKIP_SHA256), op)) + for op in add_bytes_operations: + if op.xet_hash is None: + handles.append((commit.start_upload_bytes(op.source, sha256=SKIP_SHA256), op)) + for handle, op in handles: + result = handle.result() + op.xet_hash = result.xet_info.hash + op.size = result.xet_info.file_size + except KeyboardInterrupt: + abort_xet_session() + raise + finally: + if owns_progress and progress is not None: + progress.close() + + def _payload_as_ndjson() -> Iterable[bytes]: + for op in operations: + if isinstance(op, _BucketAddFile): + payload = { + "type": "addFile", + "path": op.destination, + "xetHash": op.xet_hash, + "mtime": op.mtime, + } + if op.content_type is not None: + payload["contentType"] = op.content_type + elif isinstance(op, _BucketCopyFile): + payload = { + "type": "copyFile", + "path": op.destination, + "xetHash": op.xet_hash, + "sourceRepoType": op.source_repo_type, + "sourceRepoId": op.source_repo_id, + } + else: + payload = { + "type": "deleteFile", + "path": op.path, + } + yield json.dumps(payload).encode() + yield b"\n" + + headers = { + "Content-Type": "application/x-ndjson", + **headers, + } + data = b"".join(_payload_as_ndjson()) + + response = http_backoff( + "POST", f"{self.endpoint}/api/buckets/{bucket_id}/batch", headers=headers, content=data + ) + hf_raise_for_status(response) + + @validate_hf_hub_args + def get_bucket_file_metadata( + self, + bucket_id: str, + remote_path: str, + *, + token: str | bool | None = None, + ) -> BucketFileMetadata: + """Fetch metadata of a file in a bucket. + + Args: + bucket_id (`str`): + The ID of the bucket (e.g. `"username/my-bucket"`). + remote_path (`str`): + The path of the file in the bucket. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Returns: + [`BucketFileMetadata`]: The file metadata containing size and xet information. + + Example: + ```python + >>> from huggingface_hub import get_bucket_file_metadata + >>> metadata = get_bucket_file_metadata( + ... bucket_id="username/my-bucket", + ... remote_path="models/model.safetensors", + ... ) + >>> metadata.size + 42000 + ``` + """ + response = _httpx_follow_relative_redirects_with_backoff( + "HEAD", + f"{self.endpoint}/buckets/{bucket_id}/resolve/{quote(remote_path, safe='')}", + headers=self._build_hf_headers(token=token), + retry_on_errors=True, + ) + + xet_file_data = parse_xet_file_data_from_response(response) + if xet_file_data is None: + raise ValueError(f"Could not parse xet file data for '{remote_path}' in bucket '{bucket_id}'.") + + size = response.headers.get("Content-Length") + if size is None: + raise ValueError(f"Could not get size for '{remote_path}' in bucket '{bucket_id}'.") + + return BucketFileMetadata(size=int(size), xet_file_data=xet_file_data) + + @validate_hf_hub_args + def download_bucket_files( + self, + bucket_id: str, + files: list[tuple[str | BucketFile, str | Path]], + *, + raise_on_missing_files: bool = False, + token: str | bool | None = None, + ) -> None: + """Download files from a bucket. + + Files input is a list of `(remote file, local file)` tuples where `remote file` is either the path of the file + in the bucket or a [`BucketFile`] object, and `local file` is the destination path on the local filesystem. + When passing a [`BucketFile`] object (obtained from [`list_bucket_tree`]), the method will skip the metadata + fetching step and directly download the files. + + Args: + bucket_id (`str`): + The ID of the bucket (e.g. `"username/my-bucket"`). + files (`list[tuple[Union[str, BucketFile], Union[str, Path]]]`): + Files to download as a list of tuple (source, destination). See description above for format details. + raise_on_missing_files (`bool`, *optional*): + If `True`, raise an [`EntryNotFoundError`] when a requested file does not exist in the bucket. If + `False` (default), missing files are skipped with a warning. + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + + Example: + ```python + >>> from huggingface_hub import download_bucket_files + + >>> download_bucket_files( + ... bucket_id="username/my-bucket", + ... files=[ + ... ("models/model.safetensors", "./local/model.safetensors"), + ... ("config.json", "./local/config.json"), + ... ], + ... ) + ``` + + ```python + >>> from huggingface_hub import download_bucket_files + + >>> parquet_files = [file for file in list_bucket_tree(bucket_id="username/my-bucket") if file.path.endswith(".parquet")] + >>> download_bucket_files( + ... bucket_id="username/my-bucket", + ... files=[(file, f"./local/{file.path}") for file in parquet_files], + ... ) + ``` + """ + from hf_xet import XetFileInfo # type: ignore[no-redef] + + from .utils._xet import abort_xet_session, get_xet_session, xet_headers_without_auth + + headers = self._build_hf_headers(token=token) + + if len(files) == 0: + return + + # Resolve all string paths to BucketFile objects in a single batch request + str_paths = [path for path, _ in files if not isinstance(path, BucketFile)] + bucket_files_by_path: dict[str, BucketFile] = {} + if str_paths: + bucket_files_by_path = { + info.path: info for info in self.get_bucket_paths_info(bucket_id, str_paths, token=token) + } + + # Check for missing files + missing_paths = [path for path in str_paths if path not in bucket_files_by_path] + if missing_paths: + if raise_on_missing_files: + raise EntryNotFoundError( + f"{len(missing_paths)} file(s) not found in bucket '{bucket_id}': {', '.join(missing_paths)}" + ) + for path in missing_paths: + warnings.warn(f"File '{path}' not found in bucket '{bucket_id}'. Skipping.") + + non_zero_download_items: list[tuple[XetFileInfo, str]] = [] + first_valid_bucket_file: BucketFile | None = None + for remote_file, local_path in files: + if not isinstance(remote_file, BucketFile): + if remote_file not in bucket_files_by_path: + continue # skip missing files (already warned above) + remote_file = bucket_files_by_path[remote_file] + if first_valid_bucket_file is None: + first_valid_bucket_file = remote_file + dest_path = Path(local_path).absolute() + if remote_file.size == 0: + # Create empty file without downloading + if dest_path.exists(): + if dest_path.is_dir(): + raise IsADirectoryError(f"Expected file but found directory at '{dest_path}'") + if dest_path.stat().st_size != 0: + dest_path.write_bytes(b"") + else: + dest_path.parent.mkdir(parents=True, exist_ok=True) + dest_path.touch() + else: + non_zero_download_items.append((XetFileInfo(remote_file.xet_hash, remote_file.size), str(dest_path))) + + if len(non_zero_download_items) == 0 or first_valid_bucket_file is None: + return + + # Fetch refresh route (same for all files in this bucket) + remote_path = first_valid_bucket_file.path + metadata = self.get_bucket_file_metadata(bucket_id, remote_path, token=token) + + xet_headers = xet_headers_without_auth(headers) + + # Download files + from .utils._xet_progress_reporting import XetDownloadProgressReporter + + session = get_xet_session() + + with XetDownloadProgressReporter( + reconstruction_desc="Downloading bucket files", + transfer_desc="Downloading bytes", + total=sum(xet_info.file_size for xet_info, _ in non_zero_download_items), + log_level=logger.getEffectiveLevel(), + name="huggingface_hub.download_bucket_files", + ) as progress: + try: + with session.new_file_download_group( + token_refresh_url=metadata.xet_file_data.refresh_route, + token_refresh_headers=headers, + custom_headers=xet_headers, + progress_callback=progress.update_progress, + ) as group: + for xet_info, dest in non_zero_download_items: + group.start_download_file(xet_info, dest) + except KeyboardInterrupt: + abort_xet_session() + raise + + @validate_hf_hub_args + def sync_bucket( + self, + source: str | None = None, + dest: str | None = None, + *, + delete: bool = False, + ignore_times: bool = False, + ignore_sizes: bool = False, + existing: bool = False, + ignore_existing: bool = False, + include: list[str] | None = None, + exclude: list[str] | None = None, + filter_from: str | None = None, + plan: str | None = None, + apply: str | None = None, + dry_run: bool = False, + verbose: bool = False, + quiet: bool = False, + token: bool | str | None = None, + ) -> SyncPlan: + """Sync files between a local directory and a bucket. + + This is equivalent to the ``hf buckets sync`` CLI command. One of ``source`` or ``dest`` must be a bucket path + (``hf://buckets/...``) and the other must be a local directory path. + + Args: + source (`str`, *optional*): + Source path: local directory or ``hf://buckets/namespace/bucket_name(/prefix)``. + Required unless using ``apply``. + dest (`str`, *optional*): + Destination path: local directory or ``hf://buckets/namespace/bucket_name(/prefix)``. + Required unless using ``apply``. + delete (`bool`, *optional*, defaults to `False`): + Delete destination files not present in source. + ignore_times (`bool`, *optional*, defaults to `False`): + Skip files only based on size, ignoring modification times. + ignore_sizes (`bool`, *optional*, defaults to `False`): + Skip files only based on modification times, ignoring sizes. + existing (`bool`, *optional*, defaults to `False`): + Skip creating new files on receiver (only update existing files). + ignore_existing (`bool`, *optional*, defaults to `False`): + Skip updating files that exist on receiver (only create new files). + include (`list[str]`, *optional*): + Include files matching patterns (fnmatch-style). + exclude (`list[str]`, *optional*): + Exclude files matching patterns (fnmatch-style). + filter_from (`str`, *optional*): + Path to a filter file with include/exclude rules. + plan (`str`, *optional*): + Save sync plan to this JSONL file instead of executing. + apply (`str`, *optional*): + Apply a previously saved plan file. When set, ``source`` and ``dest`` are not needed. + dry_run (`bool`, *optional*, defaults to `False`): + Print sync plan to stdout as JSONL without executing. + verbose (`bool`, *optional*, defaults to `False`): + Show detailed per-file operations. + quiet (`bool`, *optional*, defaults to `False`): + Suppress all output and progress bars. + token (Union[bool, str, None], optional): + A valid user access token. If not provided, the locally saved token will be used. + + Returns: + [`SyncPlan`]: The computed (or loaded) sync plan. + + Example: + ```python + >>> from huggingface_hub import HfApi + >>> api = HfApi() + + # Upload local directory to bucket + >>> api.sync_bucket("./data", "hf://buckets/username/my-bucket") + + # Download bucket to local directory + >>> api.sync_bucket("hf://buckets/username/my-bucket", "./data") + + # Sync with delete and filtering + >>> api.sync_bucket( + ... "./data", + ... "hf://buckets/username/my-bucket", + ... delete=True, + ... include=["*.safetensors"], + ... ) + + # Dry run: preview what would be synced + >>> plan = api.sync_bucket("./data", "hf://buckets/username/my-bucket", dry_run=True) + >>> plan.summary() + {'uploads': 3, 'downloads': 0, 'deletes': 0, 'skips': 1, 'total_size': 4096} + + # Save plan for review, then apply + >>> api.sync_bucket("./data", "hf://buckets/username/my-bucket", plan="sync-plan.jsonl") + >>> api.sync_bucket(apply="sync-plan.jsonl") + ``` + """ + return sync_bucket_internal( + source=source, + dest=dest, + api=self, + delete=delete, + ignore_times=ignore_times, + ignore_sizes=ignore_sizes, + existing=existing, + ignore_existing=ignore_existing, + include=include, + exclude=exclude, + filter_from=filter_from, + plan=plan, + apply=apply, + dry_run=dry_run, + verbose=verbose, + quiet=quiet, + token=token, + ) + + +def _parse_revision_from_pr_url(pr_url: str) -> str: + """Safely parse revision number from a PR url. + + Example: + ```py + >>> _parse_revision_from_pr_url("https://huggingface.co/bigscience/bloom/discussions/2") + "refs/pr/2" + ``` + """ + re_match = re.match(_REGEX_DISCUSSION_URL, pr_url) + if re_match is None: + raise RuntimeError(f"Unexpected response from the hub, expected a Pull Request URL but got: '{pr_url}'") + return f"refs/pr/{re_match[1]}" + + +def parse_local_safetensors_file_metadata(path: str | Path) -> SafetensorsFileMetadata: + """ + Parse metadata from a local safetensors file. + + For more details regarding the safetensors format, check out https://huggingface.co/docs/safetensors/index#format. + + Args: + path (`str` or `Path`): + Path to the safetensors file. + + Returns: + [`SafetensorsFileMetadata`]: information related to the safetensors file. + + Raises: + [`SafetensorsParsingError`]: + If the safetensors file header couldn't be parsed correctly. + `FileNotFoundError`: + If the file does not exist. + + Example: + ```py + >>> metadata = parse_local_safetensors_file_metadata("path/to/model.safetensors") + >>> metadata + SafetensorsFileMetadata( + metadata={'format': 'pt'}, + tensors={'layer.weight': TensorInfo(dtype='F32', shape=[512, 512], ...}, ...} + ) + >>> metadata.parameter_count + {'F32': 262144} + ``` + """ + path = Path(path) + filename = path.name + context_msg = f"path '{path}'" + + with open(path, "rb") as f: + # 1. Read first 8 bytes and parse/validate metadata size using shared helper + size_bytes = f.read(8) + metadata_size = _get_safetensors_metadata_size(size_bytes, filename, context_msg) + + # 2. Read metadata bytes + metadata_as_bytes = f.read(metadata_size) + if len(metadata_as_bytes) < metadata_size: + raise SafetensorsParsingError( + f"Failed to parse safetensors header for '{filename}' ({context_msg}): file is truncated. Expected " + f"{metadata_size} bytes of metadata but got {len(metadata_as_bytes)}." + ) + + # 3. Parse using shared helper + return _parse_safetensors_header(metadata_as_bytes, filename, context_msg) + + +def get_local_safetensors_metadata(path: str | Path) -> SafetensorsRepoMetadata: + """ + Parse metadata for a local safetensors file or folder. + + Supports: + - Single safetensors file (e.g., `model.safetensors`) + - Directory with non-sharded model (contains `model.safetensors`) + - Directory with sharded model (contains `model.safetensors.index.json`) + + For more details regarding the safetensors format, check out https://huggingface.co/docs/safetensors/index#format. + + Args: + path (`str` or `Path`): + Path to a safetensors file or directory containing safetensors files. + + Returns: + [`SafetensorsRepoMetadata`]: information related to the safetensors repo. + + Raises: + [`NotASafetensorsRepoError`]: + If the path is not a valid safetensors file or folder (i.e., doesn't have either a + `model.safetensors` or a `model.safetensors.index.json` file). + [`SafetensorsParsingError`]: + If a safetensors file header couldn't be parsed correctly. + `FileNotFoundError`: + If the path does not exist. + + Example: + ```py + # Parse single safetensors file + >>> metadata = get_local_safetensors_metadata("path/to/model.safetensors") + >>> metadata + SafetensorsRepoMetadata(metadata=None, sharded=False, weight_map={...}, files_metadata={...}) + + # Parse directory with sharded model + >>> metadata = get_local_safetensors_metadata("path/to/model_folder") + >>> metadata + SafetensorsRepoMetadata(metadata={'total_size': ...}, sharded=True, weight_map={...}, files_metadata={...}) + >>> len(metadata.files_metadata) + 3 # Number of safetensors shards + ``` + """ + path = Path(path) + + # Case 1: Direct path to a safetensors file + if path.is_file(): + file_metadata = parse_local_safetensors_file_metadata(path) + return SafetensorsRepoMetadata( + metadata=None, + sharded=False, + weight_map={tensor_name: path.name for tensor_name in file_metadata.tensors.keys()}, + files_metadata={path.name: file_metadata}, + ) + + # Case 2: Directory + if not path.is_dir(): + raise FileNotFoundError(f"Path '{path}' does not exist.") + + single_file_path = path / constants.SAFETENSORS_SINGLE_FILE + index_file_path = path / constants.SAFETENSORS_INDEX_FILE + + # Case 2a: Non-sharded model (single model.safetensors file) + if single_file_path.exists(): + file_metadata = parse_local_safetensors_file_metadata(single_file_path) + return SafetensorsRepoMetadata( + metadata=None, + sharded=False, + weight_map={ + tensor_name: constants.SAFETENSORS_SINGLE_FILE for tensor_name in file_metadata.tensors.keys() + }, + files_metadata={constants.SAFETENSORS_SINGLE_FILE: file_metadata}, + ) + + # Case 2b: Sharded model (model.safetensors.index.json) + if index_file_path.exists(): + with open(index_file_path) as f: + index = json.load(f) + + weight_map = index.get("weight_map", {}) + + # Parse metadata from each shard + files_metadata = {} + for shard_filename in set(weight_map.values()): + shard_path = path / shard_filename + files_metadata[shard_filename] = parse_local_safetensors_file_metadata(shard_path) + + return SafetensorsRepoMetadata( + metadata=index.get("metadata", None), + sharded=True, + weight_map=weight_map, + files_metadata=files_metadata, + ) + + # Not a valid safetensors folder + raise NotASafetensorsRepoError( + f"'{path}' is not a valid safetensors folder. Couldn't find '{constants.SAFETENSORS_INDEX_FILE}' or " + f"'{constants.SAFETENSORS_SINGLE_FILE}' files." + ) + + +api = HfApi() + +whoami = api.whoami +auth_check = api.auth_check + +list_models = api.list_models +model_info = api.model_info + +list_datasets = api.list_datasets +list_dataset_parquet_files = api.list_dataset_parquet_files +dataset_info = api.dataset_info +get_dataset_leaderboard = api.get_dataset_leaderboard + +list_spaces = api.list_spaces +list_space_templates = api.list_space_templates +search_spaces = api.search_spaces +space_info = api.space_info + +kernel_info = api.kernel_info + +list_papers = api.list_papers +paper_info = api.paper_info +read_paper = api.read_paper +list_daily_papers = api.list_daily_papers + +repo_exists = api.repo_exists +revision_exists = api.revision_exists +file_exists = api.file_exists +repo_info = api.repo_info +list_repo_files = api.list_repo_files +list_repo_refs = api.list_repo_refs +list_repo_commits = api.list_repo_commits +list_repo_tree = api.list_repo_tree +get_paths_info = api.get_paths_info +verify_repo_checksums = api.verify_repo_checksums + +get_model_tags = api.get_model_tags +get_dataset_tags = api.get_dataset_tags + +create_commit = api.create_commit +create_repo = api.create_repo +delete_repo = api.delete_repo +update_repo_settings = api.update_repo_settings +move_repo = api.move_repo +upload_file = api.upload_file +upload_folder = api.upload_folder +delete_file = api.delete_file +delete_folder = api.delete_folder +delete_files = api.delete_files +upload_large_folder = api.upload_large_folder +preupload_lfs_files = api.preupload_lfs_files +create_branch = api.create_branch +delete_branch = api.delete_branch +create_tag = api.create_tag +delete_tag = api.delete_tag +get_full_repo_name = api.get_full_repo_name + +# Danger-zone API +super_squash_history = api.super_squash_history +list_lfs_files = api.list_lfs_files +permanently_delete_lfs_files = api.permanently_delete_lfs_files + +# Safetensors helpers +get_safetensors_metadata = api.get_safetensors_metadata +parse_safetensors_file_metadata = api.parse_safetensors_file_metadata + +# Background jobs +run_as_future = api.run_as_future + +# Activity API +list_liked_repos = api.list_liked_repos +list_repo_likers = api.list_repo_likers +list_user_repos = api.list_user_repos +unlike = api.unlike + +# Community API +get_discussion_details = api.get_discussion_details +get_repo_discussions = api.get_repo_discussions +create_discussion = api.create_discussion +create_pull_request = api.create_pull_request +change_discussion_status = api.change_discussion_status +comment_discussion = api.comment_discussion +edit_discussion_comment = api.edit_discussion_comment +rename_discussion = api.rename_discussion +merge_pull_request = api.merge_pull_request + +# Space API +get_space_secrets = api.get_space_secrets +add_space_secret = api.add_space_secret +delete_space_secret = api.delete_space_secret +get_space_variables = api.get_space_variables +add_space_variable = api.add_space_variable +delete_space_variable = api.delete_space_variable +get_space_runtime = api.get_space_runtime +list_spaces_hardware = api.list_spaces_hardware +request_space_hardware = api.request_space_hardware +set_space_sleep_time = api.set_space_sleep_time +pause_space = api.pause_space +restart_space = api.restart_space +duplicate_repo = api.duplicate_repo +duplicate_space = api.duplicate_space +request_space_storage = api.request_space_storage +delete_space_storage = api.delete_space_storage +set_space_volumes = api.set_space_volumes +delete_space_volumes = api.delete_space_volumes +enable_space_dev_mode = api.enable_space_dev_mode +disable_space_dev_mode = api.disable_space_dev_mode +fetch_space_logs = api.fetch_space_logs +wait_for_space = api.wait_for_space + +# Inference Endpoint API +list_inference_endpoints = api.list_inference_endpoints +create_inference_endpoint = api.create_inference_endpoint +get_inference_endpoint = api.get_inference_endpoint +update_inference_endpoint = api.update_inference_endpoint +delete_inference_endpoint = api.delete_inference_endpoint +pause_inference_endpoint = api.pause_inference_endpoint +resume_inference_endpoint = api.resume_inference_endpoint +scale_to_zero_inference_endpoint = api.scale_to_zero_inference_endpoint +create_inference_endpoint_from_catalog = api.create_inference_endpoint_from_catalog +list_inference_catalog = api.list_inference_catalog + +# Collections API +get_collection = api.get_collection +list_collections = api.list_collections +create_collection = api.create_collection +update_collection_metadata = api.update_collection_metadata +delete_collection = api.delete_collection +add_collection_item = api.add_collection_item +update_collection_item = api.update_collection_item +delete_collection_item = api.delete_collection_item +delete_collection_item = api.delete_collection_item + +# Access requests API +list_pending_access_requests = api.list_pending_access_requests +list_accepted_access_requests = api.list_accepted_access_requests +list_rejected_access_requests = api.list_rejected_access_requests +cancel_access_request = api.cancel_access_request +accept_access_request = api.accept_access_request +reject_access_request = api.reject_access_request +grant_access = api.grant_access + +# Webhooks API +create_webhook = api.create_webhook +disable_webhook = api.disable_webhook +delete_webhook = api.delete_webhook +enable_webhook = api.enable_webhook +get_webhook = api.get_webhook +list_webhooks = api.list_webhooks +update_webhook = api.update_webhook + + +# User API +get_user_overview = api.get_user_overview +get_organization_overview = api.get_organization_overview +list_organization_followers = api.list_organization_followers +list_organization_members = api.list_organization_members +list_user_followers = api.list_user_followers +list_user_following = api.list_user_following + +# Jobs API +run_job = api.run_job +fetch_job_logs = api.fetch_job_logs +fetch_job_metrics = api.fetch_job_metrics +list_jobs = api.list_jobs +list_jobs_hardware = api.list_jobs_hardware +inspect_job = api.inspect_job +wait_for_job = api.wait_for_job +cancel_job = api.cancel_job +update_job_labels = api.update_job_labels +run_uv_job = api.run_uv_job +create_scheduled_job = api.create_scheduled_job +list_scheduled_jobs = api.list_scheduled_jobs +inspect_scheduled_job = api.inspect_scheduled_job +delete_scheduled_job = api.delete_scheduled_job +suspend_scheduled_job = api.suspend_scheduled_job +resume_scheduled_job = api.resume_scheduled_job +trigger_scheduled_job = api.trigger_scheduled_job +update_scheduled_job_labels = api.update_scheduled_job_labels +create_scheduled_uv_job = api.create_scheduled_uv_job +sync_job_volume = api.sync_job_volume + +# Buckets API +create_bucket = api.create_bucket +bucket_info = api.bucket_info +list_buckets = api.list_buckets +delete_bucket = api.delete_bucket +move_bucket = api.move_bucket +list_bucket_tree = api.list_bucket_tree +get_bucket_paths_info = api.get_bucket_paths_info +copy_files = api.copy_files +batch_bucket_files = api.batch_bucket_files +get_bucket_file_metadata = api.get_bucket_file_metadata +download_bucket_files = api.download_bucket_files +sync_bucket = api.sync_bucket diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/hf_file_system.py b/.venv/lib/python3.13/site-packages/huggingface_hub/hf_file_system.py new file mode 100644 index 0000000000000000000000000000000000000000..2407f9d4f10510a63265c5e3d71ae2826dd0d99c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/hf_file_system.py @@ -0,0 +1,1423 @@ +import os +import tempfile +import threading +from collections import deque +from collections.abc import Iterable, Iterator +from contextlib import ExitStack +from copy import deepcopy +from dataclasses import dataclass, field +from datetime import datetime +from itertools import chain +from pathlib import Path, PurePosixPath +from typing import Any, NoReturn, Union +from urllib.parse import quote, unquote + +import fsspec +import httpx +from fsspec.callbacks import _DEFAULT_CALLBACK, NoOpCallback, TqdmCallback +from fsspec.config import apply_config +from fsspec.utils import isfilelike + +from . import constants +from ._commit_api import CommitOperationCopy, CommitOperationDelete +from .errors import ( + BucketNotFoundError, + EntryNotFoundError, + HfHubHTTPError, + RepositoryNotFoundError, + RevisionNotFoundError, +) +from .file_download import hf_hub_url, http_get +from .hf_api import SPECIAL_REFS_REVISION_REGEX, BucketFile, BucketFolder, HfApi, LastCommitInfo, RepoFile, RepoFolder +from .utils import HFValidationError, hf_raise_for_status, http_backoff, http_stream_backoff, parse_hf_uri +from .utils.insecure_hashlib import md5 + + +@dataclass +class HfFileSystemResolvedPath: + """Top level Data structure containing information about a resolved Hugging Face file system path.""" + + root: str + path: str + + def unresolve(self) -> str: + return f"{self.root}/{self.path}".rstrip("/") + + +@dataclass +class HfFileSystemResolvedRepositoryPath(HfFileSystemResolvedPath): + """Data structure containing information about a resolved path in a repository.""" + + repo_type: str + repo_id: str + revision: str + path_in_repo: str + root: str = field(init=False) + path: str = field(init=False) + # The part placed after '@' in the initial path. It can be a quoted or unquoted refs revision. + # Used to reconstruct the unresolved path to return to the user. + _raw_revision: str | None = field(default=None, repr=False) + + def __post_init__(self): + repo_path = constants.REPO_TYPES_URL_PREFIXES.get(self.repo_type, "") + self.repo_id + if self._raw_revision: + self.root = f"{repo_path}@{self._raw_revision}" + elif self.revision != constants.DEFAULT_REVISION: + self.root = f"{repo_path}@{safe_revision(self.revision)}" + else: + self.root = repo_path + self.path = self.path_in_repo + + +@dataclass +class HfFileSystemResolvedBucketPath(HfFileSystemResolvedPath): + """Data structure containing information about a resolved path in a bucket.""" + + bucket_id: str + root: str = field(init=False) + + def __post_init__(self): + self.root = "buckets/" + self.bucket_id + + +# We need to improve fsspec.spec._Cached which is AbstractFileSystem's metaclass +_cached_base: Any = type(fsspec.AbstractFileSystem) + + +class _Cached(_cached_base): + """ + Metaclass for caching HfFileSystem instances according to the args. + + This creates an additional reference to the filesystem, which prevents the + filesystem from being garbage collected when all *user* references go away. + A call to the :meth:`AbstractFileSystem.clear_instance_cache` must *also* + be made for a filesystem instance to be garbage collected. + + This is a slightly modified version of `fsspec.spec._Cached` to improve it. + In particular in `_tokenize` the pid isn't taken into account for the + `fs_token` used to identify cached instances. The `fs_token` logic is also + robust to defaults values and the order of the args. Finally new instances + reuse the states from sister instances in the main thread. + """ + + def __init__(cls, *args, **kwargs): + # Hack: override https://github.com/fsspec/filesystem_spec/blob/dcb167e8f50e6273d4cfdfc4cab8fc5aa4c958bf/fsspec/spec.py#L53 + super().__init__(*args, **kwargs) + # Note: we intentionally create a reference here, to avoid garbage + # collecting instances when all other references are gone. To really + # delete a FileSystem, the cache must be cleared. + cls._cache = {} + + def __call__(cls, *args, **kwargs): + # Hack: override https://github.com/fsspec/filesystem_spec/blob/dcb167e8f50e6273d4cfdfc4cab8fc5aa4c958bf/fsspec/spec.py#L65 + # Apply fsspec config (env vars / config files) before tokenizing so that + # HfFileSystem picks up defaults the same way other fsspec filesystems do. + kwargs = apply_config(cls, kwargs) + skip = kwargs.pop("skip_instance_cache", False) + fs_token = cls._tokenize(cls, threading.get_ident(), *args, **kwargs) + fs_token_main_thread = cls._tokenize(cls, threading.main_thread().ident, *args, **kwargs) + if not skip and cls.cachable and fs_token in cls._cache: + # reuse cached instance + cls._latest = fs_token + return cls._cache[fs_token] + else: + # create new instance + obj = type.__call__(cls, *args, **kwargs) + if not skip and cls.cachable and fs_token_main_thread in cls._cache: + # reuse the cache from the main thread instance in the new instance + instance_state = cls._cache[fs_token_main_thread]._get_instance_state() + for attr, state_value in instance_state.items(): + setattr(obj, attr, state_value) + obj._fs_token_ = fs_token + obj.storage_args = args + obj.storage_options = kwargs + if cls.cachable and not skip: + cls._latest = fs_token + cls._cache[fs_token] = obj + return obj + + +class HfFileSystem(fsspec.AbstractFileSystem, metaclass=_Cached): # ty: ignore[conflicting-metaclass] + """ + Access a remote Hugging Face Hub repository as if were a local file system. + + > [!WARNING] + > [`HfFileSystem`] provides fsspec compatibility, which is useful for libraries that require it (e.g., reading + > Hugging Face datasets directly with `pandas`). However, it introduces additional overhead due to this compatibility + > layer. For better performance and reliability, it's recommended to use `HfApi` methods when possible. + + The file system supports paths for the `hf://` protocol, which follows those URL schemes: + + * Models, Datasets and Spaces repositories: + + ``` + hf://[@]/ + hf://datasets/[@]/ + hf://spaces/[@]/ + ``` + + * Buckets (generic storage): + + ``` + hf://buckets// + ``` + + Note: when using the [`HfFileSystem`] directly, passing the `hf://` protocol prefix is optional in paths. + + Args: + endpoint (`str`, *optional*): + Endpoint of the Hub. Defaults to . + token (`bool` or `str`, *optional*): + A valid user access token (string). Defaults to the locally saved + token, which is the recommended method for authentication (see + https://huggingface.co/docs/huggingface_hub/quick-start#authentication). + To disable authentication, pass `False`. + block_size (`int`, *optional*): + Block size for reading and writing files. + expand_info (`bool`, *optional*): + Whether to expand the information of the files. + **storage_options (`dict`, *optional*): + Additional options for the filesystem. See [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.__init__). + + Usage: + + ```python + >>> from huggingface_hub import hffs + + >>> # List files + >>> hffs.glob("my-username/my-model/*.bin") + ['my-username/my-model/pytorch_model.bin'] + >>> hffs.ls("datasets/my-username/my-dataset", detail=False) + ['datasets/my-username/my-dataset/.gitattributes', 'datasets/my-username/my-dataset/README.md', 'datasets/my-username/my-dataset/data.json'] + + >>> # Read/write files + >>> with hffs.open("my-username/my-model/pytorch_model.bin") as f: + ... data = f.read() + >>> with hffs.open("my-username/my-model/pytorch_model.bin", "wb") as f: + ... f.write(data) + ``` + + Specify a token for authentication: + ```python + >>> from huggingface_hub import HfFileSystem + >>> hffs = HfFileSystem(token=token) + ``` + """ + + root_marker = "" + protocol = "hf" + + def __init__( + self, + *args, + endpoint: str | None = None, + token: bool | str | None = None, + block_size: int | None = None, + expand_info: bool | None = None, + **storage_options, + ): + super().__init__(*args, **storage_options) + self.endpoint = endpoint or constants.ENDPOINT + self.token = token + self._api = HfApi(endpoint=endpoint, token=token) + self.block_size = block_size + self.expand_info = expand_info + # Maps (repo_type, repo_id, revision) to a 2-tuple with: + # * the 1st element indicating whether the repository and the revision exist + # * the 2nd element being the exception raised if the repository or revision doesn't exist + self._repo_and_revision_exists_cache: dict[tuple[str, str, str | None], tuple[bool, Exception | None]] = {} + # Same for buckets + self._bucket_exists_cache: dict[str, tuple[bool, Exception | None]] = {} + # Note: special case for buckets: revision is always None + # Maps parent directory path to path infos + self.dircache: dict[str, list[dict[str, Any]]] = {} + + @classmethod + def _tokenize(cls, threading_ident: int, *args, **kwargs) -> str: + """Deterministic token for caching""" + # make fs_token robust to default values and to kwargs order + kwargs["endpoint"] = kwargs.get("endpoint") or constants.ENDPOINT + kwargs["token"] = kwargs.get("token") + kwargs = {key: kwargs[key] for key in sorted(kwargs)} + # contrary to fsspec, we don't include pid here + tokenize_args = (cls, threading_ident, args, kwargs) + h = md5(str(tokenize_args).encode()) + return h.hexdigest() + + def _repo_and_revision_exist( + self, repo_type: str, repo_id: str, revision: str | None + ) -> tuple[bool, Exception | None]: + if (repo_type, repo_id, revision) not in self._repo_and_revision_exists_cache: + try: + self._api.repo_info( + repo_id, revision=revision, repo_type=repo_type, timeout=constants.HF_HUB_ETAG_TIMEOUT + ) + except (RepositoryNotFoundError, HFValidationError) as e: + self._repo_and_revision_exists_cache[(repo_type, repo_id, revision)] = False, e + self._repo_and_revision_exists_cache[(repo_type, repo_id, None)] = False, e + except RevisionNotFoundError as e: + self._repo_and_revision_exists_cache[(repo_type, repo_id, revision)] = False, e + self._repo_and_revision_exists_cache[(repo_type, repo_id, None)] = True, None + else: + self._repo_and_revision_exists_cache[(repo_type, repo_id, revision)] = True, None + self._repo_and_revision_exists_cache[(repo_type, repo_id, None)] = True, None + return self._repo_and_revision_exists_cache[(repo_type, repo_id, revision)] + + def _bucket_exists(self, bucket_id: str) -> tuple[bool, Exception | None]: + if bucket_id not in self._bucket_exists_cache: + try: + self._api.bucket_info(bucket_id) + except BucketNotFoundError as e: + self._bucket_exists_cache[bucket_id] = False, e + else: + self._bucket_exists_cache[bucket_id] = True, None + return self._bucket_exists_cache[bucket_id] + + def resolve_path( + self, path: str, revision: str | None = None + ) -> HfFileSystemResolvedRepositoryPath | HfFileSystemResolvedBucketPath: + """ + Resolve a Hugging Face file system path into its components. + + Args: + path (`str`): + Path to resolve. + revision (`str`, *optional*): + The revision of the repo to resolve. Defaults to the revision specified in the path. + + Returns: + [`HfFileSystemResolvedPath`]: Resolved path information containing `repo_type`, `repo_id`, `revision` and `path_in_repo`. + + Raises: + `ValueError`: + If path contains conflicting revision information. + `NotImplementedError`: + If trying to list repositories. + """ + path = self._strip_protocol(path) + if not path: + raise NotImplementedError("Access to buckets and repositories lists is not implemented.") + if path.count("/") == 0: + raise ValueError( + f"Repository id must be 'namespace/name', got '{path}'. Single-segment ids (e.g. 'gpt2') are no longer supported." + ) + + parsed = parse_hf_uri(f"{constants.HF_PROTOCOL}{path}") + + # --- Buckets --- + if parsed.is_bucket: + bucket_exists, err = self._bucket_exists(parsed.id) + if not bucket_exists: + _raise_file_not_found(path, err) + return HfFileSystemResolvedBucketPath(bucket_id=parsed.id, path=parsed.path_in_repo) + + # --- Repositories --- + # Align revision from path with explicit revision argument + if revision is not None and parsed.revision is not None and parsed.revision != revision: + # The caller provided an explicit revision that conflicts with what parse_hf_uri + # parsed. This can happen when a user has a branch literally named "refs" and a + # file at "pr/10" — parse_hf_uri would greedily match "refs/pr/10" as a special + # ref. Fall back to simple '@' splitting so the caller's revision wins. + path_without_type = path.split("/", 1)[1] if path.split("/")[0] in constants.HF_URI_TYPE_PREFIXES else path + repo_id, after_at = path_without_type.split("@", 1) + revision_in_path, path_in_repo = after_at.split("/", 1) if "/" in after_at else (after_at, "") + revision_in_path_decoded = unquote(revision_in_path) + if revision_in_path_decoded != revision: + raise ValueError( + f'Revision specified in path ("{revision_in_path_decoded}") and in `revision` argument ("{revision}") are not the same.' + ) + repo_and_revision_exist, err = self._repo_and_revision_exist(parsed.type, repo_id, revision) + if not repo_and_revision_exist: + _raise_file_not_found(path, err) + return HfFileSystemResolvedRepositoryPath( + parsed.type, repo_id, revision, path_in_repo, _raw_revision=revision_in_path + ) + + if parsed.revision is not None and revision is None: + revision = parsed.revision + + repo_and_revision_exist, err = self._repo_and_revision_exist(parsed.type, parsed.id, revision) + if not repo_and_revision_exist: + _raise_file_not_found(path, err) + + # Extract raw revision from original path for unresolve() fidelity + raw_revision: str | None = None + if "@" in path and parsed.revision is not None: + path_without_type = path.split("/", 1)[1] if path.split("/")[0] in constants.HF_URI_TYPE_PREFIXES else path + raw_after_at = path_without_type.split("@", 1)[1] + raw_revision = raw_after_at[: -(len(parsed.path_in_repo) + 1)] if parsed.path_in_repo else raw_after_at + + revision = revision if revision is not None else constants.DEFAULT_REVISION + return HfFileSystemResolvedRepositoryPath( + parsed.type, parsed.id, revision, parsed.path_in_repo, _raw_revision=raw_revision + ) + + def invalidate_cache(self, path: str | None = None) -> None: + """ + Clear the cache for a given path. + + For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.invalidate_cache). + + Args: + path (`str`, *optional*): + Path to clear from cache. If not provided, clear the entire cache. + + """ + if not path: + self.dircache.clear() + self._repo_and_revision_exists_cache.clear() + else: + resolved_path = self.resolve_path(path) + path = resolved_path.unresolve() + while path: + self.dircache.pop(path, None) + path = self._parent(path) + + # Only clear repo cache if path is to repo root + if not resolved_path.path: + if isinstance(resolved_path, HfFileSystemResolvedRepositoryPath): + self._repo_and_revision_exists_cache.pop( + (resolved_path.repo_type, resolved_path.repo_id, None), None + ) + self._repo_and_revision_exists_cache.pop( + (resolved_path.repo_type, resolved_path.repo_id, resolved_path.revision), None + ) + else: + self._bucket_exists_cache.pop(resolved_path.bucket_id, None) + + def _open( # type: ignore + self, + path: str, + mode: str = "rb", + block_size: int | None = None, + revision: str | None = None, + **kwargs, + ) -> Union["HfFileSystemFile", "HfFileSystemStreamFile"]: + block_size = block_size if block_size is not None else self.block_size + if block_size is not None: + kwargs["block_size"] = block_size + if "a" in mode: + raise NotImplementedError("Appending to remote files is not yet supported.") + if block_size == 0: + return HfFileSystemStreamFile(self, path, mode=mode, revision=revision, **kwargs) + else: + return HfFileSystemFile(self, path, mode=mode, revision=revision, **kwargs) + + def _rm(self, path: str, revision: str | None = None, **kwargs) -> None: + resolved_path = self.resolve_path(path, revision=revision) + if isinstance(resolved_path, HfFileSystemResolvedBucketPath): + self._api.batch_bucket_files(resolved_path.bucket_id, delete=[resolved_path.path]) + else: + self._api.delete_file( + path_in_repo=resolved_path.path_in_repo, + repo_id=resolved_path.repo_id, + token=self.token, + repo_type=resolved_path.repo_type, + revision=resolved_path.revision, + commit_message=kwargs.get("commit_message"), + commit_description=kwargs.get("commit_description"), + ) + self.invalidate_cache(path=resolved_path.unresolve()) + + def rm( + self, + path: str, + recursive: bool = False, + maxdepth: int | None = None, + revision: str | None = None, + **kwargs, + ) -> None: + """ + Delete files from a repository. + + For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.rm). + + > [!WARNING] + > Note: When possible, use `HfApi.delete_file()` for better performance. + + Args: + path (`str`): + Path to delete. + recursive (`bool`, *optional*): + If True, delete directory and all its contents. Defaults to False. + maxdepth (`int`, *optional*): + Maximum number of subdirectories to visit when deleting recursively. + revision (`str`, *optional*): + The git revision to delete from. + + """ + resolved_path = self.resolve_path(path, revision=revision) + paths = self.expand_path(path, recursive=recursive, maxdepth=maxdepth, revision=revision) + if isinstance(resolved_path, HfFileSystemResolvedBucketPath): + delete = [self.resolve_path(path).path for path in paths if not self.isdir(path)] + self._api.batch_bucket_files(resolved_path.bucket_id, delete=delete) + else: + paths_in_repo = [self.resolve_path(path).path for path in paths if not self.isdir(path)] + operations = [CommitOperationDelete(path_in_repo=path_in_repo) for path_in_repo in paths_in_repo] + commit_message = f"Delete {path} " + commit_message += "recursively " if recursive else "" + commit_message += f"up to depth {maxdepth} " if maxdepth is not None else "" + # TODO: use `commit_description` to list all the deleted paths? + self._api.create_commit( + repo_id=resolved_path.repo_id, + repo_type=resolved_path.repo_type, + token=self.token, + operations=operations, + revision=resolved_path.revision, + commit_message=kwargs.get("commit_message", commit_message), + commit_description=kwargs.get("commit_description"), + ) + self.invalidate_cache(path=resolved_path.unresolve()) + + def ls( + self, path: str, detail: bool = True, refresh: bool = False, revision: str | None = None, **kwargs + ) -> list[str | dict[str, Any]]: + """ + List the contents of a directory. + + For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.ls). + + > [!WARNING] + > Note: When possible, use `HfApi.list_repo_tree()` for better performance. + + Args: + path (`str`): + Path to the directory. + detail (`bool`, *optional*): + If True, returns a list of dictionaries containing file information. If False, + returns a list of file paths. Defaults to True. + refresh (`bool`, *optional*): + If True, bypass the cache and fetch the latest data. Defaults to False. + revision (`str`, *optional*): + The git revision to list from. + + Returns: + `list[Union[str, dict[str, Any]]]`: List of file paths (if detail=False) or list of file information + dictionaries (if detail=True). + """ + resolved_path = self.resolve_path(path, revision=revision) + path = resolved_path.unresolve() + try: + out = self._ls_tree(path, refresh=refresh, revision=revision, **kwargs) + except EntryNotFoundError: + # Path could be a file + if not resolved_path.path: + _raise_file_not_found(path, None) + try: + out = self._ls_tree(self._parent(path), refresh=refresh, revision=revision, **kwargs) + except EntryNotFoundError: + out = [] + out = [o for o in out if o["name"] == path] + if len(out) == 0: + _raise_file_not_found(path, None) + return out if detail else [o["name"] for o in out] + + def _ls_tree( + self, + path: str, + recursive: bool = False, + refresh: bool = False, + revision: str | None = None, + expand_info: bool | None = None, + maxdepth: int | None = None, + ): + expand_info = ( + expand_info if expand_info is not None else (self.expand_info if self.expand_info is not None else False) + ) + resolved_path = self.resolve_path(path, revision=revision) + path = resolved_path.unresolve() + root_path = resolved_path.root + maxdepth = maxdepth if recursive else 1 + + out = [] + if path in self.dircache and not refresh: + cached_path_infos = self.dircache[path] + out.extend(cached_path_infos) + dirs_not_in_dircache = [] + if recursive: + # Use BFS to traverse the cache and build the "recursive "output + # (The Hub uses a so-called "tree first" strategy for the tree endpoint but we sort the output to follow the spec so the result is (eventually) the same) + depth = 2 + dirs_to_visit = deque( + [(depth, path_info) for path_info in cached_path_infos if path_info["type"] == "directory"] + ) + while dirs_to_visit: + depth, dir_info = dirs_to_visit.popleft() + if maxdepth is None or depth <= maxdepth: + if dir_info["name"] not in self.dircache: + dirs_not_in_dircache.append(dir_info["name"]) + else: + cached_path_infos = self.dircache[dir_info["name"]] + out.extend(cached_path_infos) + dirs_to_visit.extend( + [ + (depth + 1, path_info) + for path_info in cached_path_infos + if path_info["type"] == "directory" + ] + ) + + dirs_not_expanded = [] + if expand_info and isinstance(resolved_path, HfFileSystemResolvedRepositoryPath): + # Check if there are directories in repos with non-expanded entries + dirs_not_expanded = [self._parent(o["name"]) for o in out if o["last_commit"] is None] + + if (recursive and dirs_not_in_dircache) or (expand_info and dirs_not_expanded): + # If the dircache is incomplete, find the common path of the missing and non-expanded entries + # and extend the output with the result of `_ls_tree(common_path, recursive=True)` + common_prefix = os.path.commonprefix(dirs_not_in_dircache + dirs_not_expanded) + # Get the parent directory if the common prefix itself is not a directory + common_path = ( + common_prefix.rstrip("/") + if common_prefix.endswith("/") + or common_prefix == root_path + or common_prefix in chain(dirs_not_in_dircache, dirs_not_expanded) + else self._parent(common_prefix) + ) + if maxdepth is not None: + common_path_depth = common_path[len(path) :].count("/") + maxdepth -= common_path_depth + out = [o for o in out if not o["name"].startswith(common_path + "/")] + for cached_path in list(self.dircache): + if cached_path.startswith(common_path + "/"): + self.dircache.pop(cached_path, None) + self.dircache.pop(common_path, None) + out.extend( + self._ls_tree( + common_path, + recursive=recursive, + refresh=True, + revision=revision, + expand_info=expand_info, + maxdepth=maxdepth, + ) + ) + else: + tree: Iterable[RepoFile | RepoFolder | BucketFile | BucketFolder] + if isinstance(resolved_path, HfFileSystemResolvedBucketPath): + tree = self._list_bucket_tree_with_folders( + resolved_path.bucket_id, + prefix=resolved_path.path, + recursive=recursive, + ) + else: + tree = self._api.list_repo_tree( + resolved_path.repo_id, + resolved_path.path, + recursive=recursive, + expand=expand_info, + revision=resolved_path.revision, + repo_type=resolved_path.repo_type, + ) + for path_info in tree: + cache_path = root_path + "/" + path_info.path + if isinstance(path_info, RepoFile): + cache_path_info = { + "name": cache_path, + "size": path_info.size, + "type": "file", + "blob_id": path_info.blob_id, + "lfs": path_info.lfs, + "xet_hash": path_info.xet_hash, + "last_commit": path_info.last_commit, + "security": path_info.security, + } + elif isinstance(path_info, BucketFile): + cache_path_info = { + "name": cache_path, + "size": path_info.size, + "type": "file", + "xet_hash": path_info.xet_hash, + "mtime": path_info.mtime, + "uploaded_at": path_info.uploaded_at, + } + elif isinstance(path_info, RepoFolder): + cache_path_info = { + "name": cache_path, + "size": 0, + "type": "directory", + "tree_id": path_info.tree_id, + "last_commit": path_info.last_commit, + } + else: + cache_path_info = { + "name": cache_path, + "size": 0, + "type": "directory", + "uploaded_at": path_info.uploaded_at, + } + parent_path = self._parent(cache_path_info["name"]) + self.dircache.setdefault(parent_path, []).append(cache_path_info) + depth = cache_path[len(path) :].count("/") + if maxdepth is None or depth <= maxdepth: + out.append(cache_path_info) + return out + + def _list_bucket_tree_with_folders( + self, bucket_id: str, prefix: str, recursive: bool + ) -> Iterable[BucketFile | BucketFolder]: + """Same as `HfApi.list_bucket_tree` but always includes folders""" + bucket_files = self._api.list_bucket_tree(bucket_id, prefix, recursive=recursive) + bucket_folders: dict[str, BucketFolder] = {} + min_depth = 1 + prefix.count("/") if prefix else 0 + out: list[BucketFile | BucketFolder] = [] + + for bucket_entry in bucket_files: + out.append(bucket_entry) + + # If recursive=False, both files and folders are returned by the server => nothing to do + if not recursive: + continue + + # Otherwise, let's rebuild BucketFolders manually + for parent_bucket_folder_str in list(PurePosixPath(bucket_entry.path).parents)[: -min_depth - 1]: + parent_bucket_folder = BucketFolder( + type="directory", path=str(parent_bucket_folder_str), uploaded_at=bucket_entry.uploaded_at + ) + + # If folder not visited yet, add it + if parent_bucket_folder.path not in bucket_folders: + out.append(parent_bucket_folder) + bucket_folders[parent_bucket_folder.path] = parent_bucket_folder + continue + + # Otherwise, get back BucketFolder object and update its 'uploaded_at' + if parent_bucket_folder.uploaded_at is not None: + bucket_folder = bucket_folders[parent_bucket_folder.path] + if bucket_folder.uploaded_at is None or ( + bucket_folder.uploaded_at < parent_bucket_folder.uploaded_at + ): + bucket_folder.uploaded_at = parent_bucket_folder.uploaded_at + + if not out: + raise EntryNotFoundError(f"File not found in bucket '{bucket_id}': '{prefix}'") + return out + + def walk(self, path: str, *args, **kwargs) -> Iterator[tuple[str, list[str], list[str]]]: + """ + Return all files below the given path. + + For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.walk). + + Args: + path (`str`): + Root path to list files from. + + Returns: + `Iterator[tuple[str, list[str], list[str]]]`: An iterator of (path, list of directory names, list of file names) tuples. + """ + path = self.resolve_path(path, revision=kwargs.get("revision")).unresolve() + yield from super().walk(path, *args, **kwargs) + + def glob(self, path: str, maxdepth: int | None = None, **kwargs) -> list[str]: + """ + Find files by glob-matching. + + For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.glob). + + Args: + path (`str`): + Path pattern to match. + maxdepth (`int`, *optional*): + Maximum depth to descend into directories. By default, no limit. + + Returns: + `list[str]`: List of paths matching the pattern. + """ + path = self.resolve_path(path, revision=kwargs.get("revision")).unresolve() + return super().glob(path, maxdepth=maxdepth, **kwargs) + + def find( + self, + path: str, + maxdepth: int | None = None, + withdirs: bool = False, + detail: bool = False, + refresh: bool = False, + revision: str | None = None, + **kwargs, + ) -> list[str] | dict[str, dict[str, Any]]: + """ + List all files below path. + + For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.find). + + Args: + path (`str`): + Root path to list files from. + maxdepth (`int`, *optional*): + Maximum depth to descend into subdirectories. + withdirs (`bool`, *optional*): + Include directory paths in the output. Defaults to False. + detail (`bool`, *optional*): + If True, returns a dict mapping paths to file information. Defaults to False. + refresh (`bool`, *optional*): + If True, bypass the cache and fetch the latest data. Defaults to False. + revision (`str`, *optional*): + The git revision to list from. + + Returns: + `Union[list[str], dict[str, dict[str, Any]]]`: List of paths or dict of file information. + """ + if maxdepth is not None and maxdepth < 1: + raise ValueError("maxdepth must be at least 1") + resolved_path = self.resolve_path(path, revision=revision) + path = resolved_path.unresolve() + try: + out = self._ls_tree(path, recursive=True, refresh=refresh, maxdepth=maxdepth, **kwargs) + except EntryNotFoundError: + # Path could be a file + try: + if self.info(path, revision=revision, **kwargs)["type"] == "file": + out = {path: {}} + else: + out = {} + except FileNotFoundError: + out = {} + else: + if not withdirs: + out = [o for o in out if o["type"] != "directory"] + else: + # If `withdirs=True`, include the directory itself to be consistent with the spec + path_info = self.info(path, **kwargs) + out = [path_info] + out if path_info["type"] == "directory" else out + out = {o["name"]: o for o in out} + names = sorted(out) + if not detail: + return names + else: + return {name: out[name] for name in names} + + def cp_file(self, path1: str, path2: str, revision: str | None = None, **kwargs) -> None: + """ + Copy a file within or between repositories. + + > [!WARNING] + > Note: When possible, use `HfApi.upload_file()` for better performance. + + Args: + path1 (`str`): + Source path to copy from. + path2 (`str`): + Destination path to copy to. + revision (`str`, *optional*): + The git revision to copy from. + + """ + resolved_path1 = self.resolve_path(path1, revision=revision) + resolved_path2 = self.resolve_path(path2, revision=revision) + if isinstance(resolved_path1, HfFileSystemResolvedBucketPath) or isinstance( + resolved_path2, HfFileSystemResolvedBucketPath + ): + raise NotImplementedError("Copy from/to buckets is not available yet") + + same_repo = ( + resolved_path1.repo_type == resolved_path2.repo_type and resolved_path1.repo_id == resolved_path2.repo_id + ) + + if same_repo: + commit_message = f"Copy {path1} to {path2}" + self._api.create_commit( + repo_id=resolved_path1.repo_id, + repo_type=resolved_path1.repo_type, + revision=resolved_path2.revision, + commit_message=kwargs.get("commit_message", commit_message), + commit_description=kwargs.get("commit_description", ""), + operations=[ + CommitOperationCopy( + src_path_in_repo=resolved_path1.path_in_repo, + path_in_repo=resolved_path2.path_in_repo, + src_revision=resolved_path1.revision, + ) + ], + ) + else: + with self.open(path1, "rb", revision=resolved_path1.revision) as f: + content = f.read() + commit_message = f"Copy {path1} to {path2}" + self._api.upload_file( + path_or_fileobj=content, + path_in_repo=resolved_path2.path_in_repo, + repo_id=resolved_path2.repo_id, + token=self.token, + repo_type=resolved_path2.repo_type, + revision=resolved_path2.revision, + commit_message=kwargs.get("commit_message", commit_message), + commit_description=kwargs.get("commit_description"), + ) + self.invalidate_cache(path=resolved_path1.unresolve()) + self.invalidate_cache(path=resolved_path2.unresolve()) + + def modified(self, path: str, **kwargs) -> datetime: + """ + Get the last modified time of a file. + + For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.modified). + + Args: + path (`str`): + Path to the file. + + Returns: + `datetime`: Last modified time of the file. + """ + info = self.info(path, **{**kwargs, "expand_info": True}) # type: ignore + if "last_commit" in info: + if info["last_commit"] is None: + raise NotImplementedError(f"'modified' is not implemented for repository paths like '{path}'") + return info["last_commit"].date + elif "mtime" in info and info["mtime"]: + return info["mtime"] + elif "uploaded_at" in info and info["uploaded_at"]: + return info["uploaded_at"] + else: + raise NotImplementedError(f"Cannot determined 'modified' for path '{path}' (info: {info})") + + def info(self, path: str, refresh: bool = False, revision: str | None = None, **kwargs) -> dict[str, Any]: + """ + Get information about a file or directory. + + For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.info). + + > [!WARNING] + > Note: When possible, use `HfApi.get_paths_info()` or `HfApi.repo_info()` for better performance + > (or `HfApi.get_bucket_paths_info()` or `HfApi.bucket_info()` for buckets) + + Args: + path (`str`): + Path to get info for. + refresh (`bool`, *optional*): + If True, bypass the cache and fetch the latest data. Defaults to False. + revision (`str`, *optional*): + The git revision to get info from. + + Returns: + `dict[str, Any]`: Dictionary containing file information (type, size, commit info, etc.). + + """ + resolved_path = self.resolve_path(path, revision=revision) + path = resolved_path.unresolve() + expand_info = kwargs.get( + "expand_info", self.expand_info if self.expand_info is not None else False + ) # don't expose it as a parameter in the public API to follow the spec + out: dict[str, Any] | None + if not resolved_path.path: + # Path is the root directory + out = { + "name": path, + "size": 0, + "type": "directory", + } + if isinstance(resolved_path, HfFileSystemResolvedRepositoryPath): + out["last_commit"] = None + if isinstance(resolved_path, HfFileSystemResolvedRepositoryPath) and expand_info: + last_commit = self._api.list_repo_commits( + resolved_path.repo_id, repo_type=resolved_path.repo_type, revision=resolved_path.revision + )[-1] + out = { + **out, + "tree_id": None, # TODO: tree_id of the root directory? + "last_commit": LastCommitInfo( + oid=last_commit.commit_id, title=last_commit.title, date=last_commit.created_at + ), + } + elif isinstance(resolved_path, HfFileSystemResolvedBucketPath): + parent_path = self._parent(path) + # Fill the cache with cheap call + self.ls(parent_path, refresh=refresh) + out1 = [o for o in self.dircache[parent_path] if o["name"] == path] + if not out1: + _raise_file_not_found(path, None) + out = out1[0] + else: + out = None + parent_path = self._parent(path) + if not expand_info and parent_path not in self.dircache: + # Fill the cache with cheap call + self.ls(parent_path) + if parent_path in self.dircache: + # Check if the path is in the cache + out1 = [o for o in self.dircache[parent_path] if o["name"] == path] + if not out1: + _raise_file_not_found(path, None) + out = out1[0] + if refresh or out is None or (expand_info and out and out["last_commit"] is None): + paths_info = self._api.get_paths_info( + resolved_path.repo_id, + resolved_path.path_in_repo, + expand=expand_info, + revision=resolved_path.revision, + repo_type=resolved_path.repo_type, + ) + if not paths_info: + _raise_file_not_found(path, None) + path_info = paths_info[0] + root_path = HfFileSystemResolvedRepositoryPath( + resolved_path.repo_type, + resolved_path.repo_id, + resolved_path.revision, + path_in_repo="", + _raw_revision=resolved_path._raw_revision, + ).unresolve() + if isinstance(path_info, RepoFile): + out = { + "name": root_path + "/" + path_info.path, + "size": path_info.size, + "type": "file", + "blob_id": path_info.blob_id, + "lfs": path_info.lfs, + "xet_hash": path_info.xet_hash, + "last_commit": path_info.last_commit, + "security": path_info.security, + } + else: + out = { + "name": root_path + "/" + path_info.path, + "size": 0, + "type": "directory", + "tree_id": path_info.tree_id, + "last_commit": path_info.last_commit, + } + if not expand_info: + out = {k: out[k] for k in ["name", "size", "type"]} + assert out is not None + return out + + def exists(self, path, **kwargs): + """ + Check if a file exists. + + For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.exists). + + > [!WARNING] + > Note: When possible, use `HfApi.file_exists()` for better performance. + + Args: + path (`str`): + Path to check. + + Returns: + `bool`: True if file exists, False otherwise. + """ + try: + if kwargs.get("refresh", False): + self.invalidate_cache(path) + + self.info(path, **kwargs) + return True + except OSError: + return False + + def isdir(self, path): + """ + Check if a path is a directory. + + For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.isdir). + + Args: + path (`str`): + Path to check. + + Returns: + `bool`: True if path is a directory, False otherwise. + """ + try: + return self.info(path)["type"] == "directory" + except OSError: + return False + + def isfile(self, path): + """ + Check if a path is a file. + + For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.isfile). + + Args: + path (`str`): + Path to check. + + Returns: + `bool`: True if path is a file, False otherwise. + """ + try: + return self.info(path)["type"] == "file" + except OSError: + return False + + def url(self, path: str) -> str: + """ + Get the HTTP URL of the given path. + + Args: + path (`str`): + Path to get URL for. + + Returns: + `str`: HTTP URL to access the file or directory on the Hub. + """ + resolved_path = self.resolve_path(path) + if isinstance(resolved_path, HfFileSystemResolvedBucketPath): + url = f"{self.endpoint}/buckets/{resolved_path.bucket_id}/resolve/{quote(resolved_path.path)}" + else: + url = hf_hub_url( + resolved_path.repo_id, + resolved_path.path_in_repo, + repo_type=resolved_path.repo_type, + revision=resolved_path.revision, + endpoint=self.endpoint, + ) + if self.isdir(path): + url = url.replace("/resolve/", "/tree/", 1) + return url + + def get_file(self, rpath, lpath, callback=_DEFAULT_CALLBACK, outfile=None, **kwargs) -> None: + """ + Copy single remote file to local. + + > [!WARNING] + > Note: When possible, use `HfApi.hf_hub_download()` or `HfApi.download_bucket_files` for better performance. + + Args: + rpath (`str`): + Remote path to download from. + lpath (`str`): + Local path to download to. + callback (`Callback`, *optional*): + Optional callback to track download progress. Defaults to no callback. + outfile (`IO`, *optional*): + Optional file-like object to write to. If provided, `lpath` is ignored. + + """ + revision = kwargs.get("revision") + unhandled_kwargs = set(kwargs.keys()) - {"revision"} + if not isinstance(callback, (NoOpCallback, TqdmCallback)) or len(unhandled_kwargs) > 0: + # for now, let's not handle custom callbacks + # and let's not handle custom kwargs + return super().get_file(rpath, lpath, callback=callback, outfile=outfile, **kwargs) + + # Taken from https://github.com/fsspec/filesystem_spec/blob/47b445ae4c284a82dd15e0287b1ffc410e8fc470/fsspec/spec.py#L883 + if isfilelike(lpath): + outfile = lpath + elif self.isdir(rpath): + os.makedirs(lpath, exist_ok=True) + return None + + if isinstance(lpath, (str, Path)): # otherwise, let's assume it's a file-like object + os.makedirs(os.path.dirname(lpath), exist_ok=True) + + # Open file if not already open + close_file = False + if outfile is None: + outfile = open(lpath, "wb") + close_file = True + initial_pos = outfile.tell() + + # Custom implementation of `get_file` to use `http_get`. + resolve_remote_path = self.resolve_path(rpath, revision=revision) + expected_size = self.info(rpath, revision=revision)["size"] + callback.set_size(expected_size) + try: + http_get( + url=self.url(resolve_remote_path.unresolve()), + temp_file=outfile, # type: ignore + displayed_filename=rpath, + expected_size=expected_size, + resume_size=0, + headers=self._api._build_hf_headers(), + _tqdm_bar=callback.tqdm if isinstance(callback, TqdmCallback) else None, + ) + outfile.seek(initial_pos) + finally: + # Close file only if we opened it ourselves + if close_file: + outfile.close() + + @property + def transaction(self): + """A context within which files are committed together upon exit + + Requires the file class to implement `.commit()` and `.discard()` + for the normal and exception cases. + """ + # Taken from https://github.com/fsspec/filesystem_spec/blob/3fbb6fee33b46cccb015607630843dea049d3243/fsspec/spec.py#L231 + # See https://github.com/huggingface/huggingface_hub/issues/1733 + raise NotImplementedError("Transactional commits are not supported.") + + def start_transaction(self): + """Begin write transaction for deferring files, non-context version""" + # Taken from https://github.com/fsspec/filesystem_spec/blob/3fbb6fee33b46cccb015607630843dea049d3243/fsspec/spec.py#L241 + # See https://github.com/huggingface/huggingface_hub/issues/1733 + raise NotImplementedError("Transactional commits are not supported.") + + def __reduce__(self): + # re-populate the instance cache at HfFileSystem._cache and re-populate the state of every instance + return make_instance, ( + type(self), + self.storage_args, + self.storage_options, + self._get_instance_state(), + ) + + def _get_instance_state(self): + return { + "dircache": deepcopy(self.dircache), + "_repo_and_revision_exists_cache": deepcopy(self._repo_and_revision_exists_cache), + "_bucket_exists_cache": deepcopy(self._bucket_exists_cache), + } + + +class HfFileSystemFile(fsspec.spec.AbstractBufferedFile): + def __init__(self, fs: HfFileSystem, path: str, revision: str | None = None, **kwargs): + try: + self.resolved_path = fs.resolve_path(path, revision=revision) + except FileNotFoundError as e: + if "w" in kwargs.get("mode", ""): + raise FileNotFoundError( + f"{e}.\nMake sure the repository and revision exist before writing data." + ) from e + raise + super().__init__(fs, self.resolved_path.unresolve(), **kwargs) + self.fs: HfFileSystem + + def __del__(self): + if not hasattr(self, "resolved_path"): + # Means that the constructor failed. Nothing to do. + return + return super().__del__() + + def _fetch_range(self, start: int, end: int) -> bytes: + headers = { + "range": f"bytes={start}-{end - 1}", + **self.fs._api._build_hf_headers(), + } + url = self.url() + r = http_backoff("GET", url, headers=headers, timeout=constants.HF_HUB_DOWNLOAD_TIMEOUT) + hf_raise_for_status(r) + return r.content + + def _initiate_upload(self) -> None: + self.temp_file = tempfile.NamedTemporaryFile(prefix="hffs-", delete=False) + + def _upload_chunk(self, final: bool = False) -> None: + self.buffer.seek(0) + block = self.buffer.read() + self.temp_file.write(block) + if final: + self.temp_file.close() + if isinstance(self.resolved_path, HfFileSystemResolvedBucketPath): + self.fs._api.batch_bucket_files( + self.resolved_path.bucket_id, add=[(self.temp_file.name, self.resolved_path.path)] + ) + else: + self.fs._api.upload_file( + path_or_fileobj=self.temp_file.name, + path_in_repo=self.resolved_path.path_in_repo, + repo_id=self.resolved_path.repo_id, + token=self.fs.token, + repo_type=self.resolved_path.repo_type, + revision=self.resolved_path.revision, + commit_message=self.kwargs.get("commit_message"), + commit_description=self.kwargs.get("commit_description"), + ) + os.remove(self.temp_file.name) + self.fs.invalidate_cache( + path=self.resolved_path.unresolve(), + ) + + def read(self, length=-1): + """Read remote file. + + If `length` is not provided or is -1, the entire file is downloaded and read. On POSIX systems the file is + loaded in memory directly. Otherwise, the file is downloaded to a temporary file and read from there. + """ + if self.mode == "rb" and (length is None or length == -1) and self.loc == 0: + with self.fs.open(self.path, "rb", block_size=0) as f: # block_size=0 enables fast streaming + out = f.read() + self.loc += len(out) + return out + return super().read(length) + + def url(self) -> str: + return self.fs.url(self.path) + + +class HfFileSystemStreamFile(fsspec.spec.AbstractBufferedFile): + def __init__( + self, + fs: HfFileSystem, + path: str, + mode: str = "rb", + revision: str | None = None, + block_size: int = 0, + cache_type: str = "none", + **kwargs, + ): + if block_size != 0: + raise ValueError(f"HfFileSystemStreamFile only supports block_size=0 but got {block_size}") + if cache_type != "none": + raise ValueError(f"HfFileSystemStreamFile only supports cache_type='none' but got {cache_type}") + if "w" in mode: + raise ValueError(f"HfFileSystemStreamFile only supports reading but got mode='{mode}'") + try: + self.resolved_path = fs.resolve_path(path, revision=revision) + except FileNotFoundError as e: + if "w" in kwargs.get("mode", ""): + raise FileNotFoundError( + f"{e}.\nMake sure the repository and revision exist before writing data." + ) from e + # avoid an unnecessary .info() call to instantiate .details + self.details = {"name": self.resolved_path.unresolve(), "size": None} + super().__init__( + fs, self.resolved_path.unresolve(), mode=mode, block_size=block_size, cache_type=cache_type, **kwargs + ) + self.response: httpx.Response | None = None + self.fs: HfFileSystem + self._exit_stack = ExitStack() + # streaming state + self._stream_iterator: Iterator[bytes] | None = None + self._stream_buffer = bytearray() + + def seek(self, loc: int, whence: int = 0): + if loc == 0 and whence == 1: + return + if loc == self.loc and whence == 0: + return + raise ValueError("Cannot seek streaming HF file") + + def read(self, length: int = -1): + """Read the remote file. + + If the file is already open, we reuse the connection. + Otherwise, open a new connection and read from it. + + If reading the stream fails, we retry with a new connection. + """ + if self.response is None: + self._open_connection() + + retried_once = False + while True: + try: + if self.response is None or self._stream_iterator is None: + return b"" # Already read the entire file + out = self._read_from_stream(self._stream_iterator, length) + self.loc += len(out) + return out + except Exception: + if self.response is not None: + self.response.close() + if retried_once: # Already retried once, give up + raise + # First failure, retry with range header + self._open_connection() + retried_once = True + + def _read_from_stream(self, iterator: Iterator[bytes], length: int = -1) -> bytes: + """Read up to `length` bytes from stream buffer and stream. + + If length < 0, read until EOF. + + If EOF is reached before length, fewer bytes may be returned. + """ + if length == 0: + return b"" + + if length < 0: + buf = bytearray(self._stream_buffer) + self._stream_buffer.clear() + for chunk in iterator: + buf.extend(chunk) + return bytes(buf) + + if length <= len(self._stream_buffer): + result = bytes(self._stream_buffer[:length]) + del self._stream_buffer[:length] + return result + + buf = bytearray(self._stream_buffer) + self._stream_buffer.clear() + for chunk in iterator: + need = length - len(buf) + if need > len(chunk): + buf.extend(chunk) + else: + buf.extend(chunk[:need]) + self._stream_buffer.extend(chunk[need:]) + break + return bytes(buf) + + def url(self) -> str: + return self.fs.url(self.path) + + def __del__(self): + if not hasattr(self, "resolved_path"): + # Means that the constructor failed. Nothing to do. + return + self._exit_stack.close() + return super().__del__() + + def __reduce__(self): + return reopen, (self.fs, self.path, self.mode, self.blocksize, self.cache.name) + + def _open_connection(self): + """Open a connection to the remote file.""" + # reset streaming state + self._stream_buffer.clear() + self._stream_iterator = None + + url = self.url() + headers = self.fs._api._build_hf_headers() + if self.loc > 0: + headers["Range"] = f"bytes={self.loc}-" + self.response = self._exit_stack.enter_context( + http_stream_backoff( + "GET", + url, + headers=headers, + timeout=constants.HF_HUB_DOWNLOAD_TIMEOUT, + ) + ) + + try: + hf_raise_for_status(self.response) + except HfHubHTTPError as e: + if e.response.status_code == 416: + # Range not satisfiable => means that we have already read the entire file + self.response = None + return + raise + + self._stream_iterator = self.response.iter_bytes() + + +def safe_revision(revision: str) -> str: + return revision if SPECIAL_REFS_REVISION_REGEX.match(revision) else safe_quote(revision) + + +def safe_quote(s: str) -> str: + return quote(s, safe="") + + +def _raise_file_not_found(path: str, err: Exception | None) -> NoReturn: + msg = path + if isinstance(err, RepositoryNotFoundError): + msg = f"{path} (repository not found)" + elif isinstance(err, RevisionNotFoundError): + msg = f"{path} (revision not found)" + elif isinstance(err, HFValidationError): + msg = f"{path} (invalid repository id)" + raise FileNotFoundError(msg) from err + + +def reopen(fs: HfFileSystem, path: str, mode: str, block_size: int, cache_type: str): + return fs.open(path, mode=mode, block_size=block_size, cache_type=cache_type) + + +def make_instance(cls, args, kwargs, instance_state): + fs = cls(*args, **kwargs) + for attr, state_value in instance_state.items(): + setattr(fs, attr, state_value) + return fs + + +hffs = HfFileSystem() diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/hub_mixin.py b/.venv/lib/python3.13/site-packages/huggingface_hub/hub_mixin.py new file mode 100644 index 0000000000000000000000000000000000000000..937cfe1851538aa8389222885015212c80514871 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/hub_mixin.py @@ -0,0 +1,834 @@ +import inspect +import json +import os +from collections.abc import Callable +from dataclasses import Field, asdict, dataclass, is_dataclass +from pathlib import Path +from typing import Any, ClassVar, Protocol, TypeVar + +import packaging.version + +from . import constants +from .errors import EntryNotFoundError, HfHubHTTPError +from .file_download import hf_hub_download +from .hf_api import HfApi +from .repocard import ModelCard, ModelCardData +from .utils import ( + SoftTemporaryDirectory, + is_jsonable, + is_safetensors_available, + is_simple_optional_type, + is_torch_available, + logging, + unwrap_simple_optional_type, + validate_hf_hub_args, +) + + +if is_torch_available(): + import torch # type: ignore + +if is_safetensors_available(): + import safetensors + from safetensors.torch import load_model as load_model_as_safetensor + from safetensors.torch import save_model as save_model_as_safetensor + + +logger = logging.get_logger(__name__) + + +# Type alias for dataclass instances, copied from https://github.com/python/typeshed/blob/9f28171658b9ca6c32a7cb93fbb99fc92b17858b/stdlib/_typeshed/__init__.pyi#L349 +class DataclassInstance(Protocol): + __dataclass_fields__: ClassVar[dict[str, Field]] + + +# Generic variable that is either ModelHubMixin or a subclass thereof +T = TypeVar("T", bound="ModelHubMixin") +# Generic variable to represent an args type +ARGS_T = TypeVar("ARGS_T") +ENCODER_T = Callable[[ARGS_T], Any] +DECODER_T = Callable[[Any], ARGS_T] +CODER_T = tuple[ENCODER_T, DECODER_T] + + +DEFAULT_MODEL_CARD = """ +--- +# For reference on model card metadata, see the spec: https://github.com/huggingface/hub-docs/blob/main/modelcard.md?plain=1 +# Doc / guide: https://huggingface.co/docs/hub/model-cards +{{ card_data }} +--- + +This model has been pushed to the Hub using the [PytorchModelHubMixin](https://huggingface.co/docs/huggingface_hub/package_reference/mixins#huggingface_hub.PyTorchModelHubMixin) integration: +- Code: {{ repo_url | default("[More Information Needed]", true) }} +- Paper: {{ paper_url | default("[More Information Needed]", true) }} +- Docs: {{ docs_url | default("[More Information Needed]", true) }} +""" + + +@dataclass +class MixinInfo: + model_card_template: str + model_card_data: ModelCardData + docs_url: str | None = None + paper_url: str | None = None + repo_url: str | None = None + + +class ModelHubMixin: + """ + A generic mixin to integrate ANY machine learning framework with the Hub. + + To integrate your framework, your model class must inherit from this class. Custom logic for saving/loading models + have to be overwritten in [`_from_pretrained`] and [`_save_pretrained`]. [`PyTorchModelHubMixin`] is a good example + of mixin integration with the Hub. Check out our [integration guide](../guides/integrations) for more instructions. + + When inheriting from [`ModelHubMixin`], you can define class-level attributes. These attributes are not passed to + `__init__` but to the class definition itself. This is useful to define metadata about the library integrating + [`ModelHubMixin`]. + + For more details on how to integrate the mixin with your library, checkout the [integration guide](../guides/integrations). + + Args: + repo_url (`str`, *optional*): + URL of the library repository. Used to generate model card. + paper_url (`str`, *optional*): + URL of the library paper. Used to generate model card. + docs_url (`str`, *optional*): + URL of the library documentation. Used to generate model card. + model_card_template (`str`, *optional*): + Template of the model card. Used to generate model card. Defaults to a generic template. + language (`str` or `list[str]`, *optional*): + Language supported by the library. Used to generate model card. + library_name (`str`, *optional*): + Name of the library integrating ModelHubMixin. Used to generate model card. + license (`str`, *optional*): + License of the library integrating ModelHubMixin. Used to generate model card. + E.g: "apache-2.0" + license_name (`str`, *optional*): + Name of the library integrating ModelHubMixin. Used to generate model card. + Only used if `license` is set to `other`. + E.g: "coqui-public-model-license". + license_link (`str`, *optional*): + URL to the license of the library integrating ModelHubMixin. Used to generate model card. + Only used if `license` is set to `other` and `license_name` is set. + E.g: "https://coqui.ai/cpml". + pipeline_tag (`str`, *optional*): + Tag of the pipeline. Used to generate model card. E.g. "text-classification". + tags (`list[str]`, *optional*): + Tags to be added to the model card. Used to generate model card. E.g. ["computer-vision"] + coders (`dict[Type, tuple[Callable, Callable]]`, *optional*): + Dictionary of custom types and their encoders/decoders. Used to encode/decode arguments that are not + jsonable by default. E.g. dataclasses, argparse.Namespace, OmegaConf, etc. + + Example: + + ```python + >>> from huggingface_hub import ModelHubMixin + + # Inherit from ModelHubMixin + >>> class MyCustomModel( + ... ModelHubMixin, + ... library_name="my-library", + ... tags=["computer-vision"], + ... repo_url="https://github.com/huggingface/my-cool-library", + ... paper_url="https://arxiv.org/abs/2304.12244", + ... docs_url="https://huggingface.co/docs/my-cool-library", + ... # ^ optional metadata to generate model card + ... ): + ... def __init__(self, size: int = 512, device: str = "cpu"): + ... # define how to initialize your model + ... super().__init__() + ... ... + ... + ... def _save_pretrained(self, save_directory: Path) -> None: + ... # define how to serialize your model + ... ... + ... + ... @classmethod + ... def from_pretrained( + ... cls: type[T], + ... pretrained_model_name_or_path: Union[str, Path], + ... *, + ... force_download: bool = False, + ... token: Optional[Union[str, bool]] = None, + ... cache_dir: Optional[Union[str, Path]] = None, + ... local_files_only: bool = False, + ... revision: Optional[str] = None, + ... **model_kwargs, + ... ) -> T: + ... # define how to deserialize your model + ... ... + + >>> model = MyCustomModel(size=256, device="gpu") + + # Save model weights to local directory + >>> model.save_pretrained("my-awesome-model") + + # Push model weights to the Hub + >>> model.push_to_hub("my-awesome-model") + + # Download and initialize weights from the Hub + >>> reloaded_model = MyCustomModel.from_pretrained("username/my-awesome-model") + >>> reloaded_model.size + 256 + + # Model card has been correctly populated + >>> from huggingface_hub import ModelCard + >>> card = ModelCard.load("username/my-awesome-model") + >>> card.data.tags + ["x-custom-tag", "pytorch_model_hub_mixin", "model_hub_mixin"] + >>> card.data.library_name + "my-library" + ``` + """ + + _hub_mixin_config: dict | DataclassInstance | None = None + # ^ optional config attribute automatically set in `from_pretrained` + _hub_mixin_info: MixinInfo + # ^ information about the library integrating ModelHubMixin (used to generate model card) + _hub_mixin_inject_config: bool # whether `_from_pretrained` expects `config` or not + _hub_mixin_init_parameters: dict[str, inspect.Parameter] # __init__ parameters + _hub_mixin_jsonable_default_values: dict[str, Any] # default values for __init__ parameters + _hub_mixin_jsonable_custom_types: tuple[type, ...] # custom types that can be encoded/decoded + _hub_mixin_coders: dict[type, CODER_T] # encoders/decoders for custom types + # ^ internal values to handle config + + def __init_subclass__( + cls, + *, + # Generic info for model card + repo_url: str | None = None, + paper_url: str | None = None, + docs_url: str | None = None, + # Model card template + model_card_template: str = DEFAULT_MODEL_CARD, + # Model card metadata + language: list[str] | None = None, + library_name: str | None = None, + license: str | None = None, + license_name: str | None = None, + license_link: str | None = None, + pipeline_tag: str | None = None, + tags: list[str] | None = None, + # How to encode/decode arguments with custom type into a JSON config? + coders: None + | ( + dict[type, CODER_T] + # Key is a type. + # Value is a tuple (encoder, decoder). + # Example: {MyCustomType: (lambda x: x.value, lambda data: MyCustomType(data))} + ) = None, + ) -> None: + """Inspect __init__ signature only once when subclassing + handle modelcard.""" + super().__init_subclass__() + + # Will be reused when creating modelcard + tags = tags or [] + tags.append("model_hub_mixin") + + # Initialize MixinInfo if not existent + info = MixinInfo(model_card_template=model_card_template, model_card_data=ModelCardData()) + + # If parent class has a MixinInfo, inherit from it as a copy + if hasattr(cls, "_hub_mixin_info"): + # Inherit model card template from parent class if not explicitly set + if model_card_template == DEFAULT_MODEL_CARD: + info.model_card_template = cls._hub_mixin_info.model_card_template + + # Inherit from parent model card data + info.model_card_data = ModelCardData(**cls._hub_mixin_info.model_card_data.to_dict()) + + # Inherit other info + info.docs_url = cls._hub_mixin_info.docs_url + info.paper_url = cls._hub_mixin_info.paper_url + info.repo_url = cls._hub_mixin_info.repo_url + cls._hub_mixin_info = info + + # Update MixinInfo with metadata + if model_card_template is not None and model_card_template != DEFAULT_MODEL_CARD: + info.model_card_template = model_card_template + if repo_url is not None: + info.repo_url = repo_url + if paper_url is not None: + info.paper_url = paper_url + if docs_url is not None: + info.docs_url = docs_url + if language is not None: + info.model_card_data.language = language + if library_name is not None: + info.model_card_data.library_name = library_name + if license is not None: + info.model_card_data.license = license + if license_name is not None: + info.model_card_data.license_name = license_name + if license_link is not None: + info.model_card_data.license_link = license_link + if pipeline_tag is not None: + info.model_card_data.pipeline_tag = pipeline_tag + if tags is not None: + normalized_tags = list(tags) + if info.model_card_data.tags is not None: + info.model_card_data.tags.extend(normalized_tags) + else: + info.model_card_data.tags = normalized_tags + + if info.model_card_data.tags is not None: + info.model_card_data.tags = sorted(set(info.model_card_data.tags)) + + # Handle encoders/decoders for args + cls._hub_mixin_coders = coders or {} + cls._hub_mixin_jsonable_custom_types = tuple(cls._hub_mixin_coders.keys()) + + # Inspect __init__ signature to handle config + cls._hub_mixin_init_parameters = dict(inspect.signature(cls.__init__).parameters) + cls._hub_mixin_jsonable_default_values = { + param.name: cls._encode_arg(param.default) + for param in cls._hub_mixin_init_parameters.values() + if param.default is not inspect.Parameter.empty and cls._is_jsonable(param.default) + } + cls._hub_mixin_inject_config = "config" in inspect.signature(cls._from_pretrained).parameters + + def __new__(cls: type[T], *args, **kwargs) -> T: + """Create a new instance of the class and handle config. + + 3 cases: + - If `self._hub_mixin_config` is already set, do nothing. + - If `config` is passed as a dataclass, set it as `self._hub_mixin_config`. + - Otherwise, build `self._hub_mixin_config` from default values and passed values. + """ + instance = super().__new__(cls) + + # If `config` is already set, return early + if instance._hub_mixin_config is not None: + return instance + + # Infer passed values + passed_values = { + **{ + key: value + for key, value in zip( + # [1:] to skip `self` parameter + list(cls._hub_mixin_init_parameters)[1:], + args, + ) + }, + **kwargs, + } + + # If config passed as dataclass => set it and return early + if is_dataclass(passed_values.get("config")): + instance._hub_mixin_config = passed_values["config"] + return instance + + # Otherwise, build config from default + passed values + init_config = { + # default values + **cls._hub_mixin_jsonable_default_values, + # passed values + **{ + key: cls._encode_arg(value) # Encode custom types as jsonable value + for key, value in passed_values.items() + if instance._is_jsonable(value) # Only if jsonable or we have a custom encoder + }, + } + passed_config = init_config.pop("config", {}) + + # Populate `init_config` with provided config + if isinstance(passed_config, dict): + init_config.update(passed_config) + + # Set `config` attribute and return + if init_config != {}: + instance._hub_mixin_config = init_config + return instance + + @classmethod + def _is_jsonable(cls, value: Any) -> bool: + """Check if a value is JSON serializable.""" + if is_dataclass(value): + return True + if isinstance(value, cls._hub_mixin_jsonable_custom_types): + return True + return is_jsonable(value) + + @classmethod + def _encode_arg(cls, arg: Any) -> Any: + """Encode an argument into a JSON serializable format.""" + if is_dataclass(arg): + return asdict(arg) # type: ignore[arg-type] + for type_, (encoder, _) in cls._hub_mixin_coders.items(): + if isinstance(arg, type_): + if arg is None: + return None + return encoder(arg) + return arg + + @classmethod + def _decode_arg(cls, expected_type: type[ARGS_T], value: Any) -> ARGS_T | None: + """Decode a JSON serializable value into an argument.""" + if is_simple_optional_type(expected_type): + if value is None: + return None + expected_type = unwrap_simple_optional_type(expected_type) # type: ignore + # Dataclass => handle it + if is_dataclass(expected_type): + return _load_dataclass(expected_type, value) # type: ignore + # Otherwise => check custom decoders + for type_, (_, decoder) in cls._hub_mixin_coders.items(): + if inspect.isclass(expected_type) and issubclass(expected_type, type_): + return decoder(value) + # Otherwise => don't decode + return value + + def save_pretrained( + self, + save_directory: str | Path, + *, + config: dict | DataclassInstance | None = None, + repo_id: str | None = None, + push_to_hub: bool = False, + model_card_kwargs: dict[str, Any] | None = None, + **push_to_hub_kwargs, + ) -> str | None: + """ + Save weights in local directory. + + Args: + save_directory (`str` or `Path`): + Path to directory in which the model weights and configuration will be saved. + config (`dict` or `DataclassInstance`, *optional*): + Model configuration specified as a key/value dictionary or a dataclass instance. + push_to_hub (`bool`, *optional*, defaults to `False`): + Whether or not to push your model to the Huggingface Hub after saving it. + repo_id (`str`, *optional*): + ID of your repository on the Hub. Used only if `push_to_hub=True`. Will default to the folder name if + not provided. + model_card_kwargs (`dict[str, Any]`, *optional*): + Additional arguments passed to the model card template to customize the model card. + push_to_hub_kwargs: + Additional key word arguments passed along to the [`~ModelHubMixin.push_to_hub`] method. + Returns: + `str` or `None`: url of the commit on the Hub if `push_to_hub=True`, `None` otherwise. + """ + save_directory = Path(save_directory) + save_directory.mkdir(parents=True, exist_ok=True) + + # Remove config.json if already exists. After `_save_pretrained` we don't want to overwrite config.json + # as it might have been saved by the custom `_save_pretrained` already. However we do want to overwrite + # an existing config.json if it was not saved by `_save_pretrained`. + config_path = save_directory / constants.CONFIG_NAME + config_path.unlink(missing_ok=True) + + # save model weights/files (framework-specific) + self._save_pretrained(save_directory) + + # save config (if provided and if not serialized yet in `_save_pretrained`) + if config is None: + config = self._hub_mixin_config + if config is not None: + if is_dataclass(config): + config = asdict(config) # type: ignore[arg-type] + if not config_path.exists(): + config_str = json.dumps(config, sort_keys=True, indent=2) + config_path.write_text(config_str) + + # save model card + model_card_path = save_directory / "README.md" + model_card_kwargs = model_card_kwargs if model_card_kwargs is not None else {} + if not model_card_path.exists(): # do not overwrite if already exists + self.generate_model_card(**model_card_kwargs).save(save_directory / "README.md") + + # push to the Hub if required + if push_to_hub: + kwargs = push_to_hub_kwargs.copy() # soft-copy to avoid mutating input + if config is not None: # kwarg for `push_to_hub` + kwargs["config"] = config + if repo_id is None: + repo_id = save_directory.name # Defaults to `save_directory` name + return self.push_to_hub(repo_id=repo_id, model_card_kwargs=model_card_kwargs, **kwargs) + return None + + def _save_pretrained(self, save_directory: Path) -> None: + """ + Overwrite this method in subclass to define how to save your model. + Check out our [integration guide](../guides/integrations) for instructions. + + Args: + save_directory (`str` or `Path`): + Path to directory in which the model weights and configuration will be saved. + """ + raise NotImplementedError + + @classmethod + @validate_hf_hub_args + def from_pretrained( + cls: type[T], + pretrained_model_name_or_path: str | Path, + *, + force_download: bool = False, + token: str | bool | None = None, + cache_dir: str | Path | None = None, + local_files_only: bool = False, + revision: str | None = None, + **model_kwargs, + ) -> T: + """ + Download a model from the Huggingface Hub and instantiate it. + + Args: + pretrained_model_name_or_path (`str`, `Path`): + - Either the `model_id` (string) of a model hosted on the Hub, e.g. `bigscience/bloom`. + - Or a path to a `directory` containing model weights saved using + [`~transformers.PreTrainedModel.save_pretrained`], e.g., `../path/to/my_model_directory/`. + revision (`str`, *optional*): + Revision of the model on the Hub. Can be a branch name, a git tag or any commit id. + Defaults to the latest commit on `main` branch. + force_download (`bool`, *optional*, defaults to `False`): + Whether to force (re-)downloading the model weights and configuration files from the Hub, overriding + the existing cache. + token (`str` or `bool`, *optional*): + The token to use as HTTP bearer authorization for remote files. By default, it will use the token + cached when running `hf auth login`. + cache_dir (`str`, `Path`, *optional*): + Path to the folder where cached files are stored. + local_files_only (`bool`, *optional*, defaults to `False`): + If `True`, avoid downloading the file and return the path to the local cached file if it exists. + model_kwargs (`dict`, *optional*): + Additional kwargs to pass to the model during initialization. + """ + model_id = str(pretrained_model_name_or_path) + config_file: str | None = None + if os.path.isdir(model_id): + if constants.CONFIG_NAME in os.listdir(model_id): + config_file = os.path.join(model_id, constants.CONFIG_NAME) + else: + logger.warning(f"{constants.CONFIG_NAME} not found in {Path(model_id).resolve()}") + else: + try: + config_file = hf_hub_download( + repo_id=model_id, + filename=constants.CONFIG_NAME, + revision=revision, + cache_dir=cache_dir, + force_download=force_download, + token=token, + local_files_only=local_files_only, + ) + except HfHubHTTPError as e: + logger.info(f"{constants.CONFIG_NAME} not found on the HuggingFace Hub: {str(e)}") + + # Read config + config = None + if config_file is not None: + with open(config_file, encoding="utf-8") as f: + config = json.load(f) + + # Decode custom types in config + for key, value in config.items(): + if key in cls._hub_mixin_init_parameters: + expected_type = cls._hub_mixin_init_parameters[key].annotation + if expected_type is not inspect.Parameter.empty: + config[key] = cls._decode_arg(expected_type, value) + + # Populate model_kwargs from config + for param in cls._hub_mixin_init_parameters.values(): + if param.name not in model_kwargs and param.name in config: + model_kwargs[param.name] = config[param.name] + + # Check if `config` argument was passed at init + if "config" in cls._hub_mixin_init_parameters and "config" not in model_kwargs: + # Decode `config` argument if it was passed + config_annotation = cls._hub_mixin_init_parameters["config"].annotation + config = cls._decode_arg(config_annotation, config) + + # Forward config to model initialization + model_kwargs["config"] = config + + # Inject config if `**kwargs` are expected + if is_dataclass(cls): + for key in cls.__dataclass_fields__: + if key not in model_kwargs and key in config: + model_kwargs[key] = config[key] + elif any(param.kind == inspect.Parameter.VAR_KEYWORD for param in cls._hub_mixin_init_parameters.values()): + for key, value in config.items(): # type: ignore[union-attr] + if key not in model_kwargs: + model_kwargs[key] = value + + # Finally, also inject if `_from_pretrained` expects it + if cls._hub_mixin_inject_config and "config" not in model_kwargs: + model_kwargs["config"] = config + + instance = cls._from_pretrained( + model_id=str(model_id), + revision=revision, + cache_dir=cache_dir, + force_download=force_download, + local_files_only=local_files_only, + token=token, + **model_kwargs, + ) + + # Implicitly set the config as instance attribute if not already set by the class + # This way `config` will be available when calling `save_pretrained` or `push_to_hub`. + if config is not None and (getattr(instance, "_hub_mixin_config", None) in (None, {})): + instance._hub_mixin_config = config + + return instance + + @classmethod + def _from_pretrained( + cls: type[T], + *, + model_id: str, + revision: str | None, + cache_dir: str | Path | None, + force_download: bool, + local_files_only: bool, + token: str | bool | None, + **model_kwargs, + ) -> T: + """Overwrite this method in subclass to define how to load your model from pretrained. + + Use [`hf_hub_download`] or [`snapshot_download`] to download files from the Hub before loading them. Most + args taken as input can be directly passed to those 2 methods. If needed, you can add more arguments to this + method using "model_kwargs". For example [`PyTorchModelHubMixin._from_pretrained`] takes as input a `map_location` + parameter to set on which device the model should be loaded. + + Check out our [integration guide](../guides/integrations) for more instructions. + + Args: + model_id (`str`): + ID of the model to load from the Huggingface Hub (e.g. `bigscience/bloom`). + revision (`str`, *optional*): + Revision of the model on the Hub. Can be a branch name, a git tag or any commit id. Defaults to the + latest commit on `main` branch. + force_download (`bool`, *optional*, defaults to `False`): + Whether to force (re-)downloading the model weights and configuration files from the Hub, overriding + the existing cache. + token (`str` or `bool`, *optional*): + The token to use as HTTP bearer authorization for remote files. By default, it will use the token + cached when running `hf auth login`. + cache_dir (`str`, `Path`, *optional*): + Path to the folder where cached files are stored. + local_files_only (`bool`, *optional*, defaults to `False`): + If `True`, avoid downloading the file and return the path to the local cached file if it exists. + model_kwargs: + Additional keyword arguments passed along to the [`~ModelHubMixin._from_pretrained`] method. + """ + raise NotImplementedError + + @validate_hf_hub_args + def push_to_hub( + self, + repo_id: str, + *, + config: dict | DataclassInstance | None = None, + commit_message: str = "Push model using huggingface_hub.", + private: bool | None = None, + token: str | None = None, + branch: str | None = None, + create_pr: bool | None = None, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + delete_patterns: list[str] | str | None = None, + model_card_kwargs: dict[str, Any] | None = None, + ) -> str: + """ + Upload model checkpoint to the Hub. + + Use `allow_patterns` and `ignore_patterns` to precisely filter which files should be pushed to the hub. Use + `delete_patterns` to delete existing remote files in the same commit. See [`upload_folder`] reference for more + details. + + Args: + repo_id (`str`): + ID of the repository to push to (example: `"username/my-model"`). + config (`dict` or `DataclassInstance`, *optional*): + Model configuration specified as a key/value dictionary or a dataclass instance. + commit_message (`str`, *optional*): + Message to commit while pushing. + private (`bool`, *optional*): + Whether the repository created should be private. + If `None` (default), the repo will be public unless the organization's default is private. + token (`str`, *optional*): + The token to use as HTTP bearer authorization for remote files. By default, it will use the token + cached when running `hf auth login`. + branch (`str`, *optional*): + The git branch on which to push the model. This defaults to `"main"`. + create_pr (`boolean`, *optional*): + Whether or not to create a Pull Request from `branch` with that commit. Defaults to `False`. + allow_patterns (`list[str]` or `str`, *optional*): + If provided, only files matching at least one pattern are pushed. + ignore_patterns (`list[str]` or `str`, *optional*): + If provided, files matching any of the patterns are not pushed. + delete_patterns (`list[str]` or `str`, *optional*): + If provided, remote files matching any of the patterns will be deleted from the repo. + model_card_kwargs (`dict[str, Any]`, *optional*): + Additional arguments passed to the model card template to customize the model card. + + Returns: + The url of the commit of your model in the given repository. + """ + api = HfApi(token=token) + repo_id = api.create_repo(repo_id=repo_id, private=private, exist_ok=True).repo_id + + # Push the files to the repo in a single commit + with SoftTemporaryDirectory() as tmp: + saved_path = Path(tmp) / repo_id + self.save_pretrained(saved_path, config=config, model_card_kwargs=model_card_kwargs) + return api.upload_folder( + repo_id=repo_id, + repo_type="model", + folder_path=saved_path, + commit_message=commit_message, + revision=branch, + create_pr=create_pr, + allow_patterns=allow_patterns, + ignore_patterns=ignore_patterns, + delete_patterns=delete_patterns, + ) + + def generate_model_card(self, *args, **kwargs) -> ModelCard: + card = ModelCard.from_template( + card_data=self._hub_mixin_info.model_card_data, + template_str=self._hub_mixin_info.model_card_template, + repo_url=self._hub_mixin_info.repo_url, + paper_url=self._hub_mixin_info.paper_url, + docs_url=self._hub_mixin_info.docs_url, + **kwargs, + ) + return card + + +class PyTorchModelHubMixin(ModelHubMixin): + """ + Implementation of [`ModelHubMixin`] to provide model Hub upload/download capabilities to PyTorch models. The model + is set in evaluation mode by default using `model.eval()` (dropout modules are deactivated). To train the model, + you should first set it back in training mode with `model.train()`. + + See [`ModelHubMixin`] for more details on how to use the mixin. + + Example: + + ```python + >>> import torch + >>> import torch.nn as nn + >>> from huggingface_hub import PyTorchModelHubMixin + + >>> class MyModel( + ... nn.Module, + ... PyTorchModelHubMixin, + ... library_name="keras-nlp", + ... repo_url="https://github.com/keras-team/keras-nlp", + ... paper_url="https://arxiv.org/abs/2304.12244", + ... docs_url="https://keras.io/keras_nlp/", + ... # ^ optional metadata to generate model card + ... ): + ... def __init__(self, hidden_size: int = 512, vocab_size: int = 30000, output_size: int = 4): + ... super().__init__() + ... self.param = nn.Parameter(torch.rand(hidden_size, vocab_size)) + ... self.linear = nn.Linear(output_size, vocab_size) + + ... def forward(self, x): + ... return self.linear(x + self.param) + >>> model = MyModel(hidden_size=256) + + # Save model weights to local directory + >>> model.save_pretrained("my-awesome-model") + + # Push model weights to the Hub + >>> model.push_to_hub("my-awesome-model") + + # Download and initialize weights from the Hub + >>> model = MyModel.from_pretrained("username/my-awesome-model") + >>> model.hidden_size + 256 + ``` + """ + + def __init_subclass__(cls, *args, tags: list[str] | None = None, **kwargs) -> None: + tags = tags or [] + tags.append("pytorch_model_hub_mixin") + kwargs["tags"] = tags + return super().__init_subclass__(*args, **kwargs) + + def _save_pretrained(self, save_directory: Path) -> None: + """Save weights from a Pytorch model to a local directory.""" + model_to_save = self.module if hasattr(self, "module") else self # type: ignore + save_model_as_safetensor(model_to_save, str(save_directory / constants.SAFETENSORS_SINGLE_FILE)) # type: ignore [arg-type] + + @classmethod + def _from_pretrained( + cls, + *, + model_id: str, + revision: str | None, + cache_dir: str | Path | None, + force_download: bool, + local_files_only: bool, + token: str | bool | None, + map_location: str = "cpu", + strict: bool = False, + **model_kwargs, + ): + """Load Pytorch pretrained weights and return the loaded model.""" + model = cls(**model_kwargs) + if os.path.isdir(model_id): + print("Loading weights from local directory") + model_file = os.path.join(model_id, constants.SAFETENSORS_SINGLE_FILE) + return cls._load_as_safetensor(model, model_file, map_location, strict) + else: + try: + model_file = hf_hub_download( + repo_id=model_id, + filename=constants.SAFETENSORS_SINGLE_FILE, + revision=revision, + cache_dir=cache_dir, + force_download=force_download, + token=token, + local_files_only=local_files_only, + ) + return cls._load_as_safetensor(model, model_file, map_location, strict) + except EntryNotFoundError: + model_file = hf_hub_download( + repo_id=model_id, + filename=constants.PYTORCH_WEIGHTS_NAME, + revision=revision, + cache_dir=cache_dir, + force_download=force_download, + token=token, + local_files_only=local_files_only, + ) + return cls._load_as_pickle(model, model_file, map_location, strict) + + @classmethod + def _load_as_pickle(cls, model: T, model_file: str, map_location: str, strict: bool) -> T: + state_dict = torch.load(model_file, map_location=torch.device(map_location), weights_only=True) + model.load_state_dict(state_dict, strict=strict) # type: ignore + model.eval() # type: ignore + return model + + @classmethod + def _load_as_safetensor(cls, model: T, model_file: str, map_location: str, strict: bool) -> T: + if packaging.version.parse(safetensors.__version__) < packaging.version.parse("0.4.3"): # type: ignore [attr-defined] + load_model_as_safetensor(model, model_file, strict=strict) # type: ignore [arg-type] + if map_location != "cpu": + logger.warning( + "Loading model weights on other devices than 'cpu' is not supported natively in your version of safetensors." + " This means that the model is loaded on 'cpu' first and then copied to the device." + " This leads to a slower loading time." + " Please update safetensors to version 0.4.3 or above for improved performance." + ) + model.to(map_location) # type: ignore [attr-defined] + else: + safetensors.torch.load_model(model, model_file, strict=strict, device=map_location) # type: ignore [arg-type] + model.eval() # type: ignore + return model + + +def _load_dataclass(datacls: type[DataclassInstance], data: dict) -> DataclassInstance: + """Load a dataclass instance from a dictionary. + + Fields not expected by the dataclass are ignored. + """ + return datacls(**{k: v for k, v in data.items() if k in datacls.__dataclass_fields__}) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/__init__.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_client.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_client.py new file mode 100644 index 0000000000000000000000000000000000000000..8cec83e2ab45f632d14c5c4d61f9852e3b113a66 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_client.py @@ -0,0 +1,3394 @@ +# Copyright 2023-present, the HuggingFace Inc. team. +# +# 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. +# +# Related resources: +# https://huggingface.co/tasks +# https://huggingface.co/docs/huggingface.js/inference/README +# https://github.com/huggingface/huggingface.js/tree/main/packages/inference/src +# https://github.com/huggingface/text-generation-inference/tree/main/clients/python +# https://github.com/huggingface/text-generation-inference/blob/main/clients/python/text_generation/client.py +# https://huggingface.slack.com/archives/C03E4DQ9LAJ/p1680169099087869 +# https://github.com/huggingface/unity-api#tasks +# +# Some TODO: +# - add all tasks +# +# NOTE: the philosophy of this client is "let's make it as easy as possible to use it, even if less optimized". Some +# examples of how it translates: +# - Timeout / Server unavailable is handled by the client in a single "timeout" parameter. +# - Files can be provided as bytes, file paths, or URLs and the client will try to "guess" the type. +# - Images are parsed as PIL.Image for easier manipulation. +# - Provides a "recommended model" for each task => suboptimal but user-wise quicker to get a first script running. +# - Only the main parameters are publicly exposed. Power users can always read the docs for more options. +import base64 +import logging +import os +import re +import warnings +from collections.abc import Iterable +from contextlib import ExitStack +from typing import TYPE_CHECKING, Any, Literal, Optional, Union, overload + +from huggingface_hub import constants +from huggingface_hub.errors import BadRequestError, HfHubHTTPError, InferenceTimeoutError +from huggingface_hub.inference._common import ( + TASKS_EXPECTING_IMAGES, + ContentT, + RequestParameters, + _b64_encode, + _b64_to_image, + _bytes_to_dict, + _bytes_to_image, + _bytes_to_list, + _get_unsupported_text_generation_kwargs, + _import_numpy, + _set_unsupported_text_generation_kwargs, + _stream_chat_completion_response, + _stream_text_generation_response, + raise_text_generation_error, +) +from huggingface_hub.inference._generated.types import ( + AudioClassificationOutputElement, + AudioClassificationOutputTransform, + AudioToAudioOutputElement, + AutomaticSpeechRecognitionOutput, + ChatCompletionInputGrammarType, + ChatCompletionInputMessage, + ChatCompletionInputStreamOptions, + ChatCompletionInputTool, + ChatCompletionInputToolChoiceClass, + ChatCompletionInputToolChoiceEnum, + ChatCompletionOutput, + ChatCompletionStreamOutput, + DocumentQuestionAnsweringOutputElement, + FillMaskOutputElement, + ImageClassificationOutputElement, + ImageClassificationOutputTransform, + ImageSegmentationOutputElement, + ImageSegmentationSubtask, + ImageToImageTargetSize, + ImageToTextOutput, + ImageToVideoTargetSize, + ObjectDetectionOutputElement, + Padding, + QuestionAnsweringOutputElement, + SummarizationOutput, + SummarizationTruncationStrategy, + TableQuestionAnsweringOutputElement, + TextClassificationOutputElement, + TextClassificationOutputTransform, + TextGenerationInputGrammarType, + TextGenerationOutput, + TextGenerationStreamOutput, + TextToSpeechEarlyStoppingEnum, + TokenClassificationAggregationStrategy, + TokenClassificationOutputElement, + TranslationOutput, + TranslationTruncationStrategy, + VisualQuestionAnsweringOutputElement, + ZeroShotClassificationOutputElement, + ZeroShotImageClassificationOutputElement, +) +from huggingface_hub.inference._providers import PROVIDER_OR_POLICY_T, get_provider_helper +from huggingface_hub.utils import ( + build_hf_headers, + get_session, + hf_raise_for_status, + validate_hf_hub_args, +) +from huggingface_hub.utils._auth import get_token + + +if TYPE_CHECKING: + import numpy as np + from PIL.Image import Image + +logger = logging.getLogger(__name__) + + +MODEL_KWARGS_NOT_USED_REGEX = re.compile(r"The following `model_kwargs` are not used by the model: \[(.*?)\]") + + +class InferenceClient: + """ + Initialize a new Inference Client. + + [`InferenceClient`] aims to provide a unified experience to perform inference. The client can be used + seamlessly with either the (free) Inference API, self-hosted Inference Endpoints, or third-party Inference Providers. + + Args: + model (`str`, `optional`): + The model to run inference with. Can be a model id hosted on the Hugging Face Hub, e.g. `meta-llama/Meta-Llama-3-8B-Instruct` + or a URL to a deployed Inference Endpoint. Defaults to None, in which case a recommended model is + automatically selected for the task. + Note: for better compatibility with OpenAI's client, `model` has been aliased as `base_url`. Those 2 + arguments are mutually exclusive. If a URL is passed as `model` or `base_url` for chat completion, the `(/v1)/chat/completions` suffix path will be appended to the URL. + provider (`str`, *optional*): + Name of the provider to use for inference. Can be `"cerebras"`, `"cohere"`, `"deepinfra"`, `"fal-ai"`, `"featherless-ai"`, `"fireworks-ai"`, `"groq"`, `"hf-inference"`, `"novita"`, `"nscale"`, `"openai"`, `"ovhcloud"`, `"publicai"`, `"replicate"`, `"scaleway"`, `"together"`, `"wavespeed"` or `"zai-org"`. + Defaults to "auto": automatic routing, which defaults to "fastest" provider; you can + switch to "cheapest" or "preferred" provider order at https://hf.co/settings/inference-providers. + If model is a URL or `base_url` is passed, then `provider` is not used. + token (`str`, *optional*): + Hugging Face token. Will default to the locally saved token if not provided. + Note: for better compatibility with OpenAI's client, `token` has been aliased as `api_key`. Those 2 + arguments are mutually exclusive and have the exact same behavior. + timeout (`float`, `optional`): + The maximum number of seconds to wait for a response from the server. Defaults to None, meaning it will loop until the server is available. + headers (`dict[str, str]`, `optional`): + Additional headers to send to the server. By default only the authorization and user-agent headers are sent. + Values in this dictionary will override the default values. + bill_to (`str`, `optional`): + The billing account to use for the requests. By default the requests are billed on the user's account. + Requests can only be billed to an organization the user is a member of, and which has subscribed to Enterprise Hub. + cookies (`dict[str, str]`, `optional`): + Additional cookies to send to the server. + base_url (`str`, `optional`): + Base URL to run inference. This is a duplicated argument from `model` to make [`InferenceClient`] + follow the same pattern as `openai.OpenAI` client. Cannot be used if `model` is set. Defaults to None. + api_key (`str`, `optional`): + Token to use for authentication. This is a duplicated argument from `token` to make [`InferenceClient`] + follow the same pattern as `openai.OpenAI` client. Cannot be used if `token` is set. Defaults to None. + """ + + provider: PROVIDER_OR_POLICY_T | None + + @validate_hf_hub_args + def __init__( + self, + model: str | None = None, + *, + provider: PROVIDER_OR_POLICY_T | None = None, + token: str | None = None, + timeout: float | None = None, + headers: dict[str, str] | None = None, + cookies: dict[str, str] | None = None, + bill_to: str | None = None, + # OpenAI compatibility + base_url: str | None = None, + api_key: str | None = None, + ) -> None: + if model is not None and base_url is not None: + raise ValueError( + "Received both `model` and `base_url` arguments. Please provide only one of them." + " `base_url` is an alias for `model` to make the API compatible with OpenAI's client." + " If using `base_url` for chat completion, the `/chat/completions` suffix path will be appended to the base url." + " When passing a URL as `model`, the client will not append any suffix path to it." + ) + if token is not None and api_key is not None: + raise ValueError( + "Received both `token` and `api_key` arguments. Please provide only one of them." + " `api_key` is an alias for `token` to make the API compatible with OpenAI's client." + " It has the exact same behavior as `token`." + ) + token = token if token is not None else api_key + if isinstance(token, bool): + # Legacy behavior: previously it was possible to pass `token=False` to disable authentication. This is not + # supported anymore as authentication is required. Better to explicitly raise here rather than risking + # sending the locally saved token without the user knowing about it. + if token is False: + raise ValueError( + "Cannot use `token=False` to disable authentication as authentication is required to run Inference." + ) + warnings.warn( + "Using `token=True` to automatically use the locally saved token is deprecated and will be removed in a future release. " + "Please use `token=None` instead (default).", + DeprecationWarning, + ) + token = get_token() + + self.model: str | None = base_url or model + self.token: str | None = token + + self.headers = {**headers} if headers is not None else {} + if bill_to is not None: + if ( + constants.HUGGINGFACE_HEADER_X_BILL_TO in self.headers + and self.headers[constants.HUGGINGFACE_HEADER_X_BILL_TO] != bill_to + ): + warnings.warn( + f"Overriding existing '{self.headers[constants.HUGGINGFACE_HEADER_X_BILL_TO]}' value in headers with '{bill_to}'.", + UserWarning, + ) + self.headers[constants.HUGGINGFACE_HEADER_X_BILL_TO] = bill_to + + if token is not None and not token.startswith("hf_"): + warnings.warn( + "You've provided an external provider's API key, so requests will be billed directly by the provider. " + "The `bill_to` parameter is only applicable for Hugging Face billing and will be ignored.", + UserWarning, + ) + + # Configure provider + self.provider = provider # type: ignore[assignment] + + self.cookies = cookies + self.timeout = timeout + + self.exit_stack = ExitStack() + + def __repr__(self): + return f"" + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.exit_stack.close() + + def close(self): + self.exit_stack.close() + + @overload + def _inner_post( # type: ignore[misc] + self, request_parameters: RequestParameters, *, stream: Literal[False] = ... + ) -> bytes: ... + + @overload + def _inner_post( # type: ignore[misc] + self, request_parameters: RequestParameters, *, stream: Literal[True] = ... + ) -> Iterable[str]: ... + + @overload + def _inner_post(self, request_parameters: RequestParameters, *, stream: bool = False) -> bytes | Iterable[str]: ... + + def _inner_post(self, request_parameters: RequestParameters, *, stream: bool = False) -> bytes | Iterable[str]: + """Make a request to the inference server.""" + # TODO: this should be handled in provider helpers directly + if request_parameters.task in TASKS_EXPECTING_IMAGES and "Accept" not in request_parameters.headers: + request_parameters.headers["Accept"] = "image/png" + + try: + response = self.exit_stack.enter_context( + get_session().stream( + "POST", + request_parameters.url, + json=request_parameters.json, + content=request_parameters.data, + headers=request_parameters.headers, + cookies=self.cookies, + timeout=self.timeout, + ) + ) + hf_raise_for_status(response) + if stream: + return response.iter_lines() + else: + return response.read() + except TimeoutError as error: + # Convert any `TimeoutError` to a `InferenceTimeoutError` + raise InferenceTimeoutError(f"Inference call timed out: {request_parameters.url}") from error # type: ignore + except HfHubHTTPError as error: + if error.response.status_code == 422 and request_parameters.task != "unknown": + msg = str(error.args[0]) + if len(error.response.text) > 0: + msg += f"{os.linesep}{error.response.text}{os.linesep}" + error.args = (msg,) + error.args[1:] + raise + + def audio_classification( + self, + audio: ContentT, + *, + model: str | None = None, + top_k: int | None = None, + function_to_apply: Optional["AudioClassificationOutputTransform"] = None, + ) -> list[AudioClassificationOutputElement]: + """ + Perform audio classification on the provided audio content. + + Args: + audio (Union[str, Path, bytes, BinaryIO]): + The audio content to classify. It can be raw audio bytes, a local audio file, or a URL pointing to an + audio file. + model (`str`, *optional*): + The model to use for audio classification. Can be a model ID hosted on the Hugging Face Hub + or a URL to a deployed Inference Endpoint. If not provided, the default recommended model for + audio classification will be used. + top_k (`int`, *optional*): + When specified, limits the output to the top K most probable classes. + function_to_apply (`"AudioClassificationOutputTransform"`, *optional*): + The function to apply to the model outputs in order to retrieve the scores. + + Returns: + `list[AudioClassificationOutputElement]`: List of [`AudioClassificationOutputElement`] items containing the predicted labels and their confidence. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.audio_classification("audio.flac") + [ + AudioClassificationOutputElement(score=0.4976358711719513, label='hap'), + AudioClassificationOutputElement(score=0.3677836060523987, label='neu'), + ... + ] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="audio-classification", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=audio, + parameters={"function_to_apply": function_to_apply, "top_k": top_k}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + return AudioClassificationOutputElement.parse_obj_as_list(response) + + def audio_to_audio( + self, + audio: ContentT, + *, + model: str | None = None, + ) -> list[AudioToAudioOutputElement]: + """ + Performs multiple tasks related to audio-to-audio depending on the model (eg: speech enhancement, source separation). + + Args: + audio (Union[str, Path, bytes, BinaryIO]): + The audio content for the model. It can be raw audio bytes, a local audio file, or a URL pointing to an + audio file. + model (`str`, *optional*): + The model can be any model which takes an audio file and returns another audio file. Can be a model ID hosted on the Hugging Face Hub + or a URL to a deployed Inference Endpoint. If not provided, the default recommended model for + audio_to_audio will be used. + + Returns: + `list[AudioToAudioOutputElement]`: A list of [`AudioToAudioOutputElement`] items containing audios label, content-type, and audio content in blob. + + Raises: + `InferenceTimeoutError`: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> audio_output = client.audio_to_audio("audio.flac") + >>> for i, item in enumerate(audio_output): + >>> with open(f"output_{i}.flac", "wb") as f: + f.write(item.blob) + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="audio-to-audio", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=audio, + parameters={}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + audio_output = AudioToAudioOutputElement.parse_obj_as_list(response) + for item in audio_output: + item.blob = base64.b64decode(item.blob) + return audio_output + + def automatic_speech_recognition( + self, + audio: ContentT, + *, + model: str | None = None, + extra_body: dict | None = None, + ) -> AutomaticSpeechRecognitionOutput: + """ + Perform automatic speech recognition (ASR or audio-to-text) on the given audio content. + + Args: + audio (Union[str, Path, bytes, BinaryIO]): + The content to transcribe. It can be raw audio bytes, local audio file, or a URL to an audio file. + model (`str`, *optional*): + The model to use for ASR. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. If not provided, the default recommended model for ASR will be used. + extra_body (`dict`, *optional*): + Additional provider-specific parameters to pass to the model. Refer to the provider's documentation + for supported parameters. + Returns: + [`AutomaticSpeechRecognitionOutput`]: An item containing the transcribed text and optionally the timestamp chunks. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.automatic_speech_recognition("hello_world.flac").text + "hello world" + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="automatic-speech-recognition", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=audio, + parameters={**(extra_body or {})}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + response = provider_helper.get_response(response, request_params=request_parameters) + return AutomaticSpeechRecognitionOutput.parse_obj_as_instance(response) + + @overload + def chat_completion( # type: ignore + self, + messages: list[dict | ChatCompletionInputMessage], + *, + model: str | None = None, + stream: Literal[False] = False, + frequency_penalty: float | None = None, + logit_bias: list[float] | None = None, + logprobs: bool | None = None, + max_tokens: int | None = None, + n: int | None = None, + presence_penalty: float | None = None, + response_format: ChatCompletionInputGrammarType | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stream_options: ChatCompletionInputStreamOptions | None = None, + temperature: float | None = None, + tool_choice: Union[ChatCompletionInputToolChoiceClass, "ChatCompletionInputToolChoiceEnum"] | None = None, + tool_prompt: str | None = None, + tools: list[ChatCompletionInputTool] | None = None, + top_logprobs: int | None = None, + top_p: float | None = None, + extra_body: dict | None = None, + ) -> ChatCompletionOutput: ... + + @overload + def chat_completion( # type: ignore + self, + messages: list[dict | ChatCompletionInputMessage], + *, + model: str | None = None, + stream: Literal[True] = True, + frequency_penalty: float | None = None, + logit_bias: list[float] | None = None, + logprobs: bool | None = None, + max_tokens: int | None = None, + n: int | None = None, + presence_penalty: float | None = None, + response_format: ChatCompletionInputGrammarType | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stream_options: ChatCompletionInputStreamOptions | None = None, + temperature: float | None = None, + tool_choice: Union[ChatCompletionInputToolChoiceClass, "ChatCompletionInputToolChoiceEnum"] | None = None, + tool_prompt: str | None = None, + tools: list[ChatCompletionInputTool] | None = None, + top_logprobs: int | None = None, + top_p: float | None = None, + extra_body: dict | None = None, + ) -> Iterable[ChatCompletionStreamOutput]: ... + + @overload + def chat_completion( + self, + messages: list[dict | ChatCompletionInputMessage], + *, + model: str | None = None, + stream: bool = False, + frequency_penalty: float | None = None, + logit_bias: list[float] | None = None, + logprobs: bool | None = None, + max_tokens: int | None = None, + n: int | None = None, + presence_penalty: float | None = None, + response_format: ChatCompletionInputGrammarType | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stream_options: ChatCompletionInputStreamOptions | None = None, + temperature: float | None = None, + tool_choice: Union[ChatCompletionInputToolChoiceClass, "ChatCompletionInputToolChoiceEnum"] | None = None, + tool_prompt: str | None = None, + tools: list[ChatCompletionInputTool] | None = None, + top_logprobs: int | None = None, + top_p: float | None = None, + extra_body: dict | None = None, + ) -> ChatCompletionOutput | Iterable[ChatCompletionStreamOutput]: ... + + def chat_completion( + self, + messages: list[dict | ChatCompletionInputMessage], + *, + model: str | None = None, + stream: bool = False, + # Parameters from ChatCompletionInput (handled manually) + frequency_penalty: float | None = None, + logit_bias: list[float] | None = None, + logprobs: bool | None = None, + max_tokens: int | None = None, + n: int | None = None, + presence_penalty: float | None = None, + response_format: ChatCompletionInputGrammarType | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stream_options: ChatCompletionInputStreamOptions | None = None, + temperature: float | None = None, + tool_choice: Union[ChatCompletionInputToolChoiceClass, "ChatCompletionInputToolChoiceEnum"] | None = None, + tool_prompt: str | None = None, + tools: list[ChatCompletionInputTool] | None = None, + top_logprobs: int | None = None, + top_p: float | None = None, + extra_body: dict | None = None, + ) -> ChatCompletionOutput | Iterable[ChatCompletionStreamOutput]: + """ + A method for completing conversations using a specified language model. + + > [!TIP] + > The `client.chat_completion` method is aliased as `client.chat.completions.create` for compatibility with OpenAI's client. + > Inputs and outputs are strictly the same and using either syntax will yield the same results. + > Check out the [Inference guide](https://huggingface.co/docs/huggingface_hub/guides/inference#openai-compatibility) + > for more details about OpenAI's compatibility. + + > [!TIP] + > You can pass provider-specific parameters to the model by using the `extra_body` argument. + + Args: + messages (List of [`ChatCompletionInputMessage`]): + Conversation history consisting of roles and content pairs. + model (`str`, *optional*): + The model to use for chat-completion. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. If not provided, the default recommended model for chat-based text-generation will be used. + See https://huggingface.co/tasks/text-generation for more details. + If `model` is a model ID, it is passed to the server as the `model` parameter. If you want to define a + custom URL while setting `model` in the request payload, you must set `base_url` when initializing [`InferenceClient`]. + frequency_penalty (`float`, *optional*): + Penalizes new tokens based on their existing frequency + in the text so far. Range: [-2.0, 2.0]. Defaults to 0.0. + logit_bias (`list[float]`, *optional*): + Adjusts the likelihood of specific tokens appearing in the generated output. + logprobs (`bool`, *optional*): + Whether to return log probabilities of the output tokens or not. If true, returns the log + probabilities of each output token returned in the content of message. + max_tokens (`int`, *optional*): + Maximum number of tokens allowed in the response. Defaults to 100. + n (`int`, *optional*): + The number of completions to generate for each prompt. + presence_penalty (`float`, *optional*): + Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the + text so far, increasing the model's likelihood to talk about new topics. + response_format ([`ChatCompletionInputGrammarType`], *optional*): + Grammar constraints. Can be either a JSONSchema or a regex. + seed (Optional[`int`], *optional*): + Seed for reproducible control flow. Defaults to None. + stop (`list[str]`, *optional*): + Up to four strings which trigger the end of the response. + Defaults to None. + stream (`bool`, *optional*): + Enable realtime streaming of responses. Defaults to False. + stream_options ([`ChatCompletionInputStreamOptions`], *optional*): + Options for streaming completions. + temperature (`float`, *optional*): + Controls randomness of the generations. Lower values ensure + less random completions. Range: [0, 2]. Defaults to 1.0. + top_logprobs (`int`, *optional*): + An integer between 0 and 5 specifying the number of most likely tokens to return at each token + position, each with an associated log probability. logprobs must be set to true if this parameter is + used. + top_p (`float`, *optional*): + Fraction of the most likely next words to sample from. + Must be between 0 and 1. Defaults to 1.0. + tool_choice ([`ChatCompletionInputToolChoiceClass`] or [`ChatCompletionInputToolChoiceEnum`], *optional*): + The tool to use for the completion. Defaults to "auto". + tool_prompt (`str`, *optional*): + A prompt to be appended before the tools. + tools (List of [`ChatCompletionInputTool`], *optional*): + A list of tools the model may call. Currently, only functions are supported as a tool. Use this to + provide a list of functions the model may generate JSON inputs for. + extra_body (`dict`, *optional*): + Additional provider-specific parameters to pass to the model. Refer to the provider's documentation + for supported parameters. + Returns: + [`ChatCompletionOutput`] or Iterable of [`ChatCompletionStreamOutput`]: + Generated text returned from the server: + - if `stream=False`, the generated text is returned as a [`ChatCompletionOutput`] (default). + - if `stream=True`, the generated text is returned token by token as a sequence of [`ChatCompletionStreamOutput`]. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + + ```py + >>> from huggingface_hub import InferenceClient + >>> messages = [{"role": "user", "content": "What is the capital of France?"}] + >>> client = InferenceClient("meta-llama/Meta-Llama-3-8B-Instruct") + >>> client.chat_completion(messages, max_tokens=100) + ChatCompletionOutput( + choices=[ + ChatCompletionOutputComplete( + finish_reason='eos_token', + index=0, + message=ChatCompletionOutputMessage( + role='assistant', + content='The capital of France is Paris.', + name=None, + tool_calls=None + ), + logprobs=None + ) + ], + created=1719907176, + id='', + model='meta-llama/Meta-Llama-3-8B-Instruct', + object='text_completion', + system_fingerprint='2.0.4-sha-f426a33', + usage=ChatCompletionOutputUsage( + completion_tokens=8, + prompt_tokens=17, + total_tokens=25 + ) + ) + ``` + + Example using streaming: + ```py + >>> from huggingface_hub import InferenceClient + >>> messages = [{"role": "user", "content": "What is the capital of France?"}] + >>> client = InferenceClient("meta-llama/Meta-Llama-3-8B-Instruct") + >>> for token in client.chat_completion(messages, max_tokens=10, stream=True): + ... print(token) + ChatCompletionStreamOutput(choices=[ChatCompletionStreamOutputChoice(delta=ChatCompletionStreamOutputDelta(content='The', role='assistant'), index=0, finish_reason=None)], created=1710498504) + ChatCompletionStreamOutput(choices=[ChatCompletionStreamOutputChoice(delta=ChatCompletionStreamOutputDelta(content=' capital', role='assistant'), index=0, finish_reason=None)], created=1710498504) + (...) + ChatCompletionStreamOutput(choices=[ChatCompletionStreamOutputChoice(delta=ChatCompletionStreamOutputDelta(content=' may', role='assistant'), index=0, finish_reason=None)], created=1710498504) + ``` + + Example using OpenAI's syntax: + ```py + # instead of `from openai import OpenAI` + from huggingface_hub import InferenceClient + + # instead of `client = OpenAI(...)` + client = InferenceClient( + base_url=..., + api_key=..., + ) + + output = client.chat.completions.create( + model="meta-llama/Meta-Llama-3-8B-Instruct", + messages=[ + {"role": "system", "content": "You are a helpful assistant."}, + {"role": "user", "content": "Count to 10"}, + ], + stream=True, + max_tokens=1024, + ) + + for chunk in output: + print(chunk.choices[0].delta.content) + ``` + + Example using a third-party provider directly with extra (provider-specific) parameters. Usage will be billed on your Together AI account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="together", # Use Together AI provider + ... api_key="", # Pass your Together API key directly + ... ) + >>> client.chat_completion( + ... model="meta-llama/Meta-Llama-3-8B-Instruct", + ... messages=[{"role": "user", "content": "What is the capital of France?"}], + ... extra_body={"safety_model": "Meta-Llama/Llama-Guard-7b"}, + ... ) + ``` + + Example using a third-party provider through Hugging Face Routing. Usage will be billed on your Hugging Face account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="novita", # Use Novita provider + ... api_key="hf_...", # Pass your HF token + ... ) + >>> client.chat_completion( + ... model="meta-llama/Meta-Llama-3-8B-Instruct", + ... messages=[{"role": "user", "content": "What is the capital of France?"}], + ... ) + ``` + + Example using Image + Text as input: + ```py + >>> from huggingface_hub import InferenceClient + + # provide a remote URL + >>> image_url ="https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" + # or a base64-encoded image + >>> image_path = "/path/to/image.jpeg" + >>> with open(image_path, "rb") as f: + ... base64_image = base64.b64encode(f.read()).decode("utf-8") + >>> image_url = f"data:image/jpeg;base64,{base64_image}" + + >>> client = InferenceClient("meta-llama/Llama-3.2-11B-Vision-Instruct") + >>> output = client.chat.completions.create( + ... messages=[ + ... { + ... "role": "user", + ... "content": [ + ... { + ... "type": "image_url", + ... "image_url": {"url": image_url}, + ... }, + ... { + ... "type": "text", + ... "text": "Describe this image in one sentence.", + ... }, + ... ], + ... }, + ... ], + ... ) + >>> output + The image depicts the iconic Statue of Liberty situated in New York Harbor, New York, on a clear day. + ``` + + Example using tools: + ```py + >>> client = InferenceClient("meta-llama/Meta-Llama-3-70B-Instruct") + >>> messages = [ + ... { + ... "role": "system", + ... "content": "Don't make assumptions about what values to plug into functions. Ask for clarification if a user request is ambiguous.", + ... }, + ... { + ... "role": "user", + ... "content": "What's the weather like the next 3 days in San Francisco, CA?", + ... }, + ... ] + >>> tools = [ + ... { + ... "type": "function", + ... "function": { + ... "name": "get_current_weather", + ... "description": "Get the current weather", + ... "parameters": { + ... "type": "object", + ... "properties": { + ... "location": { + ... "type": "string", + ... "description": "The city and state, e.g. San Francisco, CA", + ... }, + ... "format": { + ... "type": "string", + ... "enum": ["celsius", "fahrenheit"], + ... "description": "The temperature unit to use. Infer this from the users location.", + ... }, + ... }, + ... "required": ["location", "format"], + ... }, + ... }, + ... }, + ... { + ... "type": "function", + ... "function": { + ... "name": "get_n_day_weather_forecast", + ... "description": "Get an N-day weather forecast", + ... "parameters": { + ... "type": "object", + ... "properties": { + ... "location": { + ... "type": "string", + ... "description": "The city and state, e.g. San Francisco, CA", + ... }, + ... "format": { + ... "type": "string", + ... "enum": ["celsius", "fahrenheit"], + ... "description": "The temperature unit to use. Infer this from the users location.", + ... }, + ... "num_days": { + ... "type": "integer", + ... "description": "The number of days to forecast", + ... }, + ... }, + ... "required": ["location", "format", "num_days"], + ... }, + ... }, + ... }, + ... ] + + >>> response = client.chat_completion( + ... model="meta-llama/Meta-Llama-3-70B-Instruct", + ... messages=messages, + ... tools=tools, + ... tool_choice="auto", + ... max_tokens=500, + ... ) + >>> response.choices[0].message.tool_calls[0].function + ChatCompletionOutputFunctionDefinition( + arguments={ + 'location': 'San Francisco, CA', + 'format': 'fahrenheit', + 'num_days': 3 + }, + name='get_n_day_weather_forecast', + description=None + ) + ``` + + Example using response_format: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient("meta-llama/Meta-Llama-3-70B-Instruct") + >>> messages = [ + ... { + ... "role": "user", + ... "content": "I saw a puppy a cat and a raccoon during my bike ride in the park. What did I see and when?", + ... }, + ... ] + >>> response_format = { + ... "type": "json", + ... "value": { + ... "properties": { + ... "location": {"type": "string"}, + ... "activity": {"type": "string"}, + ... "animals_seen": {"type": "integer", "minimum": 1, "maximum": 5}, + ... "animals": {"type": "array", "items": {"type": "string"}}, + ... }, + ... "required": ["location", "activity", "animals_seen", "animals"], + ... }, + ... } + >>> response = client.chat_completion( + ... messages=messages, + ... response_format=response_format, + ... max_tokens=500, + ... ) + >>> response.choices[0].message.content + '{\n\n"activity": "bike ride",\n"animals": ["puppy", "cat", "raccoon"],\n"animals_seen": 3,\n"location": "park"}' + ``` + """ + # Since `chat_completion(..., model=xxx)` is also a payload parameter for the server, we need to handle 'model' differently. + # `self.model` takes precedence over 'model' argument for building URL. + # `model` takes precedence for payload value. + model_id_or_url = self.model or model + payload_model = model or self.model + + # Get the provider helper + provider_helper = get_provider_helper( + self.provider, + task="conversational", + model=model_id_or_url + if model_id_or_url is not None and model_id_or_url.startswith(("http://", "https://")) + else payload_model, + ) + + # Prepare the payload + parameters = { + "model": payload_model, + "frequency_penalty": frequency_penalty, + "logit_bias": logit_bias, + "logprobs": logprobs, + "max_tokens": max_tokens, + "n": n, + "presence_penalty": presence_penalty, + "response_format": response_format, + "seed": seed, + "stop": stop, + "temperature": temperature, + "tool_choice": tool_choice, + "tool_prompt": tool_prompt, + "tools": tools, + "top_logprobs": top_logprobs, + "top_p": top_p, + "stream": stream, + "stream_options": stream_options, + **(extra_body or {}), + } + request_parameters = provider_helper.prepare_request( + inputs=messages, + parameters=parameters, + headers=self.headers, + model=model_id_or_url, + api_key=self.token, + ) + data = self._inner_post(request_parameters, stream=stream) + + if stream: + return _stream_chat_completion_response(data) # type: ignore + + return ChatCompletionOutput.parse_obj_as_instance(data) # type: ignore + + def document_question_answering( + self, + image: ContentT, + question: str, + *, + model: str | None = None, + doc_stride: int | None = None, + handle_impossible_answer: bool | None = None, + lang: str | None = None, + max_answer_len: int | None = None, + max_question_len: int | None = None, + max_seq_len: int | None = None, + top_k: int | None = None, + word_boxes: list[list[float] | str] | None = None, + ) -> list[DocumentQuestionAnsweringOutputElement]: + """ + Answer questions on document images. + + Args: + image (`Union[str, Path, bytes, BinaryIO]`): + The input image for the context. It can be raw bytes, an image file, or a URL to an online image. + question (`str`): + Question to be answered. + model (`str`, *optional*): + The model to use for the document question answering task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended document question answering model will be used. + Defaults to None. + doc_stride (`int`, *optional*): + If the words in the document are too long to fit with the question for the model, it will be split in + several chunks with some overlap. This argument controls the size of that overlap. + handle_impossible_answer (`bool`, *optional*): + Whether to accept impossible as an answer + lang (`str`, *optional*): + Language to use while running OCR. Defaults to english. + max_answer_len (`int`, *optional*): + The maximum length of predicted answers (e.g., only answers with a shorter length are considered). + max_question_len (`int`, *optional*): + The maximum length of the question after tokenization. It will be truncated if needed. + max_seq_len (`int`, *optional*): + The maximum length of the total sentence (context + question) in tokens of each chunk passed to the + model. The context will be split in several chunks (using doc_stride as overlap) if needed. + top_k (`int`, *optional*): + The number of answers to return (will be chosen by order of likelihood). Can return less than top_k + answers if there are not enough options available within the context. + word_boxes (`list[Union[list[float], str`, *optional*): + A list of words and bounding boxes (normalized 0->1000). If provided, the inference will skip the OCR + step and use the provided bounding boxes instead. + Returns: + `list[DocumentQuestionAnsweringOutputElement]`: a list of [`DocumentQuestionAnsweringOutputElement`] items containing the predicted label, associated probability, word ids, and page number. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.document_question_answering(image="https://huggingface.co/spaces/impira/docquery/resolve/2359223c1837a7587402bda0f2643382a6eefeab/invoice.png", question="What is the invoice number?") + [DocumentQuestionAnsweringOutputElement(answer='us-001', end=16, score=0.9999666213989258, start=16)] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="document-question-answering", model=model_id) + inputs: dict[str, Any] = {"question": question, "image": _b64_encode(image)} + request_parameters = provider_helper.prepare_request( + inputs=inputs, + parameters={ + "doc_stride": doc_stride, + "handle_impossible_answer": handle_impossible_answer, + "lang": lang, + "max_answer_len": max_answer_len, + "max_question_len": max_question_len, + "max_seq_len": max_seq_len, + "top_k": top_k, + "word_boxes": word_boxes, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + return DocumentQuestionAnsweringOutputElement.parse_obj_as_list(response) + + def feature_extraction( + self, + text: str | list[str], + *, + normalize: bool | None = None, + prompt_name: str | None = None, + truncate: bool | None = None, + truncation_direction: Literal["left", "right"] | None = None, + dimensions: int | None = None, + encoding_format: Literal["float", "base64"] | None = None, + model: str | None = None, + ) -> "np.ndarray": + """ + Generate embeddings for a given text or batch of texts. + + Args: + text (`str` or `list[str]`): + The text or list of texts to embed. + model (`str`, *optional*): + The model to use for the feature extraction task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended feature extraction model will be used. + Defaults to None. + normalize (`bool`, *optional*): + Whether to normalize the embeddings or not. + Only available on server powered by Text-Embedding-Inference. + prompt_name (`str`, *optional*): + The name of the prompt that should be used by for encoding. If not set, no prompt will be applied. + Must be a key in the `Sentence Transformers` configuration `prompts` dictionary. + For example if ``prompt_name`` is "query" and the ``prompts`` is {"query": "query: ",...}, + then the sentence "What is the capital of France?" will be encoded as "query: What is the capital of France?" + because the prompt text will be prepended before any text to encode. + truncate (`bool`, *optional*): + Whether to truncate the embeddings or not. + Only available on server powered by Text-Embedding-Inference. + truncation_direction (`Literal["left", "right"]`, *optional*): + Which side of the input should be truncated when `truncate=True` is passed. + dimensions (`int`, *optional*): + The number of dimensions the resulting output embeddings should have. + Only available on OpenAI-compatible embedding endpoints. + encoding_format (`Literal["float", "base64"]`, *optional*): + The format of the output embeddings. Either "float" or "base64". + Only available on OpenAI-compatible embedding endpoints. + + Returns: + `np.ndarray`: The embedding representing the input text(s) as a float32 numpy array. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.feature_extraction("Hi, who are you?") + array([[ 2.424802 , 2.93384 , 1.1750331 , ..., 1.240499, -0.13776633, -0.7889173 ], + [-0.42943227, -0.6364878 , -1.693462 , ..., 0.41978157, -2.4336355 , 0.6162071 ], + ..., + [ 0.28552425, -0.928395 , -1.2077185 , ..., 0.76810825, -2.1069427 , 0.6236161 ]], dtype=float32) + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="feature-extraction", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters={ + "normalize": normalize, + "prompt_name": prompt_name, + "truncate": truncate, + "truncation_direction": truncation_direction, + "dimensions": dimensions, + "encoding_format": encoding_format, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + np = _import_numpy() + return np.array(provider_helper.get_response(response), dtype="float32") + + def fill_mask( + self, + text: str, + *, + model: str | None = None, + targets: list[str] | None = None, + top_k: int | None = None, + ) -> list[FillMaskOutputElement]: + """ + Fill in a hole with a missing word (token to be precise). + + Args: + text (`str`): + a string to be filled from, must contain the [MASK] token (check model card for exact name of the mask). + model (`str`, *optional*): + The model to use for the fill mask task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended fill mask model will be used. + targets (`list[str`, *optional*): + When passed, the model will limit the scores to the passed targets instead of looking up in the whole + vocabulary. If the provided targets are not in the model vocab, they will be tokenized and the first + resulting token will be used (with a warning, and that might be slower). + top_k (`int`, *optional*): + When passed, overrides the number of predictions to return. + Returns: + `list[FillMaskOutputElement]`: a list of [`FillMaskOutputElement`] items containing the predicted label, associated + probability, token reference, and completed text. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.fill_mask("The goal of life is .") + [ + FillMaskOutputElement(score=0.06897063553333282, token=11098, token_str=' happiness', sequence='The goal of life is happiness.'), + FillMaskOutputElement(score=0.06554922461509705, token=45075, token_str=' immortality', sequence='The goal of life is immortality.') + ] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="fill-mask", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters={"targets": targets, "top_k": top_k}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + return FillMaskOutputElement.parse_obj_as_list(response) + + def image_classification( + self, + image: ContentT, + *, + model: str | None = None, + function_to_apply: Optional["ImageClassificationOutputTransform"] = None, + top_k: int | None = None, + ) -> list[ImageClassificationOutputElement]: + """ + Perform image classification on the given image using the specified model. + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The image to classify. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + model (`str`, *optional*): + The model to use for image classification. Can be a model ID hosted on the Hugging Face Hub or a URL to a + deployed Inference Endpoint. If not provided, the default recommended model for image classification will be used. + function_to_apply (`"ImageClassificationOutputTransform"`, *optional*): + The function to apply to the model outputs in order to retrieve the scores. + top_k (`int`, *optional*): + When specified, limits the output to the top K most probable classes. + Returns: + `list[ImageClassificationOutputElement]`: a list of [`ImageClassificationOutputElement`] items containing the predicted label and associated probability. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.image_classification("https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Cute_dog.jpg/320px-Cute_dog.jpg") + [ImageClassificationOutputElement(label='Blenheim spaniel', score=0.9779096841812134), ...] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="image-classification", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={"function_to_apply": function_to_apply, "top_k": top_k}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + return ImageClassificationOutputElement.parse_obj_as_list(response) + + def image_segmentation( + self, + image: ContentT, + *, + model: str | None = None, + mask_threshold: float | None = None, + overlap_mask_area_threshold: float | None = None, + subtask: Optional["ImageSegmentationSubtask"] = None, + threshold: float | None = None, + ) -> list[ImageSegmentationOutputElement]: + """ + Perform image segmentation on the given image using the specified model. + + > [!WARNING] + > You must have `PIL` installed if you want to work with images (`pip install Pillow`). + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The image to segment. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + model (`str`, *optional*): + The model to use for image segmentation. Can be a model ID hosted on the Hugging Face Hub or a URL to a + deployed Inference Endpoint. If not provided, the default recommended model for image segmentation will be used. + mask_threshold (`float`, *optional*): + Threshold to use when turning the predicted masks into binary values. + overlap_mask_area_threshold (`float`, *optional*): + Mask overlap threshold to eliminate small, disconnected segments. + subtask (`"ImageSegmentationSubtask"`, *optional*): + Segmentation task to be performed, depending on model capabilities. + threshold (`float`, *optional*): + Probability threshold to filter out predicted masks. + Returns: + `list[ImageSegmentationOutputElement]`: A list of [`ImageSegmentationOutputElement`] items containing the segmented masks and associated attributes. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.image_segmentation("cat.jpg") + [ImageSegmentationOutputElement(score=0.989008, label='LABEL_184', mask=), ...] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="image-segmentation", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={ + "mask_threshold": mask_threshold, + "overlap_mask_area_threshold": overlap_mask_area_threshold, + "subtask": subtask, + "threshold": threshold, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + response = provider_helper.get_response(response, request_parameters) + output = ImageSegmentationOutputElement.parse_obj_as_list(response) + for item in output: + item.mask = _b64_to_image(item.mask) # type: ignore + return output + + def image_to_image( + self, + image: ContentT, + prompt: str | None = None, + *, + negative_prompt: str | None = None, + num_inference_steps: int | None = None, + guidance_scale: float | None = None, + model: str | None = None, + target_size: ImageToImageTargetSize | None = None, + **kwargs, + ) -> "Image": + """ + Perform image-to-image translation using a specified model. + + > [!WARNING] + > You must have `PIL` installed if you want to work with images (`pip install Pillow`). + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The input image for translation. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + prompt (`str`, *optional*): + The text prompt to guide the image generation. + negative_prompt (`str`, *optional*): + One prompt to guide what NOT to include in image generation. + num_inference_steps (`int`, *optional*): + For diffusion models. The number of denoising steps. More denoising steps usually lead to a higher + quality image at the expense of slower inference. + guidance_scale (`float`, *optional*): + For diffusion models. A higher guidance scale value encourages the model to generate images closely + linked to the text prompt at the expense of lower image quality. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. This parameter overrides the model defined at the instance level. Defaults to None. + target_size (`ImageToImageTargetSize`, *optional*): + The size in pixels of the output image. This parameter is only supported by some providers and for + specific models. It will be ignored when unsupported. + + Returns: + `Image`: The translated image. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> image = client.image_to_image("cat.jpg", prompt="turn the cat into a tiger") + >>> image.save("tiger.jpg") + ``` + + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="image-to-image", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={ + "prompt": prompt, + "negative_prompt": negative_prompt, + "target_size": target_size, + "num_inference_steps": num_inference_steps, + "guidance_scale": guidance_scale, + **kwargs, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + response = provider_helper.get_response(response, request_parameters) + return _bytes_to_image(response) + + def image_to_video( + self, + image: ContentT, + *, + model: str | None = None, + prompt: str | None = None, + negative_prompt: str | None = None, + num_frames: float | None = None, + num_inference_steps: int | None = None, + guidance_scale: float | None = None, + seed: int | None = None, + target_size: ImageToVideoTargetSize | None = None, + **kwargs, + ) -> bytes: + """ + Generate a video from an input image. + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The input image to generate a video from. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. This parameter overrides the model defined at the instance level. Defaults to None. + prompt (`str`, *optional*): + The text prompt to guide the video generation. + negative_prompt (`str`, *optional*): + One prompt to guide what NOT to include in video generation. + num_frames (`float`, *optional*): + The num_frames parameter determines how many video frames are generated. + num_inference_steps (`int`, *optional*): + For diffusion models. The number of denoising steps. More denoising steps usually lead to a higher + quality image at the expense of slower inference. + guidance_scale (`float`, *optional*): + For diffusion models. A higher guidance scale value encourages the model to generate videos closely + linked to the text prompt at the expense of lower image quality. + seed (`int`, *optional*): + The seed to use for the video generation. + target_size (`ImageToVideoTargetSize`, *optional*): + The size in pixel of the output video frames. + num_inference_steps (`int`, *optional*): + The number of denoising steps. More denoising steps usually lead to a higher quality video at the + expense of slower inference. + seed (`int`, *optional*): + Seed for the random number generator. + + Returns: + `bytes`: The generated video. + + Examples: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> video = client.image_to_video("cat.jpg", model="Wan-AI/Wan2.2-I2V-A14B", prompt="turn the cat into a tiger") + >>> with open("tiger.mp4", "wb") as f: + ... f.write(video) + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="image-to-video", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={ + "prompt": prompt, + "negative_prompt": negative_prompt, + "num_frames": num_frames, + "num_inference_steps": num_inference_steps, + "guidance_scale": guidance_scale, + "seed": seed, + "target_size": target_size, + **kwargs, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + response = provider_helper.get_response(response, request_parameters) + return response + + def image_to_text(self, image: ContentT, *, model: str | None = None) -> ImageToTextOutput: + """ + Takes an input image and return text. + + Models can have very different outputs depending on your use case (image captioning, optical character recognition + (OCR), Pix2Struct, etc.). Please have a look to the model card to learn more about a model's specificities. + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The input image to caption. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. This parameter overrides the model defined at the instance level. Defaults to None. + + Returns: + [`ImageToTextOutput`]: The generated text. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.image_to_text("cat.jpg") + 'a cat standing in a grassy field ' + >>> client.image_to_text("https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Cute_dog.jpg/320px-Cute_dog.jpg") + 'a dog laying on the grass next to a flower pot ' + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="image-to-text", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + output_list: list[ImageToTextOutput] = ImageToTextOutput.parse_obj_as_list(response) + return output_list[0] + + def object_detection( + self, image: ContentT, *, model: str | None = None, threshold: float | None = None + ) -> list[ObjectDetectionOutputElement]: + """ + Perform object detection on the given image using the specified model. + + > [!WARNING] + > You must have `PIL` installed if you want to work with images (`pip install Pillow`). + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The image to detect objects on. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + model (`str`, *optional*): + The model to use for object detection. Can be a model ID hosted on the Hugging Face Hub or a URL to a + deployed Inference Endpoint. If not provided, the default recommended model for object detection (DETR) will be used. + threshold (`float`, *optional*): + The probability necessary to make a prediction. + Returns: + `list[ObjectDetectionOutputElement]`: A list of [`ObjectDetectionOutputElement`] items containing the bounding boxes and associated attributes. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + `ValueError`: + If the request output is not a List. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.object_detection("people.jpg") + [ObjectDetectionOutputElement(score=0.9486683011054993, label='person', box=ObjectDetectionBoundingBox(xmin=59, ymin=39, xmax=420, ymax=510)), ...] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="object-detection", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={"threshold": threshold}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + return ObjectDetectionOutputElement.parse_obj_as_list(response) + + def question_answering( + self, + question: str, + context: str, + *, + model: str | None = None, + align_to_words: bool | None = None, + doc_stride: int | None = None, + handle_impossible_answer: bool | None = None, + max_answer_len: int | None = None, + max_question_len: int | None = None, + max_seq_len: int | None = None, + top_k: int | None = None, + ) -> QuestionAnsweringOutputElement | list[QuestionAnsweringOutputElement]: + """ + Retrieve the answer to a question from a given text. + + Args: + question (`str`): + Question to be answered. + context (`str`): + The context of the question. + model (`str`): + The model to use for the question answering task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. + align_to_words (`bool`, *optional*): + Attempts to align the answer to real words. Improves quality on space separated languages. Might hurt + on non-space-separated languages (like Japanese or Chinese) + doc_stride (`int`, *optional*): + If the context is too long to fit with the question for the model, it will be split in several chunks + with some overlap. This argument controls the size of that overlap. + handle_impossible_answer (`bool`, *optional*): + Whether to accept impossible as an answer. + max_answer_len (`int`, *optional*): + The maximum length of predicted answers (e.g., only answers with a shorter length are considered). + max_question_len (`int`, *optional*): + The maximum length of the question after tokenization. It will be truncated if needed. + max_seq_len (`int`, *optional*): + The maximum length of the total sentence (context + question) in tokens of each chunk passed to the + model. The context will be split in several chunks (using docStride as overlap) if needed. + top_k (`int`, *optional*): + The number of answers to return (will be chosen by order of likelihood). Note that we return less than + topk answers if there are not enough options available within the context. + + Returns: + Union[`QuestionAnsweringOutputElement`, list[`QuestionAnsweringOutputElement`]]: + When top_k is 1 or not provided, it returns a single `QuestionAnsweringOutputElement`. + When top_k is greater than 1, it returns a list of `QuestionAnsweringOutputElement`. + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.question_answering(question="What's my name?", context="My name is Clara and I live in Berkeley.") + QuestionAnsweringOutputElement(answer='Clara', end=16, score=0.9326565265655518, start=11) + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="question-answering", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs={"question": question, "context": context}, + parameters={ + "align_to_words": align_to_words, + "doc_stride": doc_stride, + "handle_impossible_answer": handle_impossible_answer, + "max_answer_len": max_answer_len, + "max_question_len": max_question_len, + "max_seq_len": max_seq_len, + "top_k": top_k, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + # Parse the response as a single `QuestionAnsweringOutputElement` when top_k is 1 or not provided, or a list of `QuestionAnsweringOutputElement` to ensure backward compatibility. + output = QuestionAnsweringOutputElement.parse_obj(response) + return output + + def sentence_similarity( + self, sentence: str, other_sentences: list[str], *, model: str | None = None + ) -> list[float]: + """ + Compute the semantic similarity between a sentence and a list of other sentences by comparing their embeddings. + + Args: + sentence (`str`): + The main sentence to compare to others. + other_sentences (`list[str]`): + The list of sentences to compare to. + model (`str`, *optional*): + The model to use for the sentence similarity task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended sentence similarity model will be used. + Defaults to None. + + Returns: + `list[float]`: The embedding representing the input text. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.sentence_similarity( + ... "Machine learning is so easy.", + ... other_sentences=[ + ... "Deep learning is so straightforward.", + ... "This is so difficult, like rocket science.", + ... "I can't believe how much I struggled with this.", + ... ], + ... ) + [0.7785726189613342, 0.45876261591911316, 0.2906220555305481] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="sentence-similarity", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs={"source_sentence": sentence, "sentences": other_sentences}, + parameters={}, + extra_payload={}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + return _bytes_to_list(response) + + def summarization( + self, + text: str, + *, + model: str | None = None, + clean_up_tokenization_spaces: bool | None = None, + generate_parameters: dict[str, Any] | None = None, + truncation: Optional["SummarizationTruncationStrategy"] = None, + ) -> SummarizationOutput: + """ + Generate a summary of a given text using a specified model. + + Args: + text (`str`): + The input text to summarize. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. If not provided, the default recommended model for summarization will be used. + clean_up_tokenization_spaces (`bool`, *optional*): + Whether to clean up the potential extra spaces in the text output. + generate_parameters (`dict[str, Any]`, *optional*): + Additional parametrization of the text generation algorithm. + truncation (`"SummarizationTruncationStrategy"`, *optional*): + The truncation strategy to use. + Returns: + [`SummarizationOutput`]: The generated summary text. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.summarization("The Eiffel tower...") + SummarizationOutput(generated_text="The Eiffel tower is one of the most famous landmarks in the world....") + ``` + """ + parameters = { + "clean_up_tokenization_spaces": clean_up_tokenization_spaces, + "generate_parameters": generate_parameters, + "truncation": truncation, + } + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="summarization", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters=parameters, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + return SummarizationOutput.parse_obj_as_list(response)[0] + + def table_question_answering( + self, + table: dict[str, Any], + query: str, + *, + model: str | None = None, + padding: Optional["Padding"] = None, + sequential: bool | None = None, + truncation: bool | None = None, + ) -> TableQuestionAnsweringOutputElement: + """ + Retrieve the answer to a question from information given in a table. + + Args: + table (`str`): + A table of data represented as a dict of lists where entries are headers and the lists are all the + values, all lists must have the same size. + query (`str`): + The query in plain text that you want to ask the table. + model (`str`): + The model to use for the table-question-answering task. Can be a model ID hosted on the Hugging Face + Hub or a URL to a deployed Inference Endpoint. + padding (`"Padding"`, *optional*): + Activates and controls padding. + sequential (`bool`, *optional*): + Whether to do inference sequentially or as a batch. Batching is faster, but models like SQA require the + inference to be done sequentially to extract relations within sequences, given their conversational + nature. + truncation (`bool`, *optional*): + Activates and controls truncation. + + Returns: + [`TableQuestionAnsweringOutputElement`]: a table question answering output containing the answer, coordinates, cells and the aggregator used. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> query = "How many stars does the transformers repository have?" + >>> table = {"Repository": ["Transformers", "Datasets", "Tokenizers"], "Stars": ["36542", "4512", "3934"]} + >>> client.table_question_answering(table, query, model="google/tapas-base-finetuned-wtq") + TableQuestionAnsweringOutputElement(answer='36542', coordinates=[[0, 1]], cells=['36542'], aggregator='AVERAGE') + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="table-question-answering", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs={"query": query, "table": table}, + parameters={"model": model, "padding": padding, "sequential": sequential, "truncation": truncation}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + return TableQuestionAnsweringOutputElement.parse_obj_as_instance(response) + + def tabular_classification(self, table: dict[str, Any], *, model: str | None = None) -> list[str]: + """ + Classifying a target category (a group) based on a set of attributes. + + Args: + table (`dict[str, Any]`): + Set of attributes to classify. + model (`str`, *optional*): + The model to use for the tabular classification task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended tabular classification model will be used. + Defaults to None. + + Returns: + `List`: a list of labels, one per row in the initial table. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> table = { + ... "fixed_acidity": ["7.4", "7.8", "10.3"], + ... "volatile_acidity": ["0.7", "0.88", "0.32"], + ... "citric_acid": ["0", "0", "0.45"], + ... "residual_sugar": ["1.9", "2.6", "6.4"], + ... "chlorides": ["0.076", "0.098", "0.073"], + ... "free_sulfur_dioxide": ["11", "25", "5"], + ... "total_sulfur_dioxide": ["34", "67", "13"], + ... "density": ["0.9978", "0.9968", "0.9976"], + ... "pH": ["3.51", "3.2", "3.23"], + ... "sulphates": ["0.56", "0.68", "0.82"], + ... "alcohol": ["9.4", "9.8", "12.6"], + ... } + >>> client.tabular_classification(table=table, model="julien-c/wine-quality") + ["5", "5", "5"] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="tabular-classification", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=None, + extra_payload={"table": table}, + parameters={}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + return _bytes_to_list(response) + + def tabular_regression(self, table: dict[str, Any], *, model: str | None = None) -> list[float]: + """ + Predicting a numerical target value given a set of attributes/features in a table. + + Args: + table (`dict[str, Any]`): + Set of attributes stored in a table. The attributes used to predict the target can be both numerical and categorical. + model (`str`, *optional*): + The model to use for the tabular regression task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended tabular regression model will be used. + Defaults to None. + + Returns: + `List`: a list of predicted numerical target values. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> table = { + ... "Height": ["11.52", "12.48", "12.3778"], + ... "Length1": ["23.2", "24", "23.9"], + ... "Length2": ["25.4", "26.3", "26.5"], + ... "Length3": ["30", "31.2", "31.1"], + ... "Species": ["Bream", "Bream", "Bream"], + ... "Width": ["4.02", "4.3056", "4.6961"], + ... } + >>> client.tabular_regression(table, model="scikit-learn/Fish-Weight") + [110, 120, 130] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="tabular-regression", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=None, + parameters={}, + extra_payload={"table": table}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + return _bytes_to_list(response) + + def text_classification( + self, + text: str, + *, + model: str | None = None, + top_k: int | None = None, + function_to_apply: Optional["TextClassificationOutputTransform"] = None, + ) -> list[TextClassificationOutputElement]: + """ + Perform text classification (e.g. sentiment-analysis) on the given text. + + Args: + text (`str`): + A string to be classified. + model (`str`, *optional*): + The model to use for the text classification task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended text classification model will be used. + Defaults to None. + top_k (`int`, *optional*): + When specified, limits the output to the top K most probable classes. + function_to_apply (`"TextClassificationOutputTransform"`, *optional*): + The function to apply to the model outputs in order to retrieve the scores. + + Returns: + `list[TextClassificationOutputElement]`: a list of [`TextClassificationOutputElement`] items containing the predicted label and associated probability. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.text_classification("I like you") + [ + TextClassificationOutputElement(label='POSITIVE', score=0.9998695850372314), + TextClassificationOutputElement(label='NEGATIVE', score=0.0001304351753788069), + ] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="text-classification", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters={ + "function_to_apply": function_to_apply, + "top_k": top_k, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + return TextClassificationOutputElement.parse_obj_as_list(response)[0] # type: ignore + + @overload + def text_generation( + self, + prompt: str, + *, + details: Literal[True], + stream: Literal[True], + model: str | None = None, + # Parameters from `TextGenerationInputGenerateParameters` (maintained manually) + adapter_id: str | None = None, + best_of: int | None = None, + decoder_input_details: bool | None = None, + do_sample: bool | None = None, + frequency_penalty: float | None = None, + grammar: TextGenerationInputGrammarType | None = None, + max_new_tokens: int | None = None, + repetition_penalty: float | None = None, + return_full_text: bool | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stop_sequences: list[str] | None = None, # Deprecated, use `stop` instead + temperature: float | None = None, + top_k: int | None = None, + top_n_tokens: int | None = None, + top_p: float | None = None, + truncate: int | None = None, + typical_p: float | None = None, + watermark: bool | None = None, + ) -> Iterable[TextGenerationStreamOutput]: ... + + @overload + def text_generation( + self, + prompt: str, + *, + details: Literal[True], + stream: Literal[False] | None = None, + model: str | None = None, + # Parameters from `TextGenerationInputGenerateParameters` (maintained manually) + adapter_id: str | None = None, + best_of: int | None = None, + decoder_input_details: bool | None = None, + do_sample: bool | None = None, + frequency_penalty: float | None = None, + grammar: TextGenerationInputGrammarType | None = None, + max_new_tokens: int | None = None, + repetition_penalty: float | None = None, + return_full_text: bool | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stop_sequences: list[str] | None = None, # Deprecated, use `stop` instead + temperature: float | None = None, + top_k: int | None = None, + top_n_tokens: int | None = None, + top_p: float | None = None, + truncate: int | None = None, + typical_p: float | None = None, + watermark: bool | None = None, + ) -> TextGenerationOutput: ... + + @overload + def text_generation( + self, + prompt: str, + *, + details: Literal[False] | None = None, + stream: Literal[True], + model: str | None = None, + # Parameters from `TextGenerationInputGenerateParameters` (maintained manually) + adapter_id: str | None = None, + best_of: int | None = None, + decoder_input_details: bool | None = None, + do_sample: bool | None = None, + frequency_penalty: float | None = None, + grammar: TextGenerationInputGrammarType | None = None, + max_new_tokens: int | None = None, + repetition_penalty: float | None = None, + return_full_text: bool | None = None, # Manual default value + seed: int | None = None, + stop: list[str] | None = None, + stop_sequences: list[str] | None = None, # Deprecated, use `stop` instead + temperature: float | None = None, + top_k: int | None = None, + top_n_tokens: int | None = None, + top_p: float | None = None, + truncate: int | None = None, + typical_p: float | None = None, + watermark: bool | None = None, + ) -> Iterable[str]: ... + + @overload + def text_generation( + self, + prompt: str, + *, + details: Literal[False] | None = None, + stream: Literal[False] | None = None, + model: str | None = None, + # Parameters from `TextGenerationInputGenerateParameters` (maintained manually) + adapter_id: str | None = None, + best_of: int | None = None, + decoder_input_details: bool | None = None, + do_sample: bool | None = None, + frequency_penalty: float | None = None, + grammar: TextGenerationInputGrammarType | None = None, + max_new_tokens: int | None = None, + repetition_penalty: float | None = None, + return_full_text: bool | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stop_sequences: list[str] | None = None, # Deprecated, use `stop` instead + temperature: float | None = None, + top_k: int | None = None, + top_n_tokens: int | None = None, + top_p: float | None = None, + truncate: int | None = None, + typical_p: float | None = None, + watermark: bool | None = None, + ) -> str: ... + + @overload + def text_generation( + self, + prompt: str, + *, + details: bool | None = None, + stream: bool | None = None, + model: str | None = None, + # Parameters from `TextGenerationInputGenerateParameters` (maintained manually) + adapter_id: str | None = None, + best_of: int | None = None, + decoder_input_details: bool | None = None, + do_sample: bool | None = None, + frequency_penalty: float | None = None, + grammar: TextGenerationInputGrammarType | None = None, + max_new_tokens: int | None = None, + repetition_penalty: float | None = None, + return_full_text: bool | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stop_sequences: list[str] | None = None, # Deprecated, use `stop` instead + temperature: float | None = None, + top_k: int | None = None, + top_n_tokens: int | None = None, + top_p: float | None = None, + truncate: int | None = None, + typical_p: float | None = None, + watermark: bool | None = None, + ) -> str | TextGenerationOutput | Iterable[str] | Iterable[TextGenerationStreamOutput]: ... + + def text_generation( + self, + prompt: str, + *, + details: bool | None = None, + stream: bool | None = None, + model: str | None = None, + # Parameters from `TextGenerationInputGenerateParameters` (maintained manually) + adapter_id: str | None = None, + best_of: int | None = None, + decoder_input_details: bool | None = None, + do_sample: bool | None = None, + frequency_penalty: float | None = None, + grammar: TextGenerationInputGrammarType | None = None, + max_new_tokens: int | None = None, + repetition_penalty: float | None = None, + return_full_text: bool | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stop_sequences: list[str] | None = None, # Deprecated, use `stop` instead + temperature: float | None = None, + top_k: int | None = None, + top_n_tokens: int | None = None, + top_p: float | None = None, + truncate: int | None = None, + typical_p: float | None = None, + watermark: bool | None = None, + ) -> str | TextGenerationOutput | Iterable[str] | Iterable[TextGenerationStreamOutput]: + """ + Given a prompt, generate the following text. + + > [!TIP] + > If you want to generate a response from chat messages, you should use the [`InferenceClient.chat_completion`] method. + > It accepts a list of messages instead of a single text prompt and handles the chat templating for you. + + Args: + prompt (`str`): + Input text. + details (`bool`, *optional*): + By default, text_generation returns a string. Pass `details=True` if you want a detailed output (tokens, + probabilities, seed, finish reason, etc.). Only available for models running on with the + `text-generation-inference` backend. + stream (`bool`, *optional*): + By default, text_generation returns the full generated text. Pass `stream=True` if you want a stream of + tokens to be returned. Only available for models running on with the `text-generation-inference` + backend. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. This parameter overrides the model defined at the instance level. Defaults to None. + adapter_id (`str`, *optional*): + Lora adapter id. + best_of (`int`, *optional*): + Generate best_of sequences and return the one if the highest token logprobs. + decoder_input_details (`bool`, *optional*): + Return the decoder input token logprobs and ids. You must set `details=True` as well for it to be taken + into account. Defaults to `False`. + do_sample (`bool`, *optional*): + Activate logits sampling + frequency_penalty (`float`, *optional*): + Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in + the text so far, decreasing the model's likelihood to repeat the same line verbatim. + grammar ([`TextGenerationInputGrammarType`], *optional*): + Grammar constraints. Can be either a JSONSchema or a regex. + max_new_tokens (`int`, *optional*): + Maximum number of generated tokens. Defaults to 100. + repetition_penalty (`float`, *optional*): + The parameter for repetition penalty. 1.0 means no penalty. See [this + paper](https://arxiv.org/pdf/1909.05858.pdf) for more details. + return_full_text (`bool`, *optional*): + Whether to prepend the prompt to the generated text + seed (`int`, *optional*): + Random sampling seed + stop (`list[str]`, *optional*): + Stop generating tokens if a member of `stop` is generated. + stop_sequences (`list[str]`, *optional*): + Deprecated argument. Use `stop` instead. + temperature (`float`, *optional*): + The value used to module the logits distribution. + top_n_tokens (`int`, *optional*): + Return information about the `top_n_tokens` most likely tokens at each generation step, instead of + just the sampled token. + top_k (`int`, *optional`): + The number of highest probability vocabulary tokens to keep for top-k-filtering. + top_p (`float`, *optional`): + If set to < 1, only the smallest set of most probable tokens with probabilities that add up to `top_p` or + higher are kept for generation. + truncate (`int`, *optional`): + Truncate inputs tokens to the given size. + typical_p (`float`, *optional`): + Typical Decoding mass + See [Typical Decoding for Natural Language Generation](https://arxiv.org/abs/2202.00666) for more information + watermark (`bool`, *optional*): + Watermarking with [A Watermark for Large Language Models](https://arxiv.org/abs/2301.10226) + + Returns: + `Union[str, TextGenerationOutput, Iterable[str], Iterable[TextGenerationStreamOutput]]`: + Generated text returned from the server: + - if `stream=False` and `details=False`, the generated text is returned as a `str` (default) + - if `stream=True` and `details=False`, the generated text is returned token by token as a `Iterable[str]` + - if `stream=False` and `details=True`, the generated text is returned with more details as a [`~huggingface_hub.TextGenerationOutput`] + - if `details=True` and `stream=True`, the generated text is returned token by token as a iterable of [`~huggingface_hub.TextGenerationStreamOutput`] + + Raises: + `ValidationError`: + If input values are not valid. No HTTP call is made to the server. + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + + # Case 1: generate text + >>> client.text_generation("The huggingface_hub library is ", max_new_tokens=12) + '100% open source and built to be easy to use.' + + # Case 2: iterate over the generated tokens. Useful for large generation. + >>> for token in client.text_generation("The huggingface_hub library is ", max_new_tokens=12, stream=True): + ... print(token) + 100 + % + open + source + and + built + to + be + easy + to + use + . + + # Case 3: get more details about the generation process. + >>> client.text_generation("The huggingface_hub library is ", max_new_tokens=12, details=True) + TextGenerationOutput( + generated_text='100% open source and built to be easy to use.', + details=TextGenerationDetails( + finish_reason='length', + generated_tokens=12, + seed=None, + prefill=[ + TextGenerationPrefillOutputToken(id=487, text='The', logprob=None), + TextGenerationPrefillOutputToken(id=53789, text=' hugging', logprob=-13.171875), + (...) + TextGenerationPrefillOutputToken(id=204, text=' ', logprob=-7.0390625) + ], + tokens=[ + TokenElement(id=1425, text='100', logprob=-1.0175781, special=False), + TokenElement(id=16, text='%', logprob=-0.0463562, special=False), + (...) + TokenElement(id=25, text='.', logprob=-0.5703125, special=False) + ], + best_of_sequences=None + ) + ) + + # Case 4: iterate over the generated tokens with more details. + # Last object is more complete, containing the full generated text and the finish reason. + >>> for details in client.text_generation("The huggingface_hub library is ", max_new_tokens=12, details=True, stream=True): + ... print(details) + ... + TextGenerationStreamOutput(token=TokenElement(id=1425, text='100', logprob=-1.0175781, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=16, text='%', logprob=-0.0463562, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=1314, text=' open', logprob=-1.3359375, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=3178, text=' source', logprob=-0.28100586, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=273, text=' and', logprob=-0.5961914, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=3426, text=' built', logprob=-1.9423828, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=271, text=' to', logprob=-1.4121094, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=314, text=' be', logprob=-1.5224609, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=1833, text=' easy', logprob=-2.1132812, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=271, text=' to', logprob=-0.08520508, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=745, text=' use', logprob=-0.39453125, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement( + id=25, + text='.', + logprob=-0.5703125, + special=False), + generated_text='100% open source and built to be easy to use.', + details=TextGenerationStreamOutputStreamDetails(finish_reason='length', generated_tokens=12, seed=None) + ) + + # Case 5: generate constrained output using grammar + >>> response = client.text_generation( + ... prompt="I saw a puppy a cat and a raccoon during my bike ride in the park", + ... model="HuggingFaceH4/zephyr-orpo-141b-A35b-v0.1", + ... max_new_tokens=100, + ... repetition_penalty=1.3, + ... grammar={ + ... "type": "json", + ... "value": { + ... "properties": { + ... "location": {"type": "string"}, + ... "activity": {"type": "string"}, + ... "animals_seen": {"type": "integer", "minimum": 1, "maximum": 5}, + ... "animals": {"type": "array", "items": {"type": "string"}}, + ... }, + ... "required": ["location", "activity", "animals_seen", "animals"], + ... }, + ... }, + ... ) + >>> json.loads(response) + { + "activity": "bike riding", + "animals": ["puppy", "cat", "raccoon"], + "animals_seen": 3, + "location": "park" + } + ``` + """ + if decoder_input_details and not details: + warnings.warn( + "`decoder_input_details=True` has been passed to the server but `details=False` is set meaning that" + " the output from the server will be truncated." + ) + decoder_input_details = False + + if stop_sequences is not None: + warnings.warn( + "`stop_sequences` is a deprecated argument for `text_generation` task" + " and will be removed in version '0.28.0'. Use `stop` instead.", + FutureWarning, + ) + if stop is None: + stop = stop_sequences # use deprecated arg if provided + + # Build payload + parameters = { + "adapter_id": adapter_id, + "best_of": best_of, + "decoder_input_details": decoder_input_details, + "details": details, + "do_sample": do_sample, + "frequency_penalty": frequency_penalty, + "grammar": grammar, + "max_new_tokens": max_new_tokens, + "repetition_penalty": repetition_penalty, + "return_full_text": return_full_text, + "seed": seed, + "stop": stop, + "temperature": temperature, + "top_k": top_k, + "top_n_tokens": top_n_tokens, + "top_p": top_p, + "truncate": truncate, + "typical_p": typical_p, + "watermark": watermark, + } + + # Remove some parameters if not a TGI server + unsupported_kwargs = _get_unsupported_text_generation_kwargs(model) + if len(unsupported_kwargs) > 0: + # The server does not support some parameters + # => means it is not a TGI server + # => remove unsupported parameters and warn the user + + ignored_parameters = [] + for key in unsupported_kwargs: + if parameters.get(key): + ignored_parameters.append(key) + parameters.pop(key, None) + if len(ignored_parameters) > 0: + warnings.warn( + "API endpoint/model for text-generation is not served via TGI. Ignoring following parameters:" + f" {', '.join(ignored_parameters)}.", + UserWarning, + ) + if details: + warnings.warn( + "API endpoint/model for text-generation is not served via TGI. Parameter `details=True` will" + " be ignored meaning only the generated text will be returned.", + UserWarning, + ) + details = False + if stream: + raise ValueError( + "API endpoint/model for text-generation is not served via TGI. Cannot return output as a stream." + " Please pass `stream=False` as input." + ) + + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="text-generation", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=prompt, + parameters=parameters, + extra_payload={"stream": stream}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + + # Handle errors separately for more precise error messages + try: + bytes_output = self._inner_post(request_parameters, stream=stream or False) + except HfHubHTTPError as e: + match = MODEL_KWARGS_NOT_USED_REGEX.search(str(e)) + if isinstance(e, BadRequestError) and match: + unused_params = [kwarg.strip("' ") for kwarg in match.group(1).split(",")] + _set_unsupported_text_generation_kwargs(model, unused_params) + return self.text_generation( # type: ignore + prompt=prompt, + details=details, + stream=stream, + model=model_id, + adapter_id=adapter_id, + best_of=best_of, + decoder_input_details=decoder_input_details, + do_sample=do_sample, + frequency_penalty=frequency_penalty, + grammar=grammar, + max_new_tokens=max_new_tokens, + repetition_penalty=repetition_penalty, + return_full_text=return_full_text, + seed=seed, + stop=stop, + temperature=temperature, + top_k=top_k, + top_n_tokens=top_n_tokens, + top_p=top_p, + truncate=truncate, + typical_p=typical_p, + watermark=watermark, + ) + raise_text_generation_error(e) + + # Parse output + if stream: + return _stream_text_generation_response(bytes_output, details) # type: ignore + + data = _bytes_to_dict(bytes_output) # type: ignore + + # Data can be a single element (dict) or an iterable of dicts where we select the first element of. + if isinstance(data, list): + data = data[0] + response = provider_helper.get_response(data, request_parameters) + return TextGenerationOutput.parse_obj_as_instance(response) if details else response["generated_text"] + + def text_to_image( + self, + prompt: str, + *, + negative_prompt: str | None = None, + height: int | None = None, + width: int | None = None, + num_inference_steps: int | None = None, + guidance_scale: float | None = None, + model: str | None = None, + scheduler: str | None = None, + seed: int | None = None, + extra_body: dict[str, Any] | None = None, + ) -> "Image": + """ + Generate an image based on a given text using a specified model. + + > [!WARNING] + > You must have `PIL` installed if you want to work with images (`pip install Pillow`). + + > [!TIP] + > You can pass provider-specific parameters to the model by using the `extra_body` argument. + + Args: + prompt (`str`): + The prompt to generate an image from. + negative_prompt (`str`, *optional*): + One prompt to guide what NOT to include in image generation. + height (`int`, *optional*): + The height in pixels of the output image + width (`int`, *optional*): + The width in pixels of the output image + num_inference_steps (`int`, *optional*): + The number of denoising steps. More denoising steps usually lead to a higher quality image at the + expense of slower inference. + guidance_scale (`float`, *optional*): + A higher guidance scale value encourages the model to generate images closely linked to the text + prompt, but values too high may cause saturation and other artifacts. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. If not provided, the default recommended text-to-image model will be used. + Defaults to None. + scheduler (`str`, *optional*): + Override the scheduler with a compatible one. + seed (`int`, *optional*): + Seed for the random number generator. + extra_body (`dict[str, Any]`, *optional*): + Additional provider-specific parameters to pass to the model. Refer to the provider's documentation + for supported parameters. + + Returns: + `Image`: The generated image. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + + >>> image = client.text_to_image("An astronaut riding a horse on the moon.") + >>> image.save("astronaut.png") + + >>> image = client.text_to_image( + ... "An astronaut riding a horse on the moon.", + ... negative_prompt="low resolution, blurry", + ... model="stabilityai/stable-diffusion-2-1", + ... ) + >>> image.save("better_astronaut.png") + ``` + Example using a third-party provider directly. Usage will be billed on your fal.ai account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="fal-ai", # Use fal.ai provider + ... api_key="fal-ai-api-key", # Pass your fal.ai API key + ... ) + >>> image = client.text_to_image( + ... "A majestic lion in a fantasy forest", + ... model="black-forest-labs/FLUX.1-schnell", + ... ) + >>> image.save("lion.png") + ``` + + Example using a third-party provider through Hugging Face Routing. Usage will be billed on your Hugging Face account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="replicate", # Use replicate provider + ... api_key="hf_...", # Pass your HF token + ... ) + >>> image = client.text_to_image( + ... "An astronaut riding a horse on the moon.", + ... model="black-forest-labs/FLUX.1-dev", + ... ) + >>> image.save("astronaut.png") + ``` + + Example using Replicate provider with extra parameters + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="replicate", # Use replicate provider + ... api_key="hf_...", # Pass your HF token + ... ) + >>> image = client.text_to_image( + ... "An astronaut riding a horse on the moon.", + ... model="black-forest-labs/FLUX.1-schnell", + ... extra_body={"output_quality": 100}, + ... ) + >>> image.save("astronaut.png") + ``` + + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="text-to-image", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=prompt, + parameters={ + "negative_prompt": negative_prompt, + "height": height, + "width": width, + "num_inference_steps": num_inference_steps, + "guidance_scale": guidance_scale, + "scheduler": scheduler, + "seed": seed, + **(extra_body or {}), + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + response = provider_helper.get_response(response, request_parameters) + return _bytes_to_image(response) + + def text_to_video( + self, + prompt: str, + *, + model: str | None = None, + guidance_scale: float | None = None, + negative_prompt: list[str] | None = None, + num_frames: float | None = None, + num_inference_steps: int | None = None, + seed: int | None = None, + extra_body: dict[str, Any] | None = None, + ) -> bytes: + """ + Generate a video based on a given text. + + > [!TIP] + > You can pass provider-specific parameters to the model by using the `extra_body` argument. + + Args: + prompt (`str`): + The prompt to generate a video from. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. If not provided, the default recommended text-to-video model will be used. + Defaults to None. + guidance_scale (`float`, *optional*): + A higher guidance scale value encourages the model to generate videos closely linked to the text + prompt, but values too high may cause saturation and other artifacts. + negative_prompt (`list[str]`, *optional*): + One or several prompt to guide what NOT to include in video generation. + num_frames (`float`, *optional*): + The num_frames parameter determines how many video frames are generated. + num_inference_steps (`int`, *optional*): + The number of denoising steps. More denoising steps usually lead to a higher quality video at the + expense of slower inference. + seed (`int`, *optional*): + Seed for the random number generator. + extra_body (`dict[str, Any]`, *optional*): + Additional provider-specific parameters to pass to the model. Refer to the provider's documentation + for supported parameters. + + Returns: + `bytes`: The generated video. + + Example: + + Example using a third-party provider directly. Usage will be billed on your fal.ai account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="fal-ai", # Using fal.ai provider + ... api_key="fal-ai-api-key", # Pass your fal.ai API key + ... ) + >>> video = client.text_to_video( + ... "A majestic lion running in a fantasy forest", + ... model="tencent/HunyuanVideo", + ... ) + >>> with open("lion.mp4", "wb") as file: + ... file.write(video) + ``` + + Example using a third-party provider through Hugging Face Routing. Usage will be billed on your Hugging Face account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="replicate", # Using replicate provider + ... api_key="hf_...", # Pass your HF token + ... ) + >>> video = client.text_to_video( + ... "A cat running in a park", + ... model="genmo/mochi-1-preview", + ... ) + >>> with open("cat.mp4", "wb") as file: + ... file.write(video) + ``` + + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="text-to-video", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=prompt, + parameters={ + "guidance_scale": guidance_scale, + "negative_prompt": negative_prompt, + "num_frames": num_frames, + "num_inference_steps": num_inference_steps, + "seed": seed, + **(extra_body or {}), + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + response = provider_helper.get_response(response, request_parameters) + return response + + def text_to_speech( + self, + text: str, + *, + model: str | None = None, + do_sample: bool | None = None, + early_stopping: Union[bool, "TextToSpeechEarlyStoppingEnum"] | None = None, + epsilon_cutoff: float | None = None, + eta_cutoff: float | None = None, + max_length: int | None = None, + max_new_tokens: int | None = None, + min_length: int | None = None, + min_new_tokens: int | None = None, + num_beam_groups: int | None = None, + num_beams: int | None = None, + penalty_alpha: float | None = None, + temperature: float | None = None, + top_k: int | None = None, + top_p: float | None = None, + typical_p: float | None = None, + use_cache: bool | None = None, + extra_body: dict[str, Any] | None = None, + ) -> bytes: + """ + Synthesize an audio of a voice pronouncing a given text. + + > [!TIP] + > You can pass provider-specific parameters to the model by using the `extra_body` argument. + + Args: + text (`str`): + The text to synthesize. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. If not provided, the default recommended text-to-speech model will be used. + Defaults to None. + do_sample (`bool`, *optional*): + Whether to use sampling instead of greedy decoding when generating new tokens. + early_stopping (`Union[bool, "TextToSpeechEarlyStoppingEnum"]`, *optional*): + Controls the stopping condition for beam-based methods. + epsilon_cutoff (`float`, *optional*): + If set to float strictly between 0 and 1, only tokens with a conditional probability greater than + epsilon_cutoff will be sampled. In the paper, suggested values range from 3e-4 to 9e-4, depending on + the size of the model. See [Truncation Sampling as Language Model + Desmoothing](https://hf.co/papers/2210.15191) for more details. + eta_cutoff (`float`, *optional*): + Eta sampling is a hybrid of locally typical sampling and epsilon sampling. If set to float strictly + between 0 and 1, a token is only considered if it is greater than either eta_cutoff or sqrt(eta_cutoff) + * exp(-entropy(softmax(next_token_logits))). The latter term is intuitively the expected next token + probability, scaled by sqrt(eta_cutoff). In the paper, suggested values range from 3e-4 to 2e-3, + depending on the size of the model. See [Truncation Sampling as Language Model + Desmoothing](https://hf.co/papers/2210.15191) for more details. + max_length (`int`, *optional*): + The maximum length (in tokens) of the generated text, including the input. + max_new_tokens (`int`, *optional*): + The maximum number of tokens to generate. Takes precedence over max_length. + min_length (`int`, *optional*): + The minimum length (in tokens) of the generated text, including the input. + min_new_tokens (`int`, *optional*): + The minimum number of tokens to generate. Takes precedence over min_length. + num_beam_groups (`int`, *optional*): + Number of groups to divide num_beams into in order to ensure diversity among different groups of beams. + See [this paper](https://hf.co/papers/1610.02424) for more details. + num_beams (`int`, *optional*): + Number of beams to use for beam search. + penalty_alpha (`float`, *optional*): + The value balances the model confidence and the degeneration penalty in contrastive search decoding. + temperature (`float`, *optional*): + The value used to modulate the next token probabilities. + top_k (`int`, *optional*): + The number of highest probability vocabulary tokens to keep for top-k-filtering. + top_p (`float`, *optional*): + If set to float < 1, only the smallest set of most probable tokens with probabilities that add up to + top_p or higher are kept for generation. + typical_p (`float`, *optional*): + Local typicality measures how similar the conditional probability of predicting a target token next is + to the expected conditional probability of predicting a random token next, given the partial text + already generated. If set to float < 1, the smallest set of the most locally typical tokens with + probabilities that add up to typical_p or higher are kept for generation. See [this + paper](https://hf.co/papers/2202.00666) for more details. + use_cache (`bool`, *optional*): + Whether the model should use the past last key/values attentions to speed up decoding + extra_body (`dict[str, Any]`, *optional*): + Additional provider-specific parameters to pass to the model. Refer to the provider's documentation + for supported parameters. + Returns: + `bytes`: The generated audio. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from pathlib import Path + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + + >>> audio = client.text_to_speech("Hello world") + >>> Path("hello_world.flac").write_bytes(audio) + ``` + + Example using a third-party provider directly. Usage will be billed on your Replicate account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="replicate", + ... api_key="your-replicate-api-key", # Pass your Replicate API key directly + ... ) + >>> audio = client.text_to_speech( + ... text="Hello world", + ... model="OuteAI/OuteTTS-0.3-500M", + ... ) + >>> Path("hello_world.flac").write_bytes(audio) + ``` + + Example using a third-party provider through Hugging Face Routing. Usage will be billed on your Hugging Face account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="replicate", + ... api_key="hf_...", # Pass your HF token + ... ) + >>> audio =client.text_to_speech( + ... text="Hello world", + ... model="OuteAI/OuteTTS-0.3-500M", + ... ) + >>> Path("hello_world.flac").write_bytes(audio) + ``` + Example using Replicate provider with extra parameters + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="replicate", # Use replicate provider + ... api_key="hf_...", # Pass your HF token + ... ) + >>> audio = client.text_to_speech( + ... "Hello, my name is Kororo, an awesome text-to-speech model.", + ... model="hexgrad/Kokoro-82M", + ... extra_body={"voice": "af_nicole"}, + ... ) + >>> Path("hello.flac").write_bytes(audio) + ``` + + Example music-gen using "YuE-s1-7B-anneal-en-cot" on fal.ai + ```py + >>> from huggingface_hub import InferenceClient + >>> lyrics = ''' + ... [verse] + ... In the town where I was born + ... Lived a man who sailed to sea + ... And he told us of his life + ... In the land of submarines + ... So we sailed on to the sun + ... 'Til we found a sea of green + ... And we lived beneath the waves + ... In our yellow submarine + + ... [chorus] + ... We all live in a yellow submarine + ... Yellow submarine, yellow submarine + ... We all live in a yellow submarine + ... Yellow submarine, yellow submarine + ... ''' + >>> genres = "pavarotti-style tenor voice" + >>> client = InferenceClient( + ... provider="fal-ai", + ... model="m-a-p/YuE-s1-7B-anneal-en-cot", + ... api_key=..., + ... ) + >>> audio = client.text_to_speech(lyrics, extra_body={"genres": genres}) + >>> with open("output.mp3", "wb") as f: + ... f.write(audio) + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="text-to-speech", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters={ + "do_sample": do_sample, + "early_stopping": early_stopping, + "epsilon_cutoff": epsilon_cutoff, + "eta_cutoff": eta_cutoff, + "max_length": max_length, + "max_new_tokens": max_new_tokens, + "min_length": min_length, + "min_new_tokens": min_new_tokens, + "num_beam_groups": num_beam_groups, + "num_beams": num_beams, + "penalty_alpha": penalty_alpha, + "temperature": temperature, + "top_k": top_k, + "top_p": top_p, + "typical_p": typical_p, + "use_cache": use_cache, + **(extra_body or {}), + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + response = provider_helper.get_response(response) + return response + + def token_classification( + self, + text: str, + *, + model: str | None = None, + aggregation_strategy: Optional["TokenClassificationAggregationStrategy"] = None, + ignore_labels: list[str] | None = None, + stride: int | None = None, + ) -> list[TokenClassificationOutputElement]: + """ + Perform token classification on the given text. + Usually used for sentence parsing, either grammatical, or Named Entity Recognition (NER) to understand keywords contained within text. + + Args: + text (`str`): + A string to be classified. + model (`str`, *optional*): + The model to use for the token classification task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended token classification model will be used. + Defaults to None. + aggregation_strategy (`"TokenClassificationAggregationStrategy"`, *optional*): + The strategy used to fuse tokens based on model predictions + ignore_labels (`list[str`, *optional*): + A list of labels to ignore + stride (`int`, *optional*): + The number of overlapping tokens between chunks when splitting the input text. + + Returns: + `list[TokenClassificationOutputElement]`: List of [`TokenClassificationOutputElement`] items containing the entity group, confidence score, word, start and end index. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.token_classification("My name is Sarah Jessica Parker but you can call me Jessica") + [ + TokenClassificationOutputElement( + entity_group='PER', + score=0.9971321225166321, + word='Sarah Jessica Parker', + start=11, + end=31, + ), + TokenClassificationOutputElement( + entity_group='PER', + score=0.9773476123809814, + word='Jessica', + start=52, + end=59, + ) + ] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="token-classification", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters={ + "aggregation_strategy": aggregation_strategy, + "ignore_labels": ignore_labels, + "stride": stride, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + return TokenClassificationOutputElement.parse_obj_as_list(response) + + def translation( + self, + text: str, + *, + model: str | None = None, + src_lang: str | None = None, + tgt_lang: str | None = None, + clean_up_tokenization_spaces: bool | None = None, + truncation: Optional["TranslationTruncationStrategy"] = None, + generate_parameters: dict[str, Any] | None = None, + ) -> TranslationOutput: + """ + Convert text from one language to another. + + Check out https://huggingface.co/tasks/translation for more information on how to choose the best model for + your specific use case. Source and target languages usually depend on the model. + However, it is possible to specify source and target languages for certain models. If you are working with one of these models, + you can use `src_lang` and `tgt_lang` arguments to pass the relevant information. + + Args: + text (`str`): + A string to be translated. + model (`str`, *optional*): + The model to use for the translation task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended translation model will be used. + Defaults to None. + src_lang (`str`, *optional*): + The source language of the text. Required for models that can translate from multiple languages. + tgt_lang (`str`, *optional*): + Target language to translate to. Required for models that can translate to multiple languages. + clean_up_tokenization_spaces (`bool`, *optional*): + Whether to clean up the potential extra spaces in the text output. + truncation (`"TranslationTruncationStrategy"`, *optional*): + The truncation strategy to use. + generate_parameters (`dict[str, Any]`, *optional*): + Additional parametrization of the text generation algorithm. + + Returns: + [`TranslationOutput`]: The generated translated text. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + `ValueError`: + If only one of the `src_lang` and `tgt_lang` arguments are provided. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.translation("My name is Wolfgang and I live in Berlin") + 'Mein Name ist Wolfgang und ich lebe in Berlin.' + >>> client.translation("My name is Wolfgang and I live in Berlin", model="Helsinki-NLP/opus-mt-en-fr") + TranslationOutput(translation_text='Je m'appelle Wolfgang et je vis à Berlin.') + ``` + + Specifying languages: + ```py + >>> client.translation("My name is Sarah Jessica Parker but you can call me Jessica", model="facebook/mbart-large-50-many-to-many-mmt", src_lang="en_XX", tgt_lang="fr_XX") + "Mon nom est Sarah Jessica Parker mais vous pouvez m'appeler Jessica" + ``` + """ + # Throw error if only one of `src_lang` and `tgt_lang` was given + if src_lang is not None and tgt_lang is None: + raise ValueError("You cannot specify `src_lang` without specifying `tgt_lang`.") + + if src_lang is None and tgt_lang is not None: + raise ValueError("You cannot specify `tgt_lang` without specifying `src_lang`.") + + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="translation", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters={ + "src_lang": src_lang, + "tgt_lang": tgt_lang, + "clean_up_tokenization_spaces": clean_up_tokenization_spaces, + "truncation": truncation, + "generate_parameters": generate_parameters, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + return TranslationOutput.parse_obj_as_list(response)[0] + + def visual_question_answering( + self, + image: ContentT, + question: str, + *, + model: str | None = None, + top_k: int | None = None, + ) -> list[VisualQuestionAnsweringOutputElement]: + """ + Answering open-ended questions based on an image. + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The input image for the context. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + question (`str`): + Question to be answered. + model (`str`, *optional*): + The model to use for the visual question answering task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended visual question answering model will be used. + Defaults to None. + top_k (`int`, *optional*): + The number of answers to return (will be chosen by order of likelihood). Note that we return less than + topk answers if there are not enough options available within the context. + Returns: + `list[VisualQuestionAnsweringOutputElement]`: a list of [`VisualQuestionAnsweringOutputElement`] items containing the predicted label and associated probability. + + Raises: + `InferenceTimeoutError`: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.visual_question_answering( + ... image="https://huggingface.co/datasets/mishig/sample_images/resolve/main/tiger.jpg", + ... question="What is the animal doing?" + ... ) + [ + VisualQuestionAnsweringOutputElement(score=0.778609573841095, answer='laying down'), + VisualQuestionAnsweringOutputElement(score=0.6957435607910156, answer='sitting'), + ] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="visual-question-answering", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={"top_k": top_k}, + headers=self.headers, + model=model_id, + api_key=self.token, + extra_payload={"question": question, "image": _b64_encode(image)}, + ) + response = self._inner_post(request_parameters) + return VisualQuestionAnsweringOutputElement.parse_obj_as_list(response) + + def zero_shot_classification( + self, + text: str, + candidate_labels: list[str], + *, + multi_label: bool | None = False, + hypothesis_template: str | None = None, + model: str | None = None, + ) -> list[ZeroShotClassificationOutputElement]: + """ + Provide as input a text and a set of candidate labels to classify the input text. + + Args: + text (`str`): + The input text to classify. + candidate_labels (`list[str]`): + The set of possible class labels to classify the text into. + labels (`list[str]`, *optional*): + (deprecated) List of strings. Each string is the verbalization of a possible label for the input text. + multi_label (`bool`, *optional*): + Whether multiple candidate labels can be true. If false, the scores are normalized such that the sum of + the label likelihoods for each sequence is 1. If true, the labels are considered independent and + probabilities are normalized for each candidate. + hypothesis_template (`str`, *optional*): + The sentence used in conjunction with `candidate_labels` to attempt the text classification by + replacing the placeholder with the candidate labels. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. This parameter overrides the model defined at the instance level. If not provided, the default recommended zero-shot classification model will be used. + + + Returns: + `list[ZeroShotClassificationOutputElement]`: List of [`ZeroShotClassificationOutputElement`] items containing the predicted labels and their confidence. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example with `multi_label=False`: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> text = ( + ... "A new model offers an explanation for how the Galilean satellites formed around the solar system's" + ... "largest world. Konstantin Batygin did not set out to solve one of the solar system's most puzzling" + ... " mysteries when he went for a run up a hill in Nice, France." + ... ) + >>> labels = ["space & cosmos", "scientific discovery", "microbiology", "robots", "archeology"] + >>> client.zero_shot_classification(text, labels) + [ + ZeroShotClassificationOutputElement(label='scientific discovery', score=0.7961668968200684), + ZeroShotClassificationOutputElement(label='space & cosmos', score=0.18570658564567566), + ZeroShotClassificationOutputElement(label='microbiology', score=0.00730885099619627), + ZeroShotClassificationOutputElement(label='archeology', score=0.006258360575884581), + ZeroShotClassificationOutputElement(label='robots', score=0.004559356719255447), + ] + >>> client.zero_shot_classification(text, labels, multi_label=True) + [ + ZeroShotClassificationOutputElement(label='scientific discovery', score=0.9829297661781311), + ZeroShotClassificationOutputElement(label='space & cosmos', score=0.755190908908844), + ZeroShotClassificationOutputElement(label='microbiology', score=0.0005462635890580714), + ZeroShotClassificationOutputElement(label='archeology', score=0.00047131875180639327), + ZeroShotClassificationOutputElement(label='robots', score=0.00030448526376858354), + ] + ``` + + Example with `multi_label=True` and a custom `hypothesis_template`: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + >>> client.zero_shot_classification( + ... text="I really like our dinner and I'm very happy. I don't like the weather though.", + ... labels=["positive", "negative", "pessimistic", "optimistic"], + ... multi_label=True, + ... hypothesis_template="This text is {} towards the weather" + ... ) + [ + ZeroShotClassificationOutputElement(label='negative', score=0.9231801629066467), + ZeroShotClassificationOutputElement(label='pessimistic', score=0.8760990500450134), + ZeroShotClassificationOutputElement(label='optimistic', score=0.0008674879791215062), + ZeroShotClassificationOutputElement(label='positive', score=0.0005250611575320363) + ] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="zero-shot-classification", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters={ + "candidate_labels": candidate_labels, + "multi_label": multi_label, + "hypothesis_template": hypothesis_template, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + output = _bytes_to_dict(response) + return ZeroShotClassificationOutputElement.parse_obj_as_list(output) + + def zero_shot_image_classification( + self, + image: ContentT, + candidate_labels: list[str], + *, + model: str | None = None, + hypothesis_template: str | None = None, + # deprecated argument + labels: list[str] = None, # type: ignore + ) -> list[ZeroShotImageClassificationOutputElement]: + """ + Provide input image and text labels to predict text labels for the image. + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The input image to caption. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + candidate_labels (`list[str]`): + The candidate labels for this image + labels (`list[str]`, *optional*): + (deprecated) List of string possible labels. There must be at least 2 labels. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. This parameter overrides the model defined at the instance level. If not provided, the default recommended zero-shot image classification model will be used. + hypothesis_template (`str`, *optional*): + The sentence used in conjunction with `candidate_labels` to attempt the image classification by + replacing the placeholder with the candidate labels. + + Returns: + `list[ZeroShotImageClassificationOutputElement]`: List of [`ZeroShotImageClassificationOutputElement`] items containing the predicted labels and their confidence. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient() + + >>> client.zero_shot_image_classification( + ... "https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Cute_dog.jpg/320px-Cute_dog.jpg", + ... labels=["dog", "cat", "horse"], + ... ) + [ZeroShotImageClassificationOutputElement(label='dog', score=0.956),...] + ``` + """ + # Raise ValueError if input is less than 2 labels + if len(candidate_labels) < 2: + raise ValueError("You must specify at least 2 classes to compare.") + + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="zero-shot-image-classification", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={ + "candidate_labels": candidate_labels, + "hypothesis_template": hypothesis_template, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = self._inner_post(request_parameters) + return ZeroShotImageClassificationOutputElement.parse_obj_as_list(response) + + def get_endpoint_info(self, *, model: str | None = None) -> dict[str, Any]: + """ + Get information about the deployed endpoint. + + This endpoint is only available on endpoints powered by Text-Generation-Inference (TGI) or Text-Embedding-Inference (TEI). + Endpoints powered by `transformers` return an empty payload. + + Args: + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. This parameter overrides the model defined at the instance level. Defaults to None. + + Returns: + `dict[str, Any]`: Information about the endpoint. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient("meta-llama/Meta-Llama-3-70B-Instruct") + >>> client.get_endpoint_info() + { + 'model_id': 'meta-llama/Meta-Llama-3-70B-Instruct', + 'model_sha': None, + 'model_dtype': 'torch.float16', + 'model_device_type': 'cuda', + 'model_pipeline_tag': None, + 'max_concurrent_requests': 128, + 'max_best_of': 2, + 'max_stop_sequences': 4, + 'max_input_length': 8191, + 'max_total_tokens': 8192, + 'waiting_served_ratio': 0.3, + 'max_batch_total_tokens': 1259392, + 'max_waiting_tokens': 20, + 'max_batch_size': None, + 'validation_workers': 32, + 'max_client_batch_size': 4, + 'version': '2.0.2', + 'sha': 'dccab72549635c7eb5ddb17f43f0b7cdff07c214', + 'docker_label': 'sha-dccab72' + } + ``` + """ + if self.provider != "hf-inference": + raise ValueError(f"Getting endpoint info is not supported on '{self.provider}'.") + + model = model or self.model + if model is None: + raise ValueError("Model id not provided.") + if model.startswith(("http://", "https://")): + url = model.rstrip("/") + "/info" + else: + url = f"{constants.INFERENCE_ENDPOINT}/models/{model}/info" + + response = get_session().get(url, headers=build_hf_headers(token=self.token)) + hf_raise_for_status(response) + return response.json() + + def health_check(self, model: str | None = None) -> bool: + """ + Check the health of the deployed endpoint. + + Health check is only available with Inference Endpoints powered by Text-Generation-Inference (TGI) or Text-Embedding-Inference (TEI). + + Args: + model (`str`, *optional*): + URL of the Inference Endpoint. This parameter overrides the model defined at the instance level. Defaults to None. + + Returns: + `bool`: True if everything is working fine. + + Example: + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient("https://jzgu0buei5.us-east-1.aws.endpoints.huggingface.cloud") + >>> client.health_check() + True + ``` + """ + if self.provider != "hf-inference": + raise ValueError(f"Health check is not supported on '{self.provider}'.") + + model = model or self.model + if model is None: + raise ValueError("Model id not provided.") + if not model.startswith(("http://", "https://")): + raise ValueError("Model must be an Inference Endpoint URL.") + url = model.rstrip("/") + "/health" + + response = get_session().get(url, headers=build_hf_headers(token=self.token)) + return response.status_code == 200 + + @property + def chat(self) -> "ProxyClientChat": + return ProxyClientChat(self) + + +class _ProxyClient: + """Proxy class to be able to call `client.chat.completion.create(...)` as OpenAI client.""" + + def __init__(self, client: InferenceClient): + self._client = client + + +class ProxyClientChat(_ProxyClient): + """Proxy class to be able to call `client.chat.completion.create(...)` as OpenAI client.""" + + @property + def completions(self) -> "ProxyClientChatCompletions": + return ProxyClientChatCompletions(self._client) + + +class ProxyClientChatCompletions(_ProxyClient): + """Proxy class to be able to call `client.chat.completion.create(...)` as OpenAI client.""" + + @property + def create(self): + return self._client.chat_completion diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_common.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_common.py new file mode 100644 index 0000000000000000000000000000000000000000..1c3bdc60610ba80cf0db1140ab88b83e6b20253f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_common.py @@ -0,0 +1,432 @@ +# Copyright 2023-present, the HuggingFace Inc. team. +# +# 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. +"""Contains utilities used by both the sync and async inference clients.""" + +import base64 +import io +import json +import logging +import mimetypes +from collections.abc import AsyncIterable, Iterable +from dataclasses import dataclass +from pathlib import Path +from typing import TYPE_CHECKING, Any, BinaryIO, Literal, NoReturn, Union, overload + +import httpx + +from huggingface_hub.errors import ( + GenerationError, + HfHubHTTPError, + IncompleteGenerationError, + OverloadedError, + TextGenerationError, + UnknownError, + ValidationError, +) + +from ..utils import get_session, is_numpy_available, is_pillow_available +from ._generated.types import ChatCompletionStreamOutput, TextGenerationStreamOutput + + +if TYPE_CHECKING: + from PIL.Image import Image + +# TYPES +UrlT = str +PathT = Union[str, Path] +ContentT = Union[bytes, BinaryIO, PathT, UrlT, "Image", bytearray, memoryview] + +# Use to set an Accept: image/png header +TASKS_EXPECTING_IMAGES = {"text-to-image", "image-to-image"} + +logger = logging.getLogger(__name__) + + +@dataclass +class RequestParameters: + url: str + task: str + model: str | None + json: str | dict | list | None + data: bytes | None + headers: dict[str, Any] + + +class MimeBytes(bytes): + """ + A bytes object with a mime type. + To be returned by `_prepare_payload_open_as_mime_bytes` in subclasses. + + Example: + ```python + >>> b = MimeBytes(b"hello", "text/plain") + >>> isinstance(b, bytes) + True + >>> b.mime_type + 'text/plain' + ``` + """ + + mime_type: str | None + + def __new__(cls, data: bytes, mime_type: str | None = None): + obj = super().__new__(cls, data) + obj.mime_type = mime_type + if isinstance(data, MimeBytes) and mime_type is None: + obj.mime_type = data.mime_type + return obj + + +## IMPORT UTILS + + +def _import_numpy(): + """Make sure `numpy` is installed on the machine.""" + if not is_numpy_available(): + raise ImportError("Please install numpy to use deal with embeddings (`pip install numpy`).") + import numpy + + return numpy + + +def _import_pil_image(): + """Make sure `PIL` is installed on the machine.""" + if not is_pillow_available(): + raise ImportError( + "Please install Pillow to use deal with images (`pip install Pillow`). If you don't want the image to be" + " post-processed, use `client.post(...)` and get the raw response from the server." + ) + from PIL import Image + + return Image + + +## ENCODING / DECODING UTILS + + +@overload +def _open_as_mime_bytes(content: ContentT) -> MimeBytes: ... # means "if input is not None, output is not None" + + +@overload +def _open_as_mime_bytes(content: Literal[None]) -> Literal[None]: ... # means "if input is None, output is None" + + +def _open_as_mime_bytes(content: ContentT | None) -> MimeBytes | None: + """Open `content` as a binary file, either from a URL, a local path, raw bytes, or a PIL Image. + + Do nothing if `content` is None. + """ + # If content is None, yield None + if content is None: + return None + + # If content is bytes, return it + if isinstance(content, bytes): + return MimeBytes(content) + + # If content is raw binary data (bytearray, memoryview) + if isinstance(content, (bytearray, memoryview)): + return MimeBytes(bytes(content)) + + # If content is a binary file-like object + if hasattr(content, "read"): # duck-typing instead of isinstance(content, BinaryIO) + logger.debug("Reading content from BinaryIO") + data = content.read() + mime_type = mimetypes.guess_type(str(content.name))[0] if hasattr(content, "name") else None + if isinstance(data, str): + raise TypeError("Expected binary stream (bytes), but got text stream") + return MimeBytes(data, mime_type=mime_type) + + # If content is a string => must be either a URL or a path + if isinstance(content, str): + if content.startswith("https://") or content.startswith("http://"): + logger.debug(f"Downloading content from {content}") + response = get_session().get(content) + mime_type = response.headers.get("Content-Type") + if mime_type is None: + mime_type = mimetypes.guess_type(content)[0] + return MimeBytes(response.content, mime_type=mime_type) + + content = Path(content) + if not content.exists(): + raise FileNotFoundError( + f"File not found at {content}. If `data` is a string, it must either be a URL or a path to a local" + " file. To pass raw content, please encode it as bytes first." + ) + + # If content is a Path => open it + if isinstance(content, Path): + logger.debug(f"Opening content from {content}") + return MimeBytes(content.read_bytes(), mime_type=mimetypes.guess_type(content)[0]) + + # If content is a PIL Image => convert to bytes + if is_pillow_available(): + from PIL import Image + + if isinstance(content, Image.Image): + logger.debug("Converting PIL Image to bytes") + buffer = io.BytesIO() + format = content.format or "PNG" + content.save(buffer, format=format) + return MimeBytes(buffer.getvalue(), mime_type=f"image/{format.lower()}") + + # If nothing matched, raise error + raise TypeError( + f"Unsupported content type: {type(content)}. " + "Expected one of: bytes, bytearray, BinaryIO, memoryview, Path, str (URL or file path), or PIL.Image.Image." + ) + + +def _b64_encode(content: ContentT) -> str: + """Encode a raw file (image, audio) into base64. Can be bytes, an opened file, a path or a URL.""" + raw_bytes = _open_as_mime_bytes(content) + return base64.b64encode(raw_bytes).decode() + + +def _as_url(content: ContentT, default_mime_type: str) -> str: + if isinstance(content, str) and content.startswith(("http://", "https://", "data:")): + return content + + # Convert content to bytes + raw_bytes = _open_as_mime_bytes(content) + + # Get MIME type + mime_type = raw_bytes.mime_type or default_mime_type + + # Encode content to base64 + encoded_data = base64.b64encode(raw_bytes).decode() + + # Build data URL + return f"data:{mime_type};base64,{encoded_data}" + + +def _b64_to_image(encoded_image: str) -> "Image": + """Parse a base64-encoded string into a PIL Image.""" + Image = _import_pil_image() + return Image.open(io.BytesIO(base64.b64decode(encoded_image))) + + +def _bytes_to_list(content: bytes) -> list: + """Parse bytes from a Response object into a Python list. + + Expects the response body to be JSON-encoded data. + + NOTE: This is exactly the same implementation as `_bytes_to_dict` and will not complain if the returned data is a + dictionary. The only advantage of having both is to help the user (and mypy) understand what kind of data to expect. + """ + return json.loads(content.decode()) + + +def _bytes_to_dict(content: bytes) -> dict: + """Parse bytes from a Response object into a Python dictionary. + + Expects the response body to be JSON-encoded data. + + NOTE: This is exactly the same implementation as `_bytes_to_list` and will not complain if the returned data is a + list. The only advantage of having both is to help the user (and mypy) understand what kind of data to expect. + """ + return json.loads(content.decode()) + + +def _bytes_to_image(content: bytes) -> "Image": + """Parse bytes from a Response object into a PIL Image. + + Expects the response body to be raw bytes. To deal with b64 encoded images, use `_b64_to_image` instead. + """ + Image = _import_pil_image() + return Image.open(io.BytesIO(content)) + + +def _as_dict(response: bytes | dict) -> dict: + return json.loads(response) if isinstance(response, bytes) else response + + +## STREAMING UTILS + + +def _stream_text_generation_response( + output_lines: Iterable[str], details: bool +) -> Iterable[str] | Iterable[TextGenerationStreamOutput]: + """Used in `InferenceClient.text_generation`.""" + # Parse ServerSentEvents + for line in output_lines: + try: + output = _format_text_generation_stream_output(line, details) + except StopIteration: + break + if output is not None: + yield output + + +async def _async_stream_text_generation_response( + output_lines: AsyncIterable[str], details: bool +) -> AsyncIterable[str] | AsyncIterable[TextGenerationStreamOutput]: + """Used in `AsyncInferenceClient.text_generation`.""" + # Parse ServerSentEvents + async for line in output_lines: + try: + output = _format_text_generation_stream_output(line, details) + except StopIteration: + break + if output is not None: + yield output + + +def _format_text_generation_stream_output(line: str, details: bool) -> str | TextGenerationStreamOutput | None: + if not line.startswith("data:"): + return None # empty line + + if line.strip() == "data: [DONE]": + raise StopIteration("[DONE] signal received.") + + # Decode payload + payload = line.lstrip("data:").rstrip("/n") + json_payload = json.loads(payload) + + # Either an error as being returned + if json_payload.get("error") is not None: + raise _parse_text_generation_error(json_payload["error"], json_payload.get("error_type")) + + # Or parse token payload + output = TextGenerationStreamOutput.parse_obj_as_instance(json_payload) + return output.token.text if not details else output + + +def _stream_chat_completion_response( + lines: Iterable[str], +) -> Iterable[ChatCompletionStreamOutput]: + """Used in `InferenceClient.chat_completion` if model is served with TGI.""" + for line in lines: + try: + output = _format_chat_completion_stream_output(line) + except StopIteration: + break + if output is not None: + yield output + + +async def _async_stream_chat_completion_response( + lines: AsyncIterable[str], +) -> AsyncIterable[ChatCompletionStreamOutput]: + """Used in `AsyncInferenceClient.chat_completion`.""" + async for line in lines: + try: + output = _format_chat_completion_stream_output(line) + except StopIteration: + break + if output is not None: + yield output + + +def _format_chat_completion_stream_output( + line: str, +) -> ChatCompletionStreamOutput | None: + if not line.startswith("data:"): + return None # empty line + + if line.strip() == "data: [DONE]": + raise StopIteration("[DONE] signal received.") + + # Decode payload + json_payload = json.loads(line.lstrip("data:").strip()) + + # Either an error as being returned + if json_payload.get("error") is not None: + raise _parse_text_generation_error(json_payload["error"], json_payload.get("error_type")) + + # Or parse token payload + return ChatCompletionStreamOutput.parse_obj_as_instance(json_payload) + + +async def _async_yield_from(client: httpx.AsyncClient, response: httpx.Response) -> AsyncIterable[str]: + async for line in response.aiter_lines(): + yield line.strip() + + +# "TGI servers" are servers running with the `text-generation-inference` backend. +# This backend is the go-to solution to run large language models at scale. However, +# for some smaller models (e.g. "gpt2") the default `transformers` + `api-inference` +# solution is still in use. +# +# Both approaches have very similar APIs, but not exactly the same. What we do first in +# the `text_generation` method is to assume the model is served via TGI. If we realize +# it's not the case (i.e. we receive an HTTP 400 Bad Request), we fall back to the +# default API with a warning message. When that's the case, We remember the unsupported +# attributes for this model in the `_UNSUPPORTED_TEXT_GENERATION_KWARGS` global variable. +# +# In addition, TGI servers have a built-in API route for chat-completion, which is not +# available on the default API. We use this route to provide a more consistent behavior +# when available. +# +# For more details, see https://github.com/huggingface/text-generation-inference and +# https://huggingface.co/docs/api-inference/detailed_parameters#text-generation-task. + +_UNSUPPORTED_TEXT_GENERATION_KWARGS: dict[str | None, list[str]] = {} + + +def _set_unsupported_text_generation_kwargs(model: str | None, unsupported_kwargs: list[str]) -> None: + _UNSUPPORTED_TEXT_GENERATION_KWARGS.setdefault(model, []).extend(unsupported_kwargs) + + +def _get_unsupported_text_generation_kwargs(model: str | None) -> list[str]: + return _UNSUPPORTED_TEXT_GENERATION_KWARGS.get(model, []) + + +# TEXT GENERATION ERRORS +# ---------------------- +# Text-generation errors are parsed separately to handle as much as possible the errors returned by the text generation +# inference project (https://github.com/huggingface/text-generation-inference). +# ---------------------- + + +def raise_text_generation_error(http_error: HfHubHTTPError) -> NoReturn: + """ + Try to parse text-generation-inference error message and raise HTTPError in any case. + + Args: + error (`HTTPError`): + The HTTPError that have been raised. + """ + # Try to parse a Text Generation Inference error + if http_error.response is None: + raise http_error + + try: + # Hacky way to retrieve payload in case of aiohttp error + payload = getattr(http_error, "response_error_payload", None) or http_error.response.json() + error = payload.get("error") + error_type = payload.get("error_type") + except Exception: # no payload + raise http_error + + # If error_type => more information than `hf_raise_for_status` + if error_type is not None: + exception = _parse_text_generation_error(error, error_type) + raise exception from http_error + + # Otherwise, fallback to default error + raise http_error + + +def _parse_text_generation_error(error: str | None, error_type: str | None) -> TextGenerationError: + if error_type == "generation": + return GenerationError(error) # type: ignore + if error_type == "incomplete_generation": + return IncompleteGenerationError(error) # type: ignore + if error_type == "overloaded": + return OverloadedError(error) # type: ignore + if error_type == "validation": + return ValidationError(error) # type: ignore + return UnknownError(error) # type: ignore diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/__init__.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/_async_client.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/_async_client.py new file mode 100644 index 0000000000000000000000000000000000000000..5bdcb6746da371feb4bc189bca13cee8105c0423 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/_async_client.py @@ -0,0 +1,3452 @@ +# Copyright 2023-present, the HuggingFace Inc. team. +# +# 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. +# +# WARNING +# This entire file has been adapted from the sync-client code in `src/huggingface_hub/inference/_client.py`. +# Any change in InferenceClient will be automatically reflected in AsyncInferenceClient. +# To re-generate the code, run `make style` or `python ./utils/generate_async_inference_client.py --update`. +# WARNING +import asyncio +import base64 +import logging +import os +import re +import warnings +from contextlib import AsyncExitStack +from typing import TYPE_CHECKING, Any, AsyncIterable, Literal, Optional, Union, overload + +import httpx + +from huggingface_hub import constants +from huggingface_hub.errors import BadRequestError, HfHubHTTPError, InferenceTimeoutError +from huggingface_hub.inference._common import ( + TASKS_EXPECTING_IMAGES, + ContentT, + RequestParameters, + _async_stream_chat_completion_response, + _async_stream_text_generation_response, + _b64_encode, + _b64_to_image, + _bytes_to_dict, + _bytes_to_image, + _bytes_to_list, + _get_unsupported_text_generation_kwargs, + _import_numpy, + _set_unsupported_text_generation_kwargs, + raise_text_generation_error, +) +from huggingface_hub.inference._generated.types import ( + AudioClassificationOutputElement, + AudioClassificationOutputTransform, + AudioToAudioOutputElement, + AutomaticSpeechRecognitionOutput, + ChatCompletionInputGrammarType, + ChatCompletionInputMessage, + ChatCompletionInputStreamOptions, + ChatCompletionInputTool, + ChatCompletionInputToolChoiceClass, + ChatCompletionInputToolChoiceEnum, + ChatCompletionOutput, + ChatCompletionStreamOutput, + DocumentQuestionAnsweringOutputElement, + FillMaskOutputElement, + ImageClassificationOutputElement, + ImageClassificationOutputTransform, + ImageSegmentationOutputElement, + ImageSegmentationSubtask, + ImageToImageTargetSize, + ImageToTextOutput, + ImageToVideoTargetSize, + ObjectDetectionOutputElement, + Padding, + QuestionAnsweringOutputElement, + SummarizationOutput, + SummarizationTruncationStrategy, + TableQuestionAnsweringOutputElement, + TextClassificationOutputElement, + TextClassificationOutputTransform, + TextGenerationInputGrammarType, + TextGenerationOutput, + TextGenerationStreamOutput, + TextToSpeechEarlyStoppingEnum, + TokenClassificationAggregationStrategy, + TokenClassificationOutputElement, + TranslationOutput, + TranslationTruncationStrategy, + VisualQuestionAnsweringOutputElement, + ZeroShotClassificationOutputElement, + ZeroShotImageClassificationOutputElement, +) +from huggingface_hub.inference._providers import PROVIDER_OR_POLICY_T, get_provider_helper +from huggingface_hub.utils import ( + build_hf_headers, + get_async_session, + hf_raise_for_status, + validate_hf_hub_args, +) +from huggingface_hub.utils._auth import get_token + +from .._common import _async_yield_from + + +if TYPE_CHECKING: + import numpy as np + from PIL.Image import Image + +logger = logging.getLogger(__name__) + + +MODEL_KWARGS_NOT_USED_REGEX = re.compile(r"The following `model_kwargs` are not used by the model: \[(.*?)\]") + + +class AsyncInferenceClient: + """ + Initialize a new Inference Client. + + [`InferenceClient`] aims to provide a unified experience to perform inference. The client can be used + seamlessly with either the (free) Inference API, self-hosted Inference Endpoints, or third-party Inference Providers. + + Args: + model (`str`, `optional`): + The model to run inference with. Can be a model id hosted on the Hugging Face Hub, e.g. `meta-llama/Meta-Llama-3-8B-Instruct` + or a URL to a deployed Inference Endpoint. Defaults to None, in which case a recommended model is + automatically selected for the task. + Note: for better compatibility with OpenAI's client, `model` has been aliased as `base_url`. Those 2 + arguments are mutually exclusive. If a URL is passed as `model` or `base_url` for chat completion, the `(/v1)/chat/completions` suffix path will be appended to the URL. + provider (`str`, *optional*): + Name of the provider to use for inference. Can be `"cerebras"`, `"cohere"`, `"deepinfra"`, `"fal-ai"`, `"featherless-ai"`, `"fireworks-ai"`, `"groq"`, `"hf-inference"`, `"novita"`, `"nscale"`, `"openai"`, `"ovhcloud"`, `"publicai"`, `"replicate"`, `"scaleway"`, `"together"`, `"wavespeed"` or `"zai-org"`. + Defaults to "auto": automatic routing, which defaults to "fastest" provider; you can + switch to "cheapest" or "preferred" provider order at https://hf.co/settings/inference-providers. + If model is a URL or `base_url` is passed, then `provider` is not used. + token (`str`, *optional*): + Hugging Face token. Will default to the locally saved token if not provided. + Note: for better compatibility with OpenAI's client, `token` has been aliased as `api_key`. Those 2 + arguments are mutually exclusive and have the exact same behavior. + timeout (`float`, `optional`): + The maximum number of seconds to wait for a response from the server. Defaults to None, meaning it will loop until the server is available. + headers (`dict[str, str]`, `optional`): + Additional headers to send to the server. By default only the authorization and user-agent headers are sent. + Values in this dictionary will override the default values. + bill_to (`str`, `optional`): + The billing account to use for the requests. By default the requests are billed on the user's account. + Requests can only be billed to an organization the user is a member of, and which has subscribed to Enterprise Hub. + cookies (`dict[str, str]`, `optional`): + Additional cookies to send to the server. + base_url (`str`, `optional`): + Base URL to run inference. This is a duplicated argument from `model` to make [`InferenceClient`] + follow the same pattern as `openai.OpenAI` client. Cannot be used if `model` is set. Defaults to None. + api_key (`str`, `optional`): + Token to use for authentication. This is a duplicated argument from `token` to make [`InferenceClient`] + follow the same pattern as `openai.OpenAI` client. Cannot be used if `token` is set. Defaults to None. + """ + + provider: PROVIDER_OR_POLICY_T | None + + @validate_hf_hub_args + def __init__( + self, + model: str | None = None, + *, + provider: PROVIDER_OR_POLICY_T | None = None, + token: str | None = None, + timeout: float | None = None, + headers: dict[str, str] | None = None, + cookies: dict[str, str] | None = None, + bill_to: str | None = None, + # OpenAI compatibility + base_url: str | None = None, + api_key: str | None = None, + ) -> None: + if model is not None and base_url is not None: + raise ValueError( + "Received both `model` and `base_url` arguments. Please provide only one of them." + " `base_url` is an alias for `model` to make the API compatible with OpenAI's client." + " If using `base_url` for chat completion, the `/chat/completions` suffix path will be appended to the base url." + " When passing a URL as `model`, the client will not append any suffix path to it." + ) + if token is not None and api_key is not None: + raise ValueError( + "Received both `token` and `api_key` arguments. Please provide only one of them." + " `api_key` is an alias for `token` to make the API compatible with OpenAI's client." + " It has the exact same behavior as `token`." + ) + token = token if token is not None else api_key + if isinstance(token, bool): + # Legacy behavior: previously it was possible to pass `token=False` to disable authentication. This is not + # supported anymore as authentication is required. Better to explicitly raise here rather than risking + # sending the locally saved token without the user knowing about it. + if token is False: + raise ValueError( + "Cannot use `token=False` to disable authentication as authentication is required to run Inference." + ) + warnings.warn( + "Using `token=True` to automatically use the locally saved token is deprecated and will be removed in a future release. " + "Please use `token=None` instead (default).", + DeprecationWarning, + ) + token = get_token() + + self.model: str | None = base_url or model + self.token: str | None = token + + self.headers = {**headers} if headers is not None else {} + if bill_to is not None: + if ( + constants.HUGGINGFACE_HEADER_X_BILL_TO in self.headers + and self.headers[constants.HUGGINGFACE_HEADER_X_BILL_TO] != bill_to + ): + warnings.warn( + f"Overriding existing '{self.headers[constants.HUGGINGFACE_HEADER_X_BILL_TO]}' value in headers with '{bill_to}'.", + UserWarning, + ) + self.headers[constants.HUGGINGFACE_HEADER_X_BILL_TO] = bill_to + + if token is not None and not token.startswith("hf_"): + warnings.warn( + "You've provided an external provider's API key, so requests will be billed directly by the provider. " + "The `bill_to` parameter is only applicable for Hugging Face billing and will be ignored.", + UserWarning, + ) + + # Configure provider + self.provider = provider # type: ignore[assignment] + + self.cookies = cookies + self.timeout = timeout + + self.exit_stack = AsyncExitStack() + self._async_client: Optional[httpx.AsyncClient] = None + + def __repr__(self): + return f"" + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc_value, traceback): + await self.close() + + async def close(self): + """Close the client. + + This method is automatically called when using the client as a context manager. + """ + await self.exit_stack.aclose() + + async def _get_async_client(self): + """Get a unique async client for this AsyncInferenceClient instance. + + Returns the same client instance on subsequent calls, ensuring proper + connection reuse and resource management through the exit stack. + """ + if self._async_client is None: + self._async_client = await self.exit_stack.enter_async_context(get_async_session()) + return self._async_client + + @overload + async def _inner_post( # type: ignore[misc] + self, request_parameters: RequestParameters, *, stream: Literal[False] = ... + ) -> bytes: ... + + @overload + async def _inner_post( # type: ignore[misc] + self, request_parameters: RequestParameters, *, stream: Literal[True] = ... + ) -> AsyncIterable[str]: ... + + @overload + async def _inner_post( + self, request_parameters: RequestParameters, *, stream: bool = False + ) -> bytes | AsyncIterable[str]: ... + + async def _inner_post( + self, request_parameters: RequestParameters, *, stream: bool = False + ) -> bytes | AsyncIterable[str]: + """Make a request to the inference server.""" + + # TODO: this should be handled in provider helpers directly + if request_parameters.task in TASKS_EXPECTING_IMAGES and "Accept" not in request_parameters.headers: + request_parameters.headers["Accept"] = "image/png" + + try: + client = await self._get_async_client() + if stream: + response = await self.exit_stack.enter_async_context( + client.stream( + "POST", + request_parameters.url, + json=request_parameters.json, + data=request_parameters.data, + headers=request_parameters.headers, + cookies=self.cookies, + timeout=self.timeout, + ) + ) + hf_raise_for_status(response) + return _async_yield_from(client, response) + else: + response = await client.post( + request_parameters.url, + json=request_parameters.json, + data=request_parameters.data, + headers=request_parameters.headers, + cookies=self.cookies, + timeout=self.timeout, + ) + hf_raise_for_status(response) + return response.content + except asyncio.TimeoutError as error: + # Convert any `TimeoutError` to a `InferenceTimeoutError` + raise InferenceTimeoutError(f"Inference call timed out: {request_parameters.url}") from error # type: ignore + except HfHubHTTPError as error: + if error.response.status_code == 422 and request_parameters.task != "unknown": + msg = str(error.args[0]) + if len(error.response.text) > 0: + msg += f"{os.linesep}{error.response.text}{os.linesep}" + error.args = (msg,) + error.args[1:] + raise + + async def audio_classification( + self, + audio: ContentT, + *, + model: str | None = None, + top_k: int | None = None, + function_to_apply: Optional["AudioClassificationOutputTransform"] = None, + ) -> list[AudioClassificationOutputElement]: + """ + Perform audio classification on the provided audio content. + + Args: + audio (Union[str, Path, bytes, BinaryIO]): + The audio content to classify. It can be raw audio bytes, a local audio file, or a URL pointing to an + audio file. + model (`str`, *optional*): + The model to use for audio classification. Can be a model ID hosted on the Hugging Face Hub + or a URL to a deployed Inference Endpoint. If not provided, the default recommended model for + audio classification will be used. + top_k (`int`, *optional*): + When specified, limits the output to the top K most probable classes. + function_to_apply (`"AudioClassificationOutputTransform"`, *optional*): + The function to apply to the model outputs in order to retrieve the scores. + + Returns: + `list[AudioClassificationOutputElement]`: List of [`AudioClassificationOutputElement`] items containing the predicted labels and their confidence. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.audio_classification("audio.flac") + [ + AudioClassificationOutputElement(score=0.4976358711719513, label='hap'), + AudioClassificationOutputElement(score=0.3677836060523987, label='neu'), + ... + ] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="audio-classification", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=audio, + parameters={"function_to_apply": function_to_apply, "top_k": top_k}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + return AudioClassificationOutputElement.parse_obj_as_list(response) + + async def audio_to_audio( + self, + audio: ContentT, + *, + model: str | None = None, + ) -> list[AudioToAudioOutputElement]: + """ + Performs multiple tasks related to audio-to-audio depending on the model (eg: speech enhancement, source separation). + + Args: + audio (Union[str, Path, bytes, BinaryIO]): + The audio content for the model. It can be raw audio bytes, a local audio file, or a URL pointing to an + audio file. + model (`str`, *optional*): + The model can be any model which takes an audio file and returns another audio file. Can be a model ID hosted on the Hugging Face Hub + or a URL to a deployed Inference Endpoint. If not provided, the default recommended model for + audio_to_audio will be used. + + Returns: + `list[AudioToAudioOutputElement]`: A list of [`AudioToAudioOutputElement`] items containing audios label, content-type, and audio content in blob. + + Raises: + `InferenceTimeoutError`: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> audio_output = await client.audio_to_audio("audio.flac") + >>> async for i, item in enumerate(audio_output): + >>> with open(f"output_{i}.flac", "wb") as f: + f.write(item.blob) + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="audio-to-audio", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=audio, + parameters={}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + audio_output = AudioToAudioOutputElement.parse_obj_as_list(response) + for item in audio_output: + item.blob = base64.b64decode(item.blob) + return audio_output + + async def automatic_speech_recognition( + self, + audio: ContentT, + *, + model: str | None = None, + extra_body: dict | None = None, + ) -> AutomaticSpeechRecognitionOutput: + """ + Perform automatic speech recognition (ASR or audio-to-text) on the given audio content. + + Args: + audio (Union[str, Path, bytes, BinaryIO]): + The content to transcribe. It can be raw audio bytes, local audio file, or a URL to an audio file. + model (`str`, *optional*): + The model to use for ASR. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. If not provided, the default recommended model for ASR will be used. + extra_body (`dict`, *optional*): + Additional provider-specific parameters to pass to the model. Refer to the provider's documentation + for supported parameters. + Returns: + [`AutomaticSpeechRecognitionOutput`]: An item containing the transcribed text and optionally the timestamp chunks. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.automatic_speech_recognition("hello_world.flac").text + "hello world" + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="automatic-speech-recognition", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=audio, + parameters={**(extra_body or {})}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + response = provider_helper.get_response(response, request_params=request_parameters) + return AutomaticSpeechRecognitionOutput.parse_obj_as_instance(response) + + @overload + async def chat_completion( # type: ignore + self, + messages: list[dict | ChatCompletionInputMessage], + *, + model: str | None = None, + stream: Literal[False] = False, + frequency_penalty: float | None = None, + logit_bias: list[float] | None = None, + logprobs: bool | None = None, + max_tokens: int | None = None, + n: int | None = None, + presence_penalty: float | None = None, + response_format: ChatCompletionInputGrammarType | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stream_options: ChatCompletionInputStreamOptions | None = None, + temperature: float | None = None, + tool_choice: Union[ChatCompletionInputToolChoiceClass, "ChatCompletionInputToolChoiceEnum"] | None = None, + tool_prompt: str | None = None, + tools: list[ChatCompletionInputTool] | None = None, + top_logprobs: int | None = None, + top_p: float | None = None, + extra_body: dict | None = None, + ) -> ChatCompletionOutput: ... + + @overload + async def chat_completion( # type: ignore + self, + messages: list[dict | ChatCompletionInputMessage], + *, + model: str | None = None, + stream: Literal[True] = True, + frequency_penalty: float | None = None, + logit_bias: list[float] | None = None, + logprobs: bool | None = None, + max_tokens: int | None = None, + n: int | None = None, + presence_penalty: float | None = None, + response_format: ChatCompletionInputGrammarType | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stream_options: ChatCompletionInputStreamOptions | None = None, + temperature: float | None = None, + tool_choice: Union[ChatCompletionInputToolChoiceClass, "ChatCompletionInputToolChoiceEnum"] | None = None, + tool_prompt: str | None = None, + tools: list[ChatCompletionInputTool] | None = None, + top_logprobs: int | None = None, + top_p: float | None = None, + extra_body: dict | None = None, + ) -> AsyncIterable[ChatCompletionStreamOutput]: ... + + @overload + async def chat_completion( + self, + messages: list[dict | ChatCompletionInputMessage], + *, + model: str | None = None, + stream: bool = False, + frequency_penalty: float | None = None, + logit_bias: list[float] | None = None, + logprobs: bool | None = None, + max_tokens: int | None = None, + n: int | None = None, + presence_penalty: float | None = None, + response_format: ChatCompletionInputGrammarType | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stream_options: ChatCompletionInputStreamOptions | None = None, + temperature: float | None = None, + tool_choice: Union[ChatCompletionInputToolChoiceClass, "ChatCompletionInputToolChoiceEnum"] | None = None, + tool_prompt: str | None = None, + tools: list[ChatCompletionInputTool] | None = None, + top_logprobs: int | None = None, + top_p: float | None = None, + extra_body: dict | None = None, + ) -> ChatCompletionOutput | AsyncIterable[ChatCompletionStreamOutput]: ... + + async def chat_completion( + self, + messages: list[dict | ChatCompletionInputMessage], + *, + model: str | None = None, + stream: bool = False, + # Parameters from ChatCompletionInput (handled manually) + frequency_penalty: float | None = None, + logit_bias: list[float] | None = None, + logprobs: bool | None = None, + max_tokens: int | None = None, + n: int | None = None, + presence_penalty: float | None = None, + response_format: ChatCompletionInputGrammarType | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stream_options: ChatCompletionInputStreamOptions | None = None, + temperature: float | None = None, + tool_choice: Union[ChatCompletionInputToolChoiceClass, "ChatCompletionInputToolChoiceEnum"] | None = None, + tool_prompt: str | None = None, + tools: list[ChatCompletionInputTool] | None = None, + top_logprobs: int | None = None, + top_p: float | None = None, + extra_body: dict | None = None, + ) -> ChatCompletionOutput | AsyncIterable[ChatCompletionStreamOutput]: + """ + A method for completing conversations using a specified language model. + + > [!TIP] + > The `client.chat_completion` method is aliased as `client.chat.completions.create` for compatibility with OpenAI's client. + > Inputs and outputs are strictly the same and using either syntax will yield the same results. + > Check out the [Inference guide](https://huggingface.co/docs/huggingface_hub/guides/inference#openai-compatibility) + > for more details about OpenAI's compatibility. + + > [!TIP] + > You can pass provider-specific parameters to the model by using the `extra_body` argument. + + Args: + messages (List of [`ChatCompletionInputMessage`]): + Conversation history consisting of roles and content pairs. + model (`str`, *optional*): + The model to use for chat-completion. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. If not provided, the default recommended model for chat-based text-generation will be used. + See https://huggingface.co/tasks/text-generation for more details. + If `model` is a model ID, it is passed to the server as the `model` parameter. If you want to define a + custom URL while setting `model` in the request payload, you must set `base_url` when initializing [`InferenceClient`]. + frequency_penalty (`float`, *optional*): + Penalizes new tokens based on their existing frequency + in the text so far. Range: [-2.0, 2.0]. Defaults to 0.0. + logit_bias (`list[float]`, *optional*): + Adjusts the likelihood of specific tokens appearing in the generated output. + logprobs (`bool`, *optional*): + Whether to return log probabilities of the output tokens or not. If true, returns the log + probabilities of each output token returned in the content of message. + max_tokens (`int`, *optional*): + Maximum number of tokens allowed in the response. Defaults to 100. + n (`int`, *optional*): + The number of completions to generate for each prompt. + presence_penalty (`float`, *optional*): + Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the + text so far, increasing the model's likelihood to talk about new topics. + response_format ([`ChatCompletionInputGrammarType`], *optional*): + Grammar constraints. Can be either a JSONSchema or a regex. + seed (Optional[`int`], *optional*): + Seed for reproducible control flow. Defaults to None. + stop (`list[str]`, *optional*): + Up to four strings which trigger the end of the response. + Defaults to None. + stream (`bool`, *optional*): + Enable realtime streaming of responses. Defaults to False. + stream_options ([`ChatCompletionInputStreamOptions`], *optional*): + Options for streaming completions. + temperature (`float`, *optional*): + Controls randomness of the generations. Lower values ensure + less random completions. Range: [0, 2]. Defaults to 1.0. + top_logprobs (`int`, *optional*): + An integer between 0 and 5 specifying the number of most likely tokens to return at each token + position, each with an associated log probability. logprobs must be set to true if this parameter is + used. + top_p (`float`, *optional*): + Fraction of the most likely next words to sample from. + Must be between 0 and 1. Defaults to 1.0. + tool_choice ([`ChatCompletionInputToolChoiceClass`] or [`ChatCompletionInputToolChoiceEnum`], *optional*): + The tool to use for the completion. Defaults to "auto". + tool_prompt (`str`, *optional*): + A prompt to be appended before the tools. + tools (List of [`ChatCompletionInputTool`], *optional*): + A list of tools the model may call. Currently, only functions are supported as a tool. Use this to + provide a list of functions the model may generate JSON inputs for. + extra_body (`dict`, *optional*): + Additional provider-specific parameters to pass to the model. Refer to the provider's documentation + for supported parameters. + Returns: + [`ChatCompletionOutput`] or Iterable of [`ChatCompletionStreamOutput`]: + Generated text returned from the server: + - if `stream=False`, the generated text is returned as a [`ChatCompletionOutput`] (default). + - if `stream=True`, the generated text is returned token by token as a sequence of [`ChatCompletionStreamOutput`]. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> messages = [{"role": "user", "content": "What is the capital of France?"}] + >>> client = AsyncInferenceClient("meta-llama/Meta-Llama-3-8B-Instruct") + >>> await client.chat_completion(messages, max_tokens=100) + ChatCompletionOutput( + choices=[ + ChatCompletionOutputComplete( + finish_reason='eos_token', + index=0, + message=ChatCompletionOutputMessage( + role='assistant', + content='The capital of France is Paris.', + name=None, + tool_calls=None + ), + logprobs=None + ) + ], + created=1719907176, + id='', + model='meta-llama/Meta-Llama-3-8B-Instruct', + object='text_completion', + system_fingerprint='2.0.4-sha-f426a33', + usage=ChatCompletionOutputUsage( + completion_tokens=8, + prompt_tokens=17, + total_tokens=25 + ) + ) + ``` + + Example using streaming: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> messages = [{"role": "user", "content": "What is the capital of France?"}] + >>> client = AsyncInferenceClient("meta-llama/Meta-Llama-3-8B-Instruct") + >>> async for token in await client.chat_completion(messages, max_tokens=10, stream=True): + ... print(token) + ChatCompletionStreamOutput(choices=[ChatCompletionStreamOutputChoice(delta=ChatCompletionStreamOutputDelta(content='The', role='assistant'), index=0, finish_reason=None)], created=1710498504) + ChatCompletionStreamOutput(choices=[ChatCompletionStreamOutputChoice(delta=ChatCompletionStreamOutputDelta(content=' capital', role='assistant'), index=0, finish_reason=None)], created=1710498504) + (...) + ChatCompletionStreamOutput(choices=[ChatCompletionStreamOutputChoice(delta=ChatCompletionStreamOutputDelta(content=' may', role='assistant'), index=0, finish_reason=None)], created=1710498504) + ``` + + Example using OpenAI's syntax: + ```py + # Must be run in an async context + # instead of `from openai import OpenAI` + from huggingface_hub import AsyncInferenceClient + + # instead of `client = OpenAI(...)` + client = AsyncInferenceClient( + base_url=..., + api_key=..., + ) + + output = await client.chat.completions.create( + model="meta-llama/Meta-Llama-3-8B-Instruct", + messages=[ + {"role": "system", "content": "You are a helpful assistant."}, + {"role": "user", "content": "Count to 10"}, + ], + stream=True, + max_tokens=1024, + ) + + for chunk in output: + print(chunk.choices[0].delta.content) + ``` + + Example using a third-party provider directly with extra (provider-specific) parameters. Usage will be billed on your Together AI account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="together", # Use Together AI provider + ... api_key="", # Pass your Together API key directly + ... ) + >>> client.chat_completion( + ... model="meta-llama/Meta-Llama-3-8B-Instruct", + ... messages=[{"role": "user", "content": "What is the capital of France?"}], + ... extra_body={"safety_model": "Meta-Llama/Llama-Guard-7b"}, + ... ) + ``` + + Example using a third-party provider through Hugging Face Routing. Usage will be billed on your Hugging Face account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="novita", # Use Novita provider + ... api_key="hf_...", # Pass your HF token + ... ) + >>> client.chat_completion( + ... model="meta-llama/Meta-Llama-3-8B-Instruct", + ... messages=[{"role": "user", "content": "What is the capital of France?"}], + ... ) + ``` + + Example using Image + Text as input: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + + # provide a remote URL + >>> image_url ="https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" + # or a base64-encoded image + >>> image_path = "/path/to/image.jpeg" + >>> with open(image_path, "rb") as f: + ... base64_image = base64.b64encode(f.read()).decode("utf-8") + >>> image_url = f"data:image/jpeg;base64,{base64_image}" + + >>> client = AsyncInferenceClient("meta-llama/Llama-3.2-11B-Vision-Instruct") + >>> output = await client.chat.completions.create( + ... messages=[ + ... { + ... "role": "user", + ... "content": [ + ... { + ... "type": "image_url", + ... "image_url": {"url": image_url}, + ... }, + ... { + ... "type": "text", + ... "text": "Describe this image in one sentence.", + ... }, + ... ], + ... }, + ... ], + ... ) + >>> output + The image depicts the iconic Statue of Liberty situated in New York Harbor, New York, on a clear day. + ``` + + Example using tools: + ```py + # Must be run in an async context + >>> client = AsyncInferenceClient("meta-llama/Meta-Llama-3-70B-Instruct") + >>> messages = [ + ... { + ... "role": "system", + ... "content": "Don't make assumptions about what values to plug into functions. Ask for clarification if a user request is ambiguous.", + ... }, + ... { + ... "role": "user", + ... "content": "What's the weather like the next 3 days in San Francisco, CA?", + ... }, + ... ] + >>> tools = [ + ... { + ... "type": "function", + ... "function": { + ... "name": "get_current_weather", + ... "description": "Get the current weather", + ... "parameters": { + ... "type": "object", + ... "properties": { + ... "location": { + ... "type": "string", + ... "description": "The city and state, e.g. San Francisco, CA", + ... }, + ... "format": { + ... "type": "string", + ... "enum": ["celsius", "fahrenheit"], + ... "description": "The temperature unit to use. Infer this from the users location.", + ... }, + ... }, + ... "required": ["location", "format"], + ... }, + ... }, + ... }, + ... { + ... "type": "function", + ... "function": { + ... "name": "get_n_day_weather_forecast", + ... "description": "Get an N-day weather forecast", + ... "parameters": { + ... "type": "object", + ... "properties": { + ... "location": { + ... "type": "string", + ... "description": "The city and state, e.g. San Francisco, CA", + ... }, + ... "format": { + ... "type": "string", + ... "enum": ["celsius", "fahrenheit"], + ... "description": "The temperature unit to use. Infer this from the users location.", + ... }, + ... "num_days": { + ... "type": "integer", + ... "description": "The number of days to forecast", + ... }, + ... }, + ... "required": ["location", "format", "num_days"], + ... }, + ... }, + ... }, + ... ] + + >>> response = await client.chat_completion( + ... model="meta-llama/Meta-Llama-3-70B-Instruct", + ... messages=messages, + ... tools=tools, + ... tool_choice="auto", + ... max_tokens=500, + ... ) + >>> response.choices[0].message.tool_calls[0].function + ChatCompletionOutputFunctionDefinition( + arguments={ + 'location': 'San Francisco, CA', + 'format': 'fahrenheit', + 'num_days': 3 + }, + name='get_n_day_weather_forecast', + description=None + ) + ``` + + Example using response_format: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient("meta-llama/Meta-Llama-3-70B-Instruct") + >>> messages = [ + ... { + ... "role": "user", + ... "content": "I saw a puppy a cat and a raccoon during my bike ride in the park. What did I see and when?", + ... }, + ... ] + >>> response_format = { + ... "type": "json", + ... "value": { + ... "properties": { + ... "location": {"type": "string"}, + ... "activity": {"type": "string"}, + ... "animals_seen": {"type": "integer", "minimum": 1, "maximum": 5}, + ... "animals": {"type": "array", "items": {"type": "string"}}, + ... }, + ... "required": ["location", "activity", "animals_seen", "animals"], + ... }, + ... } + >>> response = await client.chat_completion( + ... messages=messages, + ... response_format=response_format, + ... max_tokens=500, + ... ) + >>> response.choices[0].message.content + '{\n\n"activity": "bike ride",\n"animals": ["puppy", "cat", "raccoon"],\n"animals_seen": 3,\n"location": "park"}' + ``` + """ + # Since `chat_completion(..., model=xxx)` is also a payload parameter for the server, we need to handle 'model' differently. + # `self.model` takes precedence over 'model' argument for building URL. + # `model` takes precedence for payload value. + model_id_or_url = self.model or model + payload_model = model or self.model + + # Get the provider helper + provider_helper = get_provider_helper( + self.provider, + task="conversational", + model=model_id_or_url + if model_id_or_url is not None and model_id_or_url.startswith(("http://", "https://")) + else payload_model, + ) + + # Prepare the payload + parameters = { + "model": payload_model, + "frequency_penalty": frequency_penalty, + "logit_bias": logit_bias, + "logprobs": logprobs, + "max_tokens": max_tokens, + "n": n, + "presence_penalty": presence_penalty, + "response_format": response_format, + "seed": seed, + "stop": stop, + "temperature": temperature, + "tool_choice": tool_choice, + "tool_prompt": tool_prompt, + "tools": tools, + "top_logprobs": top_logprobs, + "top_p": top_p, + "stream": stream, + "stream_options": stream_options, + **(extra_body or {}), + } + request_parameters = provider_helper.prepare_request( + inputs=messages, + parameters=parameters, + headers=self.headers, + model=model_id_or_url, + api_key=self.token, + ) + data = await self._inner_post(request_parameters, stream=stream) + + if stream: + return _async_stream_chat_completion_response(data) # type: ignore + + return ChatCompletionOutput.parse_obj_as_instance(data) # type: ignore + + async def document_question_answering( + self, + image: ContentT, + question: str, + *, + model: str | None = None, + doc_stride: int | None = None, + handle_impossible_answer: bool | None = None, + lang: str | None = None, + max_answer_len: int | None = None, + max_question_len: int | None = None, + max_seq_len: int | None = None, + top_k: int | None = None, + word_boxes: list[list[float] | str] | None = None, + ) -> list[DocumentQuestionAnsweringOutputElement]: + """ + Answer questions on document images. + + Args: + image (`Union[str, Path, bytes, BinaryIO]`): + The input image for the context. It can be raw bytes, an image file, or a URL to an online image. + question (`str`): + Question to be answered. + model (`str`, *optional*): + The model to use for the document question answering task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended document question answering model will be used. + Defaults to None. + doc_stride (`int`, *optional*): + If the words in the document are too long to fit with the question for the model, it will be split in + several chunks with some overlap. This argument controls the size of that overlap. + handle_impossible_answer (`bool`, *optional*): + Whether to accept impossible as an answer + lang (`str`, *optional*): + Language to use while running OCR. Defaults to english. + max_answer_len (`int`, *optional*): + The maximum length of predicted answers (e.g., only answers with a shorter length are considered). + max_question_len (`int`, *optional*): + The maximum length of the question after tokenization. It will be truncated if needed. + max_seq_len (`int`, *optional*): + The maximum length of the total sentence (context + question) in tokens of each chunk passed to the + model. The context will be split in several chunks (using doc_stride as overlap) if needed. + top_k (`int`, *optional*): + The number of answers to return (will be chosen by order of likelihood). Can return less than top_k + answers if there are not enough options available within the context. + word_boxes (`list[Union[list[float], str`, *optional*): + A list of words and bounding boxes (normalized 0->1000). If provided, the inference will skip the OCR + step and use the provided bounding boxes instead. + Returns: + `list[DocumentQuestionAnsweringOutputElement]`: a list of [`DocumentQuestionAnsweringOutputElement`] items containing the predicted label, associated probability, word ids, and page number. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.document_question_answering(image="https://huggingface.co/spaces/impira/docquery/resolve/2359223c1837a7587402bda0f2643382a6eefeab/invoice.png", question="What is the invoice number?") + [DocumentQuestionAnsweringOutputElement(answer='us-001', end=16, score=0.9999666213989258, start=16)] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="document-question-answering", model=model_id) + inputs: dict[str, Any] = {"question": question, "image": _b64_encode(image)} + request_parameters = provider_helper.prepare_request( + inputs=inputs, + parameters={ + "doc_stride": doc_stride, + "handle_impossible_answer": handle_impossible_answer, + "lang": lang, + "max_answer_len": max_answer_len, + "max_question_len": max_question_len, + "max_seq_len": max_seq_len, + "top_k": top_k, + "word_boxes": word_boxes, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + return DocumentQuestionAnsweringOutputElement.parse_obj_as_list(response) + + async def feature_extraction( + self, + text: str | list[str], + *, + normalize: bool | None = None, + prompt_name: str | None = None, + truncate: bool | None = None, + truncation_direction: Literal["left", "right"] | None = None, + dimensions: int | None = None, + encoding_format: Literal["float", "base64"] | None = None, + model: str | None = None, + ) -> "np.ndarray": + """ + Generate embeddings for a given text or batch of texts. + + Args: + text (`str` or `list[str]`): + The text or list of texts to embed. + model (`str`, *optional*): + The model to use for the feature extraction task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended feature extraction model will be used. + Defaults to None. + normalize (`bool`, *optional*): + Whether to normalize the embeddings or not. + Only available on server powered by Text-Embedding-Inference. + prompt_name (`str`, *optional*): + The name of the prompt that should be used by for encoding. If not set, no prompt will be applied. + Must be a key in the `Sentence Transformers` configuration `prompts` dictionary. + For example if ``prompt_name`` is "query" and the ``prompts`` is {"query": "query: ",...}, + then the sentence "What is the capital of France?" will be encoded as "query: What is the capital of France?" + because the prompt text will be prepended before any text to encode. + truncate (`bool`, *optional*): + Whether to truncate the embeddings or not. + Only available on server powered by Text-Embedding-Inference. + truncation_direction (`Literal["left", "right"]`, *optional*): + Which side of the input should be truncated when `truncate=True` is passed. + dimensions (`int`, *optional*): + The number of dimensions the resulting output embeddings should have. + Only available on OpenAI-compatible embedding endpoints. + encoding_format (`Literal["float", "base64"]`, *optional*): + The format of the output embeddings. Either "float" or "base64". + Only available on OpenAI-compatible embedding endpoints. + + Returns: + `np.ndarray`: The embedding representing the input text(s) as a float32 numpy array. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.feature_extraction("Hi, who are you?") + array([[ 2.424802 , 2.93384 , 1.1750331 , ..., 1.240499, -0.13776633, -0.7889173 ], + [-0.42943227, -0.6364878 , -1.693462 , ..., 0.41978157, -2.4336355 , 0.6162071 ], + ..., + [ 0.28552425, -0.928395 , -1.2077185 , ..., 0.76810825, -2.1069427 , 0.6236161 ]], dtype=float32) + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="feature-extraction", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters={ + "normalize": normalize, + "prompt_name": prompt_name, + "truncate": truncate, + "truncation_direction": truncation_direction, + "dimensions": dimensions, + "encoding_format": encoding_format, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + np = _import_numpy() + return np.array(provider_helper.get_response(response), dtype="float32") + + async def fill_mask( + self, + text: str, + *, + model: str | None = None, + targets: list[str] | None = None, + top_k: int | None = None, + ) -> list[FillMaskOutputElement]: + """ + Fill in a hole with a missing word (token to be precise). + + Args: + text (`str`): + a string to be filled from, must contain the [MASK] token (check model card for exact name of the mask). + model (`str`, *optional*): + The model to use for the fill mask task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended fill mask model will be used. + targets (`list[str`, *optional*): + When passed, the model will limit the scores to the passed targets instead of looking up in the whole + vocabulary. If the provided targets are not in the model vocab, they will be tokenized and the first + resulting token will be used (with a warning, and that might be slower). + top_k (`int`, *optional*): + When passed, overrides the number of predictions to return. + Returns: + `list[FillMaskOutputElement]`: a list of [`FillMaskOutputElement`] items containing the predicted label, associated + probability, token reference, and completed text. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.fill_mask("The goal of life is .") + [ + FillMaskOutputElement(score=0.06897063553333282, token=11098, token_str=' happiness', sequence='The goal of life is happiness.'), + FillMaskOutputElement(score=0.06554922461509705, token=45075, token_str=' immortality', sequence='The goal of life is immortality.') + ] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="fill-mask", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters={"targets": targets, "top_k": top_k}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + return FillMaskOutputElement.parse_obj_as_list(response) + + async def image_classification( + self, + image: ContentT, + *, + model: str | None = None, + function_to_apply: Optional["ImageClassificationOutputTransform"] = None, + top_k: int | None = None, + ) -> list[ImageClassificationOutputElement]: + """ + Perform image classification on the given image using the specified model. + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The image to classify. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + model (`str`, *optional*): + The model to use for image classification. Can be a model ID hosted on the Hugging Face Hub or a URL to a + deployed Inference Endpoint. If not provided, the default recommended model for image classification will be used. + function_to_apply (`"ImageClassificationOutputTransform"`, *optional*): + The function to apply to the model outputs in order to retrieve the scores. + top_k (`int`, *optional*): + When specified, limits the output to the top K most probable classes. + Returns: + `list[ImageClassificationOutputElement]`: a list of [`ImageClassificationOutputElement`] items containing the predicted label and associated probability. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.image_classification("https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Cute_dog.jpg/320px-Cute_dog.jpg") + [ImageClassificationOutputElement(label='Blenheim spaniel', score=0.9779096841812134), ...] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="image-classification", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={"function_to_apply": function_to_apply, "top_k": top_k}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + return ImageClassificationOutputElement.parse_obj_as_list(response) + + async def image_segmentation( + self, + image: ContentT, + *, + model: str | None = None, + mask_threshold: float | None = None, + overlap_mask_area_threshold: float | None = None, + subtask: Optional["ImageSegmentationSubtask"] = None, + threshold: float | None = None, + ) -> list[ImageSegmentationOutputElement]: + """ + Perform image segmentation on the given image using the specified model. + + > [!WARNING] + > You must have `PIL` installed if you want to work with images (`pip install Pillow`). + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The image to segment. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + model (`str`, *optional*): + The model to use for image segmentation. Can be a model ID hosted on the Hugging Face Hub or a URL to a + deployed Inference Endpoint. If not provided, the default recommended model for image segmentation will be used. + mask_threshold (`float`, *optional*): + Threshold to use when turning the predicted masks into binary values. + overlap_mask_area_threshold (`float`, *optional*): + Mask overlap threshold to eliminate small, disconnected segments. + subtask (`"ImageSegmentationSubtask"`, *optional*): + Segmentation task to be performed, depending on model capabilities. + threshold (`float`, *optional*): + Probability threshold to filter out predicted masks. + Returns: + `list[ImageSegmentationOutputElement]`: A list of [`ImageSegmentationOutputElement`] items containing the segmented masks and associated attributes. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.image_segmentation("cat.jpg") + [ImageSegmentationOutputElement(score=0.989008, label='LABEL_184', mask=), ...] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="image-segmentation", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={ + "mask_threshold": mask_threshold, + "overlap_mask_area_threshold": overlap_mask_area_threshold, + "subtask": subtask, + "threshold": threshold, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + response = provider_helper.get_response(response, request_parameters) + output = ImageSegmentationOutputElement.parse_obj_as_list(response) + for item in output: + item.mask = _b64_to_image(item.mask) # type: ignore + return output + + async def image_to_image( + self, + image: ContentT, + prompt: str | None = None, + *, + negative_prompt: str | None = None, + num_inference_steps: int | None = None, + guidance_scale: float | None = None, + model: str | None = None, + target_size: ImageToImageTargetSize | None = None, + **kwargs, + ) -> "Image": + """ + Perform image-to-image translation using a specified model. + + > [!WARNING] + > You must have `PIL` installed if you want to work with images (`pip install Pillow`). + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The input image for translation. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + prompt (`str`, *optional*): + The text prompt to guide the image generation. + negative_prompt (`str`, *optional*): + One prompt to guide what NOT to include in image generation. + num_inference_steps (`int`, *optional*): + For diffusion models. The number of denoising steps. More denoising steps usually lead to a higher + quality image at the expense of slower inference. + guidance_scale (`float`, *optional*): + For diffusion models. A higher guidance scale value encourages the model to generate images closely + linked to the text prompt at the expense of lower image quality. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. This parameter overrides the model defined at the instance level. Defaults to None. + target_size (`ImageToImageTargetSize`, *optional*): + The size in pixels of the output image. This parameter is only supported by some providers and for + specific models. It will be ignored when unsupported. + + Returns: + `Image`: The translated image. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> image = await client.image_to_image("cat.jpg", prompt="turn the cat into a tiger") + >>> image.save("tiger.jpg") + ``` + + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="image-to-image", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={ + "prompt": prompt, + "negative_prompt": negative_prompt, + "target_size": target_size, + "num_inference_steps": num_inference_steps, + "guidance_scale": guidance_scale, + **kwargs, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + response = provider_helper.get_response(response, request_parameters) + return _bytes_to_image(response) + + async def image_to_video( + self, + image: ContentT, + *, + model: str | None = None, + prompt: str | None = None, + negative_prompt: str | None = None, + num_frames: float | None = None, + num_inference_steps: int | None = None, + guidance_scale: float | None = None, + seed: int | None = None, + target_size: ImageToVideoTargetSize | None = None, + **kwargs, + ) -> bytes: + """ + Generate a video from an input image. + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The input image to generate a video from. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. This parameter overrides the model defined at the instance level. Defaults to None. + prompt (`str`, *optional*): + The text prompt to guide the video generation. + negative_prompt (`str`, *optional*): + One prompt to guide what NOT to include in video generation. + num_frames (`float`, *optional*): + The num_frames parameter determines how many video frames are generated. + num_inference_steps (`int`, *optional*): + For diffusion models. The number of denoising steps. More denoising steps usually lead to a higher + quality image at the expense of slower inference. + guidance_scale (`float`, *optional*): + For diffusion models. A higher guidance scale value encourages the model to generate videos closely + linked to the text prompt at the expense of lower image quality. + seed (`int`, *optional*): + The seed to use for the video generation. + target_size (`ImageToVideoTargetSize`, *optional*): + The size in pixel of the output video frames. + num_inference_steps (`int`, *optional*): + The number of denoising steps. More denoising steps usually lead to a higher quality video at the + expense of slower inference. + seed (`int`, *optional*): + Seed for the random number generator. + + Returns: + `bytes`: The generated video. + + Examples: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> video = await client.image_to_video("cat.jpg", model="Wan-AI/Wan2.2-I2V-A14B", prompt="turn the cat into a tiger") + >>> with open("tiger.mp4", "wb") as f: + ... f.write(video) + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="image-to-video", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={ + "prompt": prompt, + "negative_prompt": negative_prompt, + "num_frames": num_frames, + "num_inference_steps": num_inference_steps, + "guidance_scale": guidance_scale, + "seed": seed, + "target_size": target_size, + **kwargs, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + response = provider_helper.get_response(response, request_parameters) + return response + + async def image_to_text(self, image: ContentT, *, model: str | None = None) -> ImageToTextOutput: + """ + Takes an input image and return text. + + Models can have very different outputs depending on your use case (image captioning, optical character recognition + (OCR), Pix2Struct, etc.). Please have a look to the model card to learn more about a model's specificities. + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The input image to caption. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. This parameter overrides the model defined at the instance level. Defaults to None. + + Returns: + [`ImageToTextOutput`]: The generated text. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.image_to_text("cat.jpg") + 'a cat standing in a grassy field ' + >>> await client.image_to_text("https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Cute_dog.jpg/320px-Cute_dog.jpg") + 'a dog laying on the grass next to a flower pot ' + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="image-to-text", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + output_list: list[ImageToTextOutput] = ImageToTextOutput.parse_obj_as_list(response) + return output_list[0] + + async def object_detection( + self, image: ContentT, *, model: str | None = None, threshold: float | None = None + ) -> list[ObjectDetectionOutputElement]: + """ + Perform object detection on the given image using the specified model. + + > [!WARNING] + > You must have `PIL` installed if you want to work with images (`pip install Pillow`). + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The image to detect objects on. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + model (`str`, *optional*): + The model to use for object detection. Can be a model ID hosted on the Hugging Face Hub or a URL to a + deployed Inference Endpoint. If not provided, the default recommended model for object detection (DETR) will be used. + threshold (`float`, *optional*): + The probability necessary to make a prediction. + Returns: + `list[ObjectDetectionOutputElement]`: A list of [`ObjectDetectionOutputElement`] items containing the bounding boxes and associated attributes. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + `ValueError`: + If the request output is not a List. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.object_detection("people.jpg") + [ObjectDetectionOutputElement(score=0.9486683011054993, label='person', box=ObjectDetectionBoundingBox(xmin=59, ymin=39, xmax=420, ymax=510)), ...] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="object-detection", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={"threshold": threshold}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + return ObjectDetectionOutputElement.parse_obj_as_list(response) + + async def question_answering( + self, + question: str, + context: str, + *, + model: str | None = None, + align_to_words: bool | None = None, + doc_stride: int | None = None, + handle_impossible_answer: bool | None = None, + max_answer_len: int | None = None, + max_question_len: int | None = None, + max_seq_len: int | None = None, + top_k: int | None = None, + ) -> QuestionAnsweringOutputElement | list[QuestionAnsweringOutputElement]: + """ + Retrieve the answer to a question from a given text. + + Args: + question (`str`): + Question to be answered. + context (`str`): + The context of the question. + model (`str`): + The model to use for the question answering task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. + align_to_words (`bool`, *optional*): + Attempts to align the answer to real words. Improves quality on space separated languages. Might hurt + on non-space-separated languages (like Japanese or Chinese) + doc_stride (`int`, *optional*): + If the context is too long to fit with the question for the model, it will be split in several chunks + with some overlap. This argument controls the size of that overlap. + handle_impossible_answer (`bool`, *optional*): + Whether to accept impossible as an answer. + max_answer_len (`int`, *optional*): + The maximum length of predicted answers (e.g., only answers with a shorter length are considered). + max_question_len (`int`, *optional*): + The maximum length of the question after tokenization. It will be truncated if needed. + max_seq_len (`int`, *optional*): + The maximum length of the total sentence (context + question) in tokens of each chunk passed to the + model. The context will be split in several chunks (using docStride as overlap) if needed. + top_k (`int`, *optional*): + The number of answers to return (will be chosen by order of likelihood). Note that we return less than + topk answers if there are not enough options available within the context. + + Returns: + Union[`QuestionAnsweringOutputElement`, list[`QuestionAnsweringOutputElement`]]: + When top_k is 1 or not provided, it returns a single `QuestionAnsweringOutputElement`. + When top_k is greater than 1, it returns a list of `QuestionAnsweringOutputElement`. + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.question_answering(question="What's my name?", context="My name is Clara and I live in Berkeley.") + QuestionAnsweringOutputElement(answer='Clara', end=16, score=0.9326565265655518, start=11) + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="question-answering", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs={"question": question, "context": context}, + parameters={ + "align_to_words": align_to_words, + "doc_stride": doc_stride, + "handle_impossible_answer": handle_impossible_answer, + "max_answer_len": max_answer_len, + "max_question_len": max_question_len, + "max_seq_len": max_seq_len, + "top_k": top_k, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + # Parse the response as a single `QuestionAnsweringOutputElement` when top_k is 1 or not provided, or a list of `QuestionAnsweringOutputElement` to ensure backward compatibility. + output = QuestionAnsweringOutputElement.parse_obj(response) + return output + + async def sentence_similarity( + self, sentence: str, other_sentences: list[str], *, model: str | None = None + ) -> list[float]: + """ + Compute the semantic similarity between a sentence and a list of other sentences by comparing their embeddings. + + Args: + sentence (`str`): + The main sentence to compare to others. + other_sentences (`list[str]`): + The list of sentences to compare to. + model (`str`, *optional*): + The model to use for the sentence similarity task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended sentence similarity model will be used. + Defaults to None. + + Returns: + `list[float]`: The embedding representing the input text. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.sentence_similarity( + ... "Machine learning is so easy.", + ... other_sentences=[ + ... "Deep learning is so straightforward.", + ... "This is so difficult, like rocket science.", + ... "I can't believe how much I struggled with this.", + ... ], + ... ) + [0.7785726189613342, 0.45876261591911316, 0.2906220555305481] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="sentence-similarity", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs={"source_sentence": sentence, "sentences": other_sentences}, + parameters={}, + extra_payload={}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + return _bytes_to_list(response) + + async def summarization( + self, + text: str, + *, + model: str | None = None, + clean_up_tokenization_spaces: bool | None = None, + generate_parameters: dict[str, Any] | None = None, + truncation: Optional["SummarizationTruncationStrategy"] = None, + ) -> SummarizationOutput: + """ + Generate a summary of a given text using a specified model. + + Args: + text (`str`): + The input text to summarize. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. If not provided, the default recommended model for summarization will be used. + clean_up_tokenization_spaces (`bool`, *optional*): + Whether to clean up the potential extra spaces in the text output. + generate_parameters (`dict[str, Any]`, *optional*): + Additional parametrization of the text generation algorithm. + truncation (`"SummarizationTruncationStrategy"`, *optional*): + The truncation strategy to use. + Returns: + [`SummarizationOutput`]: The generated summary text. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.summarization("The Eiffel tower...") + SummarizationOutput(generated_text="The Eiffel tower is one of the most famous landmarks in the world....") + ``` + """ + parameters = { + "clean_up_tokenization_spaces": clean_up_tokenization_spaces, + "generate_parameters": generate_parameters, + "truncation": truncation, + } + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="summarization", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters=parameters, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + return SummarizationOutput.parse_obj_as_list(response)[0] + + async def table_question_answering( + self, + table: dict[str, Any], + query: str, + *, + model: str | None = None, + padding: Optional["Padding"] = None, + sequential: bool | None = None, + truncation: bool | None = None, + ) -> TableQuestionAnsweringOutputElement: + """ + Retrieve the answer to a question from information given in a table. + + Args: + table (`str`): + A table of data represented as a dict of lists where entries are headers and the lists are all the + values, all lists must have the same size. + query (`str`): + The query in plain text that you want to ask the table. + model (`str`): + The model to use for the table-question-answering task. Can be a model ID hosted on the Hugging Face + Hub or a URL to a deployed Inference Endpoint. + padding (`"Padding"`, *optional*): + Activates and controls padding. + sequential (`bool`, *optional*): + Whether to do inference sequentially or as a batch. Batching is faster, but models like SQA require the + inference to be done sequentially to extract relations within sequences, given their conversational + nature. + truncation (`bool`, *optional*): + Activates and controls truncation. + + Returns: + [`TableQuestionAnsweringOutputElement`]: a table question answering output containing the answer, coordinates, cells and the aggregator used. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> query = "How many stars does the transformers repository have?" + >>> table = {"Repository": ["Transformers", "Datasets", "Tokenizers"], "Stars": ["36542", "4512", "3934"]} + >>> await client.table_question_answering(table, query, model="google/tapas-base-finetuned-wtq") + TableQuestionAnsweringOutputElement(answer='36542', coordinates=[[0, 1]], cells=['36542'], aggregator='AVERAGE') + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="table-question-answering", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs={"query": query, "table": table}, + parameters={"model": model, "padding": padding, "sequential": sequential, "truncation": truncation}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + return TableQuestionAnsweringOutputElement.parse_obj_as_instance(response) + + async def tabular_classification(self, table: dict[str, Any], *, model: str | None = None) -> list[str]: + """ + Classifying a target category (a group) based on a set of attributes. + + Args: + table (`dict[str, Any]`): + Set of attributes to classify. + model (`str`, *optional*): + The model to use for the tabular classification task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended tabular classification model will be used. + Defaults to None. + + Returns: + `List`: a list of labels, one per row in the initial table. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> table = { + ... "fixed_acidity": ["7.4", "7.8", "10.3"], + ... "volatile_acidity": ["0.7", "0.88", "0.32"], + ... "citric_acid": ["0", "0", "0.45"], + ... "residual_sugar": ["1.9", "2.6", "6.4"], + ... "chlorides": ["0.076", "0.098", "0.073"], + ... "free_sulfur_dioxide": ["11", "25", "5"], + ... "total_sulfur_dioxide": ["34", "67", "13"], + ... "density": ["0.9978", "0.9968", "0.9976"], + ... "pH": ["3.51", "3.2", "3.23"], + ... "sulphates": ["0.56", "0.68", "0.82"], + ... "alcohol": ["9.4", "9.8", "12.6"], + ... } + >>> await client.tabular_classification(table=table, model="julien-c/wine-quality") + ["5", "5", "5"] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="tabular-classification", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=None, + extra_payload={"table": table}, + parameters={}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + return _bytes_to_list(response) + + async def tabular_regression(self, table: dict[str, Any], *, model: str | None = None) -> list[float]: + """ + Predicting a numerical target value given a set of attributes/features in a table. + + Args: + table (`dict[str, Any]`): + Set of attributes stored in a table. The attributes used to predict the target can be both numerical and categorical. + model (`str`, *optional*): + The model to use for the tabular regression task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended tabular regression model will be used. + Defaults to None. + + Returns: + `List`: a list of predicted numerical target values. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> table = { + ... "Height": ["11.52", "12.48", "12.3778"], + ... "Length1": ["23.2", "24", "23.9"], + ... "Length2": ["25.4", "26.3", "26.5"], + ... "Length3": ["30", "31.2", "31.1"], + ... "Species": ["Bream", "Bream", "Bream"], + ... "Width": ["4.02", "4.3056", "4.6961"], + ... } + >>> await client.tabular_regression(table, model="scikit-learn/Fish-Weight") + [110, 120, 130] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="tabular-regression", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=None, + parameters={}, + extra_payload={"table": table}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + return _bytes_to_list(response) + + async def text_classification( + self, + text: str, + *, + model: str | None = None, + top_k: int | None = None, + function_to_apply: Optional["TextClassificationOutputTransform"] = None, + ) -> list[TextClassificationOutputElement]: + """ + Perform text classification (e.g. sentiment-analysis) on the given text. + + Args: + text (`str`): + A string to be classified. + model (`str`, *optional*): + The model to use for the text classification task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended text classification model will be used. + Defaults to None. + top_k (`int`, *optional*): + When specified, limits the output to the top K most probable classes. + function_to_apply (`"TextClassificationOutputTransform"`, *optional*): + The function to apply to the model outputs in order to retrieve the scores. + + Returns: + `list[TextClassificationOutputElement]`: a list of [`TextClassificationOutputElement`] items containing the predicted label and associated probability. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.text_classification("I like you") + [ + TextClassificationOutputElement(label='POSITIVE', score=0.9998695850372314), + TextClassificationOutputElement(label='NEGATIVE', score=0.0001304351753788069), + ] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="text-classification", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters={ + "function_to_apply": function_to_apply, + "top_k": top_k, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + return TextClassificationOutputElement.parse_obj_as_list(response)[0] # type: ignore + + @overload + async def text_generation( + self, + prompt: str, + *, + details: Literal[True], + stream: Literal[True], + model: str | None = None, + # Parameters from `TextGenerationInputGenerateParameters` (maintained manually) + adapter_id: str | None = None, + best_of: int | None = None, + decoder_input_details: bool | None = None, + do_sample: bool | None = None, + frequency_penalty: float | None = None, + grammar: TextGenerationInputGrammarType | None = None, + max_new_tokens: int | None = None, + repetition_penalty: float | None = None, + return_full_text: bool | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stop_sequences: list[str] | None = None, # Deprecated, use `stop` instead + temperature: float | None = None, + top_k: int | None = None, + top_n_tokens: int | None = None, + top_p: float | None = None, + truncate: int | None = None, + typical_p: float | None = None, + watermark: bool | None = None, + ) -> AsyncIterable[TextGenerationStreamOutput]: ... + + @overload + async def text_generation( + self, + prompt: str, + *, + details: Literal[True], + stream: Literal[False] | None = None, + model: str | None = None, + # Parameters from `TextGenerationInputGenerateParameters` (maintained manually) + adapter_id: str | None = None, + best_of: int | None = None, + decoder_input_details: bool | None = None, + do_sample: bool | None = None, + frequency_penalty: float | None = None, + grammar: TextGenerationInputGrammarType | None = None, + max_new_tokens: int | None = None, + repetition_penalty: float | None = None, + return_full_text: bool | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stop_sequences: list[str] | None = None, # Deprecated, use `stop` instead + temperature: float | None = None, + top_k: int | None = None, + top_n_tokens: int | None = None, + top_p: float | None = None, + truncate: int | None = None, + typical_p: float | None = None, + watermark: bool | None = None, + ) -> TextGenerationOutput: ... + + @overload + async def text_generation( + self, + prompt: str, + *, + details: Literal[False] | None = None, + stream: Literal[True], + model: str | None = None, + # Parameters from `TextGenerationInputGenerateParameters` (maintained manually) + adapter_id: str | None = None, + best_of: int | None = None, + decoder_input_details: bool | None = None, + do_sample: bool | None = None, + frequency_penalty: float | None = None, + grammar: TextGenerationInputGrammarType | None = None, + max_new_tokens: int | None = None, + repetition_penalty: float | None = None, + return_full_text: bool | None = None, # Manual default value + seed: int | None = None, + stop: list[str] | None = None, + stop_sequences: list[str] | None = None, # Deprecated, use `stop` instead + temperature: float | None = None, + top_k: int | None = None, + top_n_tokens: int | None = None, + top_p: float | None = None, + truncate: int | None = None, + typical_p: float | None = None, + watermark: bool | None = None, + ) -> AsyncIterable[str]: ... + + @overload + async def text_generation( + self, + prompt: str, + *, + details: Literal[False] | None = None, + stream: Literal[False] | None = None, + model: str | None = None, + # Parameters from `TextGenerationInputGenerateParameters` (maintained manually) + adapter_id: str | None = None, + best_of: int | None = None, + decoder_input_details: bool | None = None, + do_sample: bool | None = None, + frequency_penalty: float | None = None, + grammar: TextGenerationInputGrammarType | None = None, + max_new_tokens: int | None = None, + repetition_penalty: float | None = None, + return_full_text: bool | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stop_sequences: list[str] | None = None, # Deprecated, use `stop` instead + temperature: float | None = None, + top_k: int | None = None, + top_n_tokens: int | None = None, + top_p: float | None = None, + truncate: int | None = None, + typical_p: float | None = None, + watermark: bool | None = None, + ) -> str: ... + + @overload + async def text_generation( + self, + prompt: str, + *, + details: bool | None = None, + stream: bool | None = None, + model: str | None = None, + # Parameters from `TextGenerationInputGenerateParameters` (maintained manually) + adapter_id: str | None = None, + best_of: int | None = None, + decoder_input_details: bool | None = None, + do_sample: bool | None = None, + frequency_penalty: float | None = None, + grammar: TextGenerationInputGrammarType | None = None, + max_new_tokens: int | None = None, + repetition_penalty: float | None = None, + return_full_text: bool | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stop_sequences: list[str] | None = None, # Deprecated, use `stop` instead + temperature: float | None = None, + top_k: int | None = None, + top_n_tokens: int | None = None, + top_p: float | None = None, + truncate: int | None = None, + typical_p: float | None = None, + watermark: bool | None = None, + ) -> str | TextGenerationOutput | AsyncIterable[str] | AsyncIterable[TextGenerationStreamOutput]: ... + + async def text_generation( + self, + prompt: str, + *, + details: bool | None = None, + stream: bool | None = None, + model: str | None = None, + # Parameters from `TextGenerationInputGenerateParameters` (maintained manually) + adapter_id: str | None = None, + best_of: int | None = None, + decoder_input_details: bool | None = None, + do_sample: bool | None = None, + frequency_penalty: float | None = None, + grammar: TextGenerationInputGrammarType | None = None, + max_new_tokens: int | None = None, + repetition_penalty: float | None = None, + return_full_text: bool | None = None, + seed: int | None = None, + stop: list[str] | None = None, + stop_sequences: list[str] | None = None, # Deprecated, use `stop` instead + temperature: float | None = None, + top_k: int | None = None, + top_n_tokens: int | None = None, + top_p: float | None = None, + truncate: int | None = None, + typical_p: float | None = None, + watermark: bool | None = None, + ) -> str | TextGenerationOutput | AsyncIterable[str] | AsyncIterable[TextGenerationStreamOutput]: + """ + Given a prompt, generate the following text. + + > [!TIP] + > If you want to generate a response from chat messages, you should use the [`InferenceClient.chat_completion`] method. + > It accepts a list of messages instead of a single text prompt and handles the chat templating for you. + + Args: + prompt (`str`): + Input text. + details (`bool`, *optional*): + By default, text_generation returns a string. Pass `details=True` if you want a detailed output (tokens, + probabilities, seed, finish reason, etc.). Only available for models running on with the + `text-generation-inference` backend. + stream (`bool`, *optional*): + By default, text_generation returns the full generated text. Pass `stream=True` if you want a stream of + tokens to be returned. Only available for models running on with the `text-generation-inference` + backend. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. This parameter overrides the model defined at the instance level. Defaults to None. + adapter_id (`str`, *optional*): + Lora adapter id. + best_of (`int`, *optional*): + Generate best_of sequences and return the one if the highest token logprobs. + decoder_input_details (`bool`, *optional*): + Return the decoder input token logprobs and ids. You must set `details=True` as well for it to be taken + into account. Defaults to `False`. + do_sample (`bool`, *optional*): + Activate logits sampling + frequency_penalty (`float`, *optional*): + Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in + the text so far, decreasing the model's likelihood to repeat the same line verbatim. + grammar ([`TextGenerationInputGrammarType`], *optional*): + Grammar constraints. Can be either a JSONSchema or a regex. + max_new_tokens (`int`, *optional*): + Maximum number of generated tokens. Defaults to 100. + repetition_penalty (`float`, *optional*): + The parameter for repetition penalty. 1.0 means no penalty. See [this + paper](https://arxiv.org/pdf/1909.05858.pdf) for more details. + return_full_text (`bool`, *optional*): + Whether to prepend the prompt to the generated text + seed (`int`, *optional*): + Random sampling seed + stop (`list[str]`, *optional*): + Stop generating tokens if a member of `stop` is generated. + stop_sequences (`list[str]`, *optional*): + Deprecated argument. Use `stop` instead. + temperature (`float`, *optional*): + The value used to module the logits distribution. + top_n_tokens (`int`, *optional*): + Return information about the `top_n_tokens` most likely tokens at each generation step, instead of + just the sampled token. + top_k (`int`, *optional`): + The number of highest probability vocabulary tokens to keep for top-k-filtering. + top_p (`float`, *optional`): + If set to < 1, only the smallest set of most probable tokens with probabilities that add up to `top_p` or + higher are kept for generation. + truncate (`int`, *optional`): + Truncate inputs tokens to the given size. + typical_p (`float`, *optional`): + Typical Decoding mass + See [Typical Decoding for Natural Language Generation](https://arxiv.org/abs/2202.00666) for more information + watermark (`bool`, *optional*): + Watermarking with [A Watermark for Large Language Models](https://arxiv.org/abs/2301.10226) + + Returns: + `Union[str, TextGenerationOutput, AsyncIterable[str], AsyncIterable[TextGenerationStreamOutput]]`: + Generated text returned from the server: + - if `stream=False` and `details=False`, the generated text is returned as a `str` (default) + - if `stream=True` and `details=False`, the generated text is returned token by token as a `AsyncIterable[str]` + - if `stream=False` and `details=True`, the generated text is returned with more details as a [`~huggingface_hub.TextGenerationOutput`] + - if `details=True` and `stream=True`, the generated text is returned token by token as a iterable of [`~huggingface_hub.TextGenerationStreamOutput`] + + Raises: + `ValidationError`: + If input values are not valid. No HTTP call is made to the server. + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + + # Case 1: generate text + >>> await client.text_generation("The huggingface_hub library is ", max_new_tokens=12) + '100% open source and built to be easy to use.' + + # Case 2: iterate over the generated tokens. Useful for large generation. + >>> async for token in await client.text_generation("The huggingface_hub library is ", max_new_tokens=12, stream=True): + ... print(token) + 100 + % + open + source + and + built + to + be + easy + to + use + . + + # Case 3: get more details about the generation process. + >>> await client.text_generation("The huggingface_hub library is ", max_new_tokens=12, details=True) + TextGenerationOutput( + generated_text='100% open source and built to be easy to use.', + details=TextGenerationDetails( + finish_reason='length', + generated_tokens=12, + seed=None, + prefill=[ + TextGenerationPrefillOutputToken(id=487, text='The', logprob=None), + TextGenerationPrefillOutputToken(id=53789, text=' hugging', logprob=-13.171875), + (...) + TextGenerationPrefillOutputToken(id=204, text=' ', logprob=-7.0390625) + ], + tokens=[ + TokenElement(id=1425, text='100', logprob=-1.0175781, special=False), + TokenElement(id=16, text='%', logprob=-0.0463562, special=False), + (...) + TokenElement(id=25, text='.', logprob=-0.5703125, special=False) + ], + best_of_sequences=None + ) + ) + + # Case 4: iterate over the generated tokens with more details. + # Last object is more complete, containing the full generated text and the finish reason. + >>> async for details in await client.text_generation("The huggingface_hub library is ", max_new_tokens=12, details=True, stream=True): + ... print(details) + ... + TextGenerationStreamOutput(token=TokenElement(id=1425, text='100', logprob=-1.0175781, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=16, text='%', logprob=-0.0463562, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=1314, text=' open', logprob=-1.3359375, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=3178, text=' source', logprob=-0.28100586, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=273, text=' and', logprob=-0.5961914, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=3426, text=' built', logprob=-1.9423828, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=271, text=' to', logprob=-1.4121094, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=314, text=' be', logprob=-1.5224609, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=1833, text=' easy', logprob=-2.1132812, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=271, text=' to', logprob=-0.08520508, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement(id=745, text=' use', logprob=-0.39453125, special=False), generated_text=None, details=None) + TextGenerationStreamOutput(token=TokenElement( + id=25, + text='.', + logprob=-0.5703125, + special=False), + generated_text='100% open source and built to be easy to use.', + details=TextGenerationStreamOutputStreamDetails(finish_reason='length', generated_tokens=12, seed=None) + ) + + # Case 5: generate constrained output using grammar + >>> response = await client.text_generation( + ... prompt="I saw a puppy a cat and a raccoon during my bike ride in the park", + ... model="HuggingFaceH4/zephyr-orpo-141b-A35b-v0.1", + ... max_new_tokens=100, + ... repetition_penalty=1.3, + ... grammar={ + ... "type": "json", + ... "value": { + ... "properties": { + ... "location": {"type": "string"}, + ... "activity": {"type": "string"}, + ... "animals_seen": {"type": "integer", "minimum": 1, "maximum": 5}, + ... "animals": {"type": "array", "items": {"type": "string"}}, + ... }, + ... "required": ["location", "activity", "animals_seen", "animals"], + ... }, + ... }, + ... ) + >>> json.loads(response) + { + "activity": "bike riding", + "animals": ["puppy", "cat", "raccoon"], + "animals_seen": 3, + "location": "park" + } + ``` + """ + if decoder_input_details and not details: + warnings.warn( + "`decoder_input_details=True` has been passed to the server but `details=False` is set meaning that" + " the output from the server will be truncated." + ) + decoder_input_details = False + + if stop_sequences is not None: + warnings.warn( + "`stop_sequences` is a deprecated argument for `text_generation` task" + " and will be removed in version '0.28.0'. Use `stop` instead.", + FutureWarning, + ) + if stop is None: + stop = stop_sequences # use deprecated arg if provided + + # Build payload + parameters = { + "adapter_id": adapter_id, + "best_of": best_of, + "decoder_input_details": decoder_input_details, + "details": details, + "do_sample": do_sample, + "frequency_penalty": frequency_penalty, + "grammar": grammar, + "max_new_tokens": max_new_tokens, + "repetition_penalty": repetition_penalty, + "return_full_text": return_full_text, + "seed": seed, + "stop": stop, + "temperature": temperature, + "top_k": top_k, + "top_n_tokens": top_n_tokens, + "top_p": top_p, + "truncate": truncate, + "typical_p": typical_p, + "watermark": watermark, + } + + # Remove some parameters if not a TGI server + unsupported_kwargs = _get_unsupported_text_generation_kwargs(model) + if len(unsupported_kwargs) > 0: + # The server does not support some parameters + # => means it is not a TGI server + # => remove unsupported parameters and warn the user + + ignored_parameters = [] + for key in unsupported_kwargs: + if parameters.get(key): + ignored_parameters.append(key) + parameters.pop(key, None) + if len(ignored_parameters) > 0: + warnings.warn( + "API endpoint/model for text-generation is not served via TGI. Ignoring following parameters:" + f" {', '.join(ignored_parameters)}.", + UserWarning, + ) + if details: + warnings.warn( + "API endpoint/model for text-generation is not served via TGI. Parameter `details=True` will" + " be ignored meaning only the generated text will be returned.", + UserWarning, + ) + details = False + if stream: + raise ValueError( + "API endpoint/model for text-generation is not served via TGI. Cannot return output as a stream." + " Please pass `stream=False` as input." + ) + + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="text-generation", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=prompt, + parameters=parameters, + extra_payload={"stream": stream}, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + + # Handle errors separately for more precise error messages + try: + bytes_output = await self._inner_post(request_parameters, stream=stream or False) + except HfHubHTTPError as e: + match = MODEL_KWARGS_NOT_USED_REGEX.search(str(e)) + if isinstance(e, BadRequestError) and match: + unused_params = [kwarg.strip("' ") for kwarg in match.group(1).split(",")] + _set_unsupported_text_generation_kwargs(model, unused_params) + return await self.text_generation( # type: ignore + prompt=prompt, + details=details, + stream=stream, + model=model_id, + adapter_id=adapter_id, + best_of=best_of, + decoder_input_details=decoder_input_details, + do_sample=do_sample, + frequency_penalty=frequency_penalty, + grammar=grammar, + max_new_tokens=max_new_tokens, + repetition_penalty=repetition_penalty, + return_full_text=return_full_text, + seed=seed, + stop=stop, + temperature=temperature, + top_k=top_k, + top_n_tokens=top_n_tokens, + top_p=top_p, + truncate=truncate, + typical_p=typical_p, + watermark=watermark, + ) + raise_text_generation_error(e) + + # Parse output + if stream: + return _async_stream_text_generation_response(bytes_output, details) # type: ignore + + data = _bytes_to_dict(bytes_output) # type: ignore + + # Data can be a single element (dict) or an iterable of dicts where we select the first element of. + if isinstance(data, list): + data = data[0] + response = provider_helper.get_response(data, request_parameters) + return TextGenerationOutput.parse_obj_as_instance(response) if details else response["generated_text"] + + async def text_to_image( + self, + prompt: str, + *, + negative_prompt: str | None = None, + height: int | None = None, + width: int | None = None, + num_inference_steps: int | None = None, + guidance_scale: float | None = None, + model: str | None = None, + scheduler: str | None = None, + seed: int | None = None, + extra_body: dict[str, Any] | None = None, + ) -> "Image": + """ + Generate an image based on a given text using a specified model. + + > [!WARNING] + > You must have `PIL` installed if you want to work with images (`pip install Pillow`). + + > [!TIP] + > You can pass provider-specific parameters to the model by using the `extra_body` argument. + + Args: + prompt (`str`): + The prompt to generate an image from. + negative_prompt (`str`, *optional*): + One prompt to guide what NOT to include in image generation. + height (`int`, *optional*): + The height in pixels of the output image + width (`int`, *optional*): + The width in pixels of the output image + num_inference_steps (`int`, *optional*): + The number of denoising steps. More denoising steps usually lead to a higher quality image at the + expense of slower inference. + guidance_scale (`float`, *optional*): + A higher guidance scale value encourages the model to generate images closely linked to the text + prompt, but values too high may cause saturation and other artifacts. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. If not provided, the default recommended text-to-image model will be used. + Defaults to None. + scheduler (`str`, *optional*): + Override the scheduler with a compatible one. + seed (`int`, *optional*): + Seed for the random number generator. + extra_body (`dict[str, Any]`, *optional*): + Additional provider-specific parameters to pass to the model. Refer to the provider's documentation + for supported parameters. + + Returns: + `Image`: The generated image. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + + >>> image = await client.text_to_image("An astronaut riding a horse on the moon.") + >>> image.save("astronaut.png") + + >>> image = await client.text_to_image( + ... "An astronaut riding a horse on the moon.", + ... negative_prompt="low resolution, blurry", + ... model="stabilityai/stable-diffusion-2-1", + ... ) + >>> image.save("better_astronaut.png") + ``` + Example using a third-party provider directly. Usage will be billed on your fal.ai account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="fal-ai", # Use fal.ai provider + ... api_key="fal-ai-api-key", # Pass your fal.ai API key + ... ) + >>> image = client.text_to_image( + ... "A majestic lion in a fantasy forest", + ... model="black-forest-labs/FLUX.1-schnell", + ... ) + >>> image.save("lion.png") + ``` + + Example using a third-party provider through Hugging Face Routing. Usage will be billed on your Hugging Face account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="replicate", # Use replicate provider + ... api_key="hf_...", # Pass your HF token + ... ) + >>> image = client.text_to_image( + ... "An astronaut riding a horse on the moon.", + ... model="black-forest-labs/FLUX.1-dev", + ... ) + >>> image.save("astronaut.png") + ``` + + Example using Replicate provider with extra parameters + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="replicate", # Use replicate provider + ... api_key="hf_...", # Pass your HF token + ... ) + >>> image = client.text_to_image( + ... "An astronaut riding a horse on the moon.", + ... model="black-forest-labs/FLUX.1-schnell", + ... extra_body={"output_quality": 100}, + ... ) + >>> image.save("astronaut.png") + ``` + + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="text-to-image", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=prompt, + parameters={ + "negative_prompt": negative_prompt, + "height": height, + "width": width, + "num_inference_steps": num_inference_steps, + "guidance_scale": guidance_scale, + "scheduler": scheduler, + "seed": seed, + **(extra_body or {}), + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + response = provider_helper.get_response(response, request_parameters) + return _bytes_to_image(response) + + async def text_to_video( + self, + prompt: str, + *, + model: str | None = None, + guidance_scale: float | None = None, + negative_prompt: list[str] | None = None, + num_frames: float | None = None, + num_inference_steps: int | None = None, + seed: int | None = None, + extra_body: dict[str, Any] | None = None, + ) -> bytes: + """ + Generate a video based on a given text. + + > [!TIP] + > You can pass provider-specific parameters to the model by using the `extra_body` argument. + + Args: + prompt (`str`): + The prompt to generate a video from. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. If not provided, the default recommended text-to-video model will be used. + Defaults to None. + guidance_scale (`float`, *optional*): + A higher guidance scale value encourages the model to generate videos closely linked to the text + prompt, but values too high may cause saturation and other artifacts. + negative_prompt (`list[str]`, *optional*): + One or several prompt to guide what NOT to include in video generation. + num_frames (`float`, *optional*): + The num_frames parameter determines how many video frames are generated. + num_inference_steps (`int`, *optional*): + The number of denoising steps. More denoising steps usually lead to a higher quality video at the + expense of slower inference. + seed (`int`, *optional*): + Seed for the random number generator. + extra_body (`dict[str, Any]`, *optional*): + Additional provider-specific parameters to pass to the model. Refer to the provider's documentation + for supported parameters. + + Returns: + `bytes`: The generated video. + + Example: + + Example using a third-party provider directly. Usage will be billed on your fal.ai account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="fal-ai", # Using fal.ai provider + ... api_key="fal-ai-api-key", # Pass your fal.ai API key + ... ) + >>> video = client.text_to_video( + ... "A majestic lion running in a fantasy forest", + ... model="tencent/HunyuanVideo", + ... ) + >>> with open("lion.mp4", "wb") as file: + ... file.write(video) + ``` + + Example using a third-party provider through Hugging Face Routing. Usage will be billed on your Hugging Face account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="replicate", # Using replicate provider + ... api_key="hf_...", # Pass your HF token + ... ) + >>> video = client.text_to_video( + ... "A cat running in a park", + ... model="genmo/mochi-1-preview", + ... ) + >>> with open("cat.mp4", "wb") as file: + ... file.write(video) + ``` + + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="text-to-video", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=prompt, + parameters={ + "guidance_scale": guidance_scale, + "negative_prompt": negative_prompt, + "num_frames": num_frames, + "num_inference_steps": num_inference_steps, + "seed": seed, + **(extra_body or {}), + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + response = provider_helper.get_response(response, request_parameters) + return response + + async def text_to_speech( + self, + text: str, + *, + model: str | None = None, + do_sample: bool | None = None, + early_stopping: Union[bool, "TextToSpeechEarlyStoppingEnum"] | None = None, + epsilon_cutoff: float | None = None, + eta_cutoff: float | None = None, + max_length: int | None = None, + max_new_tokens: int | None = None, + min_length: int | None = None, + min_new_tokens: int | None = None, + num_beam_groups: int | None = None, + num_beams: int | None = None, + penalty_alpha: float | None = None, + temperature: float | None = None, + top_k: int | None = None, + top_p: float | None = None, + typical_p: float | None = None, + use_cache: bool | None = None, + extra_body: dict[str, Any] | None = None, + ) -> bytes: + """ + Synthesize an audio of a voice pronouncing a given text. + + > [!TIP] + > You can pass provider-specific parameters to the model by using the `extra_body` argument. + + Args: + text (`str`): + The text to synthesize. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. If not provided, the default recommended text-to-speech model will be used. + Defaults to None. + do_sample (`bool`, *optional*): + Whether to use sampling instead of greedy decoding when generating new tokens. + early_stopping (`Union[bool, "TextToSpeechEarlyStoppingEnum"]`, *optional*): + Controls the stopping condition for beam-based methods. + epsilon_cutoff (`float`, *optional*): + If set to float strictly between 0 and 1, only tokens with a conditional probability greater than + epsilon_cutoff will be sampled. In the paper, suggested values range from 3e-4 to 9e-4, depending on + the size of the model. See [Truncation Sampling as Language Model + Desmoothing](https://hf.co/papers/2210.15191) for more details. + eta_cutoff (`float`, *optional*): + Eta sampling is a hybrid of locally typical sampling and epsilon sampling. If set to float strictly + between 0 and 1, a token is only considered if it is greater than either eta_cutoff or sqrt(eta_cutoff) + * exp(-entropy(softmax(next_token_logits))). The latter term is intuitively the expected next token + probability, scaled by sqrt(eta_cutoff). In the paper, suggested values range from 3e-4 to 2e-3, + depending on the size of the model. See [Truncation Sampling as Language Model + Desmoothing](https://hf.co/papers/2210.15191) for more details. + max_length (`int`, *optional*): + The maximum length (in tokens) of the generated text, including the input. + max_new_tokens (`int`, *optional*): + The maximum number of tokens to generate. Takes precedence over max_length. + min_length (`int`, *optional*): + The minimum length (in tokens) of the generated text, including the input. + min_new_tokens (`int`, *optional*): + The minimum number of tokens to generate. Takes precedence over min_length. + num_beam_groups (`int`, *optional*): + Number of groups to divide num_beams into in order to ensure diversity among different groups of beams. + See [this paper](https://hf.co/papers/1610.02424) for more details. + num_beams (`int`, *optional*): + Number of beams to use for beam search. + penalty_alpha (`float`, *optional*): + The value balances the model confidence and the degeneration penalty in contrastive search decoding. + temperature (`float`, *optional*): + The value used to modulate the next token probabilities. + top_k (`int`, *optional*): + The number of highest probability vocabulary tokens to keep for top-k-filtering. + top_p (`float`, *optional*): + If set to float < 1, only the smallest set of most probable tokens with probabilities that add up to + top_p or higher are kept for generation. + typical_p (`float`, *optional*): + Local typicality measures how similar the conditional probability of predicting a target token next is + to the expected conditional probability of predicting a random token next, given the partial text + already generated. If set to float < 1, the smallest set of the most locally typical tokens with + probabilities that add up to typical_p or higher are kept for generation. See [this + paper](https://hf.co/papers/2202.00666) for more details. + use_cache (`bool`, *optional*): + Whether the model should use the past last key/values attentions to speed up decoding + extra_body (`dict[str, Any]`, *optional*): + Additional provider-specific parameters to pass to the model. Refer to the provider's documentation + for supported parameters. + Returns: + `bytes`: The generated audio. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from pathlib import Path + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + + >>> audio = await client.text_to_speech("Hello world") + >>> Path("hello_world.flac").write_bytes(audio) + ``` + + Example using a third-party provider directly. Usage will be billed on your Replicate account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="replicate", + ... api_key="your-replicate-api-key", # Pass your Replicate API key directly + ... ) + >>> audio = client.text_to_speech( + ... text="Hello world", + ... model="OuteAI/OuteTTS-0.3-500M", + ... ) + >>> Path("hello_world.flac").write_bytes(audio) + ``` + + Example using a third-party provider through Hugging Face Routing. Usage will be billed on your Hugging Face account. + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="replicate", + ... api_key="hf_...", # Pass your HF token + ... ) + >>> audio =client.text_to_speech( + ... text="Hello world", + ... model="OuteAI/OuteTTS-0.3-500M", + ... ) + >>> Path("hello_world.flac").write_bytes(audio) + ``` + Example using Replicate provider with extra parameters + ```py + >>> from huggingface_hub import InferenceClient + >>> client = InferenceClient( + ... provider="replicate", # Use replicate provider + ... api_key="hf_...", # Pass your HF token + ... ) + >>> audio = client.text_to_speech( + ... "Hello, my name is Kororo, an awesome text-to-speech model.", + ... model="hexgrad/Kokoro-82M", + ... extra_body={"voice": "af_nicole"}, + ... ) + >>> Path("hello.flac").write_bytes(audio) + ``` + + Example music-gen using "YuE-s1-7B-anneal-en-cot" on fal.ai + ```py + >>> from huggingface_hub import InferenceClient + >>> lyrics = ''' + ... [verse] + ... In the town where I was born + ... Lived a man who sailed to sea + ... And he told us of his life + ... In the land of submarines + ... So we sailed on to the sun + ... 'Til we found a sea of green + ... And we lived beneath the waves + ... In our yellow submarine + + ... [chorus] + ... We all live in a yellow submarine + ... Yellow submarine, yellow submarine + ... We all live in a yellow submarine + ... Yellow submarine, yellow submarine + ... ''' + >>> genres = "pavarotti-style tenor voice" + >>> client = InferenceClient( + ... provider="fal-ai", + ... model="m-a-p/YuE-s1-7B-anneal-en-cot", + ... api_key=..., + ... ) + >>> audio = client.text_to_speech(lyrics, extra_body={"genres": genres}) + >>> with open("output.mp3", "wb") as f: + ... f.write(audio) + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="text-to-speech", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters={ + "do_sample": do_sample, + "early_stopping": early_stopping, + "epsilon_cutoff": epsilon_cutoff, + "eta_cutoff": eta_cutoff, + "max_length": max_length, + "max_new_tokens": max_new_tokens, + "min_length": min_length, + "min_new_tokens": min_new_tokens, + "num_beam_groups": num_beam_groups, + "num_beams": num_beams, + "penalty_alpha": penalty_alpha, + "temperature": temperature, + "top_k": top_k, + "top_p": top_p, + "typical_p": typical_p, + "use_cache": use_cache, + **(extra_body or {}), + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + response = provider_helper.get_response(response) + return response + + async def token_classification( + self, + text: str, + *, + model: str | None = None, + aggregation_strategy: Optional["TokenClassificationAggregationStrategy"] = None, + ignore_labels: list[str] | None = None, + stride: int | None = None, + ) -> list[TokenClassificationOutputElement]: + """ + Perform token classification on the given text. + Usually used for sentence parsing, either grammatical, or Named Entity Recognition (NER) to understand keywords contained within text. + + Args: + text (`str`): + A string to be classified. + model (`str`, *optional*): + The model to use for the token classification task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended token classification model will be used. + Defaults to None. + aggregation_strategy (`"TokenClassificationAggregationStrategy"`, *optional*): + The strategy used to fuse tokens based on model predictions + ignore_labels (`list[str`, *optional*): + A list of labels to ignore + stride (`int`, *optional*): + The number of overlapping tokens between chunks when splitting the input text. + + Returns: + `list[TokenClassificationOutputElement]`: List of [`TokenClassificationOutputElement`] items containing the entity group, confidence score, word, start and end index. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.token_classification("My name is Sarah Jessica Parker but you can call me Jessica") + [ + TokenClassificationOutputElement( + entity_group='PER', + score=0.9971321225166321, + word='Sarah Jessica Parker', + start=11, + end=31, + ), + TokenClassificationOutputElement( + entity_group='PER', + score=0.9773476123809814, + word='Jessica', + start=52, + end=59, + ) + ] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="token-classification", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters={ + "aggregation_strategy": aggregation_strategy, + "ignore_labels": ignore_labels, + "stride": stride, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + return TokenClassificationOutputElement.parse_obj_as_list(response) + + async def translation( + self, + text: str, + *, + model: str | None = None, + src_lang: str | None = None, + tgt_lang: str | None = None, + clean_up_tokenization_spaces: bool | None = None, + truncation: Optional["TranslationTruncationStrategy"] = None, + generate_parameters: dict[str, Any] | None = None, + ) -> TranslationOutput: + """ + Convert text from one language to another. + + Check out https://huggingface.co/tasks/translation for more information on how to choose the best model for + your specific use case. Source and target languages usually depend on the model. + However, it is possible to specify source and target languages for certain models. If you are working with one of these models, + you can use `src_lang` and `tgt_lang` arguments to pass the relevant information. + + Args: + text (`str`): + A string to be translated. + model (`str`, *optional*): + The model to use for the translation task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended translation model will be used. + Defaults to None. + src_lang (`str`, *optional*): + The source language of the text. Required for models that can translate from multiple languages. + tgt_lang (`str`, *optional*): + Target language to translate to. Required for models that can translate to multiple languages. + clean_up_tokenization_spaces (`bool`, *optional*): + Whether to clean up the potential extra spaces in the text output. + truncation (`"TranslationTruncationStrategy"`, *optional*): + The truncation strategy to use. + generate_parameters (`dict[str, Any]`, *optional*): + Additional parametrization of the text generation algorithm. + + Returns: + [`TranslationOutput`]: The generated translated text. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + `ValueError`: + If only one of the `src_lang` and `tgt_lang` arguments are provided. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.translation("My name is Wolfgang and I live in Berlin") + 'Mein Name ist Wolfgang und ich lebe in Berlin.' + >>> await client.translation("My name is Wolfgang and I live in Berlin", model="Helsinki-NLP/opus-mt-en-fr") + TranslationOutput(translation_text='Je m'appelle Wolfgang et je vis à Berlin.') + ``` + + Specifying languages: + ```py + >>> client.translation("My name is Sarah Jessica Parker but you can call me Jessica", model="facebook/mbart-large-50-many-to-many-mmt", src_lang="en_XX", tgt_lang="fr_XX") + "Mon nom est Sarah Jessica Parker mais vous pouvez m'appeler Jessica" + ``` + """ + # Throw error if only one of `src_lang` and `tgt_lang` was given + if src_lang is not None and tgt_lang is None: + raise ValueError("You cannot specify `src_lang` without specifying `tgt_lang`.") + + if src_lang is None and tgt_lang is not None: + raise ValueError("You cannot specify `tgt_lang` without specifying `src_lang`.") + + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="translation", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters={ + "src_lang": src_lang, + "tgt_lang": tgt_lang, + "clean_up_tokenization_spaces": clean_up_tokenization_spaces, + "truncation": truncation, + "generate_parameters": generate_parameters, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + return TranslationOutput.parse_obj_as_list(response)[0] + + async def visual_question_answering( + self, + image: ContentT, + question: str, + *, + model: str | None = None, + top_k: int | None = None, + ) -> list[VisualQuestionAnsweringOutputElement]: + """ + Answering open-ended questions based on an image. + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The input image for the context. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + question (`str`): + Question to be answered. + model (`str`, *optional*): + The model to use for the visual question answering task. Can be a model ID hosted on the Hugging Face Hub or a URL to + a deployed Inference Endpoint. If not provided, the default recommended visual question answering model will be used. + Defaults to None. + top_k (`int`, *optional*): + The number of answers to return (will be chosen by order of likelihood). Note that we return less than + topk answers if there are not enough options available within the context. + Returns: + `list[VisualQuestionAnsweringOutputElement]`: a list of [`VisualQuestionAnsweringOutputElement`] items containing the predicted label and associated probability. + + Raises: + `InferenceTimeoutError`: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.visual_question_answering( + ... image="https://huggingface.co/datasets/mishig/sample_images/resolve/main/tiger.jpg", + ... question="What is the animal doing?" + ... ) + [ + VisualQuestionAnsweringOutputElement(score=0.778609573841095, answer='laying down'), + VisualQuestionAnsweringOutputElement(score=0.6957435607910156, answer='sitting'), + ] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="visual-question-answering", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={"top_k": top_k}, + headers=self.headers, + model=model_id, + api_key=self.token, + extra_payload={"question": question, "image": _b64_encode(image)}, + ) + response = await self._inner_post(request_parameters) + return VisualQuestionAnsweringOutputElement.parse_obj_as_list(response) + + async def zero_shot_classification( + self, + text: str, + candidate_labels: list[str], + *, + multi_label: bool | None = False, + hypothesis_template: str | None = None, + model: str | None = None, + ) -> list[ZeroShotClassificationOutputElement]: + """ + Provide as input a text and a set of candidate labels to classify the input text. + + Args: + text (`str`): + The input text to classify. + candidate_labels (`list[str]`): + The set of possible class labels to classify the text into. + labels (`list[str]`, *optional*): + (deprecated) List of strings. Each string is the verbalization of a possible label for the input text. + multi_label (`bool`, *optional*): + Whether multiple candidate labels can be true. If false, the scores are normalized such that the sum of + the label likelihoods for each sequence is 1. If true, the labels are considered independent and + probabilities are normalized for each candidate. + hypothesis_template (`str`, *optional*): + The sentence used in conjunction with `candidate_labels` to attempt the text classification by + replacing the placeholder with the candidate labels. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. This parameter overrides the model defined at the instance level. If not provided, the default recommended zero-shot classification model will be used. + + + Returns: + `list[ZeroShotClassificationOutputElement]`: List of [`ZeroShotClassificationOutputElement`] items containing the predicted labels and their confidence. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example with `multi_label=False`: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> text = ( + ... "A new model offers an explanation for how the Galilean satellites formed around the solar system's" + ... "largest world. Konstantin Batygin did not set out to solve one of the solar system's most puzzling" + ... " mysteries when he went for a run up a hill in Nice, France." + ... ) + >>> labels = ["space & cosmos", "scientific discovery", "microbiology", "robots", "archeology"] + >>> await client.zero_shot_classification(text, labels) + [ + ZeroShotClassificationOutputElement(label='scientific discovery', score=0.7961668968200684), + ZeroShotClassificationOutputElement(label='space & cosmos', score=0.18570658564567566), + ZeroShotClassificationOutputElement(label='microbiology', score=0.00730885099619627), + ZeroShotClassificationOutputElement(label='archeology', score=0.006258360575884581), + ZeroShotClassificationOutputElement(label='robots', score=0.004559356719255447), + ] + >>> await client.zero_shot_classification(text, labels, multi_label=True) + [ + ZeroShotClassificationOutputElement(label='scientific discovery', score=0.9829297661781311), + ZeroShotClassificationOutputElement(label='space & cosmos', score=0.755190908908844), + ZeroShotClassificationOutputElement(label='microbiology', score=0.0005462635890580714), + ZeroShotClassificationOutputElement(label='archeology', score=0.00047131875180639327), + ZeroShotClassificationOutputElement(label='robots', score=0.00030448526376858354), + ] + ``` + + Example with `multi_label=True` and a custom `hypothesis_template`: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + >>> await client.zero_shot_classification( + ... text="I really like our dinner and I'm very happy. I don't like the weather though.", + ... labels=["positive", "negative", "pessimistic", "optimistic"], + ... multi_label=True, + ... hypothesis_template="This text is {} towards the weather" + ... ) + [ + ZeroShotClassificationOutputElement(label='negative', score=0.9231801629066467), + ZeroShotClassificationOutputElement(label='pessimistic', score=0.8760990500450134), + ZeroShotClassificationOutputElement(label='optimistic', score=0.0008674879791215062), + ZeroShotClassificationOutputElement(label='positive', score=0.0005250611575320363) + ] + ``` + """ + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="zero-shot-classification", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=text, + parameters={ + "candidate_labels": candidate_labels, + "multi_label": multi_label, + "hypothesis_template": hypothesis_template, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + output = _bytes_to_dict(response) + return ZeroShotClassificationOutputElement.parse_obj_as_list(output) + + async def zero_shot_image_classification( + self, + image: ContentT, + candidate_labels: list[str], + *, + model: str | None = None, + hypothesis_template: str | None = None, + # deprecated argument + labels: list[str] = None, # type: ignore + ) -> list[ZeroShotImageClassificationOutputElement]: + """ + Provide input image and text labels to predict text labels for the image. + + Args: + image (`Union[str, Path, bytes, BinaryIO, PIL.Image.Image]`): + The input image to caption. It can be raw bytes, an image file, a URL to an online image, or a PIL Image. + candidate_labels (`list[str]`): + The candidate labels for this image + labels (`list[str]`, *optional*): + (deprecated) List of string possible labels. There must be at least 2 labels. + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. This parameter overrides the model defined at the instance level. If not provided, the default recommended zero-shot image classification model will be used. + hypothesis_template (`str`, *optional*): + The sentence used in conjunction with `candidate_labels` to attempt the image classification by + replacing the placeholder with the candidate labels. + + Returns: + `list[ZeroShotImageClassificationOutputElement]`: List of [`ZeroShotImageClassificationOutputElement`] items containing the predicted labels and their confidence. + + Raises: + [`InferenceTimeoutError`]: + If the model is unavailable or the request times out. + [`HfHubHTTPError`]: + If the request fails with an HTTP error status code other than HTTP 503. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient() + + >>> await client.zero_shot_image_classification( + ... "https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Cute_dog.jpg/320px-Cute_dog.jpg", + ... labels=["dog", "cat", "horse"], + ... ) + [ZeroShotImageClassificationOutputElement(label='dog', score=0.956),...] + ``` + """ + # Raise ValueError if input is less than 2 labels + if len(candidate_labels) < 2: + raise ValueError("You must specify at least 2 classes to compare.") + + model_id = model or self.model + provider_helper = get_provider_helper(self.provider, task="zero-shot-image-classification", model=model_id) + request_parameters = provider_helper.prepare_request( + inputs=image, + parameters={ + "candidate_labels": candidate_labels, + "hypothesis_template": hypothesis_template, + }, + headers=self.headers, + model=model_id, + api_key=self.token, + ) + response = await self._inner_post(request_parameters) + return ZeroShotImageClassificationOutputElement.parse_obj_as_list(response) + + async def get_endpoint_info(self, *, model: str | None = None) -> dict[str, Any]: + """ + Get information about the deployed endpoint. + + This endpoint is only available on endpoints powered by Text-Generation-Inference (TGI) or Text-Embedding-Inference (TEI). + Endpoints powered by `transformers` return an empty payload. + + Args: + model (`str`, *optional*): + The model to use for inference. Can be a model ID hosted on the Hugging Face Hub or a URL to a deployed + Inference Endpoint. This parameter overrides the model defined at the instance level. Defaults to None. + + Returns: + `dict[str, Any]`: Information about the endpoint. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient("meta-llama/Meta-Llama-3-70B-Instruct") + >>> await client.get_endpoint_info() + { + 'model_id': 'meta-llama/Meta-Llama-3-70B-Instruct', + 'model_sha': None, + 'model_dtype': 'torch.float16', + 'model_device_type': 'cuda', + 'model_pipeline_tag': None, + 'max_concurrent_requests': 128, + 'max_best_of': 2, + 'max_stop_sequences': 4, + 'max_input_length': 8191, + 'max_total_tokens': 8192, + 'waiting_served_ratio': 0.3, + 'max_batch_total_tokens': 1259392, + 'max_waiting_tokens': 20, + 'max_batch_size': None, + 'validation_workers': 32, + 'max_client_batch_size': 4, + 'version': '2.0.2', + 'sha': 'dccab72549635c7eb5ddb17f43f0b7cdff07c214', + 'docker_label': 'sha-dccab72' + } + ``` + """ + if self.provider != "hf-inference": + raise ValueError(f"Getting endpoint info is not supported on '{self.provider}'.") + + model = model or self.model + if model is None: + raise ValueError("Model id not provided.") + if model.startswith(("http://", "https://")): + url = model.rstrip("/") + "/info" + else: + url = f"{constants.INFERENCE_ENDPOINT}/models/{model}/info" + + client = await self._get_async_client() + response = await client.get(url, headers=build_hf_headers(token=self.token)) + hf_raise_for_status(response) + return response.json() + + async def health_check(self, model: str | None = None) -> bool: + """ + Check the health of the deployed endpoint. + + Health check is only available with Inference Endpoints powered by Text-Generation-Inference (TGI) or Text-Embedding-Inference (TEI). + + Args: + model (`str`, *optional*): + URL of the Inference Endpoint. This parameter overrides the model defined at the instance level. Defaults to None. + + Returns: + `bool`: True if everything is working fine. + + Example: + ```py + # Must be run in an async context + >>> from huggingface_hub import AsyncInferenceClient + >>> client = AsyncInferenceClient("https://jzgu0buei5.us-east-1.aws.endpoints.huggingface.cloud") + >>> await client.health_check() + True + ``` + """ + if self.provider != "hf-inference": + raise ValueError(f"Health check is not supported on '{self.provider}'.") + + model = model or self.model + if model is None: + raise ValueError("Model id not provided.") + if not model.startswith(("http://", "https://")): + raise ValueError("Model must be an Inference Endpoint URL.") + url = model.rstrip("/") + "/health" + + client = await self._get_async_client() + response = await client.get(url, headers=build_hf_headers(token=self.token)) + return response.status_code == 200 + + @property + def chat(self) -> "ProxyClientChat": + return ProxyClientChat(self) + + +class _ProxyClient: + """Proxy class to be able to call `client.chat.completion.create(...)` as OpenAI client.""" + + def __init__(self, client: AsyncInferenceClient): + self._client = client + + +class ProxyClientChat(_ProxyClient): + """Proxy class to be able to call `client.chat.completion.create(...)` as OpenAI client.""" + + @property + def completions(self) -> "ProxyClientChatCompletions": + return ProxyClientChatCompletions(self._client) + + +class ProxyClientChatCompletions(_ProxyClient): + """Proxy class to be able to call `client.chat.completion.create(...)` as OpenAI client.""" + + @property + def create(self): + return self._client.chat_completion diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/__init__.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9f95dca555d80774ec863bf26d147dd43f15aeb6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/__init__.py @@ -0,0 +1,204 @@ +# This file is auto-generated by `utils/generate_inference_types.py`. +# Do not modify it manually. +# +# ruff: noqa: F401 + +from .audio_classification import ( + AudioClassificationInput, + AudioClassificationOutputElement, + AudioClassificationOutputTransform, + AudioClassificationParameters, +) +from .audio_to_audio import AudioToAudioInput, AudioToAudioOutputElement +from .automatic_speech_recognition import ( + AutomaticSpeechRecognitionEarlyStoppingEnum, + AutomaticSpeechRecognitionGenerationParameters, + AutomaticSpeechRecognitionInput, + AutomaticSpeechRecognitionOutput, + AutomaticSpeechRecognitionOutputChunk, + AutomaticSpeechRecognitionParameters, +) +from .base import BaseInferenceType +from .chat_completion import ( + ChatCompletionInput, + ChatCompletionInputFunctionDefinition, + ChatCompletionInputFunctionName, + ChatCompletionInputGrammarType, + ChatCompletionInputJSONSchema, + ChatCompletionInputMessage, + ChatCompletionInputMessageChunk, + ChatCompletionInputMessageChunkType, + ChatCompletionInputResponseFormatJSONObject, + ChatCompletionInputResponseFormatJSONSchema, + ChatCompletionInputResponseFormatText, + ChatCompletionInputStreamOptions, + ChatCompletionInputTool, + ChatCompletionInputToolCall, + ChatCompletionInputToolChoiceClass, + ChatCompletionInputToolChoiceEnum, + ChatCompletionInputURL, + ChatCompletionOutput, + ChatCompletionOutputComplete, + ChatCompletionOutputFunctionDefinition, + ChatCompletionOutputLogprob, + ChatCompletionOutputLogprobs, + ChatCompletionOutputMessage, + ChatCompletionOutputToolCall, + ChatCompletionOutputTopLogprob, + ChatCompletionOutputUsage, + ChatCompletionStreamOutput, + ChatCompletionStreamOutputChoice, + ChatCompletionStreamOutputDelta, + ChatCompletionStreamOutputDeltaToolCall, + ChatCompletionStreamOutputFunction, + ChatCompletionStreamOutputLogprob, + ChatCompletionStreamOutputLogprobs, + ChatCompletionStreamOutputTopLogprob, + ChatCompletionStreamOutputUsage, +) +from .depth_estimation import DepthEstimationInput, DepthEstimationOutput +from .document_question_answering import ( + DocumentQuestionAnsweringInput, + DocumentQuestionAnsweringInputData, + DocumentQuestionAnsweringOutputElement, + DocumentQuestionAnsweringParameters, +) +from .feature_extraction import FeatureExtractionInput, FeatureExtractionInputTruncationDirection +from .fill_mask import FillMaskInput, FillMaskOutputElement, FillMaskParameters +from .image_classification import ( + ImageClassificationInput, + ImageClassificationOutputElement, + ImageClassificationOutputTransform, + ImageClassificationParameters, +) +from .image_segmentation import ( + ImageSegmentationInput, + ImageSegmentationOutputElement, + ImageSegmentationParameters, + ImageSegmentationSubtask, +) +from .image_text_to_image import ( + ImageTextToImageInput, + ImageTextToImageOutput, + ImageTextToImageParameters, + ImageTextToImageTargetSize, +) +from .image_text_to_video import ( + ImageTextToVideoInput, + ImageTextToVideoOutput, + ImageTextToVideoParameters, + ImageTextToVideoTargetSize, +) +from .image_to_image import ImageToImageInput, ImageToImageOutput, ImageToImageParameters, ImageToImageTargetSize +from .image_to_text import ( + ImageToTextEarlyStoppingEnum, + ImageToTextGenerationParameters, + ImageToTextInput, + ImageToTextOutput, + ImageToTextParameters, +) +from .image_to_video import ImageToVideoInput, ImageToVideoOutput, ImageToVideoParameters, ImageToVideoTargetSize +from .object_detection import ( + ObjectDetectionBoundingBox, + ObjectDetectionInput, + ObjectDetectionOutputElement, + ObjectDetectionParameters, +) +from .question_answering import ( + QuestionAnsweringInput, + QuestionAnsweringInputData, + QuestionAnsweringOutputElement, + QuestionAnsweringParameters, +) +from .sentence_similarity import SentenceSimilarityInput, SentenceSimilarityInputData +from .summarization import ( + SummarizationInput, + SummarizationOutput, + SummarizationParameters, + SummarizationTruncationStrategy, +) +from .table_question_answering import ( + Padding, + TableQuestionAnsweringInput, + TableQuestionAnsweringInputData, + TableQuestionAnsweringOutputElement, + TableQuestionAnsweringParameters, +) +from .text2text_generation import ( + Text2TextGenerationInput, + Text2TextGenerationOutput, + Text2TextGenerationParameters, + Text2TextGenerationTruncationStrategy, +) +from .text_classification import ( + TextClassificationInput, + TextClassificationOutputElement, + TextClassificationOutputTransform, + TextClassificationParameters, +) +from .text_generation import ( + TextGenerationInput, + TextGenerationInputGenerateParameters, + TextGenerationInputGrammarType, + TextGenerationOutput, + TextGenerationOutputBestOfSequence, + TextGenerationOutputDetails, + TextGenerationOutputFinishReason, + TextGenerationOutputPrefillToken, + TextGenerationOutputToken, + TextGenerationStreamOutput, + TextGenerationStreamOutputStreamDetails, + TextGenerationStreamOutputToken, + TypeEnum, +) +from .text_to_audio import ( + TextToAudioEarlyStoppingEnum, + TextToAudioGenerationParameters, + TextToAudioInput, + TextToAudioOutput, + TextToAudioParameters, +) +from .text_to_image import TextToImageInput, TextToImageOutput, TextToImageParameters +from .text_to_speech import ( + TextToSpeechEarlyStoppingEnum, + TextToSpeechGenerationParameters, + TextToSpeechInput, + TextToSpeechOutput, + TextToSpeechParameters, +) +from .text_to_video import TextToVideoInput, TextToVideoOutput, TextToVideoParameters +from .token_classification import ( + TokenClassificationAggregationStrategy, + TokenClassificationInput, + TokenClassificationOutputElement, + TokenClassificationParameters, +) +from .translation import TranslationInput, TranslationOutput, TranslationParameters, TranslationTruncationStrategy +from .video_classification import ( + VideoClassificationInput, + VideoClassificationOutputElement, + VideoClassificationOutputTransform, + VideoClassificationParameters, +) +from .visual_question_answering import ( + VisualQuestionAnsweringInput, + VisualQuestionAnsweringInputData, + VisualQuestionAnsweringOutputElement, + VisualQuestionAnsweringParameters, +) +from .zero_shot_classification import ( + ZeroShotClassificationInput, + ZeroShotClassificationOutputElement, + ZeroShotClassificationParameters, +) +from .zero_shot_image_classification import ( + ZeroShotImageClassificationInput, + ZeroShotImageClassificationOutputElement, + ZeroShotImageClassificationParameters, +) +from .zero_shot_object_detection import ( + ZeroShotObjectDetectionBoundingBox, + ZeroShotObjectDetectionInput, + ZeroShotObjectDetectionOutputElement, + ZeroShotObjectDetectionParameters, +) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/audio_classification.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/audio_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..b99507c4a7caaeaa306a5b20348c36eb2099b2e2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/audio_classification.py @@ -0,0 +1,43 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Literal, Optional + +from .base import BaseInferenceType, dataclass_with_extra + + +AudioClassificationOutputTransform = Literal["sigmoid", "softmax", "none"] + + +@dataclass_with_extra +class AudioClassificationParameters(BaseInferenceType): + """Additional inference parameters for Audio Classification""" + + function_to_apply: Optional["AudioClassificationOutputTransform"] = None + """The function to apply to the model outputs in order to retrieve the scores.""" + top_k: int | None = None + """When specified, limits the output to the top K most probable classes.""" + + +@dataclass_with_extra +class AudioClassificationInput(BaseInferenceType): + """Inputs for Audio Classification inference""" + + inputs: str + """The input audio data as a base64-encoded string. If no `parameters` are provided, you can + also provide the audio data as a raw bytes payload. + """ + parameters: AudioClassificationParameters | None = None + """Additional inference parameters for Audio Classification""" + + +@dataclass_with_extra +class AudioClassificationOutputElement(BaseInferenceType): + """Outputs for Audio Classification inference""" + + label: str + """The predicted class label.""" + score: float + """The corresponding probability.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/audio_to_audio.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/audio_to_audio.py new file mode 100644 index 0000000000000000000000000000000000000000..43f376b5345fab6b854b028d1c17416c020d7bc1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/audio_to_audio.py @@ -0,0 +1,30 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any + +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class AudioToAudioInput(BaseInferenceType): + """Inputs for Audio to Audio inference""" + + inputs: Any + """The input audio data""" + + +@dataclass_with_extra +class AudioToAudioOutputElement(BaseInferenceType): + """Outputs of inference for the Audio To Audio task + A generated audio file with its label. + """ + + blob: Any + """The generated audio file.""" + content_type: str + """The content type of audio file.""" + label: str + """The label of the audio file.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/automatic_speech_recognition.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/automatic_speech_recognition.py new file mode 100644 index 0000000000000000000000000000000000000000..9d728bfdb83377c6726fce804013a33fdb2fbdbd --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/automatic_speech_recognition.py @@ -0,0 +1,113 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Literal, Union + +from .base import BaseInferenceType, dataclass_with_extra + + +AutomaticSpeechRecognitionEarlyStoppingEnum = Literal["never"] + + +@dataclass_with_extra +class AutomaticSpeechRecognitionGenerationParameters(BaseInferenceType): + """Parametrization of the text generation process""" + + do_sample: bool | None = None + """Whether to use sampling instead of greedy decoding when generating new tokens.""" + early_stopping: Union[bool, "AutomaticSpeechRecognitionEarlyStoppingEnum"] | None = None + """Controls the stopping condition for beam-based methods.""" + epsilon_cutoff: float | None = None + """If set to float strictly between 0 and 1, only tokens with a conditional probability + greater than epsilon_cutoff will be sampled. In the paper, suggested values range from + 3e-4 to 9e-4, depending on the size of the model. See [Truncation Sampling as Language + Model Desmoothing](https://hf.co/papers/2210.15191) for more details. + """ + eta_cutoff: float | None = None + """Eta sampling is a hybrid of locally typical sampling and epsilon sampling. If set to + float strictly between 0 and 1, a token is only considered if it is greater than either + eta_cutoff or sqrt(eta_cutoff) * exp(-entropy(softmax(next_token_logits))). The latter + term is intuitively the expected next token probability, scaled by sqrt(eta_cutoff). In + the paper, suggested values range from 3e-4 to 2e-3, depending on the size of the model. + See [Truncation Sampling as Language Model Desmoothing](https://hf.co/papers/2210.15191) + for more details. + """ + max_length: int | None = None + """The maximum length (in tokens) of the generated text, including the input.""" + max_new_tokens: int | None = None + """The maximum number of tokens to generate. Takes precedence over max_length.""" + min_length: int | None = None + """The minimum length (in tokens) of the generated text, including the input.""" + min_new_tokens: int | None = None + """The minimum number of tokens to generate. Takes precedence over min_length.""" + num_beam_groups: int | None = None + """Number of groups to divide num_beams into in order to ensure diversity among different + groups of beams. See [this paper](https://hf.co/papers/1610.02424) for more details. + """ + num_beams: int | None = None + """Number of beams to use for beam search.""" + penalty_alpha: float | None = None + """The value balances the model confidence and the degeneration penalty in contrastive + search decoding. + """ + temperature: float | None = None + """The value used to modulate the next token probabilities.""" + top_k: int | None = None + """The number of highest probability vocabulary tokens to keep for top-k-filtering.""" + top_p: float | None = None + """If set to float < 1, only the smallest set of most probable tokens with probabilities + that add up to top_p or higher are kept for generation. + """ + typical_p: float | None = None + """Local typicality measures how similar the conditional probability of predicting a target + token next is to the expected conditional probability of predicting a random token next, + given the partial text already generated. If set to float < 1, the smallest set of the + most locally typical tokens with probabilities that add up to typical_p or higher are + kept for generation. See [this paper](https://hf.co/papers/2202.00666) for more details. + """ + use_cache: bool | None = None + """Whether the model should use the past last key/values attentions to speed up decoding""" + + +@dataclass_with_extra +class AutomaticSpeechRecognitionParameters(BaseInferenceType): + """Additional inference parameters for Automatic Speech Recognition""" + + generation_parameters: AutomaticSpeechRecognitionGenerationParameters | None = None + """Parametrization of the text generation process""" + return_timestamps: bool | None = None + """Whether to output corresponding timestamps with the generated text""" + + +@dataclass_with_extra +class AutomaticSpeechRecognitionInput(BaseInferenceType): + """Inputs for Automatic Speech Recognition inference""" + + inputs: str + """The input audio data as a base64-encoded string. If no `parameters` are provided, you can + also provide the audio data as a raw bytes payload. + """ + parameters: AutomaticSpeechRecognitionParameters | None = None + """Additional inference parameters for Automatic Speech Recognition""" + + +@dataclass_with_extra +class AutomaticSpeechRecognitionOutputChunk(BaseInferenceType): + text: str + """A chunk of text identified by the model""" + timestamp: list[float] + """The start and end timestamps corresponding with the text""" + + +@dataclass_with_extra +class AutomaticSpeechRecognitionOutput(BaseInferenceType): + """Outputs of inference for the Automatic Speech Recognition task""" + + text: str + """The recognized text.""" + chunks: list[AutomaticSpeechRecognitionOutputChunk] | None = None + """When returnTimestamps is enabled, chunks contains a list of audio chunks identified by + the model. + """ diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/base.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/base.py new file mode 100644 index 0000000000000000000000000000000000000000..ad4016f2d57d11e13dad44c161d3bce3ef741d50 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/base.py @@ -0,0 +1,167 @@ +# Copyright 2024 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains a base class for all inference types.""" + +import inspect +import json +import types +from dataclasses import asdict, dataclass +from typing import Any, TypeVar, get_args + +from typing_extensions import dataclass_transform + + +T = TypeVar("T", bound="BaseInferenceType") + + +def _repr_with_extra(self): + fields = list(self.__dataclass_fields__.keys()) + other_fields = list(k for k in self.__dict__ if k not in fields) + return f"{self.__class__.__name__}({', '.join(f'{k}={self.__dict__[k]!r}' for k in fields + other_fields)})" + + +@dataclass_transform() +def dataclass_with_extra(cls: type[T]) -> type[T]: + """Decorator to add a custom __repr__ method to a dataclass, showing all fields, including extra ones. + + This decorator only works with dataclasses that inherit from `BaseInferenceType`. + """ + cls = dataclass(cls) + cls.__repr__ = _repr_with_extra # type: ignore[method-assign] + return cls + + +@dataclass +class BaseInferenceType(dict): + """Base class for all inference types. + + Object is a dataclass and a dict for backward compatibility but plan is to remove the dict part in the future. + + Handle parsing from dict, list and json strings in a permissive way to ensure future-compatibility (e.g. all fields + are made optional, and non-expected fields are added as dict attributes). + """ + + @classmethod + def parse_obj_as_list(cls: type[T], data: bytes | str | list | dict) -> list[T]: + """Alias to parse server response and return a single instance. + + See `parse_obj` for more details. + """ + output = cls.parse_obj(data) + if not isinstance(output, list): + raise ValueError(f"Invalid input data for {cls}. Expected a list, but got {type(output)}.") + return output + + @classmethod + def parse_obj_as_instance(cls: type[T], data: bytes | str | list | dict) -> T: + """Alias to parse server response and return a single instance. + + See `parse_obj` for more details. + """ + output = cls.parse_obj(data) + if isinstance(output, list): + raise ValueError(f"Invalid input data for {cls}. Expected a single instance, but got a list.") + return output + + @classmethod + def parse_obj(cls: type[T], data: bytes | str | list | dict) -> list[T] | T: + """Parse server response as a dataclass or list of dataclasses. + + To enable future-compatibility, we want to handle cases where the server return more fields than expected. + In such cases, we don't want to raise an error but still create the dataclass object. Remaining fields are + added as dict attributes. + """ + # Parse server response (from bytes) + if isinstance(data, bytes): + data = data.decode() + if isinstance(data, str): + data = json.loads(data) + + # If a list, parse each item individually + if isinstance(data, list): + return [cls.parse_obj(d) for d in data] # type: ignore + + # At this point, we expect a dict + if not isinstance(data, dict): + raise ValueError(f"Invalid data type: {type(data)}") + + init_values = {} + other_values = {} + for key, value in data.items(): + key = normalize_key(key) + if key in cls.__dataclass_fields__ and cls.__dataclass_fields__[key].init: + if isinstance(value, dict) or isinstance(value, list): + field_type = cls.__dataclass_fields__[key].type + + # if `field_type` is a `BaseInferenceType`, parse it + if inspect.isclass(field_type) and issubclass(field_type, BaseInferenceType): + value = field_type.parse_obj(value) + + # otherwise, recursively parse nested dataclasses (if possible) + # `get_args` returns handle Union and Optional for us + else: + expected_types = get_args(field_type) + for expected_type in expected_types: + if ( + isinstance(expected_type, types.GenericAlias) and expected_type.__origin__ is list + ) or getattr(expected_type, "_name", None) == "List": + expected_type = get_args(expected_type)[ + 0 + ] # assume same type for all items in the list + if inspect.isclass(expected_type) and issubclass(expected_type, BaseInferenceType): + value = expected_type.parse_obj(value) + break + init_values[key] = value + else: + other_values[key] = value + + # Make all missing fields default to None + # => ensure that dataclass initialization will never fail even if the server does not return all fields. + for key in cls.__dataclass_fields__: + if key not in init_values: + init_values[key] = None + + # Initialize dataclass with expected values + item = cls(**init_values) + + # Add remaining fields as dict attributes + item.update(other_values) + + # Add remaining fields as extra dataclass fields. + # They won't be part of the dataclass fields but will be accessible as attributes. + # Use @dataclass_with_extra to show them in __repr__. + item.__dict__.update(other_values) + return item + + def __post_init__(self): + self.update(asdict(self)) + + def __setitem__(self, __key: Any, __value: Any) -> None: + # Hacky way to keep dataclass values in sync when dict is updated + super().__setitem__(__key, __value) + if __key in self.__dataclass_fields__ and getattr(self, __key, None) != __value: + self.__setattr__(__key, __value) + return + + def __setattr__(self, __name: str, __value: Any) -> None: + # Hacky way to keep dict values is sync when dataclass is updated + super().__setattr__(__name, __value) + if self.get(__name) != __value: + self[__name] = __value + return + + +def normalize_key(key: str) -> str: + # e.g "content-type" -> "content_type", "Accept" -> "accept" + return key.replace("-", "_").replace(" ", "_").lower() diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/chat_completion.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/chat_completion.py new file mode 100644 index 0000000000000000000000000000000000000000..3a5d69ef70ed25d0ed0731c6a6b536e3130cdd73 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/chat_completion.py @@ -0,0 +1,347 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any, Literal, Union + +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class ChatCompletionInputURL(BaseInferenceType): + url: str + + +ChatCompletionInputMessageChunkType = Literal["text", "image_url"] + + +@dataclass_with_extra +class ChatCompletionInputMessageChunk(BaseInferenceType): + type: "ChatCompletionInputMessageChunkType" + image_url: ChatCompletionInputURL | None = None + text: str | None = None + + +@dataclass_with_extra +class ChatCompletionInputFunctionDefinition(BaseInferenceType): + name: str + parameters: Any + description: str | None = None + + +@dataclass_with_extra +class ChatCompletionInputToolCall(BaseInferenceType): + function: ChatCompletionInputFunctionDefinition + id: str + type: str + + +@dataclass_with_extra +class ChatCompletionInputMessage(BaseInferenceType): + role: str + content: list[ChatCompletionInputMessageChunk] | str | None = None + name: str | None = None + tool_calls: list[ChatCompletionInputToolCall] | None = None + + +@dataclass_with_extra +class ChatCompletionInputJSONSchema(BaseInferenceType): + name: str + """ + The name of the response format. + """ + description: str | None = None + """ + A description of what the response format is for, used by the model to determine + how to respond in the format. + """ + schema: dict[str, object] | None = None + """ + The schema for the response format, described as a JSON Schema object. Learn how + to build JSON schemas [here](https://json-schema.org/). + """ + strict: bool | None = None + """ + Whether to enable strict schema adherence when generating the output. If set to + true, the model will always follow the exact schema defined in the `schema` + field. + """ + + +@dataclass_with_extra +class ChatCompletionInputResponseFormatText(BaseInferenceType): + type: Literal["text"] + + +@dataclass_with_extra +class ChatCompletionInputResponseFormatJSONSchema(BaseInferenceType): + type: Literal["json_schema"] + json_schema: ChatCompletionInputJSONSchema + + +@dataclass_with_extra +class ChatCompletionInputResponseFormatJSONObject(BaseInferenceType): + type: Literal["json_object"] + + +ChatCompletionInputGrammarType = Union[ + ChatCompletionInputResponseFormatText, + ChatCompletionInputResponseFormatJSONSchema, + ChatCompletionInputResponseFormatJSONObject, +] + + +@dataclass_with_extra +class ChatCompletionInputStreamOptions(BaseInferenceType): + include_usage: bool | None = None + """If set, an additional chunk will be streamed before the data: [DONE] message. The usage + field on this chunk shows the token usage statistics for the entire request, and the + choices field will always be an empty array. All other chunks will also include a usage + field, but with a null value. + """ + + +@dataclass_with_extra +class ChatCompletionInputFunctionName(BaseInferenceType): + name: str + + +@dataclass_with_extra +class ChatCompletionInputToolChoiceClass(BaseInferenceType): + function: ChatCompletionInputFunctionName + + +ChatCompletionInputToolChoiceEnum = Literal["auto", "none", "required"] + + +@dataclass_with_extra +class ChatCompletionInputTool(BaseInferenceType): + function: ChatCompletionInputFunctionDefinition + type: str + + +@dataclass_with_extra +class ChatCompletionInput(BaseInferenceType): + """Chat Completion Input. + Auto-generated from TGI specs. + For more details, check out + https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-tgi-import.ts. + """ + + messages: list[ChatCompletionInputMessage] + """A list of messages comprising the conversation so far.""" + frequency_penalty: float | None = None + """Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing + frequency in the text so far, + decreasing the model's likelihood to repeat the same line verbatim. + """ + logit_bias: list[float] | None = None + """UNUSED + Modify the likelihood of specified tokens appearing in the completion. Accepts a JSON + object that maps tokens + (specified by their token ID in the tokenizer) to an associated bias value from -100 to + 100. Mathematically, + the bias is added to the logits generated by the model prior to sampling. The exact + effect will vary per model, + but values between -1 and 1 should decrease or increase likelihood of selection; values + like -100 or 100 should + result in a ban or exclusive selection of the relevant token. + """ + logprobs: bool | None = None + """Whether to return log probabilities of the output tokens or not. If true, returns the log + probabilities of each + output token returned in the content of message. + """ + max_tokens: int | None = None + """The maximum number of tokens that can be generated in the chat completion.""" + model: str | None = None + """[UNUSED] ID of the model to use. See the model endpoint compatibility table for details + on which models work with the Chat API. + """ + n: int | None = None + """UNUSED + How many chat completion choices to generate for each input message. Note that you will + be charged based on the + number of generated tokens across all of the choices. Keep n as 1 to minimize costs. + """ + presence_penalty: float | None = None + """Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they + appear in the text so far, + increasing the model's likelihood to talk about new topics + """ + response_format: ChatCompletionInputGrammarType | None = None + seed: int | None = None + stop: list[str] | None = None + """Up to 4 sequences where the API will stop generating further tokens.""" + stream: bool | None = None + stream_options: ChatCompletionInputStreamOptions | None = None + temperature: float | None = None + """What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the + output more random, while + lower values like 0.2 will make it more focused and deterministic. + We generally recommend altering this or `top_p` but not both. + """ + tool_choice: Union[ChatCompletionInputToolChoiceClass, "ChatCompletionInputToolChoiceEnum"] | None = None + tool_prompt: str | None = None + """A prompt to be appended before the tools""" + tools: list[ChatCompletionInputTool] | None = None + """A list of tools the model may call. Currently, only functions are supported as a tool. + Use this to provide a list of + functions the model may generate JSON inputs for. + """ + top_logprobs: int | None = None + """An integer between 0 and 5 specifying the number of most likely tokens to return at each + token position, each with + an associated log probability. logprobs must be set to true if this parameter is used. + """ + top_p: float | None = None + """An alternative to sampling with temperature, called nucleus sampling, where the model + considers the results of the + tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% + probability mass are considered. + """ + + +@dataclass_with_extra +class ChatCompletionOutputTopLogprob(BaseInferenceType): + logprob: float + token: str + + +@dataclass_with_extra +class ChatCompletionOutputLogprob(BaseInferenceType): + logprob: float + token: str + top_logprobs: list[ChatCompletionOutputTopLogprob] + + +@dataclass_with_extra +class ChatCompletionOutputLogprobs(BaseInferenceType): + content: list[ChatCompletionOutputLogprob] + + +@dataclass_with_extra +class ChatCompletionOutputFunctionDefinition(BaseInferenceType): + arguments: str + name: str + description: str | None = None + + +@dataclass_with_extra +class ChatCompletionOutputToolCall(BaseInferenceType): + function: ChatCompletionOutputFunctionDefinition + id: str + type: str + + +@dataclass_with_extra +class ChatCompletionOutputMessage(BaseInferenceType): + role: str + content: str | None = None + reasoning: str | None = None + tool_call_id: str | None = None + tool_calls: list[ChatCompletionOutputToolCall] | None = None + + +@dataclass_with_extra +class ChatCompletionOutputComplete(BaseInferenceType): + finish_reason: str + index: int + message: ChatCompletionOutputMessage + logprobs: ChatCompletionOutputLogprobs | None = None + + +@dataclass_with_extra +class ChatCompletionOutputUsage(BaseInferenceType): + completion_tokens: int + prompt_tokens: int + total_tokens: int + + +@dataclass_with_extra +class ChatCompletionOutput(BaseInferenceType): + """Chat Completion Output. + Auto-generated from TGI specs. + For more details, check out + https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-tgi-import.ts. + """ + + choices: list[ChatCompletionOutputComplete] + created: int + id: str + model: str + system_fingerprint: str + usage: ChatCompletionOutputUsage + + +@dataclass_with_extra +class ChatCompletionStreamOutputFunction(BaseInferenceType): + arguments: str + name: str | None = None + + +@dataclass_with_extra +class ChatCompletionStreamOutputDeltaToolCall(BaseInferenceType): + function: ChatCompletionStreamOutputFunction + id: str + index: int + type: str + + +@dataclass_with_extra +class ChatCompletionStreamOutputDelta(BaseInferenceType): + role: str + content: str | None = None + reasoning: str | None = None + tool_call_id: str | None = None + tool_calls: list[ChatCompletionStreamOutputDeltaToolCall] | None = None + + +@dataclass_with_extra +class ChatCompletionStreamOutputTopLogprob(BaseInferenceType): + logprob: float + token: str + + +@dataclass_with_extra +class ChatCompletionStreamOutputLogprob(BaseInferenceType): + logprob: float + token: str + top_logprobs: list[ChatCompletionStreamOutputTopLogprob] + + +@dataclass_with_extra +class ChatCompletionStreamOutputLogprobs(BaseInferenceType): + content: list[ChatCompletionStreamOutputLogprob] + + +@dataclass_with_extra +class ChatCompletionStreamOutputChoice(BaseInferenceType): + delta: ChatCompletionStreamOutputDelta + index: int + finish_reason: str | None = None + logprobs: ChatCompletionStreamOutputLogprobs | None = None + + +@dataclass_with_extra +class ChatCompletionStreamOutputUsage(BaseInferenceType): + completion_tokens: int + prompt_tokens: int + total_tokens: int + + +@dataclass_with_extra +class ChatCompletionStreamOutput(BaseInferenceType): + """Chat Completion Stream Output. + Auto-generated from TGI specs. + For more details, check out + https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-tgi-import.ts. + """ + + choices: list[ChatCompletionStreamOutputChoice] + created: int + id: str + model: str + system_fingerprint: str + usage: ChatCompletionStreamOutputUsage | None = None diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/depth_estimation.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/depth_estimation.py new file mode 100644 index 0000000000000000000000000000000000000000..cf26998ed518acd9e0f16d2f0f0de264a941840c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/depth_estimation.py @@ -0,0 +1,28 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any + +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class DepthEstimationInput(BaseInferenceType): + """Inputs for Depth Estimation inference""" + + inputs: Any + """The input image data""" + parameters: dict[str, Any] | None = None + """Additional inference parameters for Depth Estimation""" + + +@dataclass_with_extra +class DepthEstimationOutput(BaseInferenceType): + """Outputs of inference for the Depth Estimation task""" + + depth: Any + """The predicted depth as an image""" + predicted_depth: Any + """The predicted depth as a tensor""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/document_question_answering.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/document_question_answering.py new file mode 100644 index 0000000000000000000000000000000000000000..0ec9c29e306671a389321e332b9bc197e77e3c65 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/document_question_answering.py @@ -0,0 +1,80 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any + +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class DocumentQuestionAnsweringInputData(BaseInferenceType): + """One (document, question) pair to answer""" + + image: Any + """The image on which the question is asked""" + question: str + """A question to ask of the document""" + + +@dataclass_with_extra +class DocumentQuestionAnsweringParameters(BaseInferenceType): + """Additional inference parameters for Document Question Answering""" + + doc_stride: int | None = None + """If the words in the document are too long to fit with the question for the model, it will + be split in several chunks with some overlap. This argument controls the size of that + overlap. + """ + handle_impossible_answer: bool | None = None + """Whether to accept impossible as an answer""" + lang: str | None = None + """Language to use while running OCR. Defaults to english.""" + max_answer_len: int | None = None + """The maximum length of predicted answers (e.g., only answers with a shorter length are + considered). + """ + max_question_len: int | None = None + """The maximum length of the question after tokenization. It will be truncated if needed.""" + max_seq_len: int | None = None + """The maximum length of the total sentence (context + question) in tokens of each chunk + passed to the model. The context will be split in several chunks (using doc_stride as + overlap) if needed. + """ + top_k: int | None = None + """The number of answers to return (will be chosen by order of likelihood). Can return less + than top_k answers if there are not enough options available within the context. + """ + word_boxes: list[list[float] | str] | None = None + """A list of words and bounding boxes (normalized 0->1000). If provided, the inference will + skip the OCR step and use the provided bounding boxes instead. + """ + + +@dataclass_with_extra +class DocumentQuestionAnsweringInput(BaseInferenceType): + """Inputs for Document Question Answering inference""" + + inputs: DocumentQuestionAnsweringInputData + """One (document, question) pair to answer""" + parameters: DocumentQuestionAnsweringParameters | None = None + """Additional inference parameters for Document Question Answering""" + + +@dataclass_with_extra +class DocumentQuestionAnsweringOutputElement(BaseInferenceType): + """Outputs of inference for the Document Question Answering task""" + + answer: str + """The answer to the question.""" + end: int + """The end word index of the answer (in the OCR’d version of the input or provided word + boxes). + """ + score: float + """The probability associated to the answer.""" + start: int + """The start word index of the answer (in the OCR’d version of the input or provided word + boxes). + """ diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/feature_extraction.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/feature_extraction.py new file mode 100644 index 0000000000000000000000000000000000000000..e2868432b8dc937582b467ba14bcb12c3148eaf7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/feature_extraction.py @@ -0,0 +1,36 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Literal, Optional + +from .base import BaseInferenceType, dataclass_with_extra + + +FeatureExtractionInputTruncationDirection = Literal["left", "right"] + + +@dataclass_with_extra +class FeatureExtractionInput(BaseInferenceType): + """Feature Extraction Input. + Auto-generated from TEI specs. + For more details, check out + https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-tei-import.ts. + """ + + inputs: list[str] | str + """The text or list of texts to embed.""" + normalize: bool | None = None + prompt_name: str | None = None + """The name of the prompt that should be used by for encoding. If not set, no prompt + will be applied. + Must be a key in the `sentence-transformers` configuration `prompts` dictionary. + For example if ``prompt_name`` is "query" and the ``prompts`` is {"query": "query: ", + ...}, + then the sentence "What is the capital of France?" will be encoded as + "query: What is the capital of France?" because the prompt text will be prepended before + any text to encode. + """ + truncate: bool | None = None + truncation_direction: Optional["FeatureExtractionInputTruncationDirection"] = None diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/fill_mask.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/fill_mask.py new file mode 100644 index 0000000000000000000000000000000000000000..84fcac730ee43763150068ddeca63a1ed127d59c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/fill_mask.py @@ -0,0 +1,47 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any + +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class FillMaskParameters(BaseInferenceType): + """Additional inference parameters for Fill Mask""" + + targets: list[str] | None = None + """When passed, the model will limit the scores to the passed targets instead of looking up + in the whole vocabulary. If the provided targets are not in the model vocab, they will be + tokenized and the first resulting token will be used (with a warning, and that might be + slower). + """ + top_k: int | None = None + """When passed, overrides the number of predictions to return.""" + + +@dataclass_with_extra +class FillMaskInput(BaseInferenceType): + """Inputs for Fill Mask inference""" + + inputs: str + """The text with masked tokens""" + parameters: FillMaskParameters | None = None + """Additional inference parameters for Fill Mask""" + + +@dataclass_with_extra +class FillMaskOutputElement(BaseInferenceType): + """Outputs of inference for the Fill Mask task""" + + score: float + """The corresponding probability""" + sequence: str + """The corresponding input with the mask token prediction.""" + token: int + """The predicted token id (to replace the masked one).""" + token_str: Any + fill_mask_output_token_str: str | None = None + """The predicted token (to replace the masked one).""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_classification.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..a0d2d564b7d573cea0847308bbb723d519a5cede --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_classification.py @@ -0,0 +1,43 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Literal, Optional + +from .base import BaseInferenceType, dataclass_with_extra + + +ImageClassificationOutputTransform = Literal["sigmoid", "softmax", "none"] + + +@dataclass_with_extra +class ImageClassificationParameters(BaseInferenceType): + """Additional inference parameters for Image Classification""" + + function_to_apply: Optional["ImageClassificationOutputTransform"] = None + """The function to apply to the model outputs in order to retrieve the scores.""" + top_k: int | None = None + """When specified, limits the output to the top K most probable classes.""" + + +@dataclass_with_extra +class ImageClassificationInput(BaseInferenceType): + """Inputs for Image Classification inference""" + + inputs: str + """The input image data as a base64-encoded string. If no `parameters` are provided, you can + also provide the image data as a raw bytes payload. + """ + parameters: ImageClassificationParameters | None = None + """Additional inference parameters for Image Classification""" + + +@dataclass_with_extra +class ImageClassificationOutputElement(BaseInferenceType): + """Outputs of inference for the Image Classification task""" + + label: str + """The predicted class label.""" + score: float + """The corresponding probability.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_segmentation.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_segmentation.py new file mode 100644 index 0000000000000000000000000000000000000000..d2938d89cab79329d1aeac3b16d85c8b76e49cdc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_segmentation.py @@ -0,0 +1,51 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Literal, Optional + +from .base import BaseInferenceType, dataclass_with_extra + + +ImageSegmentationSubtask = Literal["instance", "panoptic", "semantic"] + + +@dataclass_with_extra +class ImageSegmentationParameters(BaseInferenceType): + """Additional inference parameters for Image Segmentation""" + + mask_threshold: float | None = None + """Threshold to use when turning the predicted masks into binary values.""" + overlap_mask_area_threshold: float | None = None + """Mask overlap threshold to eliminate small, disconnected segments.""" + subtask: Optional["ImageSegmentationSubtask"] = None + """Segmentation task to be performed, depending on model capabilities.""" + threshold: float | None = None + """Probability threshold to filter out predicted masks.""" + + +@dataclass_with_extra +class ImageSegmentationInput(BaseInferenceType): + """Inputs for Image Segmentation inference""" + + inputs: str + """The input image data as a base64-encoded string. If no `parameters` are provided, you can + also provide the image data as a raw bytes payload. + """ + parameters: ImageSegmentationParameters | None = None + """Additional inference parameters for Image Segmentation""" + + +@dataclass_with_extra +class ImageSegmentationOutputElement(BaseInferenceType): + """Outputs of inference for the Image Segmentation task + A predicted mask / segment + """ + + label: str + """The label of the predicted segment.""" + mask: str + """The corresponding mask as a black-and-white image (base64-encoded).""" + score: float | None = None + """The score or confidence degree the model has.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_text_to_image.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_text_to_image.py new file mode 100644 index 0000000000000000000000000000000000000000..d711f40ca021e5dfa3c072d19b5730d615dec6eb --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_text_to_image.py @@ -0,0 +1,67 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any + +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class ImageTextToImageTargetSize(BaseInferenceType): + """The size in pixels of the output image. This parameter is only supported by some + providers and for specific models. It will be ignored when unsupported. + """ + + height: int + width: int + + +@dataclass_with_extra +class ImageTextToImageParameters(BaseInferenceType): + """Additional inference parameters for Image Text To Image""" + + guidance_scale: float | None = None + """For diffusion models. A higher guidance scale value encourages the model to generate + images closely linked to the text prompt at the expense of lower image quality. + """ + negative_prompt: str | None = None + """One prompt to guide what NOT to include in image generation.""" + num_inference_steps: int | None = None + """For diffusion models. The number of denoising steps. More denoising steps usually lead to + a higher quality image at the expense of slower inference. + """ + prompt: str | None = None + """The text prompt to guide the image generation. Either this or inputs (image) must be + provided. + """ + seed: int | None = None + """Seed for the random number generator.""" + target_size: ImageTextToImageTargetSize | None = None + """The size in pixels of the output image. This parameter is only supported by some + providers and for specific models. It will be ignored when unsupported. + """ + + +@dataclass_with_extra +class ImageTextToImageInput(BaseInferenceType): + """Inputs for Image Text To Image inference. Either inputs (image) or prompt (in parameters) + must be provided, or both. + """ + + inputs: str | None = None + """The input image data as a base64-encoded string. If no `parameters` are provided, you can + also provide the image data as a raw bytes payload. Either this or prompt must be + provided. + """ + parameters: ImageTextToImageParameters | None = None + """Additional inference parameters for Image Text To Image""" + + +@dataclass_with_extra +class ImageTextToImageOutput(BaseInferenceType): + """Outputs of inference for the Image Text To Image task""" + + image: Any + """The generated image returned as raw bytes in the payload.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_text_to_video.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_text_to_video.py new file mode 100644 index 0000000000000000000000000000000000000000..870bb16c04add8cfb7909da74cef902b98486f85 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_text_to_video.py @@ -0,0 +1,65 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any + +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class ImageTextToVideoTargetSize(BaseInferenceType): + """The size in pixel of the output video frames.""" + + height: int + width: int + + +@dataclass_with_extra +class ImageTextToVideoParameters(BaseInferenceType): + """Additional inference parameters for Image Text To Video""" + + guidance_scale: float | None = None + """For diffusion models. A higher guidance scale value encourages the model to generate + videos closely linked to the text prompt at the expense of lower image quality. + """ + negative_prompt: str | None = None + """One prompt to guide what NOT to include in video generation.""" + num_frames: float | None = None + """The num_frames parameter determines how many video frames are generated.""" + num_inference_steps: int | None = None + """The number of denoising steps. More denoising steps usually lead to a higher quality + video at the expense of slower inference. + """ + prompt: str | None = None + """The text prompt to guide the video generation. Either this or inputs (image) must be + provided. + """ + seed: int | None = None + """Seed for the random number generator.""" + target_size: ImageTextToVideoTargetSize | None = None + """The size in pixel of the output video frames.""" + + +@dataclass_with_extra +class ImageTextToVideoInput(BaseInferenceType): + """Inputs for Image Text To Video inference. Either inputs (image) or prompt (in parameters) + must be provided, or both. + """ + + inputs: str | None = None + """The input image data as a base64-encoded string. If no `parameters` are provided, you can + also provide the image data as a raw bytes payload. Either this or prompt must be + provided. + """ + parameters: ImageTextToVideoParameters | None = None + """Additional inference parameters for Image Text To Video""" + + +@dataclass_with_extra +class ImageTextToVideoOutput(BaseInferenceType): + """Outputs of inference for the Image Text To Video task""" + + video: Any + """The generated video returned as raw bytes in the payload.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_to_image.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_to_image.py new file mode 100644 index 0000000000000000000000000000000000000000..6e943d73915803c05211e0d8b1a0e64fc4fdba3a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_to_image.py @@ -0,0 +1,60 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any + +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class ImageToImageTargetSize(BaseInferenceType): + """The size in pixels of the output image. This parameter is only supported by some + providers and for specific models. It will be ignored when unsupported. + """ + + height: int + width: int + + +@dataclass_with_extra +class ImageToImageParameters(BaseInferenceType): + """Additional inference parameters for Image To Image""" + + guidance_scale: float | None = None + """For diffusion models. A higher guidance scale value encourages the model to generate + images closely linked to the text prompt at the expense of lower image quality. + """ + negative_prompt: str | None = None + """One prompt to guide what NOT to include in image generation.""" + num_inference_steps: int | None = None + """For diffusion models. The number of denoising steps. More denoising steps usually lead to + a higher quality image at the expense of slower inference. + """ + prompt: str | None = None + """The text prompt to guide the image generation.""" + target_size: ImageToImageTargetSize | None = None + """The size in pixels of the output image. This parameter is only supported by some + providers and for specific models. It will be ignored when unsupported. + """ + + +@dataclass_with_extra +class ImageToImageInput(BaseInferenceType): + """Inputs for Image To Image inference""" + + inputs: str + """The input image data as a base64-encoded string. If no `parameters` are provided, you can + also provide the image data as a raw bytes payload. + """ + parameters: ImageToImageParameters | None = None + """Additional inference parameters for Image To Image""" + + +@dataclass_with_extra +class ImageToImageOutput(BaseInferenceType): + """Outputs of inference for the Image To Image task""" + + image: Any + """The output image returned as raw bytes in the payload.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_to_text.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_to_text.py new file mode 100644 index 0000000000000000000000000000000000000000..3924a6612c8b246069215e2ad581dc058f54ac41 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_to_text.py @@ -0,0 +1,100 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any, Literal, Union + +from .base import BaseInferenceType, dataclass_with_extra + + +ImageToTextEarlyStoppingEnum = Literal["never"] + + +@dataclass_with_extra +class ImageToTextGenerationParameters(BaseInferenceType): + """Parametrization of the text generation process""" + + do_sample: bool | None = None + """Whether to use sampling instead of greedy decoding when generating new tokens.""" + early_stopping: Union[bool, "ImageToTextEarlyStoppingEnum"] | None = None + """Controls the stopping condition for beam-based methods.""" + epsilon_cutoff: float | None = None + """If set to float strictly between 0 and 1, only tokens with a conditional probability + greater than epsilon_cutoff will be sampled. In the paper, suggested values range from + 3e-4 to 9e-4, depending on the size of the model. See [Truncation Sampling as Language + Model Desmoothing](https://hf.co/papers/2210.15191) for more details. + """ + eta_cutoff: float | None = None + """Eta sampling is a hybrid of locally typical sampling and epsilon sampling. If set to + float strictly between 0 and 1, a token is only considered if it is greater than either + eta_cutoff or sqrt(eta_cutoff) * exp(-entropy(softmax(next_token_logits))). The latter + term is intuitively the expected next token probability, scaled by sqrt(eta_cutoff). In + the paper, suggested values range from 3e-4 to 2e-3, depending on the size of the model. + See [Truncation Sampling as Language Model Desmoothing](https://hf.co/papers/2210.15191) + for more details. + """ + max_length: int | None = None + """The maximum length (in tokens) of the generated text, including the input.""" + max_new_tokens: int | None = None + """The maximum number of tokens to generate. Takes precedence over max_length.""" + min_length: int | None = None + """The minimum length (in tokens) of the generated text, including the input.""" + min_new_tokens: int | None = None + """The minimum number of tokens to generate. Takes precedence over min_length.""" + num_beam_groups: int | None = None + """Number of groups to divide num_beams into in order to ensure diversity among different + groups of beams. See [this paper](https://hf.co/papers/1610.02424) for more details. + """ + num_beams: int | None = None + """Number of beams to use for beam search.""" + penalty_alpha: float | None = None + """The value balances the model confidence and the degeneration penalty in contrastive + search decoding. + """ + temperature: float | None = None + """The value used to modulate the next token probabilities.""" + top_k: int | None = None + """The number of highest probability vocabulary tokens to keep for top-k-filtering.""" + top_p: float | None = None + """If set to float < 1, only the smallest set of most probable tokens with probabilities + that add up to top_p or higher are kept for generation. + """ + typical_p: float | None = None + """Local typicality measures how similar the conditional probability of predicting a target + token next is to the expected conditional probability of predicting a random token next, + given the partial text already generated. If set to float < 1, the smallest set of the + most locally typical tokens with probabilities that add up to typical_p or higher are + kept for generation. See [this paper](https://hf.co/papers/2202.00666) for more details. + """ + use_cache: bool | None = None + """Whether the model should use the past last key/values attentions to speed up decoding""" + + +@dataclass_with_extra +class ImageToTextParameters(BaseInferenceType): + """Additional inference parameters for Image To Text""" + + generation_parameters: ImageToTextGenerationParameters | None = None + """Parametrization of the text generation process""" + max_new_tokens: int | None = None + """The amount of maximum tokens to generate.""" + + +@dataclass_with_extra +class ImageToTextInput(BaseInferenceType): + """Inputs for Image To Text inference""" + + inputs: Any + """The input image data""" + parameters: ImageToTextParameters | None = None + """Additional inference parameters for Image To Text""" + + +@dataclass_with_extra +class ImageToTextOutput(BaseInferenceType): + """Outputs of inference for the Image To Text task""" + + generated_text: Any + image_to_text_output_generated_text: str | None = None + """The generated text.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_to_video.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_to_video.py new file mode 100644 index 0000000000000000000000000000000000000000..b14883f044c13c935f7b3d41f23a50f0b7c29850 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/image_to_video.py @@ -0,0 +1,60 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any + +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class ImageToVideoTargetSize(BaseInferenceType): + """The size in pixel of the output video frames.""" + + height: int + width: int + + +@dataclass_with_extra +class ImageToVideoParameters(BaseInferenceType): + """Additional inference parameters for Image To Video""" + + guidance_scale: float | None = None + """For diffusion models. A higher guidance scale value encourages the model to generate + videos closely linked to the text prompt at the expense of lower image quality. + """ + negative_prompt: str | None = None + """One prompt to guide what NOT to include in video generation.""" + num_frames: float | None = None + """The num_frames parameter determines how many video frames are generated.""" + num_inference_steps: int | None = None + """The number of denoising steps. More denoising steps usually lead to a higher quality + video at the expense of slower inference. + """ + prompt: str | None = None + """The text prompt to guide the video generation.""" + seed: int | None = None + """Seed for the random number generator.""" + target_size: ImageToVideoTargetSize | None = None + """The size in pixel of the output video frames.""" + + +@dataclass_with_extra +class ImageToVideoInput(BaseInferenceType): + """Inputs for Image To Video inference""" + + inputs: str + """The input image data as a base64-encoded string. If no `parameters` are provided, you can + also provide the image data as a raw bytes payload. + """ + parameters: ImageToVideoParameters | None = None + """Additional inference parameters for Image To Video""" + + +@dataclass_with_extra +class ImageToVideoOutput(BaseInferenceType): + """Outputs of inference for the Image To Video task""" + + video: Any + """The generated video returned as raw bytes in the payload.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/object_detection.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/object_detection.py new file mode 100644 index 0000000000000000000000000000000000000000..1c7ef7843424c75e0af2d7363a8561bec57b81f3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/object_detection.py @@ -0,0 +1,56 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class ObjectDetectionParameters(BaseInferenceType): + """Additional inference parameters for Object Detection""" + + threshold: float | None = None + """The probability necessary to make a prediction.""" + + +@dataclass_with_extra +class ObjectDetectionInput(BaseInferenceType): + """Inputs for Object Detection inference""" + + inputs: str + """The input image data as a base64-encoded string. If no `parameters` are provided, you can + also provide the image data as a raw bytes payload. + """ + parameters: ObjectDetectionParameters | None = None + """Additional inference parameters for Object Detection""" + + +@dataclass_with_extra +class ObjectDetectionBoundingBox(BaseInferenceType): + """The predicted bounding box. Coordinates are relative to the top left corner of the input + image. + """ + + xmax: int + """The x-coordinate of the bottom-right corner of the bounding box.""" + xmin: int + """The x-coordinate of the top-left corner of the bounding box.""" + ymax: int + """The y-coordinate of the bottom-right corner of the bounding box.""" + ymin: int + """The y-coordinate of the top-left corner of the bounding box.""" + + +@dataclass_with_extra +class ObjectDetectionOutputElement(BaseInferenceType): + """Outputs of inference for the Object Detection task""" + + box: ObjectDetectionBoundingBox + """The predicted bounding box. Coordinates are relative to the top left corner of the input + image. + """ + label: str + """The predicted label for the bounding box.""" + score: float + """The associated score / probability.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/question_answering.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/question_answering.py new file mode 100644 index 0000000000000000000000000000000000000000..ee97c638d68c3bedf4fe8e8f9a8f996d4955e30a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/question_answering.py @@ -0,0 +1,72 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class QuestionAnsweringInputData(BaseInferenceType): + """One (context, question) pair to answer""" + + context: str + """The context to be used for answering the question""" + question: str + """The question to be answered""" + + +@dataclass_with_extra +class QuestionAnsweringParameters(BaseInferenceType): + """Additional inference parameters for Question Answering""" + + align_to_words: bool | None = None + """Attempts to align the answer to real words. Improves quality on space separated + languages. Might hurt on non-space-separated languages (like Japanese or Chinese) + """ + doc_stride: int | None = None + """If the context is too long to fit with the question for the model, it will be split in + several chunks with some overlap. This argument controls the size of that overlap. + """ + handle_impossible_answer: bool | None = None + """Whether to accept impossible as an answer.""" + max_answer_len: int | None = None + """The maximum length of predicted answers (e.g., only answers with a shorter length are + considered). + """ + max_question_len: int | None = None + """The maximum length of the question after tokenization. It will be truncated if needed.""" + max_seq_len: int | None = None + """The maximum length of the total sentence (context + question) in tokens of each chunk + passed to the model. The context will be split in several chunks (using docStride as + overlap) if needed. + """ + top_k: int | None = None + """The number of answers to return (will be chosen by order of likelihood). Note that we + return less than topk answers if there are not enough options available within the + context. + """ + + +@dataclass_with_extra +class QuestionAnsweringInput(BaseInferenceType): + """Inputs for Question Answering inference""" + + inputs: QuestionAnsweringInputData + """One (context, question) pair to answer""" + parameters: QuestionAnsweringParameters | None = None + """Additional inference parameters for Question Answering""" + + +@dataclass_with_extra +class QuestionAnsweringOutputElement(BaseInferenceType): + """Outputs of inference for the Question Answering task""" + + answer: str + """The answer to the question.""" + end: int + """The character position in the input where the answer ends.""" + score: float + """The probability associated to the answer.""" + start: int + """The character position in the input where the answer begins.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/sentence_similarity.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/sentence_similarity.py new file mode 100644 index 0000000000000000000000000000000000000000..a06c32d395fce557784f95ca77c0a62f04b255db --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/sentence_similarity.py @@ -0,0 +1,27 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any + +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class SentenceSimilarityInputData(BaseInferenceType): + sentences: list[str] + """A list of strings which will be compared against the source_sentence.""" + source_sentence: str + """The string that you wish to compare the other strings with. This can be a phrase, + sentence, or longer passage, depending on the model being used. + """ + + +@dataclass_with_extra +class SentenceSimilarityInput(BaseInferenceType): + """Inputs for Sentence similarity inference""" + + inputs: SentenceSimilarityInputData + parameters: dict[str, Any] | None = None + """Additional inference parameters for Sentence Similarity""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/summarization.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/summarization.py new file mode 100644 index 0000000000000000000000000000000000000000..35f2a86f308f9d4839f46ac6496097961a2df723 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/summarization.py @@ -0,0 +1,41 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any, Literal, Optional + +from .base import BaseInferenceType, dataclass_with_extra + + +SummarizationTruncationStrategy = Literal["do_not_truncate", "longest_first", "only_first", "only_second"] + + +@dataclass_with_extra +class SummarizationParameters(BaseInferenceType): + """Additional inference parameters for summarization.""" + + clean_up_tokenization_spaces: bool | None = None + """Whether to clean up the potential extra spaces in the text output.""" + generate_parameters: dict[str, Any] | None = None + """Additional parametrization of the text generation algorithm.""" + truncation: Optional["SummarizationTruncationStrategy"] = None + """The truncation strategy to use.""" + + +@dataclass_with_extra +class SummarizationInput(BaseInferenceType): + """Inputs for Summarization inference""" + + inputs: str + """The input text to summarize.""" + parameters: SummarizationParameters | None = None + """Additional inference parameters for summarization.""" + + +@dataclass_with_extra +class SummarizationOutput(BaseInferenceType): + """Outputs of inference for the Summarization task""" + + summary_text: str + """The summarized text.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/table_question_answering.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/table_question_answering.py new file mode 100644 index 0000000000000000000000000000000000000000..1909f0d2b77551ff8b7b4cf0df199a46e5c72197 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/table_question_answering.py @@ -0,0 +1,62 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Literal, Optional + +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class TableQuestionAnsweringInputData(BaseInferenceType): + """One (table, question) pair to answer""" + + question: str + """The question to be answered about the table""" + table: dict[str, list[str]] + """The table to serve as context for the questions""" + + +Padding = Literal["do_not_pad", "longest", "max_length"] + + +@dataclass_with_extra +class TableQuestionAnsweringParameters(BaseInferenceType): + """Additional inference parameters for Table Question Answering""" + + padding: Optional["Padding"] = None + """Activates and controls padding.""" + sequential: bool | None = None + """Whether to do inference sequentially or as a batch. Batching is faster, but models like + SQA require the inference to be done sequentially to extract relations within sequences, + given their conversational nature. + """ + truncation: bool | None = None + """Activates and controls truncation.""" + + +@dataclass_with_extra +class TableQuestionAnsweringInput(BaseInferenceType): + """Inputs for Table Question Answering inference""" + + inputs: TableQuestionAnsweringInputData + """One (table, question) pair to answer""" + parameters: TableQuestionAnsweringParameters | None = None + """Additional inference parameters for Table Question Answering""" + + +@dataclass_with_extra +class TableQuestionAnsweringOutputElement(BaseInferenceType): + """Outputs of inference for the Table Question Answering task""" + + answer: str + """The answer of the question given the table. If there is an aggregator, the answer will be + preceded by `AGGREGATOR >`. + """ + cells: list[str] + """list of strings made up of the answer cell values.""" + coordinates: list[list[int]] + """Coordinates of the cells of the answers.""" + aggregator: str | None = None + """If the model has an aggregator, this returns the aggregator.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text2text_generation.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text2text_generation.py new file mode 100644 index 0000000000000000000000000000000000000000..b4508823749a52d3238fc288e62e479e126e1827 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text2text_generation.py @@ -0,0 +1,42 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any, Literal, Optional + +from .base import BaseInferenceType, dataclass_with_extra + + +Text2TextGenerationTruncationStrategy = Literal["do_not_truncate", "longest_first", "only_first", "only_second"] + + +@dataclass_with_extra +class Text2TextGenerationParameters(BaseInferenceType): + """Additional inference parameters for Text2text Generation""" + + clean_up_tokenization_spaces: bool | None = None + """Whether to clean up the potential extra spaces in the text output.""" + generate_parameters: dict[str, Any] | None = None + """Additional parametrization of the text generation algorithm""" + truncation: Optional["Text2TextGenerationTruncationStrategy"] = None + """The truncation strategy to use""" + + +@dataclass_with_extra +class Text2TextGenerationInput(BaseInferenceType): + """Inputs for Text2text Generation inference""" + + inputs: str + """The input text data""" + parameters: Text2TextGenerationParameters | None = None + """Additional inference parameters for Text2text Generation""" + + +@dataclass_with_extra +class Text2TextGenerationOutput(BaseInferenceType): + """Outputs of inference for the Text2text Generation task""" + + generated_text: Any + text2_text_generation_output_generated_text: str | None = None + """The generated text.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_classification.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..9df576b4de724a73be32ff5ecbf81dd5ea576f91 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_classification.py @@ -0,0 +1,41 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Literal, Optional + +from .base import BaseInferenceType, dataclass_with_extra + + +TextClassificationOutputTransform = Literal["sigmoid", "softmax", "none"] + + +@dataclass_with_extra +class TextClassificationParameters(BaseInferenceType): + """Additional inference parameters for Text Classification""" + + function_to_apply: Optional["TextClassificationOutputTransform"] = None + """The function to apply to the model outputs in order to retrieve the scores.""" + top_k: int | None = None + """When specified, limits the output to the top K most probable classes.""" + + +@dataclass_with_extra +class TextClassificationInput(BaseInferenceType): + """Inputs for Text Classification inference""" + + inputs: str + """The text to classify""" + parameters: TextClassificationParameters | None = None + """Additional inference parameters for Text Classification""" + + +@dataclass_with_extra +class TextClassificationOutputElement(BaseInferenceType): + """Outputs of inference for the Text Classification task""" + + label: str + """The predicted class label.""" + score: float + """The corresponding probability.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_generation.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_generation.py new file mode 100644 index 0000000000000000000000000000000000000000..1b2269955bcaef7f23972b00ca8991b6854f8181 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_generation.py @@ -0,0 +1,168 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any, Literal + +from .base import BaseInferenceType, dataclass_with_extra + + +TypeEnum = Literal["json", "regex", "json_schema"] + + +@dataclass_with_extra +class TextGenerationInputGrammarType(BaseInferenceType): + type: "TypeEnum" + value: Any + """A string that represents a [JSON Schema](https://json-schema.org/). + JSON Schema is a declarative language that allows to annotate JSON documents + with types and descriptions. + """ + + +@dataclass_with_extra +class TextGenerationInputGenerateParameters(BaseInferenceType): + adapter_id: str | None = None + """Lora adapter id""" + best_of: int | None = None + """Generate best_of sequences and return the one if the highest token logprobs.""" + decoder_input_details: bool | None = None + """Whether to return decoder input token logprobs and ids.""" + details: bool | None = None + """Whether to return generation details.""" + do_sample: bool | None = None + """Activate logits sampling.""" + frequency_penalty: float | None = None + """The parameter for frequency penalty. 1.0 means no penalty + Penalize new tokens based on their existing frequency in the text so far, + decreasing the model's likelihood to repeat the same line verbatim. + """ + grammar: TextGenerationInputGrammarType | None = None + max_new_tokens: int | None = None + """Maximum number of tokens to generate.""" + repetition_penalty: float | None = None + """The parameter for repetition penalty. 1.0 means no penalty. + See [this paper](https://arxiv.org/pdf/1909.05858.pdf) for more details. + """ + return_full_text: bool | None = None + """Whether to prepend the prompt to the generated text""" + seed: int | None = None + """Random sampling seed.""" + stop: list[str] | None = None + """Stop generating tokens if a member of `stop` is generated.""" + temperature: float | None = None + """The value used to module the logits distribution.""" + top_k: int | None = None + """The number of highest probability vocabulary tokens to keep for top-k-filtering.""" + top_n_tokens: int | None = None + """The number of highest probability vocabulary tokens to keep for top-n-filtering.""" + top_p: float | None = None + """Top-p value for nucleus sampling.""" + truncate: int | None = None + """Truncate inputs tokens to the given size.""" + typical_p: float | None = None + """Typical Decoding mass + See [Typical Decoding for Natural Language Generation](https://arxiv.org/abs/2202.00666) + for more information. + """ + watermark: bool | None = None + """Watermarking with [A Watermark for Large Language + Models](https://arxiv.org/abs/2301.10226). + """ + + +@dataclass_with_extra +class TextGenerationInput(BaseInferenceType): + """Text Generation Input. + Auto-generated from TGI specs. + For more details, check out + https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-tgi-import.ts. + """ + + inputs: str + parameters: TextGenerationInputGenerateParameters | None = None + stream: bool | None = None + + +TextGenerationOutputFinishReason = Literal["length", "eos_token", "stop_sequence"] + + +@dataclass_with_extra +class TextGenerationOutputPrefillToken(BaseInferenceType): + id: int + logprob: float + text: str + + +@dataclass_with_extra +class TextGenerationOutputToken(BaseInferenceType): + id: int + logprob: float + special: bool + text: str + + +@dataclass_with_extra +class TextGenerationOutputBestOfSequence(BaseInferenceType): + finish_reason: "TextGenerationOutputFinishReason" + generated_text: str + generated_tokens: int + prefill: list[TextGenerationOutputPrefillToken] + tokens: list[TextGenerationOutputToken] + seed: int | None = None + top_tokens: list[list[TextGenerationOutputToken]] | None = None + + +@dataclass_with_extra +class TextGenerationOutputDetails(BaseInferenceType): + finish_reason: "TextGenerationOutputFinishReason" + generated_tokens: int + prefill: list[TextGenerationOutputPrefillToken] + tokens: list[TextGenerationOutputToken] + best_of_sequences: list[TextGenerationOutputBestOfSequence] | None = None + seed: int | None = None + top_tokens: list[list[TextGenerationOutputToken]] | None = None + + +@dataclass_with_extra +class TextGenerationOutput(BaseInferenceType): + """Text Generation Output. + Auto-generated from TGI specs. + For more details, check out + https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-tgi-import.ts. + """ + + generated_text: str + details: TextGenerationOutputDetails | None = None + + +@dataclass_with_extra +class TextGenerationStreamOutputStreamDetails(BaseInferenceType): + finish_reason: "TextGenerationOutputFinishReason" + generated_tokens: int + input_length: int + seed: int | None = None + + +@dataclass_with_extra +class TextGenerationStreamOutputToken(BaseInferenceType): + id: int + logprob: float + special: bool + text: str + + +@dataclass_with_extra +class TextGenerationStreamOutput(BaseInferenceType): + """Text Generation Stream Output. + Auto-generated from TGI specs. + For more details, check out + https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-tgi-import.ts. + """ + + index: int + token: TextGenerationStreamOutputToken + details: TextGenerationStreamOutputStreamDetails | None = None + generated_text: str | None = None + top_tokens: list[TextGenerationStreamOutputToken] | None = None diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_to_audio.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_to_audio.py new file mode 100644 index 0000000000000000000000000000000000000000..35033f5129cdfb3d3e7512727bdfc248c882d35e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_to_audio.py @@ -0,0 +1,99 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any, Literal, Union + +from .base import BaseInferenceType, dataclass_with_extra + + +TextToAudioEarlyStoppingEnum = Literal["never"] + + +@dataclass_with_extra +class TextToAudioGenerationParameters(BaseInferenceType): + """Parametrization of the text generation process""" + + do_sample: bool | None = None + """Whether to use sampling instead of greedy decoding when generating new tokens.""" + early_stopping: Union[bool, "TextToAudioEarlyStoppingEnum"] | None = None + """Controls the stopping condition for beam-based methods.""" + epsilon_cutoff: float | None = None + """If set to float strictly between 0 and 1, only tokens with a conditional probability + greater than epsilon_cutoff will be sampled. In the paper, suggested values range from + 3e-4 to 9e-4, depending on the size of the model. See [Truncation Sampling as Language + Model Desmoothing](https://hf.co/papers/2210.15191) for more details. + """ + eta_cutoff: float | None = None + """Eta sampling is a hybrid of locally typical sampling and epsilon sampling. If set to + float strictly between 0 and 1, a token is only considered if it is greater than either + eta_cutoff or sqrt(eta_cutoff) * exp(-entropy(softmax(next_token_logits))). The latter + term is intuitively the expected next token probability, scaled by sqrt(eta_cutoff). In + the paper, suggested values range from 3e-4 to 2e-3, depending on the size of the model. + See [Truncation Sampling as Language Model Desmoothing](https://hf.co/papers/2210.15191) + for more details. + """ + max_length: int | None = None + """The maximum length (in tokens) of the generated text, including the input.""" + max_new_tokens: int | None = None + """The maximum number of tokens to generate. Takes precedence over max_length.""" + min_length: int | None = None + """The minimum length (in tokens) of the generated text, including the input.""" + min_new_tokens: int | None = None + """The minimum number of tokens to generate. Takes precedence over min_length.""" + num_beam_groups: int | None = None + """Number of groups to divide num_beams into in order to ensure diversity among different + groups of beams. See [this paper](https://hf.co/papers/1610.02424) for more details. + """ + num_beams: int | None = None + """Number of beams to use for beam search.""" + penalty_alpha: float | None = None + """The value balances the model confidence and the degeneration penalty in contrastive + search decoding. + """ + temperature: float | None = None + """The value used to modulate the next token probabilities.""" + top_k: int | None = None + """The number of highest probability vocabulary tokens to keep for top-k-filtering.""" + top_p: float | None = None + """If set to float < 1, only the smallest set of most probable tokens with probabilities + that add up to top_p or higher are kept for generation. + """ + typical_p: float | None = None + """Local typicality measures how similar the conditional probability of predicting a target + token next is to the expected conditional probability of predicting a random token next, + given the partial text already generated. If set to float < 1, the smallest set of the + most locally typical tokens with probabilities that add up to typical_p or higher are + kept for generation. See [this paper](https://hf.co/papers/2202.00666) for more details. + """ + use_cache: bool | None = None + """Whether the model should use the past last key/values attentions to speed up decoding""" + + +@dataclass_with_extra +class TextToAudioParameters(BaseInferenceType): + """Additional inference parameters for Text To Audio""" + + generation_parameters: TextToAudioGenerationParameters | None = None + """Parametrization of the text generation process""" + + +@dataclass_with_extra +class TextToAudioInput(BaseInferenceType): + """Inputs for Text To Audio inference""" + + inputs: str + """The input text data""" + parameters: TextToAudioParameters | None = None + """Additional inference parameters for Text To Audio""" + + +@dataclass_with_extra +class TextToAudioOutput(BaseInferenceType): + """Outputs of inference for the Text To Audio task""" + + audio: Any + """The generated audio waveform.""" + sampling_rate: float + """The sampling rate of the generated audio waveform.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_to_image.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_to_image.py new file mode 100644 index 0000000000000000000000000000000000000000..716f240385fba6116b8b19b88e177536a3d18ec0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_to_image.py @@ -0,0 +1,50 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any + +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class TextToImageParameters(BaseInferenceType): + """Additional inference parameters for Text To Image""" + + guidance_scale: float | None = None + """A higher guidance scale value encourages the model to generate images closely linked to + the text prompt, but values too high may cause saturation and other artifacts. + """ + height: int | None = None + """The height in pixels of the output image""" + negative_prompt: str | None = None + """One prompt to guide what NOT to include in image generation.""" + num_inference_steps: int | None = None + """The number of denoising steps. More denoising steps usually lead to a higher quality + image at the expense of slower inference. + """ + scheduler: str | None = None + """Override the scheduler with a compatible one.""" + seed: int | None = None + """Seed for the random number generator.""" + width: int | None = None + """The width in pixels of the output image""" + + +@dataclass_with_extra +class TextToImageInput(BaseInferenceType): + """Inputs for Text To Image inference""" + + inputs: str + """The input text data (sometimes called "prompt")""" + parameters: TextToImageParameters | None = None + """Additional inference parameters for Text To Image""" + + +@dataclass_with_extra +class TextToImageOutput(BaseInferenceType): + """Outputs of inference for the Text To Image task""" + + image: Any + """The generated image returned as raw bytes in the payload.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_to_speech.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_to_speech.py new file mode 100644 index 0000000000000000000000000000000000000000..588e0d1a566bde3bf66a3a07271638c6f42ecb95 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_to_speech.py @@ -0,0 +1,99 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any, Literal, Union + +from .base import BaseInferenceType, dataclass_with_extra + + +TextToSpeechEarlyStoppingEnum = Literal["never"] + + +@dataclass_with_extra +class TextToSpeechGenerationParameters(BaseInferenceType): + """Parametrization of the text generation process""" + + do_sample: bool | None = None + """Whether to use sampling instead of greedy decoding when generating new tokens.""" + early_stopping: Union[bool, "TextToSpeechEarlyStoppingEnum"] | None = None + """Controls the stopping condition for beam-based methods.""" + epsilon_cutoff: float | None = None + """If set to float strictly between 0 and 1, only tokens with a conditional probability + greater than epsilon_cutoff will be sampled. In the paper, suggested values range from + 3e-4 to 9e-4, depending on the size of the model. See [Truncation Sampling as Language + Model Desmoothing](https://hf.co/papers/2210.15191) for more details. + """ + eta_cutoff: float | None = None + """Eta sampling is a hybrid of locally typical sampling and epsilon sampling. If set to + float strictly between 0 and 1, a token is only considered if it is greater than either + eta_cutoff or sqrt(eta_cutoff) * exp(-entropy(softmax(next_token_logits))). The latter + term is intuitively the expected next token probability, scaled by sqrt(eta_cutoff). In + the paper, suggested values range from 3e-4 to 2e-3, depending on the size of the model. + See [Truncation Sampling as Language Model Desmoothing](https://hf.co/papers/2210.15191) + for more details. + """ + max_length: int | None = None + """The maximum length (in tokens) of the generated text, including the input.""" + max_new_tokens: int | None = None + """The maximum number of tokens to generate. Takes precedence over max_length.""" + min_length: int | None = None + """The minimum length (in tokens) of the generated text, including the input.""" + min_new_tokens: int | None = None + """The minimum number of tokens to generate. Takes precedence over min_length.""" + num_beam_groups: int | None = None + """Number of groups to divide num_beams into in order to ensure diversity among different + groups of beams. See [this paper](https://hf.co/papers/1610.02424) for more details. + """ + num_beams: int | None = None + """Number of beams to use for beam search.""" + penalty_alpha: float | None = None + """The value balances the model confidence and the degeneration penalty in contrastive + search decoding. + """ + temperature: float | None = None + """The value used to modulate the next token probabilities.""" + top_k: int | None = None + """The number of highest probability vocabulary tokens to keep for top-k-filtering.""" + top_p: float | None = None + """If set to float < 1, only the smallest set of most probable tokens with probabilities + that add up to top_p or higher are kept for generation. + """ + typical_p: float | None = None + """Local typicality measures how similar the conditional probability of predicting a target + token next is to the expected conditional probability of predicting a random token next, + given the partial text already generated. If set to float < 1, the smallest set of the + most locally typical tokens with probabilities that add up to typical_p or higher are + kept for generation. See [this paper](https://hf.co/papers/2202.00666) for more details. + """ + use_cache: bool | None = None + """Whether the model should use the past last key/values attentions to speed up decoding""" + + +@dataclass_with_extra +class TextToSpeechParameters(BaseInferenceType): + """Additional inference parameters for Text To Speech""" + + generation_parameters: TextToSpeechGenerationParameters | None = None + """Parametrization of the text generation process""" + + +@dataclass_with_extra +class TextToSpeechInput(BaseInferenceType): + """Inputs for Text To Speech inference""" + + inputs: str + """The input text data""" + parameters: TextToSpeechParameters | None = None + """Additional inference parameters for Text To Speech""" + + +@dataclass_with_extra +class TextToSpeechOutput(BaseInferenceType): + """Outputs of inference for the Text To Speech task""" + + audio: Any + """The generated audio""" + sampling_rate: float | None = None + """The sampling rate of the generated audio waveform.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_to_video.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_to_video.py new file mode 100644 index 0000000000000000000000000000000000000000..6e357113cecccce1653c8db977ecd2ca392a79b1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/text_to_video.py @@ -0,0 +1,46 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any + +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class TextToVideoParameters(BaseInferenceType): + """Additional inference parameters for Text To Video""" + + guidance_scale: float | None = None + """A higher guidance scale value encourages the model to generate videos closely linked to + the text prompt, but values too high may cause saturation and other artifacts. + """ + negative_prompt: list[str] | None = None + """One or several prompt to guide what NOT to include in video generation.""" + num_frames: float | None = None + """The num_frames parameter determines how many video frames are generated.""" + num_inference_steps: int | None = None + """The number of denoising steps. More denoising steps usually lead to a higher quality + video at the expense of slower inference. + """ + seed: int | None = None + """Seed for the random number generator.""" + + +@dataclass_with_extra +class TextToVideoInput(BaseInferenceType): + """Inputs for Text To Video inference""" + + inputs: str + """The input text data (sometimes called "prompt")""" + parameters: TextToVideoParameters | None = None + """Additional inference parameters for Text To Video""" + + +@dataclass_with_extra +class TextToVideoOutput(BaseInferenceType): + """Outputs of inference for the Text To Video task""" + + video: Any + """The generated video returned as raw bytes in the payload.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/token_classification.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/token_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..abf21d19a60b4b90b87309dba367e2ea578f1fea --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/token_classification.py @@ -0,0 +1,51 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Literal, Optional + +from .base import BaseInferenceType, dataclass_with_extra + + +TokenClassificationAggregationStrategy = Literal["none", "simple", "first", "average", "max"] + + +@dataclass_with_extra +class TokenClassificationParameters(BaseInferenceType): + """Additional inference parameters for Token Classification""" + + aggregation_strategy: Optional["TokenClassificationAggregationStrategy"] = None + """The strategy used to fuse tokens based on model predictions""" + ignore_labels: list[str] | None = None + """A list of labels to ignore""" + stride: int | None = None + """The number of overlapping tokens between chunks when splitting the input text.""" + + +@dataclass_with_extra +class TokenClassificationInput(BaseInferenceType): + """Inputs for Token Classification inference""" + + inputs: str + """The input text data""" + parameters: TokenClassificationParameters | None = None + """Additional inference parameters for Token Classification""" + + +@dataclass_with_extra +class TokenClassificationOutputElement(BaseInferenceType): + """Outputs of inference for the Token Classification task""" + + end: int + """The character position in the input where this group ends.""" + score: float + """The associated score / probability""" + start: int + """The character position in the input where this group begins.""" + word: str + """The corresponding text""" + entity: str | None = None + """The predicted label for a single token""" + entity_group: str | None = None + """The predicted label for a group of one or more tokens""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/translation.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/translation.py new file mode 100644 index 0000000000000000000000000000000000000000..58e0b9de2921843846ac0d3cc65faf7d7089e59f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/translation.py @@ -0,0 +1,49 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any, Literal, Optional + +from .base import BaseInferenceType, dataclass_with_extra + + +TranslationTruncationStrategy = Literal["do_not_truncate", "longest_first", "only_first", "only_second"] + + +@dataclass_with_extra +class TranslationParameters(BaseInferenceType): + """Additional inference parameters for Translation""" + + clean_up_tokenization_spaces: bool | None = None + """Whether to clean up the potential extra spaces in the text output.""" + generate_parameters: dict[str, Any] | None = None + """Additional parametrization of the text generation algorithm.""" + src_lang: str | None = None + """The source language of the text. Required for models that can translate from multiple + languages. + """ + tgt_lang: str | None = None + """Target language to translate to. Required for models that can translate to multiple + languages. + """ + truncation: Optional["TranslationTruncationStrategy"] = None + """The truncation strategy to use.""" + + +@dataclass_with_extra +class TranslationInput(BaseInferenceType): + """Inputs for Translation inference""" + + inputs: str + """The text to translate.""" + parameters: TranslationParameters | None = None + """Additional inference parameters for Translation""" + + +@dataclass_with_extra +class TranslationOutput(BaseInferenceType): + """Outputs of inference for the Translation task""" + + translation_text: str + """The translated text.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/video_classification.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/video_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..489a602c171e0b86fd5404d805c5773adea3b0ee --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/video_classification.py @@ -0,0 +1,45 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any, Literal, Optional + +from .base import BaseInferenceType, dataclass_with_extra + + +VideoClassificationOutputTransform = Literal["sigmoid", "softmax", "none"] + + +@dataclass_with_extra +class VideoClassificationParameters(BaseInferenceType): + """Additional inference parameters for Video Classification""" + + frame_sampling_rate: int | None = None + """The sampling rate used to select frames from the video.""" + function_to_apply: Optional["VideoClassificationOutputTransform"] = None + """The function to apply to the model outputs in order to retrieve the scores.""" + num_frames: int | None = None + """The number of sampled frames to consider for classification.""" + top_k: int | None = None + """When specified, limits the output to the top K most probable classes.""" + + +@dataclass_with_extra +class VideoClassificationInput(BaseInferenceType): + """Inputs for Video Classification inference""" + + inputs: Any + """The input video data""" + parameters: VideoClassificationParameters | None = None + """Additional inference parameters for Video Classification""" + + +@dataclass_with_extra +class VideoClassificationOutputElement(BaseInferenceType): + """Outputs of inference for the Video Classification task""" + + label: str + """The predicted class label.""" + score: float + """The corresponding probability.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/visual_question_answering.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/visual_question_answering.py new file mode 100644 index 0000000000000000000000000000000000000000..73f532aa06981778515a82fa5e151a1cff6b687d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/visual_question_answering.py @@ -0,0 +1,49 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from typing import Any + +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class VisualQuestionAnsweringInputData(BaseInferenceType): + """One (image, question) pair to answer""" + + image: Any + """The image.""" + question: str + """The question to answer based on the image.""" + + +@dataclass_with_extra +class VisualQuestionAnsweringParameters(BaseInferenceType): + """Additional inference parameters for Visual Question Answering""" + + top_k: int | None = None + """The number of answers to return (will be chosen by order of likelihood). Note that we + return less than topk answers if there are not enough options available within the + context. + """ + + +@dataclass_with_extra +class VisualQuestionAnsweringInput(BaseInferenceType): + """Inputs for Visual Question Answering inference""" + + inputs: VisualQuestionAnsweringInputData + """One (image, question) pair to answer""" + parameters: VisualQuestionAnsweringParameters | None = None + """Additional inference parameters for Visual Question Answering""" + + +@dataclass_with_extra +class VisualQuestionAnsweringOutputElement(BaseInferenceType): + """Outputs of inference for the Visual Question Answering task""" + + score: float + """The associated score / probability""" + answer: str | None = None + """The answer to the question""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/zero_shot_classification.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/zero_shot_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..a04f1a59353f97b9840d994e9eaed636479189a7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/zero_shot_classification.py @@ -0,0 +1,43 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class ZeroShotClassificationParameters(BaseInferenceType): + """Additional inference parameters for Zero Shot Classification""" + + candidate_labels: list[str] + """The set of possible class labels to classify the text into.""" + hypothesis_template: str | None = None + """The sentence used in conjunction with `candidate_labels` to attempt the text + classification by replacing the placeholder with the candidate labels. + """ + multi_label: bool | None = None + """Whether multiple candidate labels can be true. If false, the scores are normalized such + that the sum of the label likelihoods for each sequence is 1. If true, the labels are + considered independent and probabilities are normalized for each candidate. + """ + + +@dataclass_with_extra +class ZeroShotClassificationInput(BaseInferenceType): + """Inputs for Zero Shot Classification inference""" + + inputs: str + """The text to classify""" + parameters: ZeroShotClassificationParameters + """Additional inference parameters for Zero Shot Classification""" + + +@dataclass_with_extra +class ZeroShotClassificationOutputElement(BaseInferenceType): + """Outputs of inference for the Zero Shot Classification task""" + + label: str + """The predicted class label.""" + score: float + """The corresponding probability.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/zero_shot_image_classification.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/zero_shot_image_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..65c5cd2530665787e1e7d1fc49a6826646b141c8 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/zero_shot_image_classification.py @@ -0,0 +1,38 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class ZeroShotImageClassificationParameters(BaseInferenceType): + """Additional inference parameters for Zero Shot Image Classification""" + + candidate_labels: list[str] + """The candidate labels for this image""" + hypothesis_template: str | None = None + """The sentence used in conjunction with `candidate_labels` to attempt the image + classification by replacing the placeholder with the candidate labels. + """ + + +@dataclass_with_extra +class ZeroShotImageClassificationInput(BaseInferenceType): + """Inputs for Zero Shot Image Classification inference""" + + inputs: str + """The input image data to classify as a base64-encoded string.""" + parameters: ZeroShotImageClassificationParameters + """Additional inference parameters for Zero Shot Image Classification""" + + +@dataclass_with_extra +class ZeroShotImageClassificationOutputElement(BaseInferenceType): + """Outputs of inference for the Zero Shot Image Classification task""" + + label: str + """The predicted class label.""" + score: float + """The corresponding probability.""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/zero_shot_object_detection.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/zero_shot_object_detection.py new file mode 100644 index 0000000000000000000000000000000000000000..e981463b253f61aa0f4c71636813e5fb65d48717 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_generated/types/zero_shot_object_detection.py @@ -0,0 +1,50 @@ +# Inference code generated from the JSON schema spec in @huggingface/tasks. +# +# See: +# - script: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/scripts/inference-codegen.ts +# - specs: https://github.com/huggingface/huggingface.js/tree/main/packages/tasks/src/tasks. +from .base import BaseInferenceType, dataclass_with_extra + + +@dataclass_with_extra +class ZeroShotObjectDetectionParameters(BaseInferenceType): + """Additional inference parameters for Zero Shot Object Detection""" + + candidate_labels: list[str] + """The candidate labels for this image""" + + +@dataclass_with_extra +class ZeroShotObjectDetectionInput(BaseInferenceType): + """Inputs for Zero Shot Object Detection inference""" + + inputs: str + """The input image data as a base64-encoded string.""" + parameters: ZeroShotObjectDetectionParameters + """Additional inference parameters for Zero Shot Object Detection""" + + +@dataclass_with_extra +class ZeroShotObjectDetectionBoundingBox(BaseInferenceType): + """The predicted bounding box. Coordinates are relative to the top left corner of the input + image. + """ + + xmax: int + xmin: int + ymax: int + ymin: int + + +@dataclass_with_extra +class ZeroShotObjectDetectionOutputElement(BaseInferenceType): + """Outputs of inference for the Zero Shot Object Detection task""" + + box: ZeroShotObjectDetectionBoundingBox + """The predicted bounding box. Coordinates are relative to the top left corner of the input + image. + """ + label: str + """A candidate label""" + score: float + """The associated score / probability""" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/__init__.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/_cli_hacks.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/_cli_hacks.py new file mode 100644 index 0000000000000000000000000000000000000000..abf3c41dd687cdaab2969cc5a28455c804105856 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/_cli_hacks.py @@ -0,0 +1,88 @@ +import asyncio +import sys +from functools import partial + +import click + + +def _patch_anyio_open_process(): + """ + Patch anyio.open_process to allow detached processes on Windows and Unix-like systems. + + This is necessary to prevent the MCP client from being interrupted by Ctrl+C when running in the CLI. + """ + import subprocess + + import anyio + + if getattr(anyio, "_tiny_agents_patched", False): + return + anyio._tiny_agents_patched = True # ty: ignore[invalid-assignment] + + original_open_process = anyio.open_process + + if sys.platform == "win32": + # On Windows, we need to set the creation flags to create a new process group + + async def open_process_in_new_group(*args, **kwargs): + """ + Wrapper for open_process to handle Windows-specific process creation flags. + """ + # Ensure we pass the creation flags for Windows + kwargs.setdefault("creationflags", subprocess.CREATE_NEW_PROCESS_GROUP) + return await original_open_process(*args, **kwargs) + + anyio.open_process = open_process_in_new_group # ty: ignore[invalid-assignment] + else: + # For Unix-like systems, we can use setsid to create a new session + async def open_process_in_new_group(*args, **kwargs): + """ + Wrapper for open_process to handle Unix-like systems with start_new_session=True. + """ + kwargs.setdefault("start_new_session", True) + return await original_open_process(*args, **kwargs) + + anyio.open_process = open_process_in_new_group # ty: ignore[invalid-assignment] + + +async def _async_prompt(exit_event: asyncio.Event, prompt: str = "» ") -> str: + """ + Asynchronous prompt function that reads input from stdin without blocking. + + This function is designed to work in an asynchronous context, allowing the event loop to gracefully stop it (e.g. on Ctrl+C). + + Alternatively, we could use https://github.com/vxgmichel/aioconsole but that would be an additional dependency. + """ + loop = asyncio.get_event_loop() + + if sys.platform == "win32": + # Windows: Use run_in_executor to avoid blocking the event loop + # Degraded solution: this is not ideal as user will have to CTRL+C once more to stop the prompt (and it'll not be graceful) + return await loop.run_in_executor(None, partial(click.prompt, prompt, prompt_suffix=" ")) + else: + # UNIX-like: Use loop.add_reader for non-blocking stdin read + future = loop.create_future() + + def on_input(): + line = sys.stdin.readline() + loop.remove_reader(sys.stdin) + future.set_result(line) + + print(prompt, end=" ", flush=True) + loop.add_reader(sys.stdin, on_input) # not supported on Windows + + # Wait for user input or exit event + # Wait until either the user hits enter or exit_event is set + exit_task = asyncio.create_task(exit_event.wait()) + await asyncio.wait( + [future, exit_task], + return_when=asyncio.FIRST_COMPLETED, + ) + + # Check which one has been triggered + if exit_event.is_set(): + future.cancel() + return "" + + line = await future + return line.strip() diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/agent.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/agent.py new file mode 100644 index 0000000000000000000000000000000000000000..1d867032fa53f721928ef182329d0aa694b83885 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/agent.py @@ -0,0 +1,100 @@ +from __future__ import annotations + +import asyncio +from typing import AsyncGenerator, Iterable, Optional, Union + +from huggingface_hub import ChatCompletionInputMessage, ChatCompletionStreamOutput, MCPClient + +from .._providers import PROVIDER_OR_POLICY_T +from .constants import DEFAULT_SYSTEM_PROMPT, EXIT_LOOP_TOOLS, MAX_NUM_TURNS +from .types import ServerConfig + + +class Agent(MCPClient): + """ + Implementation of a Simple Agent, which is a simple while loop built right on top of an [`MCPClient`]. + + > [!WARNING] + > This class is experimental and might be subject to breaking changes in the future without prior notice. + + Args: + model (`str`, *optional*): + The model to run inference with. Can be a model id hosted on the Hugging Face Hub, e.g. `meta-llama/Meta-Llama-3-8B-Instruct` + or a URL to a deployed Inference Endpoint or other local or remote endpoint. + servers (`Iterable[dict]`): + MCP servers to connect to. Each server is a dictionary containing a `type` key and a `config` key. The `type` key can be `"stdio"` or `"sse"`, and the `config` key is a dictionary of arguments for the server. + provider (`str`, *optional*): + Name of the provider to use for inference. Defaults to "auto" i.e. the first of the providers available for the model, sorted by the user's order in https://hf.co/settings/inference-providers. + If model is a URL or `base_url` is passed, then `provider` is not used. + base_url (`str`, *optional*): + The base URL to run inference. Defaults to None. + api_key (`str`, *optional*): + Token to use for authentication. Will default to the locally Hugging Face saved token if not provided. You can also use your own provider API key to interact directly with the provider's service. + prompt (`str`, *optional*): + The system prompt to use for the agent. Defaults to the default system prompt in `constants.py`. + """ + + def __init__( + self, + *, + model: Optional[str] = None, + servers: Iterable[ServerConfig], + provider: Optional[PROVIDER_OR_POLICY_T] = None, + base_url: Optional[str] = None, + api_key: Optional[str] = None, + prompt: Optional[str] = None, + ): + super().__init__(model=model, provider=provider, base_url=base_url, api_key=api_key) + self._servers_cfg = list(servers) + self.messages: list[Union[dict, ChatCompletionInputMessage]] = [ + {"role": "system", "content": prompt or DEFAULT_SYSTEM_PROMPT} + ] + + async def load_tools(self) -> None: + for cfg in self._servers_cfg: + await self.add_mcp_server(**cfg) + + async def run( + self, + user_input: str, + *, + abort_event: Optional[asyncio.Event] = None, + ) -> AsyncGenerator[Union[ChatCompletionStreamOutput, ChatCompletionInputMessage], None]: + """ + Run the agent with the given user input. + + Args: + user_input (`str`): + The user input to run the agent with. + abort_event (`asyncio.Event`, *optional*): + An event that can be used to abort the agent. If the event is set, the agent will stop running. + """ + self.messages.append({"role": "user", "content": user_input}) + + num_turns: int = 0 + next_turn_should_call_tools = True + + while True: + if abort_event and abort_event.is_set(): + return + + async for item in self.process_single_turn_with_tools( + self.messages, + exit_loop_tools=EXIT_LOOP_TOOLS, + exit_if_first_chunk_no_tool=(num_turns > 0 and next_turn_should_call_tools), + ): + yield item + + num_turns += 1 + last = self.messages[-1] + + if last.get("role") == "tool" and last.get("name") in {t.function.name for t in EXIT_LOOP_TOOLS}: + return + + if last.get("role") != "tool" and num_turns > MAX_NUM_TURNS: + return + + if last.get("role") != "tool" and next_turn_should_call_tools: + return + + next_turn_should_call_tools = last.get("role") != "tool" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/cli.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/cli.py new file mode 100644 index 0000000000000000000000000000000000000000..2d1d14d478838893e03a953e96771f4048a6b713 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/cli.py @@ -0,0 +1,245 @@ +import asyncio +import os +import signal +import traceback +from typing import Optional + +import click + +from ...utils import ANSI +from ._cli_hacks import _async_prompt, _patch_anyio_open_process +from .agent import Agent +from .utils import _load_agent_config + + +@click.group( + help="A squad of lightweight composable AI applications built on Hugging Face's Inference Client and MCP stack." +) +def app() -> None: + pass + + +async def run_agent( + agent_path: Optional[str], +) -> None: + """ + Tiny Agent loop. + + Args: + agent_path (`str`, *optional*): + Path to a local folder containing an `agent.json` and optionally a custom `PROMPT.md` or `AGENTS.md` file or a built-in agent stored in a Hugging Face dataset. + + """ + _patch_anyio_open_process() # Hacky way to prevent stdio connections to be stopped by Ctrl+C + + config, prompt = _load_agent_config(agent_path) + + inputs = config.get("inputs", []) + servers = config.get("servers", []) + + abort_event = asyncio.Event() + exit_event = asyncio.Event() + first_sigint = True + + loop = asyncio.get_running_loop() + original_sigint_handler = signal.getsignal(signal.SIGINT) + + def _sigint_handler() -> None: + nonlocal first_sigint + if first_sigint: + first_sigint = False + abort_event.set() + print(ANSI.red("\nInterrupted. Press Ctrl+C again to quit."), flush=True) + return + + print(ANSI.red("\nExiting..."), flush=True) + exit_event.set() + + try: + sigint_registered_in_loop = False + try: + loop.add_signal_handler(signal.SIGINT, _sigint_handler) + sigint_registered_in_loop = True + except (AttributeError, NotImplementedError): + # Windows (or any loop that doesn't support it) : fall back to sync + signal.signal(signal.SIGINT, lambda *_: _sigint_handler()) + + # Handle inputs (i.e. env variables injection) + resolved_inputs: dict[str, str] = {} + + if len(inputs) > 0: + print( + ANSI.bold( + ANSI.blue( + "Some initial inputs are required by the agent. " + "Please provide a value or leave empty to load from env." + ) + ) + ) + for input_item in inputs: + input_id = input_item["id"] + description = input_item["description"] + env_special_value = f"${{input:{input_id}}}" + + # Check if the input is used by any server or as an apiKey + input_usages = set() + for server in servers: + # Check stdio's "env" and http/sse's "headers" mappings + env_or_headers = server.get("env", {}) if server["type"] == "stdio" else server.get("headers", {}) + for key, value in env_or_headers.items(): + if env_special_value in value: + input_usages.add(key) + + raw_api_key = config.get("apiKey") + if isinstance(raw_api_key, str) and env_special_value in raw_api_key: + input_usages.add("apiKey") + + if not input_usages: + print( + ANSI.yellow( + f"Input '{input_id}' defined in config but not used by any server or as an API key." + " Skipping." + ) + ) + continue + + # Prompt user for input + env_variable_key = input_id.replace("-", "_").upper() + print( + ANSI.blue(f" • {input_id}") + f": {description}. (default: load from {env_variable_key}).", + end=" ", + ) + user_input = (await _async_prompt(exit_event=exit_event)).strip() + if exit_event.is_set(): + return + + # Fallback to environment variable when user left blank + final_value = user_input + if not final_value: + final_value = os.getenv(env_variable_key, "") + if final_value: + print(ANSI.green(f"Value successfully loaded from '{env_variable_key}'")) + else: + print( + ANSI.yellow( + f"No value found for '{env_variable_key}' in environment variables. Continuing." + ) + ) + resolved_inputs[input_id] = final_value + + # Inject resolved value (can be empty) into stdio's env or http/sse's headers + for server in servers: + env_or_headers = server.get("env", {}) if server["type"] == "stdio" else server.get("headers", {}) + for key, value in env_or_headers.items(): + if env_special_value in value: + env_or_headers[key] = env_or_headers[key].replace(env_special_value, final_value) + + print() + + raw_api_key = config.get("apiKey") + if isinstance(raw_api_key, str): + substituted_api_key = raw_api_key + for input_id, val in resolved_inputs.items(): + substituted_api_key = substituted_api_key.replace(f"${{input:{input_id}}}", val) + config["apiKey"] = substituted_api_key + # Main agent loop + async with Agent( + provider=config.get("provider"), # type: ignore + model=config.get("model"), + base_url=config.get("endpointUrl"), # type: ignore[arg-type] + api_key=config.get("apiKey"), + servers=servers, # type: ignore[arg-type] + prompt=prompt, + ) as agent: + await agent.load_tools() + print(ANSI.bold(ANSI.blue("Agent loaded with {} tools:".format(len(agent.available_tools))))) + for t in agent.available_tools: + print(ANSI.blue(f" • {t.function.name}")) + + while True: + abort_event.clear() + + # Check if we should exit + if exit_event.is_set(): + return + + try: + user_input = await _async_prompt(exit_event=exit_event) + first_sigint = True + except EOFError: + print(ANSI.red("\nEOF received, exiting."), flush=True) + break + except KeyboardInterrupt: + if not first_sigint and abort_event.is_set(): + continue + else: + print(ANSI.red("\nKeyboard interrupt during input processing."), flush=True) + break + + try: + async for chunk in agent.run(user_input, abort_event=abort_event): + if abort_event.is_set() and not first_sigint: + break + if exit_event.is_set(): + return + + if hasattr(chunk, "choices"): + delta = chunk.choices[0].delta + if delta.content: + print(delta.content, end="", flush=True) + if delta.tool_calls: + for call in delta.tool_calls: + if call.id: + print(f"", end="") + if call.function.name: + print(f"{call.function.name}", end=" ") + if call.function.arguments: + print(f"{call.function.arguments}", end="") + else: + print( + ANSI.green(f"\n\nTool[{chunk.name}] {chunk.tool_call_id}\n{chunk.content}\n"), + flush=True, + ) + + print() + + except Exception as e: + tb_str = traceback.format_exc() + print(ANSI.red(f"\nError during agent run: {e}\n{tb_str}"), flush=True) + first_sigint = True # Allow graceful interrupt for the next command + + except Exception as e: + tb_str = traceback.format_exc() + print(ANSI.red(f"\nAn unexpected error occurred: {e}\n{tb_str}"), flush=True) + raise e + + finally: + if sigint_registered_in_loop: + try: + loop.remove_signal_handler(signal.SIGINT) + except (AttributeError, NotImplementedError): + pass + else: + signal.signal(signal.SIGINT, original_sigint_handler) + + +@app.command("run", help="Run the Agent in the CLI") +@click.argument("path", required=False) +def run(path: Optional[str]) -> None: + """ + Run the agent from PATH: a local folder containing an agent.json file or a built-in agent + stored in the 'tiny-agents/tiny-agents' Hugging Face dataset + (https://huggingface.co/datasets/tiny-agents/tiny-agents). + """ + try: + asyncio.run(run_agent(path)) + except KeyboardInterrupt: + print(ANSI.red("\nApplication terminated by KeyboardInterrupt."), flush=True) + raise click.exceptions.Exit(code=130) + except Exception as e: + print(ANSI.red(f"\nAn unexpected error occurred: {e}"), flush=True) + raise e + + +if __name__ == "__main__": + app() diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/constants.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/constants.py new file mode 100644 index 0000000000000000000000000000000000000000..7fb7b562c4ff2df3c0fadb72dfd64cfe01144f36 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/constants.py @@ -0,0 +1,81 @@ +from __future__ import annotations + +import sys +from pathlib import Path + +from huggingface_hub import ChatCompletionInputTool + + +FILENAME_CONFIG = "agent.json" +PROMPT_FILENAMES = ("PROMPT.md", "AGENTS.md") + +DEFAULT_AGENT = { + "model": "Qwen/Qwen2.5-72B-Instruct", + "provider": "novita", + "servers": [ + { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@modelcontextprotocol/server-filesystem", + str(Path.home() / ("Desktop" if sys.platform == "darwin" else "")), + ], + }, + { + "type": "stdio", + "command": "npx", + "args": ["@playwright/mcp@latest"], + }, + ], +} + + +DEFAULT_SYSTEM_PROMPT = """ +You are an agent - please keep going until the user’s query is completely +resolved, before ending your turn and yielding back to the user. Only terminate +your turn when you are sure that the problem is solved, or if you need more +info from the user to solve the problem. +If you are not sure about anything pertaining to the user’s request, use your +tools to read files and gather the relevant information: do NOT guess or make +up an answer. +You MUST plan extensively before each function call, and reflect extensively +on the outcomes of the previous function calls. DO NOT do this entire process +by making function calls only, as this can impair your ability to solve the +problem and think insightfully. +""".strip() + +MAX_NUM_TURNS = 10 + +TASK_COMPLETE_TOOL: ChatCompletionInputTool = ChatCompletionInputTool.parse_obj( # type: ignore + { + "type": "function", + "function": { + "name": "task_complete", + "description": "Call this tool when the task given by the user is complete", + "parameters": { + "type": "object", + "properties": {}, + }, + }, + } +) + +ASK_QUESTION_TOOL: ChatCompletionInputTool = ChatCompletionInputTool.parse_obj( # type: ignore + { + "type": "function", + "function": { + "name": "ask_question", + "description": "Ask the user for more info required to solve or clarify their problem.", + "parameters": { + "type": "object", + "properties": {}, + }, + }, + } +) + +EXIT_LOOP_TOOLS: list[ChatCompletionInputTool] = [TASK_COMPLETE_TOOL, ASK_QUESTION_TOOL] + + +DEFAULT_REPO_ID = "tiny-agents/tiny-agents" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/mcp_client.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/mcp_client.py new file mode 100644 index 0000000000000000000000000000000000000000..7331d13fa619f513c78ac8f1bd795a26f0695201 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/mcp_client.py @@ -0,0 +1,395 @@ +import json +import logging +from contextlib import AsyncExitStack +from datetime import timedelta +from pathlib import Path +from typing import TYPE_CHECKING, Any, AsyncIterable, Literal, Optional, TypedDict, Union, overload + +from typing_extensions import NotRequired, TypeAlias, Unpack + +from ...utils._runtime import get_hf_hub_version +from .._generated._async_client import AsyncInferenceClient +from .._generated.types import ( + ChatCompletionInputMessage, + ChatCompletionInputTool, + ChatCompletionStreamOutput, + ChatCompletionStreamOutputDeltaToolCall, +) +from .._providers import PROVIDER_OR_POLICY_T +from .utils import format_result + + +if TYPE_CHECKING: + from mcp import ClientSession + +logger = logging.getLogger(__name__) + +# Type alias for tool names +ToolName: TypeAlias = str + +ServerType: TypeAlias = Literal["stdio", "sse", "http"] + + +class StdioServerParameters_T(TypedDict): + command: str + args: NotRequired[list[str]] + env: NotRequired[dict[str, str]] + cwd: NotRequired[Union[str, Path, None]] + + +class SSEServerParameters_T(TypedDict): + url: str + headers: NotRequired[dict[str, Any]] + timeout: NotRequired[float] + sse_read_timeout: NotRequired[float] + + +class StreamableHTTPParameters_T(TypedDict): + url: str + headers: NotRequired[dict[str, Any]] + timeout: NotRequired[timedelta] + sse_read_timeout: NotRequired[timedelta] + terminate_on_close: NotRequired[bool] + + +class MCPClient: + """ + Client for connecting to one or more MCP servers and processing chat completions with tools. + + > [!WARNING] + > This class is experimental and might be subject to breaking changes in the future without prior notice. + + Args: + model (`str`, `optional`): + The model to run inference with. Can be a model id hosted on the Hugging Face Hub, e.g. `meta-llama/Meta-Llama-3-8B-Instruct` + or a URL to a deployed Inference Endpoint or other local or remote endpoint. + provider (`str`, *optional*): + Name of the provider to use for inference. Defaults to "auto" i.e. the first of the providers available for the model, sorted by the user's order in https://hf.co/settings/inference-providers. + If model is a URL or `base_url` is passed, then `provider` is not used. + base_url (`str`, *optional*): + The base URL to run inference. Defaults to None. + api_key (`str`, `optional`): + Token to use for authentication. Will default to the locally Hugging Face saved token if not provided. You can also use your own provider API key to interact directly with the provider's service. + """ + + def __init__( + self, + *, + model: Optional[str] = None, + provider: Optional[PROVIDER_OR_POLICY_T] = None, + base_url: Optional[str] = None, + api_key: Optional[str] = None, + ): + # Initialize MCP sessions as a dictionary of ClientSession objects + self.sessions: dict[ToolName, "ClientSession"] = {} + self.exit_stack = AsyncExitStack() + self.available_tools: list[ChatCompletionInputTool] = [] + # To be able to send the model in the payload if `base_url` is provided + if model is None and base_url is None: + raise ValueError("At least one of `model` or `base_url` should be set in `MCPClient`.") + self.payload_model = model + self.client = AsyncInferenceClient( + model=None if base_url is not None else model, + provider=provider, + api_key=api_key, + base_url=base_url, + ) + + async def __aenter__(self): + """Enter the context manager""" + await self.client.__aenter__() + await self.exit_stack.__aenter__() + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + """Exit the context manager""" + await self.client.__aexit__(exc_type, exc_val, exc_tb) + await self.cleanup() + + async def cleanup(self): + """Clean up resources""" + await self.client.close() + await self.exit_stack.aclose() + + @overload + async def add_mcp_server(self, type: Literal["stdio"], **params: Unpack[StdioServerParameters_T]): ... + + @overload + async def add_mcp_server(self, type: Literal["sse"], **params: Unpack[SSEServerParameters_T]): ... + + @overload + async def add_mcp_server(self, type: Literal["http"], **params: Unpack[StreamableHTTPParameters_T]): ... + + async def add_mcp_server(self, type: ServerType, **params: Any): + """Connect to an MCP server + + Args: + type (`str`): + Type of the server to connect to. Can be one of: + - "stdio": Standard input/output server (local) + - "sse": Server-sent events (SSE) server + - "http": StreamableHTTP server + **params (`dict[str, Any]`): + Server parameters that can be either: + - For stdio servers: + - command (str): The command to run the MCP server + - args (list[str], optional): Arguments for the command + - env (dict[str, str], optional): Environment variables for the command + - cwd (Union[str, Path, None], optional): Working directory for the command + - allowed_tools (list[str], optional): List of tool names to allow from this server + - For SSE servers: + - url (str): The URL of the SSE server + - headers (dict[str, Any], optional): Headers for the SSE connection + - timeout (float, optional): Connection timeout + - sse_read_timeout (float, optional): SSE read timeout + - allowed_tools (list[str], optional): List of tool names to allow from this server + - For StreamableHTTP servers: + - url (str): The URL of the StreamableHTTP server + - headers (dict[str, Any], optional): Headers for the StreamableHTTP connection + - timeout (timedelta, optional): Connection timeout + - sse_read_timeout (timedelta, optional): SSE read timeout + - terminate_on_close (bool, optional): Whether to terminate on close + - allowed_tools (list[str], optional): List of tool names to allow from this server + """ + from mcp import ClientSession, StdioServerParameters + from mcp import types as mcp_types + + # Extract allowed_tools configuration if provided + allowed_tools = params.pop("allowed_tools", None) + + # Determine server type and create appropriate parameters + if type == "stdio": + # Handle stdio server + from mcp.client.stdio import stdio_client + + logger.info(f"Connecting to stdio MCP server with command: {params['command']} {params.get('args', [])}") + + client_kwargs = {"command": params["command"]} + for key in ["args", "env", "cwd"]: + if params.get(key) is not None: + client_kwargs[key] = params[key] + server_params = StdioServerParameters(**client_kwargs) + read, write = await self.exit_stack.enter_async_context(stdio_client(server_params)) + elif type == "sse": + # Handle SSE server + from mcp.client.sse import sse_client + + logger.info(f"Connecting to SSE MCP server at: {params['url']}") + + client_kwargs = {"url": params["url"]} + for key in ["headers", "timeout", "sse_read_timeout"]: + if params.get(key) is not None: + client_kwargs[key] = params[key] + read, write = await self.exit_stack.enter_async_context(sse_client(**client_kwargs)) + elif type == "http": + # Handle StreamableHTTP server + from mcp.client.streamable_http import streamablehttp_client + + logger.info(f"Connecting to StreamableHTTP MCP server at: {params['url']}") + + client_kwargs = {"url": params["url"]} + for key in ["headers", "timeout", "sse_read_timeout", "terminate_on_close"]: + if params.get(key) is not None: + client_kwargs[key] = params[key] + read, write, _ = await self.exit_stack.enter_async_context(streamablehttp_client(**client_kwargs)) + # ^ TODO: should be handle `get_session_id_callback`? (function to retrieve the current session ID) + else: + raise ValueError(f"Unsupported server type: {type}") + + session = await self.exit_stack.enter_async_context( + ClientSession( + read_stream=read, + write_stream=write, + client_info=mcp_types.Implementation( + name="huggingface_hub.MCPClient", + version=get_hf_hub_version(), + ), + ) + ) + + logger.debug("Initializing session...") + await session.initialize() + + # List available tools + response = await session.list_tools() + logger.debug("Connected to server with tools:", [tool.name for tool in response.tools]) + + # Filter tools based on allowed_tools configuration + filtered_tools = response.tools + + if allowed_tools is not None: + filtered_tools = [tool for tool in response.tools if tool.name in allowed_tools] + logger.debug( + f"Tool filtering applied. Using {len(filtered_tools)} of {len(response.tools)} available tools: {[tool.name for tool in filtered_tools]}" + ) + + for tool in filtered_tools: + if tool.name in self.sessions: + logger.warning(f"Tool '{tool.name}' already defined by another server. Skipping.") + continue + + # Map tool names to their server for later lookup + self.sessions[tool.name] = session + + # Add tool to the list of available tools (for use in chat completions) + self.available_tools.append( + ChatCompletionInputTool.parse_obj_as_instance( + { + "type": "function", + "function": { + "name": tool.name, + "description": tool.description, + "parameters": tool.inputSchema, + }, + } + ) + ) + + async def process_single_turn_with_tools( + self, + messages: list[Union[dict, ChatCompletionInputMessage]], + exit_loop_tools: Optional[list[ChatCompletionInputTool]] = None, + exit_if_first_chunk_no_tool: bool = False, + ) -> AsyncIterable[Union[ChatCompletionStreamOutput, ChatCompletionInputMessage]]: + """Process a query using `self.model` and available tools, yielding chunks and tool outputs. + + Args: + messages (`list[dict]`): + List of message objects representing the conversation history + exit_loop_tools (`list[ChatCompletionInputTool]`, *optional*): + List of tools that should exit the generator when called + exit_if_first_chunk_no_tool (`bool`, *optional*): + Exit if no tool is present in the first chunks. Default to False. + + Yields: + [`ChatCompletionStreamOutput`] chunks or [`ChatCompletionInputMessage`] objects + """ + # Prepare tools list based on options + tools = self.available_tools + if exit_loop_tools is not None: + tools = [*exit_loop_tools, *self.available_tools] + + # Create the streaming request + response = await self.client.chat.completions.create( + model=self.payload_model, + messages=messages, + tools=tools, + tool_choice="auto", + stream=True, + ) + + message: dict[str, Any] = {"role": "unknown", "content": ""} + final_tool_calls: dict[int, ChatCompletionStreamOutputDeltaToolCall] = {} + num_of_chunks = 0 + + # Read from stream + async for chunk in response: + num_of_chunks += 1 + delta = chunk.choices[0].delta if chunk.choices and len(chunk.choices) > 0 else None + if not delta: + continue + + # Process message + if delta.role: + message["role"] = delta.role + if delta.content: + message["content"] += delta.content + + # Process tool calls + if delta.tool_calls: + for tool_call in delta.tool_calls: + idx = tool_call.index + # first chunk for this tool call + if idx not in final_tool_calls: + final_tool_calls[idx] = tool_call + if final_tool_calls[idx].function.arguments is None: + final_tool_calls[idx].function.arguments = "" + continue + # safety before concatenating text to .function.arguments + if final_tool_calls[idx].function.arguments is None: + final_tool_calls[idx].function.arguments = "" + + if tool_call.function.arguments: + final_tool_calls[idx].function.arguments += tool_call.function.arguments + + # Optionally exit early if no tools in first chunks + if exit_if_first_chunk_no_tool and num_of_chunks <= 2 and len(final_tool_calls) == 0: + return + + # Yield each chunk to caller + yield chunk + + # Add the assistant message with tool calls (if any) to messages + if message["content"] or final_tool_calls: + # if the role is unknown, set it to assistant + if message.get("role") == "unknown": + message["role"] = "assistant" + # Convert final_tool_calls to the format expected by OpenAI + if final_tool_calls: + tool_calls_list: list[dict[str, Any]] = [] + for tc in final_tool_calls.values(): + tool_calls_list.append( + { + "id": tc.id, + "type": "function", + "function": { + "name": tc.function.name, + "arguments": tc.function.arguments or "{}", + }, + } + ) + message["tool_calls"] = tool_calls_list + messages.append(message) + + # Process tool calls one by one + for tool_call in final_tool_calls.values(): + function_name = tool_call.function.name + if function_name is None: + message = ChatCompletionInputMessage.parse_obj_as_instance( + { + "role": "tool", + "tool_call_id": tool_call.id, + "content": "Invalid tool call with no function name.", + } + ) + messages.append(message) + yield message + continue # move to next tool call + try: + function_args = json.loads(tool_call.function.arguments or "{}") + except json.JSONDecodeError as err: + tool_message = { + "role": "tool", + "tool_call_id": tool_call.id, + "name": function_name, + "content": f"Invalid JSON generated by the model: {err}", + } + tool_message_as_obj = ChatCompletionInputMessage.parse_obj_as_instance(tool_message) + messages.append(tool_message_as_obj) + yield tool_message_as_obj + continue # move to next tool call + + tool_message = {"role": "tool", "tool_call_id": tool_call.id, "content": "", "name": function_name} + + # Check if this is an exit loop tool + if exit_loop_tools and function_name in [t.function.name for t in exit_loop_tools]: + tool_message_as_obj = ChatCompletionInputMessage.parse_obj_as_instance(tool_message) + messages.append(tool_message_as_obj) + yield tool_message_as_obj + return + + # Execute tool call with the appropriate session + session = self.sessions.get(function_name) + if session is not None: + try: + result = await session.call_tool(function_name, function_args) + tool_message["content"] = format_result(result) + except Exception as err: + tool_message["content"] = f"Error: MCP tool call failed with error message: {err}" + else: + tool_message["content"] = f"Error: No session found for tool: {function_name}" + + # Yield tool message + tool_message_as_obj = ChatCompletionInputMessage.parse_obj_as_instance(tool_message) + messages.append(tool_message_as_obj) + yield tool_message_as_obj diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/types.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/types.py new file mode 100644 index 0000000000000000000000000000000000000000..a531929a8e574e52075b59cec88e24d93cb1dbd7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/types.py @@ -0,0 +1,45 @@ +from typing import Literal, TypedDict, Union + +from typing_extensions import NotRequired + + +class InputConfig(TypedDict, total=False): + id: str + description: str + type: str + password: bool + + +class StdioServerConfig(TypedDict): + type: Literal["stdio"] + command: str + args: list[str] + env: dict[str, str] + cwd: str + allowed_tools: NotRequired[list[str]] + + +class HTTPServerConfig(TypedDict): + type: Literal["http"] + url: str + headers: dict[str, str] + allowed_tools: NotRequired[list[str]] + + +class SSEServerConfig(TypedDict): + type: Literal["sse"] + url: str + headers: dict[str, str] + allowed_tools: NotRequired[list[str]] + + +ServerConfig = Union[StdioServerConfig, HTTPServerConfig, SSEServerConfig] + + +# AgentConfig root object +class AgentConfig(TypedDict): + model: str + provider: str + apiKey: NotRequired[str] + inputs: list[InputConfig] + servers: list[ServerConfig] diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/utils.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..5df9d5183df75f11ad902f514b9f2b6cf5041d6f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_mcp/utils.py @@ -0,0 +1,130 @@ +""" +Utility functions for MCPClient and Tiny Agents. + +Formatting utilities taken from the JS SDK: https://github.com/huggingface/huggingface.js/blob/main/packages/mcp-client/src/ResultFormatter.ts. +""" + +import json +from pathlib import Path +from typing import TYPE_CHECKING, Optional + +from huggingface_hub import snapshot_download +from huggingface_hub.errors import EntryNotFoundError + +from .constants import DEFAULT_AGENT, DEFAULT_REPO_ID, FILENAME_CONFIG, PROMPT_FILENAMES +from .types import AgentConfig + + +if TYPE_CHECKING: + from mcp import types as mcp_types + + +def format_result(result: "mcp_types.CallToolResult") -> str: + """ + Formats a mcp.types.CallToolResult content into a human-readable string. + + Args: + result (CallToolResult) + Object returned by mcp.ClientSession.call_tool. + + Returns: + str + A formatted string representing the content of the result. + """ + content = result.content + + if len(content) == 0: + return "[No content]" + + formatted_parts: list[str] = [] + + for item in content: + match item.type: + case "text": + formatted_parts.append(item.text) + + case "image": + formatted_parts.append( + f"[Binary Content: Image {item.mimeType}, {_get_base64_size(item.data)} bytes]\n" + f"The task is complete and the content accessible to the User" + ) + + case "audio": + formatted_parts.append( + f"[Binary Content: Audio {item.mimeType}, {_get_base64_size(item.data)} bytes]\n" + f"The task is complete and the content accessible to the User" + ) + + case "resource": + resource = item.resource + + if hasattr(resource, "text") and isinstance(resource.text, str): + formatted_parts.append(resource.text) + + elif hasattr(resource, "blob") and isinstance(resource.blob, str): + formatted_parts.append( + f"[Binary Content ({resource.uri}): {resource.mimeType}," + f" {_get_base64_size(resource.blob)} bytes]\n" + f"The task is complete and the content accessible to the User" + ) + + return "\n".join(formatted_parts) + + +def _get_base64_size(base64_str: str) -> int: + """Estimate the byte size of a base64-encoded string.""" + # Remove any prefix like "data:image/png;base64," + if "," in base64_str: + base64_str = base64_str.split(",")[1] + + padding = 0 + if base64_str.endswith("=="): + padding = 2 + elif base64_str.endswith("="): + padding = 1 + + return (len(base64_str) * 3) // 4 - padding + + +def _load_agent_config(agent_path: Optional[str]) -> tuple[AgentConfig, Optional[str]]: + """Load server config and prompt.""" + + def _read_dir(directory: Path) -> tuple[AgentConfig, Optional[str]]: + cfg_file = directory / FILENAME_CONFIG + if not cfg_file.exists(): + raise FileNotFoundError(f" Config file not found in {directory}! Please make sure it exists locally") + + config: AgentConfig = json.loads(cfg_file.read_text(encoding="utf-8")) + prompt: Optional[str] = None + for filename in PROMPT_FILENAMES: + prompt_file = directory / filename + if prompt_file.exists(): + prompt = prompt_file.read_text(encoding="utf-8") + break + return config, prompt + + if agent_path is None: + return DEFAULT_AGENT, None # type: ignore + + path = Path(agent_path).expanduser() + + if path.is_file(): + return json.loads(path.read_text(encoding="utf-8")), None + + if path.is_dir(): + return _read_dir(path) + + # fetch from the Hub + try: + repo_dir = Path( + snapshot_download( + repo_id=DEFAULT_REPO_ID, + allow_patterns=f"{agent_path}/*", + repo_type="dataset", + ) + ) + return _read_dir(repo_dir / agent_path) + except Exception as err: + raise EntryNotFoundError( + f" Agent {agent_path} not found in tiny-agents/tiny-agents! Please make sure it exists in https://huggingface.co/datasets/tiny-agents/tiny-agents." + ) from err diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/__init__.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..fec1b5040ec7bb259d5444e9a714beb9fb4f8e87 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/__init__.py @@ -0,0 +1,254 @@ +from typing import Literal, Union + +from huggingface_hub.inference._providers.featherless_ai import ( + FeatherlessConversationalTask, + FeatherlessTextGenerationTask, +) +from huggingface_hub.utils import logging + +from ._common import AutoRouterConversationalTask, TaskProviderHelper, _fetch_inference_provider_mapping +from .cerebras import CerebrasConversationalTask +from .cohere import CohereConversationalTask +from .deepinfra import ( + DeepInfraAutomaticSpeechRecognitionTask, + DeepInfraConversationalTask, + DeepInfraTextGenerationTask, +) +from .fal_ai import ( + FalAIAutomaticSpeechRecognitionTask, + FalAIImageSegmentationTask, + FalAIImageToImageTask, + FalAIImageToVideoTask, + FalAITextToImageTask, + FalAITextToSpeechTask, + FalAITextToVideoTask, +) +from .fireworks_ai import FireworksAIConversationalTask +from .groq import GroqConversationalTask +from .hf_inference import ( + HFInferenceBinaryInputTask, + HFInferenceConversational, + HFInferenceFeatureExtractionTask, + HFInferenceTask, +) +from .novita import NovitaConversationalTask, NovitaTextGenerationTask, NovitaTextToVideoTask +from .nscale import NscaleConversationalTask, NscaleTextToImageTask +from .openai import OpenAIConversationalTask +from .ovhcloud import OVHcloudConversationalTask +from .publicai import PublicAIConversationalTask +from .replicate import ( + ReplicateAutomaticSpeechRecognitionTask, + ReplicateImageToImageTask, + ReplicateTask, + ReplicateTextToImageTask, + ReplicateTextToSpeechTask, +) +from .scaleway import ScalewayConversationalTask, ScalewayFeatureExtractionTask +from .together import ( + TogetherConversationalTask, + TogetherFeatureExtractionTask, + TogetherImageToImageTask, + TogetherImageToVideoTask, + TogetherTextGenerationTask, + TogetherTextToImageTask, + TogetherTextToSpeechTask, + TogetherTextToVideoTask, +) +from .wavespeed import ( + WavespeedAIImageToImageTask, + WavespeedAIImageToVideoTask, + WavespeedAITextToImageTask, + WavespeedAITextToVideoTask, +) +from .zai_org import ZaiConversationalTask, ZaiTextToImageTask + + +logger = logging.get_logger(__name__) + + +PROVIDER_T = Literal[ + "cerebras", + "cohere", + "deepinfra", + "fal-ai", + "featherless-ai", + "fireworks-ai", + "groq", + "hf-inference", + "novita", + "nscale", + "openai", + "ovhcloud", + "publicai", + "replicate", + "scaleway", + "together", + "wavespeed", + "zai-org", +] + +PROVIDER_OR_POLICY_T = Union[PROVIDER_T, Literal["auto"]] + +CONVERSATIONAL_AUTO_ROUTER = AutoRouterConversationalTask() + +PROVIDERS: dict[PROVIDER_T, dict[str, TaskProviderHelper]] = { + "cerebras": { + "conversational": CerebrasConversationalTask(), + }, + "cohere": { + "conversational": CohereConversationalTask(), + }, + "deepinfra": { + "automatic-speech-recognition": DeepInfraAutomaticSpeechRecognitionTask(), + "conversational": DeepInfraConversationalTask(), + "text-generation": DeepInfraTextGenerationTask(), + }, + "fal-ai": { + "automatic-speech-recognition": FalAIAutomaticSpeechRecognitionTask(), + "text-to-image": FalAITextToImageTask(), + "text-to-speech": FalAITextToSpeechTask(), + "text-to-video": FalAITextToVideoTask(), + "image-to-video": FalAIImageToVideoTask(), + "image-to-image": FalAIImageToImageTask(), + "image-segmentation": FalAIImageSegmentationTask(), + }, + "featherless-ai": { + "conversational": FeatherlessConversationalTask(), + "text-generation": FeatherlessTextGenerationTask(), + }, + "fireworks-ai": { + "conversational": FireworksAIConversationalTask(), + }, + "groq": { + "conversational": GroqConversationalTask(), + }, + "hf-inference": { + "text-to-image": HFInferenceTask("text-to-image"), + "conversational": HFInferenceConversational(), + "text-generation": HFInferenceTask("text-generation"), + "text-classification": HFInferenceTask("text-classification"), + "question-answering": HFInferenceTask("question-answering"), + "audio-classification": HFInferenceBinaryInputTask("audio-classification"), + "automatic-speech-recognition": HFInferenceBinaryInputTask("automatic-speech-recognition"), + "fill-mask": HFInferenceTask("fill-mask"), + "feature-extraction": HFInferenceFeatureExtractionTask(), + "image-classification": HFInferenceBinaryInputTask("image-classification"), + "image-segmentation": HFInferenceBinaryInputTask("image-segmentation"), + "document-question-answering": HFInferenceTask("document-question-answering"), + "image-to-text": HFInferenceBinaryInputTask("image-to-text"), + "object-detection": HFInferenceBinaryInputTask("object-detection"), + "audio-to-audio": HFInferenceBinaryInputTask("audio-to-audio"), + "zero-shot-image-classification": HFInferenceBinaryInputTask("zero-shot-image-classification"), + "zero-shot-classification": HFInferenceTask("zero-shot-classification"), + "image-to-image": HFInferenceBinaryInputTask("image-to-image"), + "sentence-similarity": HFInferenceTask("sentence-similarity"), + "table-question-answering": HFInferenceTask("table-question-answering"), + "tabular-classification": HFInferenceTask("tabular-classification"), + "text-to-speech": HFInferenceTask("text-to-speech"), + "token-classification": HFInferenceTask("token-classification"), + "translation": HFInferenceTask("translation"), + "summarization": HFInferenceTask("summarization"), + "visual-question-answering": HFInferenceBinaryInputTask("visual-question-answering"), + }, + "novita": { + "text-generation": NovitaTextGenerationTask(), + "conversational": NovitaConversationalTask(), + "text-to-video": NovitaTextToVideoTask(), + }, + "nscale": { + "conversational": NscaleConversationalTask(), + "text-to-image": NscaleTextToImageTask(), + }, + "openai": { + "conversational": OpenAIConversationalTask(), + }, + "ovhcloud": { + "conversational": OVHcloudConversationalTask(), + }, + "publicai": { + "conversational": PublicAIConversationalTask(), + }, + "replicate": { + "automatic-speech-recognition": ReplicateAutomaticSpeechRecognitionTask(), + "image-to-image": ReplicateImageToImageTask(), + "text-to-image": ReplicateTextToImageTask(), + "text-to-speech": ReplicateTextToSpeechTask(), + "text-to-video": ReplicateTask("text-to-video"), + }, + "scaleway": { + "conversational": ScalewayConversationalTask(), + "feature-extraction": ScalewayFeatureExtractionTask(), + }, + "together": { + "conversational": TogetherConversationalTask(), + "feature-extraction": TogetherFeatureExtractionTask(), + "image-to-image": TogetherImageToImageTask(), + "image-to-video": TogetherImageToVideoTask(), + "text-generation": TogetherTextGenerationTask(), + "text-to-image": TogetherTextToImageTask(), + "text-to-speech": TogetherTextToSpeechTask(), + "text-to-video": TogetherTextToVideoTask(), + }, + "wavespeed": { + "text-to-image": WavespeedAITextToImageTask(), + "text-to-video": WavespeedAITextToVideoTask(), + "image-to-image": WavespeedAIImageToImageTask(), + "image-to-video": WavespeedAIImageToVideoTask(), + }, + "zai-org": { + "conversational": ZaiConversationalTask(), + "text-to-image": ZaiTextToImageTask(), + }, +} + + +def get_provider_helper(provider: PROVIDER_OR_POLICY_T | None, task: str, model: str | None) -> TaskProviderHelper: + """Get provider helper instance by name and task. + + Args: + provider (`str`, *optional*): name of the provider, or "auto" to automatically select the provider for the model. + task (`str`): Name of the task + model (`str`, *optional*): Name of the model + Returns: + TaskProviderHelper: Helper instance for the specified provider and task + + Raises: + ValueError: If provider or task is not supported + """ + + if (model is None and provider in (None, "auto")) or ( + model is not None and model.startswith(("http://", "https://")) + ): + provider = "hf-inference" + + if provider is None: + logger.info( + "No provider specified for task `conversational`. Defaulting to server-side auto routing." + if task == "conversational" + else "Defaulting to 'auto' which will select the first provider available for the model, sorted by the user's order in https://hf.co/settings/inference-providers." + ) + provider = "auto" + + if provider == "auto": + if model is None: + raise ValueError("Specifying a model is required when provider is 'auto'") + if task == "conversational": + # Special case: we have a dedicated auto-router for conversational models. No need to fetch provider mapping. + return CONVERSATIONAL_AUTO_ROUTER + + provider_mapping = _fetch_inference_provider_mapping(model) + provider = next(iter(provider_mapping)).provider + + provider_tasks = PROVIDERS.get(provider) # type: ignore + if provider_tasks is None: + raise ValueError( + f"Provider '{provider}' not supported. Available values: 'auto' or any provider from {list(PROVIDERS.keys())}." + "Passing 'auto' (default value) will automatically select the first provider available for the model, sorted " + "by the user's order in https://hf.co/settings/inference-providers." + ) + + if task not in provider_tasks: + raise ValueError( + f"Task '{task}' not supported for provider '{provider}'. Available tasks: {list(provider_tasks.keys())}" + ) + return provider_tasks[task] diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/_common.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/_common.py new file mode 100644 index 0000000000000000000000000000000000000000..25330e70de8aab6f9cd47ab4d8fca183a6bef434 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/_common.py @@ -0,0 +1,360 @@ +from functools import lru_cache +from typing import Any, overload + +from huggingface_hub import constants +from huggingface_hub.hf_api import InferenceProviderMapping +from huggingface_hub.inference._common import MimeBytes, RequestParameters +from huggingface_hub.inference._generated.types.chat_completion import ChatCompletionInputMessage +from huggingface_hub.utils import build_hf_headers, get_token, logging + + +logger = logging.get_logger(__name__) + + +# Dev purposes only. +# If you want to try to run inference for a new model locally before it's registered on huggingface.co +# for a given Inference Provider, you can add it to the following dictionary. +HARDCODED_MODEL_INFERENCE_MAPPING: dict[str, dict[str, InferenceProviderMapping]] = { + # "HF model ID" => InferenceProviderMapping object initialized with "Model ID on Inference Provider's side" + # + # Example: + # "Qwen/Qwen2.5-Coder-32B-Instruct": InferenceProviderMapping(hf_model_id="Qwen/Qwen2.5-Coder-32B-Instruct", + # provider_id="Qwen2.5-Coder-32B-Instruct", + # task="conversational", + # status="live") + "cerebras": {}, + "cohere": {}, + "deepinfra": {}, + "fal-ai": {}, + "fireworks-ai": {}, + "groq": {}, + "hf-inference": {}, + "nscale": {}, + "ovhcloud": {}, + "replicate": {}, + "scaleway": {}, + "together": {}, + "wavespeed": {}, + "zai-org": {}, +} + + +@overload +def filter_none(obj: dict[str, Any]) -> dict[str, Any]: ... +@overload +def filter_none(obj: list[Any]) -> list[Any]: ... + + +def filter_none(obj: dict[str, Any] | list[Any]) -> dict[str, Any] | list[Any]: + if isinstance(obj, dict): + cleaned: dict[str, Any] = {} + for k, v in obj.items(): + if v is None: + continue + if isinstance(v, (dict, list)): + v = filter_none(v) + cleaned[k] = v + return cleaned + + if isinstance(obj, list): + return [filter_none(v) if isinstance(v, (dict, list)) else v for v in obj] + + raise ValueError(f"Expected dict or list, got {type(obj)}") + + +class TaskProviderHelper: + """Base class for task-specific provider helpers.""" + + def __init__(self, provider: str, base_url: str, task: str) -> None: + self.provider = provider + self.task = task + self.base_url = base_url + + def prepare_request( + self, + *, + inputs: Any, + parameters: dict[str, Any], + headers: dict, + model: str | None, + api_key: str | None, + extra_payload: dict[str, Any] | None = None, + ) -> RequestParameters: + """ + Prepare the request to be sent to the provider. + + Each step (api_key, model, headers, url, payload) can be customized in subclasses. + """ + # api_key from user, or local token, or raise error + api_key = self._prepare_api_key(api_key) + + # mapped model from HF model ID + provider_mapping_info = self._prepare_mapping_info(model) + + # default HF headers + user headers (to customize in subclasses) + headers = self._prepare_headers(headers, api_key) + + # routed URL if HF token, or direct URL (to customize in '_prepare_route' in subclasses) + url = self._prepare_url(api_key, provider_mapping_info.provider_id) + + # prepare payload (to customize in subclasses) + payload = self._prepare_payload_as_dict(inputs, parameters, provider_mapping_info=provider_mapping_info) + if payload is not None: + payload = recursive_merge(payload, filter_none(extra_payload or {})) + + # body data (to customize in subclasses) + data = self._prepare_payload_as_bytes(inputs, parameters, provider_mapping_info, extra_payload) + + # check if both payload and data are set and return + if payload is not None and data is not None: + raise ValueError("Both payload and data cannot be set in the same request.") + if payload is None and data is None: + raise ValueError("Either payload or data must be set in the request.") + + # normalize headers to lowercase and add content-type if not present + normalized_headers = self._normalize_headers(headers, payload, data) + + return RequestParameters( + url=url, + task=self.task, + model=provider_mapping_info.provider_id, + json=payload, + data=data, + headers=normalized_headers, + ) + + def get_response( + self, + response: bytes | dict, + request_params: RequestParameters | None = None, + ) -> Any: + """ + Return the response in the expected format. + + Override this method in subclasses for customized response handling.""" + return response + + def _prepare_api_key(self, api_key: str | None) -> str: + """Return the API key to use for the request. + + Usually not overwritten in subclasses.""" + if api_key is None: + api_key = get_token() + if api_key is None: + raise ValueError( + f"You must provide an api_key to work with {self.provider} API or log in with `hf auth login`." + ) + return api_key + + def _prepare_mapping_info(self, model: str | None) -> InferenceProviderMapping: + """Return the mapped model ID to use for the request. + + Usually not overwritten in subclasses.""" + if model is None: + raise ValueError(f"Please provide an HF model ID supported by {self.provider}.") + + # hardcoded mapping for local testing + if HARDCODED_MODEL_INFERENCE_MAPPING.get(self.provider, {}).get(model): + return HARDCODED_MODEL_INFERENCE_MAPPING[self.provider][model] + + provider_mapping = None + for mapping in _fetch_inference_provider_mapping(model): + if mapping.provider == self.provider: + provider_mapping = mapping + break + + if provider_mapping is None: + raise ValueError(f"Model {model} is not supported by provider {self.provider}.") + + if provider_mapping.task != self.task: + raise ValueError( + f"Model {model} is not supported for task {self.task} and provider {self.provider}. " + f"Supported task: {provider_mapping.task}." + ) + + if provider_mapping.status == "staging": + logger.warning( + f"Model {model} is in staging mode for provider {self.provider}. Meant for test purposes only." + ) + if provider_mapping.status == "error": + logger.warning( + f"Our latest automated health check on model '{model}' for provider '{self.provider}' did not complete successfully. " + "Inference call might fail." + ) + return provider_mapping + + def _normalize_headers( + self, headers: dict[str, Any], payload: dict[str, Any] | None, data: MimeBytes | None + ) -> dict[str, Any]: + """Normalize the headers to use for the request. + + Override this method in subclasses for customized headers. + """ + normalized_headers = {key.lower(): value for key, value in headers.items() if value is not None} + if normalized_headers.get("content-type") is None: + if data is not None and data.mime_type is not None: + normalized_headers["content-type"] = data.mime_type + elif payload is not None: + normalized_headers["content-type"] = "application/json" + return normalized_headers + + def _prepare_headers(self, headers: dict, api_key: str) -> dict[str, Any]: + """Return the headers to use for the request. + + Override this method in subclasses for customized headers. + """ + return {**build_hf_headers(token=api_key), **headers} + + def _prepare_url(self, api_key: str, mapped_model: str) -> str: + """Return the URL to use for the request. + + Usually not overwritten in subclasses.""" + base_url = self._prepare_base_url(api_key) + route = self._prepare_route(mapped_model, api_key) + return f"{base_url.rstrip('/')}/{route.lstrip('/')}" + + def _prepare_base_url(self, api_key: str) -> str: + """Return the base URL to use for the request. + + Usually not overwritten in subclasses.""" + # Route to the proxy if the api_key is a HF TOKEN + if api_key.startswith("hf_"): + logger.info(f"Calling '{self.provider}' provider through Hugging Face router.") + return constants.INFERENCE_PROXY_TEMPLATE.format(provider=self.provider) + else: + logger.info(f"Calling '{self.provider}' provider directly.") + return self.base_url + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + """Return the route to use for the request. + + Override this method in subclasses for customized routes. + """ + return "" + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + """Return the payload to use for the request, as a dict. + + Override this method in subclasses for customized payloads. + Only one of `_prepare_payload_as_dict` and `_prepare_payload_as_bytes` should return a value. + """ + return None + + def _prepare_payload_as_bytes( + self, + inputs: Any, + parameters: dict, + provider_mapping_info: InferenceProviderMapping, + extra_payload: dict | None, + ) -> MimeBytes | None: + """Return the body to use for the request, as bytes. + + Override this method in subclasses for customized body data. + Only one of `_prepare_payload_as_dict` and `_prepare_payload_as_bytes` should return a value. + """ + return None + + +class BaseConversationalTask(TaskProviderHelper): + """ + Base class for conversational (chat completion) tasks. + The schema follows the OpenAI API format defined here: https://platform.openai.com/docs/api-reference/chat + """ + + def __init__(self, provider: str, base_url: str): + super().__init__(provider=provider, base_url=base_url, task="conversational") + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + return "/v1/chat/completions" + + def _prepare_payload_as_dict( + self, + inputs: list[dict | ChatCompletionInputMessage], + parameters: dict, + provider_mapping_info: InferenceProviderMapping, + ) -> dict | None: + return filter_none({"messages": inputs, **parameters, "model": provider_mapping_info.provider_id}) + + +class AutoRouterConversationalTask(BaseConversationalTask): + """ + Auto-router for conversational tasks. + + We let the Hugging Face router select the best provider for the model, based on availability and user preferences. + This is a special case since the selection is done server-side (avoid 1 API call to fetch provider mapping). + """ + + def __init__(self): + super().__init__(provider="auto", base_url="https://router.huggingface.co") + + def _prepare_base_url(self, api_key: str) -> str: + """Return the base URL to use for the request. + + Usually not overwritten in subclasses.""" + # Route to the proxy if the api_key is a HF TOKEN + if not api_key.startswith("hf_"): + raise ValueError("Cannot select auto-router when using non-Hugging Face API key.") + else: + return self.base_url # No `/auto` suffix in the URL + + def _prepare_mapping_info(self, model: str | None) -> InferenceProviderMapping: + """ + In auto-router, we don't need to fetch provider mapping info. + We just return a dummy mapping info with provider_id set to the HF model ID. + """ + if model is None: + raise ValueError("Please provide an HF model ID.") + + return InferenceProviderMapping( + provider="auto", + hf_model_id=model, + providerId=model, + status="live", + task="conversational", + ) + + +class BaseTextGenerationTask(TaskProviderHelper): + """ + Base class for text-generation (completion) tasks. + The schema follows the OpenAI API format defined here: https://platform.openai.com/docs/api-reference/completions + """ + + def __init__(self, provider: str, base_url: str): + super().__init__(provider=provider, base_url=base_url, task="text-generation") + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + return "/v1/completions" + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + return filter_none({"prompt": inputs, **parameters, "model": provider_mapping_info.provider_id}) + + +@lru_cache(maxsize=None) +def _fetch_inference_provider_mapping(model: str) -> list["InferenceProviderMapping"]: + """ + Fetch provider mappings for a model from the Hub. + """ + from huggingface_hub.hf_api import HfApi + + info = HfApi().model_info(model, expand=["inferenceProviderMapping"]) + provider_mapping = info.inference_provider_mapping + if provider_mapping is None: + raise ValueError(f"No provider mapping found for model {model}") + return provider_mapping + + +def recursive_merge(dict1: dict, dict2: dict) -> dict: + return { + **dict1, + **{ + key: recursive_merge(dict1[key], value) + if (key in dict1 and isinstance(dict1[key], dict) and isinstance(value, dict)) + else value + for key, value in dict2.items() + }, + } diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/cerebras.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/cerebras.py new file mode 100644 index 0000000000000000000000000000000000000000..a9b9c3aacb3e134a8e755297c15ece198ffe633d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/cerebras.py @@ -0,0 +1,6 @@ +from ._common import BaseConversationalTask + + +class CerebrasConversationalTask(BaseConversationalTask): + def __init__(self): + super().__init__(provider="cerebras", base_url="https://api.cerebras.ai") diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/cohere.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/cohere.py new file mode 100644 index 0000000000000000000000000000000000000000..57ddfc8246bcd2f3d63c74f78ded130dcca53992 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/cohere.py @@ -0,0 +1,32 @@ +from typing import Any + +from huggingface_hub.hf_api import InferenceProviderMapping + +from ._common import BaseConversationalTask + + +_PROVIDER = "cohere" +_BASE_URL = "https://api.cohere.com" + + +class CohereConversationalTask(BaseConversationalTask): + def __init__(self): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL) + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + return "/compatibility/v1/chat/completions" + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + payload = super()._prepare_payload_as_dict(inputs, parameters, provider_mapping_info) + response_format = parameters.get("response_format") + if isinstance(response_format, dict) and response_format.get("type") == "json_schema": + json_schema_details = response_format.get("json_schema") + if isinstance(json_schema_details, dict) and "schema" in json_schema_details: + payload["response_format"] = { # type: ignore + "type": "json_object", + "schema": json_schema_details["schema"], + } + + return payload diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/deepinfra.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/deepinfra.py new file mode 100644 index 0000000000000000000000000000000000000000..19431258b4b083e61b94166bbbe12f676e382d0c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/deepinfra.py @@ -0,0 +1,120 @@ +import json +import mimetypes +import uuid +from typing import Any + +from huggingface_hub.hf_api import InferenceProviderMapping +from huggingface_hub.inference._common import MimeBytes, RequestParameters, _as_dict, _open_as_mime_bytes + +from ._common import BaseConversationalTask, BaseTextGenerationTask, TaskProviderHelper, filter_none + + +_PROVIDER = "deepinfra" +_BASE_URL = "https://api.deepinfra.com" + + +def _form_field_value(value: Any) -> str: + if isinstance(value, str): + return value + if isinstance(value, bool): # bool before int: bool is an int subclass + return "true" if value else "false" + if isinstance(value, (int, float)): + return str(value) + return json.dumps(value) + + +def _encode_multipart(audio: MimeBytes, fields: dict[str, Any]) -> tuple[bytes, str]: + boundary = uuid.uuid4().hex + # Fall back to .wav when the MIME type is unknown: transcription servers sniff the format from the filename. + filename = "audio" + (mimetypes.guess_extension(audio.mime_type or "") or ".wav") + lines: list[bytes] = [ + f"--{boundary}".encode(), + f'Content-Disposition: form-data; name="file"; filename="{filename}"'.encode(), + f"Content-Type: {audio.mime_type or 'application/octet-stream'}".encode(), + b"", + bytes(audio), + ] + for key, value in fields.items(): + lines += [ + f"--{boundary}".encode(), + f'Content-Disposition: form-data; name="{key}"'.encode(), + b"", + _form_field_value(value).encode(), + ] + lines += [f"--{boundary}--".encode(), b""] + return b"\r\n".join(lines), f"multipart/form-data; boundary={boundary}" + + +class DeepInfraTextGenerationTask(BaseTextGenerationTask): + def __init__(self): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL) + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + return "/v1/openai/completions" + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + params = filter_none(parameters.copy()) + params["max_tokens"] = params.pop("max_new_tokens", None) + + return {"prompt": inputs, **params, "model": provider_mapping_info.provider_id} + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + output = _as_dict(response)["choices"][0] + return { + "generated_text": output["text"], + "details": { + "finish_reason": output.get("finish_reason"), + "seed": output.get("seed"), + }, + } + + +class DeepInfraConversationalTask(BaseConversationalTask): + def __init__(self): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL) + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + return "/v1/openai/chat/completions" + + +class DeepInfraAutomaticSpeechRecognitionTask(TaskProviderHelper): + def __init__(self): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL, task="automatic-speech-recognition") + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + return "/v1/openai/audio/transcriptions" + + def _prepare_payload_as_bytes( + self, + inputs: Any, + parameters: dict, + provider_mapping_info: InferenceProviderMapping, + extra_payload: dict | None, + ) -> MimeBytes | None: + # OpenAI-compatible transcription endpoint expects a multipart/form-data body, not JSON. + audio = _open_as_mime_bytes(inputs) + # `model` is applied last so parameters cannot override the mapped provider model. + fields: dict[str, Any] = { + **filter_none(parameters), + **filter_none(extra_payload or {}), + "model": provider_mapping_info.provider_id, + } + body, content_type = _encode_multipart(audio, fields) + return MimeBytes(body, mime_type=content_type) + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + output = _as_dict(response) + text = output["text"] + if not isinstance(text, str): + raise ValueError(f"Unexpected output format from DeepInfra API. Expected string, got {type(text)}.") + result: dict[str, Any] = {"text": text} + segments = output.get("segments") + if isinstance(segments, list): + result["chunks"] = [ + {"text": segment.get("text"), "timestamp": [segment.get("start"), segment.get("end")]} + for segment in segments + if isinstance(segment, dict) + ] + return result diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/fal_ai.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/fal_ai.py new file mode 100644 index 0000000000000000000000000000000000000000..41b761d5cebeb319918648c62ac3d82481a621d3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/fal_ai.py @@ -0,0 +1,300 @@ +import base64 +import time +from abc import ABC +from typing import Any +from urllib.parse import urlparse + +from huggingface_hub import constants +from huggingface_hub.hf_api import InferenceProviderMapping +from huggingface_hub.inference._common import RequestParameters, _as_dict, _as_url +from huggingface_hub.inference._providers._common import TaskProviderHelper, filter_none +from huggingface_hub.utils import get_session, hf_raise_for_status +from huggingface_hub.utils.logging import get_logger + + +logger = get_logger(__name__) + +# Arbitrary polling interval +_POLLING_INTERVAL = 0.5 + + +class FalAITask(TaskProviderHelper, ABC): + def __init__(self, task: str): + super().__init__(provider="fal-ai", base_url="https://fal.run", task=task) + + def _prepare_headers(self, headers: dict, api_key: str) -> dict[str, Any]: + headers = super()._prepare_headers(headers, api_key) + if not api_key.startswith("hf_"): + headers["authorization"] = f"Key {api_key}" + return headers + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + return f"/{mapped_model}" + + +class FalAIQueueTask(TaskProviderHelper, ABC): + def __init__(self, task: str): + super().__init__(provider="fal-ai", base_url="https://queue.fal.run", task=task) + + def _prepare_headers(self, headers: dict, api_key: str) -> dict[str, Any]: + headers = super()._prepare_headers(headers, api_key) + if not api_key.startswith("hf_"): + headers["authorization"] = f"Key {api_key}" + return headers + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + if api_key.startswith("hf_"): + # Use the queue subdomain for HF routing + return f"/{mapped_model}?_subdomain=queue" + return f"/{mapped_model}" + + def get_response( + self, + response: bytes | dict, + request_params: RequestParameters | None = None, + ) -> Any: + response_dict = _as_dict(response) + + request_id = response_dict.get("request_id") + if not request_id: + raise ValueError("No request ID found in the response") + if request_params is None: + raise ValueError( + f"A `RequestParameters` object should be provided to get {self.task} responses with Fal AI." + ) + + # extract the base url and query params + parsed_url = urlparse(request_params.url) + # a bit hacky way to concatenate the provider name without parsing `parsed_url.path` + base_url = f"{parsed_url.scheme}://{parsed_url.netloc}{'/fal-ai' if parsed_url.netloc == 'router.huggingface.co' else ''}" + query_param = f"?{parsed_url.query}" if parsed_url.query else "" + + # extracting the provider model id for status and result urls + # from the response as it might be different from the mapped model in `request_params.url` + model_id = urlparse(response_dict.get("response_url")).path + status_url = f"{base_url}{str(model_id)}/status{query_param}" + result_url = f"{base_url}{str(model_id)}{query_param}" + + status = response_dict.get("status") + logger.info("Generating the output.. this can take several minutes.") + while status != "COMPLETED": + time.sleep(_POLLING_INTERVAL) + status_response = get_session().get(status_url, headers=request_params.headers) + hf_raise_for_status(status_response) + status = status_response.json().get("status") + + return get_session().get(result_url, headers=request_params.headers).json() + + +class FalAIAutomaticSpeechRecognitionTask(FalAITask): + def __init__(self): + super().__init__("automatic-speech-recognition") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + if isinstance(inputs, str) and inputs.startswith(("http://", "https://")): + # If input is a URL, pass it directly + audio_url = inputs + else: + # If input is a file path, read it first + if isinstance(inputs, str): + with open(inputs, "rb") as f: + inputs = f.read() + + audio_b64 = base64.b64encode(inputs).decode() + content_type = "audio/mpeg" + audio_url = f"data:{content_type};base64,{audio_b64}" + + return {"audio_url": audio_url, **filter_none(parameters)} + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + text = _as_dict(response)["text"] + if not isinstance(text, str): + raise ValueError(f"Unexpected output format from FalAI API. Expected string, got {type(text)}.") + return {"text": text} + + +class FalAITextToImageTask(FalAITask): + def __init__(self): + super().__init__("text-to-image") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + payload: dict[str, Any] = { + "prompt": inputs, + **filter_none(parameters), + } + if "width" in payload and "height" in payload: + payload["image_size"] = { + "width": payload.pop("width"), + "height": payload.pop("height"), + } + if provider_mapping_info.adapter_weights_path is not None: + lora_path = constants.HUGGINGFACE_CO_URL_TEMPLATE.format( + repo_id=provider_mapping_info.hf_model_id, + revision="main", + filename=provider_mapping_info.adapter_weights_path, + ) + payload["loras"] = [{"path": lora_path, "scale": 1}] + if provider_mapping_info.provider_id == "fal-ai/lora": + # little hack: fal requires the base model for stable-diffusion-based loras but not for flux-based + # See payloads in https://fal.ai/models/fal-ai/lora/api vs https://fal.ai/models/fal-ai/flux-lora/api + payload["model_name"] = "stabilityai/stable-diffusion-xl-base-1.0" + + return payload + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + url = _as_dict(response)["images"][0]["url"] + return get_session().get(url).content + + +class FalAITextToSpeechTask(FalAITask): + def __init__(self): + super().__init__("text-to-speech") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + return {"text": inputs, **filter_none(parameters)} + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + url = _as_dict(response)["audio"]["url"] + return get_session().get(url).content + + +class FalAITextToVideoTask(FalAIQueueTask): + def __init__(self): + super().__init__("text-to-video") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + return {"prompt": inputs, **filter_none(parameters)} + + def get_response( + self, + response: bytes | dict, + request_params: RequestParameters | None = None, + ) -> Any: + output = super().get_response(response, request_params) + url = _as_dict(output)["video"]["url"] + return get_session().get(url).content + + +class FalAIImageToImageTask(FalAIQueueTask): + def __init__(self): + super().__init__("image-to-image") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + image_url = _as_url(inputs, default_mime_type="image/jpeg") + if "target_size" in parameters: + parameters["image_size"] = parameters.pop("target_size") + payload: dict[str, Any] = { + "image_url": image_url, + "image_urls": [image_url], + **filter_none(parameters), + } + if provider_mapping_info.adapter_weights_path is not None: + lora_path = constants.HUGGINGFACE_CO_URL_TEMPLATE.format( + repo_id=provider_mapping_info.hf_model_id, + revision="main", + filename=provider_mapping_info.adapter_weights_path, + ) + payload["loras"] = [{"path": lora_path, "scale": 1}] + + return payload + + def get_response( + self, + response: bytes | dict, + request_params: RequestParameters | None = None, + ) -> Any: + output = super().get_response(response, request_params) + url = _as_dict(output)["images"][0]["url"] + return get_session().get(url).content + + +class FalAIImageToVideoTask(FalAIQueueTask): + def __init__(self): + super().__init__("image-to-video") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + image_url = _as_url(inputs, default_mime_type="image/jpeg") + payload: dict[str, Any] = { + "image_url": image_url, + **filter_none(parameters), + } + if provider_mapping_info.adapter_weights_path is not None: + lora_path = constants.HUGGINGFACE_CO_URL_TEMPLATE.format( + repo_id=provider_mapping_info.hf_model_id, + revision="main", + filename=provider_mapping_info.adapter_weights_path, + ) + payload["loras"] = [{"path": lora_path, "scale": 1}] + return payload + + def get_response( + self, + response: bytes | dict, + request_params: RequestParameters | None = None, + ) -> Any: + output = super().get_response(response, request_params) + url = _as_dict(output)["video"]["url"] + return get_session().get(url).content + + +class FalAIImageSegmentationTask(FalAIQueueTask): + def __init__(self): + super().__init__("image-segmentation") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + image_url = _as_url(inputs, default_mime_type="image/png") + payload: dict[str, Any] = { + "image_url": image_url, + **filter_none(parameters), + "sync_mode": True, + } + return payload + + def get_response( + self, + response: bytes | dict, + request_params: RequestParameters | None = None, + ) -> Any: + result = super().get_response(response, request_params) + result_dict = _as_dict(result) + + if "image" not in result_dict: + raise ValueError(f"Response from fal ai image-segmentation API does not contain an image: {result_dict}") + + image_data = result_dict["image"] + if "url" not in image_data: + raise ValueError(f"Image data from fal ai image-segmentation API does not contain a URL: {image_data}") + + image_url = image_data["url"] + + if isinstance(image_url, str) and image_url.startswith("data:"): + if "," in image_url: + mask_base64 = image_url.split(",", 1)[1] + else: + raise ValueError(f"Invalid data URL format: {image_url}") + else: + # or it's a regular URL, fetch it + mask_response = get_session().get(image_url) + hf_raise_for_status(mask_response) + mask_base64 = base64.b64encode(mask_response.content).decode() + + return [ + { + "label": "mask", + "mask": mask_base64, + } + ] diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/featherless_ai.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/featherless_ai.py new file mode 100644 index 0000000000000000000000000000000000000000..1a90b332a5050340fb4e472040e05beb24e747b6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/featherless_ai.py @@ -0,0 +1,38 @@ +from typing import Any + +from huggingface_hub.hf_api import InferenceProviderMapping +from huggingface_hub.inference._common import RequestParameters, _as_dict + +from ._common import BaseConversationalTask, BaseTextGenerationTask, filter_none + + +_PROVIDER = "featherless-ai" +_BASE_URL = "https://api.featherless.ai" + + +class FeatherlessTextGenerationTask(BaseTextGenerationTask): + def __init__(self): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL) + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + params = filter_none(parameters.copy()) + params["max_tokens"] = params.pop("max_new_tokens", None) + + return {"prompt": inputs, **params, "model": provider_mapping_info.provider_id} + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + output = _as_dict(response)["choices"][0] + return { + "generated_text": output["text"], + "details": { + "finish_reason": output.get("finish_reason"), + "seed": output.get("seed"), + }, + } + + +class FeatherlessConversationalTask(BaseConversationalTask): + def __init__(self): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/fireworks_ai.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/fireworks_ai.py new file mode 100644 index 0000000000000000000000000000000000000000..4ae57662cf888c258c9b310156c8b986b8643923 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/fireworks_ai.py @@ -0,0 +1,27 @@ +from typing import Any + +from huggingface_hub.hf_api import InferenceProviderMapping + +from ._common import BaseConversationalTask + + +class FireworksAIConversationalTask(BaseConversationalTask): + def __init__(self): + super().__init__(provider="fireworks-ai", base_url="https://api.fireworks.ai") + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + return "/inference/v1/chat/completions" + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + payload = super()._prepare_payload_as_dict(inputs, parameters, provider_mapping_info) + response_format = parameters.get("response_format") + if isinstance(response_format, dict) and response_format.get("type") == "json_schema": + json_schema_details = response_format.get("json_schema") + if isinstance(json_schema_details, dict) and "schema" in json_schema_details: + payload["response_format"] = { # type: ignore + "type": "json_object", + "schema": json_schema_details["schema"], + } + return payload diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/groq.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/groq.py new file mode 100644 index 0000000000000000000000000000000000000000..11e677504e89bc02b966e7d37d9e11f1b94b297f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/groq.py @@ -0,0 +1,9 @@ +from ._common import BaseConversationalTask + + +class GroqConversationalTask(BaseConversationalTask): + def __init__(self): + super().__init__(provider="groq", base_url="https://api.groq.com") + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + return "/openai/v1/chat/completions" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/hf_inference.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/hf_inference.py new file mode 100644 index 0000000000000000000000000000000000000000..dce871ca1d643be49ed32caf788eb04571fb9e06 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/hf_inference.py @@ -0,0 +1,228 @@ +import json +from functools import lru_cache +from pathlib import Path +from typing import Any +from urllib.parse import urlparse, urlunparse + +from huggingface_hub import constants +from huggingface_hub.hf_api import InferenceProviderMapping +from huggingface_hub.inference._common import ( + MimeBytes, + RequestParameters, + _b64_encode, + _bytes_to_dict, + _open_as_mime_bytes, +) +from huggingface_hub.inference._providers._common import TaskProviderHelper, filter_none +from huggingface_hub.utils import build_hf_headers, get_session, get_token, hf_raise_for_status + + +class HFInferenceTask(TaskProviderHelper): + """Base class for HF Inference API tasks.""" + + def __init__(self, task: str): + super().__init__( + provider="hf-inference", + base_url=constants.INFERENCE_PROXY_TEMPLATE.format(provider="hf-inference"), + task=task, + ) + + def _prepare_api_key(self, api_key: str | None) -> str: + # special case: for HF Inference we allow not providing an API key + return api_key or get_token() # type: ignore + + def _prepare_mapping_info(self, model: str | None) -> InferenceProviderMapping: + if model is not None and model.startswith(("http://", "https://")): + return InferenceProviderMapping( + provider="hf-inference", providerId=model, hf_model_id=model, task=self.task, status="live" + ) + model_id = model if model is not None else _fetch_recommended_models().get(self.task) + if model_id is None: + raise ValueError( + f"Task {self.task} has no recommended model for HF Inference. Please specify a model" + " explicitly. Visit https://huggingface.co/tasks for more info." + ) + _check_supported_task(model_id, self.task) + return InferenceProviderMapping( + provider="hf-inference", providerId=model_id, hf_model_id=model_id, task=self.task, status="live" + ) + + def _prepare_url(self, api_key: str, mapped_model: str) -> str: + # hf-inference provider can handle URLs (e.g. Inference Endpoints or TGI deployment) + if mapped_model.startswith(("http://", "https://")): + return mapped_model + return ( + # Feature-extraction and sentence-similarity are the only cases where we handle models with several tasks. + f"{self.base_url}/models/{mapped_model}/pipeline/{self.task}" + if self.task in ("feature-extraction", "sentence-similarity") + # Otherwise, we use the default endpoint + else f"{self.base_url}/models/{mapped_model}" + ) + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + if isinstance(inputs, bytes): + raise ValueError(f"Unexpected binary input for task {self.task}.") + if isinstance(inputs, Path): + raise ValueError(f"Unexpected path input for task {self.task} (got {inputs})") + return filter_none({"inputs": inputs, "parameters": parameters}) + + +class HFInferenceBinaryInputTask(HFInferenceTask): + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + return None + + def _prepare_payload_as_bytes( + self, + inputs: Any, + parameters: dict, + provider_mapping_info: InferenceProviderMapping, + extra_payload: dict | None, + ) -> MimeBytes | None: + parameters = filter_none(parameters) + extra_payload = extra_payload or {} + has_parameters = len(parameters) > 0 or len(extra_payload) > 0 + + # Raise if not a binary object or a local path or a URL. + if not isinstance(inputs, (bytes, Path)) and not isinstance(inputs, str): + raise ValueError(f"Expected binary inputs or a local path or a URL. Got {inputs}") + + # Send inputs as raw content when no parameters are provided + if not has_parameters: + return _open_as_mime_bytes(inputs) + + # Otherwise encode as b64 + return MimeBytes( + json.dumps({"inputs": _b64_encode(inputs), "parameters": parameters, **extra_payload}).encode("utf-8"), + mime_type="application/json", + ) + + +class HFInferenceConversational(HFInferenceTask): + def __init__(self): + super().__init__("conversational") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + payload = filter_none(parameters) + mapped_model = provider_mapping_info.provider_id + payload_model = parameters.get("model") or mapped_model + + if payload_model is None or payload_model.startswith(("http://", "https://")): + payload_model = "dummy" + + response_format = parameters.get("response_format") + if isinstance(response_format, dict) and response_format.get("type") == "json_schema": + payload["response_format"] = { + "type": "json_object", + "value": response_format["json_schema"]["schema"], + } + return {**payload, "model": payload_model, "messages": inputs} + + def _prepare_url(self, api_key: str, mapped_model: str) -> str: + base_url = ( + mapped_model + if mapped_model.startswith(("http://", "https://")) + else f"{constants.INFERENCE_PROXY_TEMPLATE.format(provider='hf-inference')}/models/{mapped_model}" + ) + return _build_chat_completion_url(base_url) + + +def _build_chat_completion_url(model_url: str) -> str: + parsed = urlparse(model_url) + path = parsed.path.rstrip("/") + + # If the path already ends with /chat/completions, we're done! + if path.endswith("/chat/completions"): + return model_url + + # Append /chat/completions if not already present + if path.endswith("/v1"): + new_path = path + "/chat/completions" + # If path was empty or just "/", set the full path + elif not path: + new_path = "/v1/chat/completions" + # Append /v1/chat/completions if not already present + else: + new_path = path + "/v1/chat/completions" + + # Reconstruct the URL with the new path and original query parameters. + new_parsed = parsed._replace(path=new_path) + return str(urlunparse(new_parsed)) + + +@lru_cache(maxsize=1) +def _fetch_recommended_models() -> dict[str, str | None]: + response = get_session().get(f"{constants.ENDPOINT}/api/tasks", headers=build_hf_headers()) + hf_raise_for_status(response) + return {task: next(iter(details["widgetModels"]), None) for task, details in response.json().items()} + + +@lru_cache(maxsize=None) +def _check_supported_task(model: str, task: str) -> None: + from huggingface_hub.hf_api import HfApi + + model_info = HfApi().model_info(model) + pipeline_tag = model_info.pipeline_tag + tags = model_info.tags or [] + is_conversational = "conversational" in tags + if task in ("text-generation", "conversational"): + if pipeline_tag == "text-generation": + # text-generation + conversational tag -> both tasks allowed + if is_conversational: + return + # text-generation without conversational tag -> only text-generation allowed + if task == "text-generation": + return + raise ValueError(f"Model '{model}' doesn't support task '{task}'.") + + if pipeline_tag == "text2text-generation": + if task == "text-generation": + return + raise ValueError(f"Model '{model}' doesn't support task '{task}'.") + + if pipeline_tag == "image-text-to-text": + if is_conversational and task == "conversational": + return # Only conversational allowed if tagged as conversational + raise ValueError("Non-conversational image-text-to-text task is not supported.") + + if ( + task in ("feature-extraction", "sentence-similarity") + and pipeline_tag in ("feature-extraction", "sentence-similarity") + and task in tags + ): + # feature-extraction and sentence-similarity are interchangeable for HF Inference + return + + # For all other tasks, just check pipeline tag + if pipeline_tag != task: + raise ValueError( + f"Model '{model}' doesn't support task '{task}'. Supported tasks: '{pipeline_tag}', got: '{task}'" + ) + return + + +class HFInferenceFeatureExtractionTask(HFInferenceTask): + def __init__(self): + super().__init__("feature-extraction") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + if isinstance(inputs, bytes): + raise ValueError(f"Unexpected binary input for task {self.task}.") + if isinstance(inputs, Path): + raise ValueError(f"Unexpected path input for task {self.task} (got {inputs})") + + # Parameters are sent at root-level for feature-extraction task + # See specs: https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/src/tasks/feature-extraction/spec/input.json + return {"inputs": inputs, **filter_none(parameters)} + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + if isinstance(response, bytes): + return _bytes_to_dict(response) + return response diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/novita.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/novita.py new file mode 100644 index 0000000000000000000000000000000000000000..af29e72032a7eb82f1ec20bc3df529612ab8730c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/novita.py @@ -0,0 +1,69 @@ +from typing import Any + +from huggingface_hub.hf_api import InferenceProviderMapping +from huggingface_hub.inference._common import RequestParameters, _as_dict +from huggingface_hub.inference._providers._common import ( + BaseConversationalTask, + BaseTextGenerationTask, + TaskProviderHelper, + filter_none, +) +from huggingface_hub.utils import get_session + + +_PROVIDER = "novita" +_BASE_URL = "https://api.novita.ai" + + +class NovitaTextGenerationTask(BaseTextGenerationTask): + def __init__(self): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL) + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + # there is no v1/ route for novita + return "/v3/openai/completions" + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + output = _as_dict(response)["choices"][0] + return { + "generated_text": output["text"], + "details": { + "finish_reason": output.get("finish_reason"), + "seed": output.get("seed"), + }, + } + + +class NovitaConversationalTask(BaseConversationalTask): + def __init__(self): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL) + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + # there is no v1/ route for novita + return "/v3/openai/chat/completions" + + +class NovitaTextToVideoTask(TaskProviderHelper): + def __init__(self): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL, task="text-to-video") + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + return f"/v3/hf/{mapped_model}" + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + return {"prompt": inputs, **filter_none(parameters)} + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + response_dict = _as_dict(response) + if not ( + isinstance(response_dict, dict) + and "video" in response_dict + and isinstance(response_dict["video"], dict) + and "video_url" in response_dict["video"] + ): + raise ValueError("Expected response format: { 'video': { 'video_url': string } }") + + video_url = response_dict["video"]["video_url"] + return get_session().get(video_url).content diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/nscale.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/nscale.py new file mode 100644 index 0000000000000000000000000000000000000000..6a5a4c38e9f0f8ede459d36c584813cf5ef7dbac --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/nscale.py @@ -0,0 +1,44 @@ +import base64 +from typing import Any + +from huggingface_hub.hf_api import InferenceProviderMapping +from huggingface_hub.inference._common import RequestParameters, _as_dict + +from ._common import BaseConversationalTask, TaskProviderHelper, filter_none + + +class NscaleConversationalTask(BaseConversationalTask): + def __init__(self): + super().__init__(provider="nscale", base_url="https://inference.api.nscale.com") + + +class NscaleTextToImageTask(TaskProviderHelper): + def __init__(self): + super().__init__(provider="nscale", base_url="https://inference.api.nscale.com", task="text-to-image") + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + return "/v1/images/generations" + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + mapped_model = provider_mapping_info.provider_id + # Combine all parameters except inputs and parameters + parameters = filter_none(parameters) + if "width" in parameters and "height" in parameters: + parameters["size"] = f"{parameters.pop('width')}x{parameters.pop('height')}" + if "num_inference_steps" in parameters: + parameters.pop("num_inference_steps") + if "cfg_scale" in parameters: + parameters.pop("cfg_scale") + payload = { + "response_format": "b64_json", + "prompt": inputs, + "model": mapped_model, + **parameters, + } + return payload + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + response_dict = _as_dict(response) + return base64.b64decode(response_dict["data"][0]["b64_json"]) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/openai.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/openai.py new file mode 100644 index 0000000000000000000000000000000000000000..9f0f56002a6493c852836a1e5539900204fc0bb3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/openai.py @@ -0,0 +1,23 @@ +from huggingface_hub.hf_api import InferenceProviderMapping +from huggingface_hub.inference._providers._common import BaseConversationalTask + + +class OpenAIConversationalTask(BaseConversationalTask): + def __init__(self): + super().__init__(provider="openai", base_url="https://api.openai.com") + + def _prepare_api_key(self, api_key: str | None) -> str: + if api_key is None: + raise ValueError("You must provide an api_key to work with OpenAI API.") + if api_key.startswith("hf_"): + raise ValueError( + "OpenAI provider is not available through Hugging Face routing, please use your own OpenAI API key." + ) + return api_key + + def _prepare_mapping_info(self, model: str | None) -> InferenceProviderMapping: + if model is None: + raise ValueError("Please provide an OpenAI model ID, e.g. `gpt-4o` or `o1`.") + return InferenceProviderMapping( + provider="openai", providerId=model, task="conversational", status="live", hf_model_id=model + ) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/ovhcloud.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/ovhcloud.py new file mode 100644 index 0000000000000000000000000000000000000000..79be8d55089975b1ad9a0282d503cd2fc012127c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/ovhcloud.py @@ -0,0 +1,10 @@ +from huggingface_hub.inference._providers._common import BaseConversationalTask + + +_PROVIDER = "ovhcloud" +_BASE_URL = "https://oai.endpoints.kepler.ai.cloud.ovh.net" + + +class OVHcloudConversationalTask(BaseConversationalTask): + def __init__(self): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/publicai.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/publicai.py new file mode 100644 index 0000000000000000000000000000000000000000..4c88528e4f1e2eefaf6be9315c490db19ff5ca1e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/publicai.py @@ -0,0 +1,6 @@ +from ._common import BaseConversationalTask + + +class PublicAIConversationalTask(BaseConversationalTask): + def __init__(self): + super().__init__(provider="publicai", base_url="https://api.publicai.co") diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/replicate.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/replicate.py new file mode 100644 index 0000000000000000000000000000000000000000..d1aff75ec56460791b35b3acde7208d8c4a03bdb --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/replicate.py @@ -0,0 +1,160 @@ +from typing import Any + +from huggingface_hub.hf_api import InferenceProviderMapping +from huggingface_hub.inference._common import RequestParameters, _as_dict, _as_url +from huggingface_hub.inference._providers._common import TaskProviderHelper, filter_none +from huggingface_hub.utils import get_session + + +_PROVIDER = "replicate" +_BASE_URL = "https://api.replicate.com" + + +class ReplicateTask(TaskProviderHelper): + def __init__(self, task: str): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL, task=task) + + def _prepare_headers(self, headers: dict, api_key: str) -> dict[str, Any]: + headers = super()._prepare_headers(headers, api_key) + headers["Prefer"] = "wait" + return headers + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + if ":" in mapped_model: + return "/v1/predictions" + return f"/v1/models/{mapped_model}/predictions" + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + mapped_model = provider_mapping_info.provider_id + payload: dict[str, Any] = {"input": {"prompt": inputs, **filter_none(parameters)}} + if ":" in mapped_model: + version = mapped_model.split(":", 1)[1] + payload["version"] = version + return payload + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + response_dict = _as_dict(response) + if response_dict.get("output") is None: + raise TimeoutError( + f"Inference request timed out after 60 seconds. No output generated for model {response_dict.get('model')}" + "The model might be in cold state or starting up. Please try again later." + ) + output_url = ( + response_dict["output"] if isinstance(response_dict["output"], str) else response_dict["output"][0] + ) + return get_session().get(output_url).content + + +class ReplicateTextToImageTask(ReplicateTask): + def __init__(self): + super().__init__("text-to-image") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + payload: dict = super()._prepare_payload_as_dict(inputs, parameters, provider_mapping_info) # type: ignore + if provider_mapping_info.adapter_weights_path is not None: + payload["input"]["lora_weights"] = f"https://huggingface.co/{provider_mapping_info.hf_model_id}" + return payload + + +class ReplicateTextToSpeechTask(ReplicateTask): + def __init__(self): + super().__init__("text-to-speech") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + payload: dict = super()._prepare_payload_as_dict(inputs, parameters, provider_mapping_info) # type: ignore + payload["input"]["text"] = payload["input"].pop("prompt") # rename "prompt" to "text" for TTS + return payload + + +class ReplicateAutomaticSpeechRecognitionTask(ReplicateTask): + def __init__(self) -> None: + super().__init__("automatic-speech-recognition") + + def _prepare_payload_as_dict( + self, + inputs: Any, + parameters: dict, + provider_mapping_info: InferenceProviderMapping, + ) -> dict | None: + mapped_model = provider_mapping_info.provider_id + audio_url = _as_url(inputs, default_mime_type="audio/wav") + + payload: dict[str, Any] = { + "input": { + **{"audio": audio_url}, + **filter_none(parameters), + } + } + + if ":" in mapped_model: + payload["version"] = mapped_model.split(":", 1)[1] + + return payload + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + response_dict = _as_dict(response) + output = response_dict.get("output") + + if isinstance(output, str): + return {"text": output} + + if isinstance(output, list) and output: + first_item = output[0] + if isinstance(first_item, str): + return {"text": first_item} + if isinstance(first_item, dict): + output = first_item + + text: str | None = None + if isinstance(output, dict): + transcription = output.get("transcription") + if isinstance(transcription, str): + text = transcription + + translation = output.get("translation") + if isinstance(translation, str): + text = translation + + txt_file = output.get("txt_file") + if isinstance(txt_file, str): + text_response = get_session().get(txt_file) + text_response.raise_for_status() + text = text_response.text + + if text is not None: + return {"text": text} + + raise ValueError("Received malformed response from Replicate automatic-speech-recognition API") + + +class ReplicateImageToImageTask(ReplicateTask): + def __init__(self): + super().__init__("image-to-image") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + image_url = _as_url(inputs, default_mime_type="image/jpeg") + + # Different Replicate models expect the image in different keys + payload: dict[str, Any] = { + "input": { + "image": image_url, + "images": [image_url], + "input_image": image_url, + "input_images": [image_url], + **filter_none(parameters), + } + } + + mapped_model = provider_mapping_info.provider_id + if ":" in mapped_model: + version = mapped_model.split(":", 1)[1] + payload["version"] = version + return payload diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/scaleway.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/scaleway.py new file mode 100644 index 0000000000000000000000000000000000000000..a64462075a091f4a9d9a664e09be229e0fb7bdf1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/scaleway.py @@ -0,0 +1,28 @@ +from typing import Any + +from huggingface_hub.inference._common import RequestParameters, _as_dict + +from ._common import BaseConversationalTask, InferenceProviderMapping, TaskProviderHelper, filter_none + + +class ScalewayConversationalTask(BaseConversationalTask): + def __init__(self): + super().__init__(provider="scaleway", base_url="https://api.scaleway.ai") + + +class ScalewayFeatureExtractionTask(TaskProviderHelper): + def __init__(self): + super().__init__(provider="scaleway", base_url="https://api.scaleway.ai", task="feature-extraction") + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + return "/v1/embeddings" + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + parameters = filter_none(parameters) + return {"input": inputs, "model": provider_mapping_info.provider_id, **parameters} + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + embeddings = _as_dict(response)["data"] + return [embedding["embedding"] for embedding in embeddings] diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/together.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/together.py new file mode 100644 index 0000000000000000000000000000000000000000..1f26595af3f919f675f14b5c4d10baa130e647d8 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/together.py @@ -0,0 +1,291 @@ +import base64 +import time +from abc import ABC +from typing import Any + +from huggingface_hub.hf_api import InferenceProviderMapping +from huggingface_hub.inference._common import ( + RequestParameters, + _as_dict, + _as_url, +) +from huggingface_hub.inference._providers._common import ( + BaseConversationalTask, + BaseTextGenerationTask, + TaskProviderHelper, + filter_none, +) +from huggingface_hub.utils import get_session, hf_raise_for_status, logging + + +logger = logging.get_logger(__name__) + +_PROVIDER = "together" +_BASE_URL = "https://api.together.xyz" + +# Polling interval for async video generation (in seconds). +_VIDEO_POLLING_INTERVAL = 2.0 + +# Upper bound on status polls (initial response may already be terminal; each further poll is one attempt). +_VIDEO_MAX_POLL_ATTEMPTS = 150 # ~5 minutes at _VIDEO_POLLING_INTERVAL + +# Job statuses that mean "keep polling". Together returns "queued" before transitioning to +# "in_progress", so we must treat both as pending. +_VIDEO_PENDING_STATUSES = {"queued", "in_progress"} + + +class TogetherTask(TaskProviderHelper, ABC): + """Base class for Together API tasks.""" + + def __init__(self, task: str): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL, task=task) + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + match self.task: + case "text-to-image" | "image-to-image": + return "/v1/images/generations" + case "text-to-speech": + return "/v1/audio/speech" + case "feature-extraction": + return "/v1/embeddings" + case "text-to-video" | "image-to-video": + # Video creation lives under /v2 (see https://docs.together.ai/reference/create-videos). + return "/v2/videos" + raise ValueError(f"Unsupported task '{self.task}' for Together API.") + + +class TogetherTextGenerationTask(BaseTextGenerationTask): + def __init__(self): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL) + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + output = _as_dict(response)["choices"][0] + return { + "generated_text": output["text"], + "details": { + "finish_reason": output.get("finish_reason"), + "seed": output.get("seed"), + }, + } + + +class TogetherConversationalTask(BaseConversationalTask): + def __init__(self): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL) + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + payload = super()._prepare_payload_as_dict(inputs, parameters, provider_mapping_info) + if payload is None: + return None + # Together accepts response_format `{type: "json_schema", schema: }` (flattened), + # so unwrap the OpenAI-style `{type: "json_schema", json_schema: {schema}}` envelope. + response_format = payload.get("response_format") + if ( + isinstance(response_format, dict) + and response_format.get("type") == "json_schema" + and isinstance(response_format.get("json_schema"), dict) + and "schema" in response_format["json_schema"] + ): + payload["response_format"] = { + "type": "json_schema", + "schema": response_format["json_schema"]["schema"], + } + return payload + + +class TogetherTextToImageTask(TogetherTask): + def __init__(self): + super().__init__("text-to-image") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + mapped_model = provider_mapping_info.provider_id + parameters = filter_none(parameters) + if "num_inference_steps" in parameters: + parameters["steps"] = parameters.pop("num_inference_steps") + + return {"prompt": inputs, "response_format": "base64", **parameters, "model": mapped_model} + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + response_dict = _as_dict(response) + return base64.b64decode(response_dict["data"][0]["b64_json"]) + + +class TogetherImageToImageTask(TogetherTask): + def __init__(self): + super().__init__("image-to-image") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + mapped_model = provider_mapping_info.provider_id + image_url = _as_url(inputs, default_mime_type="image/jpeg") + + # Filter `None` values first: the client always passes `"prompt": None` when the user + # omits the argument, so popping before filtering would yield `None` instead of the + # `""` default and send `"prompt": null` to Together (rejected by Flux Kontext). + parameters = filter_none(parameters) + prompt = parameters.pop("prompt", "") + if "num_inference_steps" in parameters: + parameters["steps"] = parameters.pop("num_inference_steps") + + # Together exposes two mutually-exclusive image inputs (see + # https://docs.together.ai/docs/image-to-image): FLUX.1 Kontext only accepts + # `image_url`; FLUX.2 [dev] and Google models (Gemini 3 Pro Image, Flash Image + # 2.5) only accept `reference_images`. FLUX.2 [pro]/[flex] accept either but + # `reference_images` is the documented default. Use `image_url` only for + # FLUX.1 Kontext models and `reference_images` for everything else. + lowered = mapped_model.lower() + use_image_url = "kontext" in lowered and "flux.1" in lowered + image_field: dict[str, Any] = {"image_url": image_url} if use_image_url else {"reference_images": [image_url]} + return { + "prompt": prompt, + **image_field, + "response_format": "base64", + **parameters, + "model": mapped_model, + } + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + response_dict = _as_dict(response) + return base64.b64decode(response_dict["data"][0]["b64_json"]) + + +class TogetherFeatureExtractionTask(TogetherTask): + def __init__(self): + super().__init__("feature-extraction") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + return { + "input": inputs, + "model": provider_mapping_info.provider_id, + **filter_none(parameters), + } + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + return [item["embedding"] for item in _as_dict(response)["data"]] + + +class TogetherTextToSpeechTask(TogetherTask): + def __init__(self): + super().__init__("text-to-speech") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + # `voice` is required by the Together API and is model-specific + # (see https://docs.together.ai/docs/text-to-speech#supported-voices), + # so we don't set a default and let the API surface a clear error if missing. + return { + "input": inputs, + "model": provider_mapping_info.provider_id, + **filter_none(parameters), + } + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + if isinstance(response, bytes): + return response + raise ValueError(f"Expected raw audio bytes for text-to-speech, got {type(response).__name__}.") + + +def _normalize_video_parameters(parameters: dict) -> dict: + """Map HF inference-client conventions onto Together's video API parameter names.""" + parameters = filter_none(parameters) + if "num_inference_steps" in parameters: + parameters["steps"] = parameters.pop("num_inference_steps") + if "target_size" in parameters: + target_size = parameters.pop("target_size") + if "width" in target_size: + parameters["width"] = target_size["width"] + if "height" in target_size: + parameters["height"] = target_size["height"] + return parameters + + +class TogetherVideoTask(TogetherTask, ABC): + """Base class for Together's asynchronous video generation tasks.""" + + def get_response(self, response: bytes | dict, request_params: RequestParameters | None = None) -> Any: + if request_params is None: + raise ValueError("A `RequestParameters` object is required to poll Together video jobs.") + + job = _as_dict(response) + job_id = job.get("id") + if not job_id: + raise ValueError("No job ID found in Together video generation response.") + + # Status polling lives at the same /v2/videos URL with the job ID appended. + status_url = f"{request_params.url}/{job_id}" + + logger.info("Generating video, polling for completion...") + # Together usually returns `status: "queued"` on the initial POST, but the field is + # optional per the spec — treat a missing status as "still pending" and poll, rather + # than falling through to the "unexpected status" error below. + status = job.get("status") + for _ in range(_VIDEO_MAX_POLL_ATTEMPTS): + if status is not None and status not in _VIDEO_PENDING_STATUSES: + break + time.sleep(_VIDEO_POLLING_INTERVAL) + status_response = get_session().get(status_url, headers=request_params.headers) + hf_raise_for_status(status_response) + job = status_response.json() + status = job.get("status") + if status is not None and status not in _VIDEO_PENDING_STATUSES: + break + else: + raise ValueError( + "Timed out while waiting for Together video generation " + f"— aborting after {_VIDEO_MAX_POLL_ATTEMPTS} status polls" + ) + + if status == "failed": + error = job.get("error") or {} + raise RuntimeError(f"Together video generation failed: {error.get('message') or 'Unknown error'}") + if status != "completed": + raise RuntimeError(f"Unexpected Together video job status: {status!r}") + + video_url = (job.get("outputs") or {}).get("video_url") + if not video_url: + raise ValueError("No video URL found in completed Together video job.") + + video_response = get_session().get(video_url) + hf_raise_for_status(video_response) + return video_response.content + + +class TogetherTextToVideoTask(TogetherVideoTask): + def __init__(self): + super().__init__("text-to-video") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + return { + "prompt": inputs, + "model": provider_mapping_info.provider_id, + **_normalize_video_parameters(parameters), + } + + +class TogetherImageToVideoTask(TogetherVideoTask): + def __init__(self): + super().__init__("image-to-video") + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + # Together expects each keyframe as `{input_image, frame: "first" | "last"}` + # for i2v models. See https://docs.together.ai/docs/inference/videos/reference-and-keyframes. + # Note: `input_image` accepts a data URL or an HTTP(S) URL but the field is capped + # at ~60KB — users with larger inputs should host the image and pass `frame_images` + # directly via `extra_body`. + return { + "model": provider_mapping_info.provider_id, + "frame_images": [{"input_image": _as_url(inputs, default_mime_type="image/png"), "frame": "first"}], + **_normalize_video_parameters(parameters), + } diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/wavespeed.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/wavespeed.py new file mode 100644 index 0000000000000000000000000000000000000000..aa38eb9da2d47c491e746af6495f669147fe181e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/wavespeed.py @@ -0,0 +1,138 @@ +import base64 +import time +from abc import ABC +from typing import Any +from urllib.parse import urlparse + +from huggingface_hub.hf_api import InferenceProviderMapping +from huggingface_hub.inference._common import RequestParameters, _as_dict +from huggingface_hub.inference._providers._common import TaskProviderHelper, filter_none +from huggingface_hub.utils import get_session, hf_raise_for_status +from huggingface_hub.utils.logging import get_logger + + +logger = get_logger(__name__) + +# Polling interval (in seconds) +_POLLING_INTERVAL = 0.5 + + +class WavespeedAITask(TaskProviderHelper, ABC): + def __init__(self, task: str): + super().__init__(provider="wavespeed", base_url="https://api.wavespeed.ai", task=task) + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + return f"/api/v3/{mapped_model}" + + def get_response( + self, + response: bytes | dict, + request_params: RequestParameters | None = None, + ) -> Any: + response_dict = _as_dict(response) + data = response_dict.get("data", {}) + result_path = data.get("urls", {}).get("get") + + if not result_path: + raise ValueError("No result URL found in the response") + if request_params is None: + raise ValueError("A `RequestParameters` object should be provided to get responses with WaveSpeed AI.") + + # Parse the request URL to determine base URL + parsed_url = urlparse(request_params.url) + # Add /wavespeed to base URL if going through HF router + if parsed_url.netloc == "router.huggingface.co": + base_url = f"{parsed_url.scheme}://{parsed_url.netloc}/wavespeed" + else: + base_url = f"{parsed_url.scheme}://{parsed_url.netloc}" + + # Extract path from result_path URL + if isinstance(result_path, str): + result_url_path = urlparse(result_path).path + else: + result_url_path = result_path + + result_url = f"{base_url}{result_url_path}" + + logger.info("Processing request, polling for results...") + + # Poll until task is completed + while True: + time.sleep(_POLLING_INTERVAL) + result_response = get_session().get(result_url, headers=request_params.headers) + hf_raise_for_status(result_response) + + result = result_response.json() + task_result = result.get("data", {}) + status = task_result.get("status") + + if status == "completed": + # Get content from the first output URL + if not task_result.get("outputs") or len(task_result["outputs"]) == 0: + raise ValueError("No output URL in completed response") + + output_url = task_result["outputs"][0] + return get_session().get(output_url).content + elif status == "failed": + error_msg = task_result.get("error", "Task failed with no specific error message") + raise ValueError(f"WaveSpeed AI task failed: {error_msg}") + elif status in ["processing", "created"]: + continue + else: + raise ValueError(f"Unknown status: {status}") + + +class WavespeedAITextToImageTask(WavespeedAITask): + def __init__(self): + super().__init__("text-to-image") + + def _prepare_payload_as_dict( + self, + inputs: Any, + parameters: dict, + provider_mapping_info: InferenceProviderMapping, + ) -> dict | None: + return {"prompt": inputs, **filter_none(parameters)} + + +class WavespeedAITextToVideoTask(WavespeedAITextToImageTask): + def __init__(self): + WavespeedAITask.__init__(self, "text-to-video") + + +class WavespeedAIImageToImageTask(WavespeedAITask): + def __init__(self): + super().__init__("image-to-image") + + def _prepare_payload_as_dict( + self, + inputs: Any, + parameters: dict, + provider_mapping_info: InferenceProviderMapping, + ) -> dict | None: + # Convert inputs to image (URL or base64) + if isinstance(inputs, str) and inputs.startswith(("http://", "https://")): + image = inputs + elif isinstance(inputs, str): + # If input is a file path, read it first + with open(inputs, "rb") as f: + file_content = f.read() + image_b64 = base64.b64encode(file_content).decode("utf-8") + image = f"data:image/jpeg;base64,{image_b64}" + else: + # If input is binary data + image_b64 = base64.b64encode(inputs).decode("utf-8") + image = f"data:image/jpeg;base64,{image_b64}" + + # Extract prompt from parameters if present + prompt = parameters.pop("prompt", None) + payload = {"image": image, **filter_none(parameters)} + if prompt is not None: + payload["prompt"] = prompt + + return payload + + +class WavespeedAIImageToVideoTask(WavespeedAIImageToImageTask): + def __init__(self): + WavespeedAITask.__init__(self, "image-to-video") diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/zai_org.py b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/zai_org.py new file mode 100644 index 0000000000000000000000000000000000000000..97225435084ab61860ef838747b5e0e7517f7bd1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/inference/_providers/zai_org.py @@ -0,0 +1,127 @@ +import time +from abc import ABC +from typing import Any + +from huggingface_hub.hf_api import InferenceProviderMapping +from huggingface_hub.inference._common import RequestParameters, _as_dict +from huggingface_hub.inference._providers._common import BaseConversationalTask, TaskProviderHelper, filter_none +from huggingface_hub.utils import get_session + + +_PROVIDER = "zai-org" +_BASE_URL = "https://api.z.ai" +_POLLING_INTERVAL = 5 # seconds +_MAX_POLL_ATTEMPTS = 60 + + +class ZaiTask(TaskProviderHelper, ABC): + def __init__(self, task: str): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL, task=task) + + def _prepare_headers(self, headers: dict, api_key: str) -> dict[str, Any]: + headers = super()._prepare_headers(headers, api_key) + headers["Accept-Language"] = "en-US,en" + headers["x-source-channel"] = "hugging_face" + return headers + + +class ZaiConversationalTask(BaseConversationalTask): + def __init__(self): + super().__init__(provider=_PROVIDER, base_url=_BASE_URL) + + def _prepare_headers(self, headers: dict, api_key: str) -> dict[str, Any]: + headers = super()._prepare_headers(headers, api_key) + headers["Accept-Language"] = "en-US,en" + headers["x-source-channel"] = "hugging_face" + return headers + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + return "/api/paas/v4/chat/completions" + + +class ZaiTextToImageTask(ZaiTask): + """Text-to-image task for ZAI provider using async API.""" + + def __init__(self): + super().__init__("text-to-image") + + def _prepare_route(self, mapped_model: str, api_key: str) -> str: + return "/api/paas/v4/async/images/generations" + + def _prepare_payload_as_dict( + self, inputs: Any, parameters: dict, provider_mapping_info: InferenceProviderMapping + ) -> dict | None: + width = parameters.pop("width", None) + height = parameters.pop("height", None) + size = None + if width is not None and height is not None: + size = f"{width}x{height}" + + payload: dict[str, Any] = { + "model": provider_mapping_info.provider_id, + "prompt": inputs, + } + if size is not None: + payload["size"] = size + + payload.update(filter_none(parameters)) + return payload + + def get_response( + self, + response: bytes | dict, + request_params: RequestParameters | None = None, + ) -> Any: + """Handle async response by polling for results.""" + response_dict = _as_dict(response) + + task_id = response_dict.get("id") + if task_id is None: + raise ValueError("No task_id in response from ZAI API") + + task_status = response_dict.get("task_status") + if task_status == "FAIL": + raise ValueError(f"ZAI image generation failed for request {task_id}") + + if task_status == "PROCESSING" and request_params is not None: + return self._poll_for_result(task_id, request_params) + + return self._extract_image(response_dict) + + def _poll_for_result(self, task_id: str, request_params: RequestParameters) -> bytes: + """Poll the async-result endpoint until completion.""" + session = get_session() + base_url = request_params.url.rsplit("/api/paas/v4/async/images/generations", 1)[0] + poll_url = f"{base_url}/api/paas/v4/async-result/{task_id}" + + for _ in range(_MAX_POLL_ATTEMPTS): + poll_response = session.get(poll_url, headers=request_params.headers) + poll_response.raise_for_status() + result = poll_response.json() + + task_status = result.get("task_status") + if task_status == "SUCCESS": + return self._extract_image(result) + elif task_status == "FAIL": + raise ValueError(f"Zai text-to-image generation failed for request {task_id}") + + time.sleep(_POLLING_INTERVAL) + + raise ValueError( + f"Timed out while waiting for the result from Zai API - aborting after {_MAX_POLL_ATTEMPTS} attempts" + ) + + def _extract_image(self, result: dict) -> bytes: + """Extract and download the image from the result.""" + image_result = result.get("image_result") + if not image_result or not isinstance(image_result, list) or len(image_result) == 0: + raise ValueError("No image_result in response from ZAI API") + + image_url = image_result[0].get("url") + if not image_url: + raise ValueError("No image URL in response from ZAI API") + + session = get_session() + image_response = session.get(image_url) + image_response.raise_for_status() + return image_response.content diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/lfs.py b/.venv/lib/python3.13/site-packages/huggingface_hub/lfs.py new file mode 100644 index 0000000000000000000000000000000000000000..9958a1c332f0ab938cb9769a6384e178fb5e7a96 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/lfs.py @@ -0,0 +1,442 @@ +# Copyright 2019-present, the HuggingFace Inc. team. +# +# 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. +"""Git LFS related type definitions and utilities""" + +import io +import re +from collections.abc import Iterable +from math import ceil +from os.path import getsize +from typing import TYPE_CHECKING, BinaryIO, TypedDict +from urllib.parse import unquote + +from huggingface_hub import constants + +from .utils import ( + build_hf_headers, + fix_hf_endpoint_in_url, + hf_raise_for_status, + http_backoff, + logging, + validate_hf_hub_args, +) +from .utils._lfs import SliceFileObj +from .utils.sha import sha256, sha_fileobj + + +if TYPE_CHECKING: + from ._commit_api import CommitOperationAdd + +logger = logging.get_logger(__name__) + +OID_REGEX = re.compile(r"^[0-9a-f]{40}$") + +LFS_MULTIPART_UPLOAD_COMMAND = "lfs-multipart-upload" + +LFS_HEADERS = { + "Accept": "application/vnd.git-lfs+json", + "Content-Type": "application/vnd.git-lfs+json", +} + + +class UploadInfo: + """ + Data structure holding required information to determine whether a blob + should be uploaded to the hub using the LFS protocol or the regular protocol. + + The SHA256 of the blob is computed lazily: creating an `UploadInfo` from a local path only reads + the first 512 bytes of the file. The full file is read (and hashed) only if `sha256` is accessed + before it has been set. When a file is uploaded through the Xet protocol, the SHA256 is computed + during upload (single read pass) and set afterwards. + + Args: + size (`int`): + Size in bytes of the blob + sample (`bytes`): + First 512 bytes of the blob + sha256 (`bytes`, *optional*): + SHA256 hash of the blob, if already known. Otherwise computed lazily from `source_path`. + source_path (`str`, *optional*): + Path to the local file the blob comes from. Required to lazily compute `sha256` if not provided. + """ + + def __init__( + self, + size: int, + sample: bytes, + sha256: bytes | None = None, + source_path: str | None = None, + ): + if sha256 is None and source_path is None: + raise ValueError("Either `sha256` or `source_path` must be provided.") + self.size = size + self.sample = sample + self._sha256 = sha256 + self._source_path = source_path + + @property + def sha256(self) -> bytes: + """SHA256 of the blob. If not set yet, reads the whole file from `source_path` to compute it.""" + if self._sha256 is None: + assert self._source_path is not None # guaranteed by __init__ + with open(self._source_path, "rb") as file: + self._sha256 = sha_fileobj(file) + return self._sha256 + + @sha256.setter + def sha256(self, value: bytes) -> None: + self._sha256 = value + + @property + def is_hashed(self) -> bool: + """Whether the SHA256 is already known (accessing `sha256` will not trigger a file read).""" + return self._sha256 is not None + + def __repr__(self) -> str: + sha = self._sha256.hex() if self._sha256 is not None else "" + return f"UploadInfo(size={self.size}, sha256={sha})" + + @classmethod + def from_path(cls, path: str): + size = getsize(path) + with open(path, "rb") as file: + sample = file.peek(512)[:512] + return cls(size=size, sample=sample, source_path=path) + + @classmethod + def from_bytes(cls, data: bytes): + sha = sha256(data).digest() + return cls(size=len(data), sample=data[:512], sha256=sha) + + @classmethod + def from_fileobj(cls, fileobj: BinaryIO): + sample = fileobj.read(512) + fileobj.seek(0, io.SEEK_SET) + sha = sha_fileobj(fileobj) + size = fileobj.tell() + fileobj.seek(0, io.SEEK_SET) + return cls(size=size, sha256=sha, sample=sample) + + +@validate_hf_hub_args +def post_lfs_batch_info( + upload_infos: Iterable[UploadInfo], + token: str | None, + repo_type: str, + repo_id: str, + revision: str | None = None, + endpoint: str | None = None, + headers: dict[str, str] | None = None, + transfers: list[str] | None = None, +) -> tuple[list[dict], list[dict], str | None]: + """ + Requests the LFS batch endpoint to retrieve upload instructions + + Learn more: https://github.com/git-lfs/git-lfs/blob/main/docs/api/batch.md + + Args: + upload_infos (`Iterable` of `UploadInfo`): + `UploadInfo` for the files that are being uploaded, typically obtained + from `CommitOperationAdd.upload_info` + token (`str` or `None`): + An authentication token (see https://huggingface.co/settings/token). + Pass `None` to fall back to the local cached token (or no token if unauthenticated). + repo_type (`str`): + Type of the repo to upload to: `"model"`, `"dataset"` or `"space"`. + repo_id (`str`): + A namespace (user or an organization) and a repo name separated + by a `/`. + revision (`str`, *optional*): + The git revision to upload to. + endpoint (`str`, *optional*): + The Hub endpoint to send the request to. Defaults to the value of `HF_ENDPOINT`. + headers (`dict`, *optional*): + Additional headers to include in the request + transfers (`list`, *optional*): + List of transfer methods to use. Defaults to ["basic", "multipart"]. + + Returns: + `LfsBatchInfo`: 3-tuple: + - First element is the list of upload instructions from the server + - Second element is a list of errors, if any + - Third element is the chosen transfer adapter if provided by the server (e.g. "basic", "multipart", "xet") + + Raises: + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If an argument is invalid or the server response is malformed. + [`HfHubHTTPError`] + If the server returned an error. + """ + endpoint = endpoint if endpoint is not None else constants.ENDPOINT + url_prefix = "" + if repo_type in constants.REPO_TYPES_URL_PREFIXES: + url_prefix = constants.REPO_TYPES_URL_PREFIXES[repo_type] + batch_url = f"{endpoint}/{url_prefix}{repo_id}.git/info/lfs/objects/batch" + payload: dict = { + "operation": "upload", + "transfers": transfers if transfers is not None else ["basic", "multipart"], + "objects": [ + { + "oid": upload.sha256.hex(), + "size": upload.size, + } + for upload in upload_infos + ], + "hash_algo": "sha256", + } + if revision is not None: + payload["ref"] = {"name": unquote(revision)} # revision has been previously 'quoted' + + headers = { + **LFS_HEADERS, + **build_hf_headers(token=token), + **(headers or {}), + } + resp = http_backoff("POST", batch_url, headers=headers, json=payload) + hf_raise_for_status(resp) + batch_info = resp.json() + + objects = batch_info.get("objects", None) + if not isinstance(objects, list): + raise ValueError("Malformed response from server") + + chosen_transfer = batch_info.get("transfer") + chosen_transfer = chosen_transfer if isinstance(chosen_transfer, str) else None + + return ( + [_validate_batch_actions(obj) for obj in objects if "error" not in obj], + [_validate_batch_error(obj) for obj in objects if "error" in obj], + chosen_transfer, + ) + + +class PayloadPartT(TypedDict): + partNumber: int + etag: str + + +class CompletionPayloadT(TypedDict): + """Payload that will be sent to the Hub when uploading multi-part.""" + + oid: str + parts: list[PayloadPartT] + + +def lfs_upload( + operation: "CommitOperationAdd", + lfs_batch_action: dict, + token: str | None = None, + headers: dict[str, str] | None = None, + endpoint: str | None = None, +) -> None: + """ + Handles uploading a given object to the Hub with the LFS protocol. + + Can be a No-op if the content of the file is already present on the hub large file storage. + + Args: + operation (`CommitOperationAdd`): + The add operation triggering this upload. + lfs_batch_action (`dict`): + Upload instructions from the LFS batch endpoint for this object. See [`~utils.lfs.post_lfs_batch_info`] for + more details. + token (`str`, *optional*): + An authentication token (see https://huggingface.co/settings/token). Used to call the + optional LFS verify step at the end of the upload. If `None`, falls back to the local + cached token. + headers (`dict`, *optional*): + Headers to include in the request, including authentication and user agent headers. + endpoint (`str`, *optional*): + The Hub endpoint to send the request to. Defaults to the value of `HF_ENDPOINT`. + + Raises: + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If `lfs_batch_action` is improperly formatted + [`HfHubHTTPError`] + If the upload resulted in an error + """ + # 0. If LFS file is already present, skip upload + _validate_batch_actions(lfs_batch_action) + actions = lfs_batch_action.get("actions") + if actions is None: + # The file was already uploaded + logger.debug(f"Content of file {operation.path_in_repo} is already present upstream - skipping upload") + return + + # 1. Validate server response (check required keys in dict) + upload_action = lfs_batch_action["actions"]["upload"] + _validate_lfs_action(upload_action) + verify_action = lfs_batch_action["actions"].get("verify") + if verify_action is not None: + _validate_lfs_action(verify_action) + + # 2. Upload file (either single part or multi-part) + header = upload_action.get("header", {}) + chunk_size = header.get("chunk_size") + upload_url = fix_hf_endpoint_in_url(upload_action["href"], endpoint=endpoint) + if chunk_size is not None: + try: + chunk_size = int(chunk_size) + except (ValueError, TypeError): + raise ValueError( + f"Malformed response from LFS batch endpoint: `chunk_size` should be an integer. Got '{chunk_size}'." + ) + _upload_multi_part(operation=operation, header=header, chunk_size=chunk_size, upload_url=upload_url) + else: + _upload_single_part(operation=operation, upload_url=upload_url) + + # 3. Verify upload went well + if verify_action is not None: + _validate_lfs_action(verify_action) + verify_url = fix_hf_endpoint_in_url(verify_action["href"], endpoint) + verify_resp = http_backoff( + "POST", + verify_url, + headers=build_hf_headers(token=token, headers=headers), + json={"oid": operation.upload_info.sha256.hex(), "size": operation.upload_info.size}, + ) + hf_raise_for_status(verify_resp) + logger.debug(f"{operation.path_in_repo}: Upload successful") + + +def _validate_lfs_action(lfs_action: dict): + """validates response from the LFS batch endpoint""" + if not ( + isinstance(lfs_action.get("href"), str) + and (lfs_action.get("header") is None or isinstance(lfs_action.get("header"), dict)) + ): + raise ValueError("lfs_action is improperly formatted") + return lfs_action + + +def _validate_batch_actions(lfs_batch_actions: dict): + """validates response from the LFS batch endpoint""" + if not (isinstance(lfs_batch_actions.get("oid"), str) and isinstance(lfs_batch_actions.get("size"), int)): + raise ValueError("lfs_batch_actions is improperly formatted") + + upload_action = lfs_batch_actions.get("actions", {}).get("upload") + verify_action = lfs_batch_actions.get("actions", {}).get("verify") + if upload_action is not None: + _validate_lfs_action(upload_action) + if verify_action is not None: + _validate_lfs_action(verify_action) + return lfs_batch_actions + + +def _validate_batch_error(lfs_batch_error: dict): + """validates response from the LFS batch endpoint""" + if not (isinstance(lfs_batch_error.get("oid"), str) and isinstance(lfs_batch_error.get("size"), int)): + raise ValueError("lfs_batch_error is improperly formatted") + error_info = lfs_batch_error.get("error") + if not ( + isinstance(error_info, dict) + and isinstance(error_info.get("message"), str) + and isinstance(error_info.get("code"), int) + ): + raise ValueError("lfs_batch_error is improperly formatted") + return lfs_batch_error + + +def _upload_single_part(operation: "CommitOperationAdd", upload_url: str) -> None: + """ + Uploads `fileobj` as a single PUT HTTP request (basic LFS transfer protocol) + + Args: + upload_url (`str`): + The URL to PUT the file to. + fileobj: + The file-like object holding the data to upload. + + Raises: + [`HfHubHTTPError`] + If the upload resulted in an error. + """ + with operation.as_file(with_tqdm=True) as fileobj: + # S3 might raise a transient 500 error -> let's retry if that happens + response = http_backoff("PUT", upload_url, data=fileobj) + hf_raise_for_status(response) + + +def _upload_multi_part(operation: "CommitOperationAdd", header: dict, chunk_size: int, upload_url: str) -> None: + """ + Uploads file using HF multipart LFS transfer protocol. + """ + # 1. Get upload URLs for each part + sorted_parts_urls = _get_sorted_parts_urls(header=header, upload_info=operation.upload_info, chunk_size=chunk_size) + + # 2. Upload parts (pure Python) + response_headers = _upload_parts_iteratively( + operation=operation, sorted_parts_urls=sorted_parts_urls, chunk_size=chunk_size + ) + + # 3. Send completion request + # NOTE: `upload_url` is the Hub completion endpoint (not the S3 upload URLs). + completion_res = http_backoff( + "POST", + upload_url, + json=_get_completion_payload(response_headers, operation.upload_info.sha256.hex()), + headers=LFS_HEADERS, + ) + hf_raise_for_status(completion_res) + + +def _get_sorted_parts_urls(header: dict, upload_info: UploadInfo, chunk_size: int) -> list[str]: + sorted_part_upload_urls = [ + upload_url + for _, upload_url in sorted( + [ + (int(part_num, 10), upload_url) + for part_num, upload_url in header.items() + if part_num.isdigit() and len(part_num) > 0 + ], + key=lambda t: t[0], + ) + ] + num_parts = len(sorted_part_upload_urls) + if num_parts != ceil(upload_info.size / chunk_size): + raise ValueError("Invalid server response to upload large LFS file") + return sorted_part_upload_urls + + +def _get_completion_payload(response_headers: list[dict], oid: str) -> CompletionPayloadT: + parts: list[PayloadPartT] = [] + for part_number, header in enumerate(response_headers): + etag = header.get("etag") + if etag is None or etag == "": + raise ValueError(f"Invalid etag (`{etag}`) returned for part {part_number + 1}") + parts.append( + { + "partNumber": part_number + 1, + "etag": etag, + } + ) + return {"oid": oid, "parts": parts} + + +def _upload_parts_iteratively( + operation: "CommitOperationAdd", sorted_parts_urls: list[str], chunk_size: int +) -> list[dict]: + headers = [] + with operation.as_file(with_tqdm=True) as fileobj: + for part_idx, part_upload_url in enumerate(sorted_parts_urls): + with SliceFileObj( + fileobj, + seek_from=chunk_size * part_idx, + read_limit=chunk_size, + ) as fileobj_slice: + # S3 might raise a transient 500 error -> let's retry if that happens + part_upload_res = http_backoff("PUT", part_upload_url, data=fileobj_slice) + hf_raise_for_status(part_upload_res) + headers.append(part_upload_res.headers) + return headers # type: ignore diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/py.typed b/.venv/lib/python3.13/site-packages/huggingface_hub/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/repocard.py b/.venv/lib/python3.13/site-packages/huggingface_hub/repocard.py new file mode 100644 index 0000000000000000000000000000000000000000..643aab95d6b93548d6af986513b6c886efeed544 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/repocard.py @@ -0,0 +1,835 @@ +import os +import re +from pathlib import Path +from typing import Any, Literal + +import yaml + +from huggingface_hub.file_download import hf_hub_download +from huggingface_hub.hf_api import upload_file +from huggingface_hub.repocard_data import ( + CardData, + DatasetCardData, + EvalResult, + ModelCardData, + SpaceCardData, + eval_results_to_model_index, + model_index_to_eval_results, +) +from huggingface_hub.utils import HfHubHTTPError, get_session, hf_raise_for_status, is_jinja_available, yaml_dump + +from . import constants +from .errors import EntryNotFoundError +from .utils import SoftTemporaryDirectory, logging, validate_hf_hub_args + + +logger = logging.get_logger(__name__) + + +TEMPLATE_MODELCARD_PATH = Path(__file__).parent / "templates" / "modelcard_template.md" +TEMPLATE_DATASETCARD_PATH = Path(__file__).parent / "templates" / "datasetcard_template.md" + +# exact same regex as in the Hub server. Please keep in sync. +# See https://github.com/huggingface/moon-landing/blob/main/server/lib/ViewMarkdown.ts#L18 +REGEX_YAML_BLOCK = re.compile(r"^(\s*---[\r\n]+)([\S\s]*?)([\r\n]+---(\r\n|\n|$))") + + +class RepoCard: + card_data_class = CardData + default_template_path = TEMPLATE_MODELCARD_PATH + repo_type = "model" + + def __init__(self, content: str, ignore_metadata_errors: bool = False): + """Initialize a RepoCard from string content. The content should be a + Markdown file with a YAML block at the beginning and a Markdown body. + + Args: + content (`str`): The content of the Markdown file. + + Example: + ```python + >>> from huggingface_hub.repocard import RepoCard + >>> text = ''' + ... --- + ... language: en + ... license: mit + ... --- + ... + ... # My repo + ... ''' + >>> card = RepoCard(text) + >>> card.data.to_dict() + {'language': 'en', 'license': 'mit'} + >>> card.text + '\\n# My repo\\n' + + ``` + > [!TIP] + > Raises the following error: + > + > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > when the content of the repo card metadata is not a dictionary. + """ + + # Set the content of the RepoCard, as well as underlying .data and .text attributes. + # See the `content` property setter for more details. + self.ignore_metadata_errors = ignore_metadata_errors + self.content = content + + @property + def content(self): + """The content of the RepoCard, including the YAML block and the Markdown body.""" + line_break = _detect_line_ending(self._content) or "\n" + return f"---{line_break}{self.data.to_yaml(line_break=line_break, original_order=self._original_order)}{line_break}---{line_break}{self.text}" + + @content.setter + def content(self, content: str): + """Set the content of the RepoCard.""" + self._content = content + + match = REGEX_YAML_BLOCK.search(content) + if match: + # Metadata found in the YAML block + yaml_block = match.group(2) + self.text = content[match.end() :] + data_dict = yaml.safe_load(yaml_block) + + if data_dict is None: + data_dict = {} + + # The YAML block's data should be a dictionary + if not isinstance(data_dict, dict): + raise ValueError("repo card metadata block should be a dict") + else: + # Model card without metadata... create empty metadata + logger.warning("Repo card metadata block was not found. Setting CardData to empty.") + data_dict = {} + self.text = content + + self.data = self.card_data_class(**data_dict, ignore_metadata_errors=self.ignore_metadata_errors) + self._original_order = list(data_dict.keys()) + + def __str__(self): + return self.content + + def save(self, filepath: Path | str): + r"""Save a RepoCard to a file. + + Args: + filepath (`Union[Path, str]`): Filepath to the markdown file to save. + + Example: + ```python + >>> from huggingface_hub.repocard import RepoCard + >>> card = RepoCard("---\nlanguage: en\n---\n# This is a test repo card") + >>> card.save("/tmp/test.md") + + ``` + """ + filepath = Path(filepath) + filepath.parent.mkdir(parents=True, exist_ok=True) + # Preserve newlines as in the existing file. + with open(filepath, mode="w", newline="", encoding="utf-8") as f: + f.write(str(self)) + + @classmethod + def load( + cls, + repo_id_or_path: str | Path, + repo_type: str | None = None, + token: str | None = None, + ignore_metadata_errors: bool = False, + ): + """Initialize a RepoCard from a Hugging Face Hub repo's README.md or a local filepath. + + Args: + repo_id_or_path (`Union[str, Path]`): + The repo ID associated with a Hugging Face Hub repo or a local filepath. + repo_type (`str`, *optional*): + The type of Hugging Face repo to push to. Defaults to None, which will use "model". Other options + are "dataset" and "space". Not used when loading from a local filepath. If this is called from a child + class, the default value will be the child class's `repo_type`. + token (`str`, *optional*): + Authentication token, obtained with `huggingface_hub.HfApi.login` method. Will default to the stored token. + ignore_metadata_errors (`str`): + If True, errors while parsing the metadata section will be ignored. Some information might be lost during + the process. Use it at your own risk. + + Returns: + [`huggingface_hub.repocard.RepoCard`]: The RepoCard (or subclass) initialized from the repo's + README.md file or filepath. + + Example: + ```python + >>> from huggingface_hub.repocard import RepoCard + >>> card = RepoCard.load("nateraw/food") + >>> assert card.data.tags == ["generated_from_trainer", "image-classification", "pytorch"] + + ``` + """ + + if Path(repo_id_or_path).is_file(): + card_path = Path(repo_id_or_path) + elif isinstance(repo_id_or_path, str): + card_path = Path( + hf_hub_download( + repo_id_or_path, + constants.REPOCARD_NAME, + repo_type=repo_type or cls.repo_type, + token=token, + ) + ) + else: + raise ValueError(f"Cannot load RepoCard: path not found on disk ({repo_id_or_path}).") + + # Preserve newlines in the existing file. + with card_path.open(mode="r", newline="", encoding="utf-8") as f: + return cls(f.read(), ignore_metadata_errors=ignore_metadata_errors) + + def validate(self, repo_type: str | None = None): + """Validates card against Hugging Face Hub's card validation logic. + Using this function requires access to the internet, so it is only called + internally by [`huggingface_hub.repocard.RepoCard.push_to_hub`]. + + Args: + repo_type (`str`, *optional*, defaults to "model"): + The type of Hugging Face repo to push to. Options are "model", "dataset", and "space". + If this function is called from a child class, the default will be the child class's `repo_type`. + + > [!TIP] + > Raises the following errors: + > + > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > if the card fails validation checks. + > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError) + > if the request to the Hub API fails for any other reason. + """ + + # If repo type is provided, otherwise, use the repo type of the card. + repo_type = repo_type or self.repo_type + + body = { + "repoType": repo_type, + "content": str(self), + } + headers = {"Accept": "text/plain"} + + try: + response = get_session().post("https://huggingface.co/api/validate-yaml", json=body, headers=headers) + hf_raise_for_status(response) + except HfHubHTTPError as exc: + if response.status_code == 400: + raise ValueError(response.text) + else: + raise exc + + def push_to_hub( + self, + repo_id: str, + token: str | None = None, + repo_type: str | None = None, + commit_message: str | None = None, + commit_description: str | None = None, + revision: str | None = None, + create_pr: bool | None = None, + parent_commit: str | None = None, + ): + """Push a RepoCard to a Hugging Face Hub repo. + + Args: + repo_id (`str`): + The repo ID of the Hugging Face Hub repo to push to. Example: "nateraw/food". + token (`str`, *optional*): + Authentication token, obtained with `huggingface_hub.HfApi.login` method. Will default to + the stored token. + repo_type (`str`, *optional*, defaults to "model"): + The type of Hugging Face repo to push to. Options are "model", "dataset", and "space". If this + function is called by a child class, it will default to the child class's `repo_type`. + commit_message (`str`, *optional*): + The summary / title / first line of the generated commit. + commit_description (`str`, *optional*) + The description of the generated commit. + revision (`str`, *optional*): + The git revision to commit from. Defaults to the head of the `"main"` branch. + create_pr (`bool`, *optional*): + Whether or not to create a Pull Request with this commit. Defaults to `False`. + parent_commit (`str`, *optional*): + The OID / SHA of the parent commit, as a hexadecimal string. Shorthands (7 first characters) are also supported. + If specified and `create_pr` is `False`, the commit will fail if `revision` does not point to `parent_commit`. + If specified and `create_pr` is `True`, the pull request will be created from `parent_commit`. + Specifying `parent_commit` ensures the repo has not changed before committing the changes, and can be + especially useful if the repo is updated / committed too concurrently. + Returns: + `str`: URL of the commit which updated the card metadata. + """ + + # If repo type is provided, otherwise, use the repo type of the card. + repo_type = repo_type or self.repo_type + + # Validate card before pushing to hub + self.validate(repo_type=repo_type) + + with SoftTemporaryDirectory() as tmpdir: + tmp_path = Path(tmpdir) / constants.REPOCARD_NAME + tmp_path.write_text(str(self), encoding="utf-8") + url = upload_file( + path_or_fileobj=str(tmp_path), + path_in_repo=constants.REPOCARD_NAME, + repo_id=repo_id, + token=token, + repo_type=repo_type, + commit_message=commit_message, + commit_description=commit_description, + create_pr=create_pr, + revision=revision, + parent_commit=parent_commit, + ) + return url + + @classmethod + def from_template( + cls, + card_data: CardData, + template_path: str | None = None, + template_str: str | None = None, + **template_kwargs, + ): + """Initialize a RepoCard from a template. By default, it uses the default template. + + Templates are Jinja2 templates that can be customized by passing keyword arguments. + + Args: + card_data (`huggingface_hub.CardData`): + A huggingface_hub.CardData instance containing the metadata you want to include in the YAML + header of the repo card on the Hugging Face Hub. + template_path (`str`, *optional*): + A path to a markdown file with optional Jinja template variables that can be filled + in with `template_kwargs`. Defaults to the default template. + template_str (`str`, *optional*): + A raw Jinja template string with optional variables. Used when neither `template_path` + nor the default template is appropriate. Ignored if `template_path` is also provided. + + Returns: + [`huggingface_hub.repocard.RepoCard`]: A RepoCard instance with the specified card data and content from the + template. + """ + if is_jinja_available(): + import jinja2 + else: + raise ImportError( + "Using RepoCard.from_template requires Jinja2 to be installed. Please" + " install it with `pip install Jinja2`." + ) + + kwargs = card_data.to_dict().copy() + kwargs.update(template_kwargs) # Template_kwargs have priority + + if template_path is not None: + template_str = Path(template_path).read_text() + if template_str is None: + template_str = Path(cls.default_template_path).read_text() + template = jinja2.Template(template_str) + content = template.render(card_data=card_data.to_yaml(), **kwargs) + return cls(content) + + +class ModelCard(RepoCard): + card_data_class = ModelCardData # type: ignore[assignment] + default_template_path = TEMPLATE_MODELCARD_PATH + repo_type = "model" + + @classmethod + def from_template( # type: ignore # violates Liskov property but easier to use + cls, + card_data: ModelCardData, + template_path: str | None = None, + template_str: str | None = None, + **template_kwargs, + ): + """Initialize a ModelCard from a template. By default, it uses the default template, which can be found here: + https://github.com/huggingface/huggingface_hub/blob/main/src/huggingface_hub/templates/modelcard_template.md + + Templates are Jinja2 templates that can be customized by passing keyword arguments. + + Args: + card_data (`huggingface_hub.ModelCardData`): + A huggingface_hub.ModelCardData instance containing the metadata you want to include in the YAML + header of the model card on the Hugging Face Hub. + template_path (`str`, *optional*): + A path to a markdown file with optional Jinja template variables that can be filled + in with `template_kwargs`. Defaults to the default template. + template_str (`str`, *optional*): + A raw Jinja template string with optional variables. Used when neither `template_path` + nor the default template is appropriate. Ignored if `template_path` is also provided. + + Returns: + [`huggingface_hub.ModelCard`]: A ModelCard instance with the specified card data and content from the + template. + + Example: + ```python + >>> from huggingface_hub import ModelCard, ModelCardData, EvalResult + + >>> # Using the Default Template + >>> card_data = ModelCardData( + ... language='en', + ... license='mit', + ... library_name='timm', + ... tags=['image-classification', 'resnet'], + ... datasets=['beans'], + ... metrics=['accuracy'], + ... ) + >>> card = ModelCard.from_template( + ... card_data, + ... model_description='This model does x + y...' + ... ) + + >>> # Including Evaluation Results + >>> card_data = ModelCardData( + ... language='en', + ... tags=['image-classification', 'resnet'], + ... eval_results=[ + ... EvalResult( + ... task_type='image-classification', + ... dataset_type='beans', + ... dataset_name='Beans', + ... metric_type='accuracy', + ... metric_value=0.9, + ... ), + ... ], + ... model_name='my-cool-model', + ... ) + >>> card = ModelCard.from_template(card_data) + + >>> # Using a Custom Template + >>> card_data = ModelCardData( + ... language='en', + ... tags=['image-classification', 'resnet'] + ... ) + >>> card = ModelCard.from_template( + ... card_data=card_data, + ... template_path='./src/huggingface_hub/templates/modelcard_template.md', + ... custom_template_var='custom value', # will be replaced in template if it exists + ... ) + + ``` + """ + return super().from_template(card_data, template_path, template_str, **template_kwargs) + + +class DatasetCard(RepoCard): + card_data_class = DatasetCardData # type: ignore[assignment] + default_template_path = TEMPLATE_DATASETCARD_PATH + repo_type = "dataset" + + @classmethod + def from_template( # type: ignore # violates Liskov property but easier to use + cls, + card_data: DatasetCardData, + template_path: str | None = None, + template_str: str | None = None, + **template_kwargs, + ): + """Initialize a DatasetCard from a template. By default, it uses the default template, which can be found here: + https://github.com/huggingface/huggingface_hub/blob/main/src/huggingface_hub/templates/datasetcard_template.md + + Templates are Jinja2 templates that can be customized by passing keyword arguments. + + Args: + card_data (`huggingface_hub.DatasetCardData`): + A huggingface_hub.DatasetCardData instance containing the metadata you want to include in the YAML + header of the dataset card on the Hugging Face Hub. + template_path (`str`, *optional*): + A path to a markdown file with optional Jinja template variables that can be filled + in with `template_kwargs`. Defaults to the default template. + template_str (`str`, *optional*): + A raw Jinja template string with optional variables. Used when neither `template_path` + nor the default template is appropriate. Ignored if `template_path` is also provided. + + Returns: + [`huggingface_hub.DatasetCard`]: A DatasetCard instance with the specified card data and content from the + template. + + Example: + ```python + >>> from huggingface_hub import DatasetCard, DatasetCardData + + >>> # Using the Default Template + >>> card_data = DatasetCardData( + ... language='en', + ... license='mit', + ... annotations_creators='crowdsourced', + ... task_categories=['text-classification'], + ... task_ids=['sentiment-classification', 'text-scoring'], + ... multilinguality='monolingual', + ... pretty_name='My Text Classification Dataset', + ... ) + >>> card = DatasetCard.from_template( + ... card_data, + ... pretty_name=card_data.pretty_name, + ... ) + + >>> # Using a Custom Template + >>> card_data = DatasetCardData( + ... language='en', + ... license='mit', + ... ) + >>> card = DatasetCard.from_template( + ... card_data=card_data, + ... template_path='./src/huggingface_hub/templates/datasetcard_template.md', + ... custom_template_var='custom value', # will be replaced in template if it exists + ... ) + + ``` + """ + return super().from_template(card_data, template_path, template_str, **template_kwargs) + + +class SpaceCard(RepoCard): + card_data_class = SpaceCardData # type: ignore[assignment] + default_template_path = TEMPLATE_MODELCARD_PATH + repo_type = "space" + + +def _detect_line_ending(content: str) -> Literal["\r", "\n", "\r\n", None]: # noqa: F722 + """Detect the line ending of a string. Used by RepoCard to avoid making huge diff on newlines. + + Uses same implementation as in Hub server, keep it in sync. + + Returns: + str: The detected line ending of the string. + """ + cr = content.count("\r") + lf = content.count("\n") + crlf = content.count("\r\n") + if cr + lf == 0: + return None + if crlf == cr and crlf == lf: + return "\r\n" + if cr > lf: + return "\r" + else: + return "\n" + + +def metadata_load(local_path: str | Path) -> dict | None: + content = Path(local_path).read_text() + match = REGEX_YAML_BLOCK.search(content) + if match: + yaml_block = match.group(2) + data = yaml.safe_load(yaml_block) + if data is None or isinstance(data, dict): + return data + raise ValueError("repo card metadata block should be a dict") + else: + return None + + +def metadata_save(local_path: str | Path, data: dict) -> None: + """ + Save the metadata dict in the upper YAML part Trying to preserve newlines as + in the existing file. Docs about open() with newline="" parameter: + https://docs.python.org/3/library/functions.html?highlight=open#open Does + not work with "^M" linebreaks, which are replaced by \n + """ + line_break = "\n" + content = "" + # try to detect existing newline character + if os.path.exists(local_path): + with open(local_path, newline="", encoding="utf8") as readme: + content = readme.read() + if isinstance(readme.newlines, tuple): + line_break = readme.newlines[0] + elif isinstance(readme.newlines, str): + line_break = readme.newlines + + # creates a new file if it not + with open(local_path, "w", newline="", encoding="utf8") as readme: + data_yaml = yaml_dump(data, sort_keys=False, line_break=line_break) + # sort_keys: keep dict order + match = REGEX_YAML_BLOCK.search(content) + if match: + output = content[: match.start()] + f"---{line_break}{data_yaml}---{line_break}" + content[match.end() :] + else: + output = f"---{line_break}{data_yaml}---{line_break}{content}" + + readme.write(output) + readme.close() + + +def metadata_eval_result( + *, + model_pretty_name: str, + task_pretty_name: str, + task_id: str, + metrics_pretty_name: str, + metrics_id: str, + metrics_value: Any, + dataset_pretty_name: str, + dataset_id: str, + metrics_config: str | None = None, + metrics_verified: bool = False, + dataset_config: str | None = None, + dataset_split: str | None = None, + dataset_revision: str | None = None, + metrics_verification_token: str | None = None, +) -> dict: + """ + Creates a metadata dict with the result from a model evaluated on a dataset. + + Args: + model_pretty_name (`str`): + The name of the model in natural language. + task_pretty_name (`str`): + The name of a task in natural language. + task_id (`str`): + Example: automatic-speech-recognition. A task id. + metrics_pretty_name (`str`): + A name for the metric in natural language. Example: Test WER. + metrics_id (`str`): + Example: wer. A metric id from https://hf.co/metrics. + metrics_value (`Any`): + The value from the metric. Example: 20.0 or "20.0 ± 1.2". + dataset_pretty_name (`str`): + The name of the dataset in natural language. + dataset_id (`str`): + Example: common_voice. A dataset id from https://hf.co/datasets. + metrics_config (`str`, *optional*): + The name of the metric configuration used in `load_metric()`. + Example: bleurt-large-512 in `load_metric("bleurt", "bleurt-large-512")`. + metrics_verified (`bool`, *optional*, defaults to `False`): + Indicates whether the metrics originate from Hugging Face's [evaluation service](https://huggingface.co/spaces/autoevaluate/model-evaluator) or not. Automatically computed by Hugging Face, do not set. + dataset_config (`str`, *optional*): + Example: fr. The name of the dataset configuration used in `load_dataset()`. + dataset_split (`str`, *optional*): + Example: test. The name of the dataset split used in `load_dataset()`. + dataset_revision (`str`, *optional*): + Example: 5503434ddd753f426f4b38109466949a1217c2bb. The name of the dataset dataset revision + used in `load_dataset()`. + metrics_verification_token (`bool`, *optional*): + A JSON Web Token that is used to verify whether the metrics originate from Hugging Face's [evaluation service](https://huggingface.co/spaces/autoevaluate/model-evaluator) or not. + + Returns: + `dict`: a metadata dict with the result from a model evaluated on a dataset. + + Example: + ```python + >>> from huggingface_hub import metadata_eval_result + >>> results = metadata_eval_result( + ... model_pretty_name="RoBERTa fine-tuned on ReactionGIF", + ... task_pretty_name="Text Classification", + ... task_id="text-classification", + ... metrics_pretty_name="Accuracy", + ... metrics_id="accuracy", + ... metrics_value=0.2662102282047272, + ... dataset_pretty_name="ReactionJPEG", + ... dataset_id="julien-c/reactionjpeg", + ... dataset_config="default", + ... dataset_split="test", + ... ) + >>> results == { + ... 'model-index': [ + ... { + ... 'name': 'RoBERTa fine-tuned on ReactionGIF', + ... 'results': [ + ... { + ... 'task': { + ... 'type': 'text-classification', + ... 'name': 'Text Classification' + ... }, + ... 'dataset': { + ... 'name': 'ReactionJPEG', + ... 'type': 'julien-c/reactionjpeg', + ... 'config': 'default', + ... 'split': 'test' + ... }, + ... 'metrics': [ + ... { + ... 'type': 'accuracy', + ... 'value': 0.2662102282047272, + ... 'name': 'Accuracy', + ... 'verified': False + ... } + ... ] + ... } + ... ] + ... } + ... ] + ... } + True + + ``` + """ + + return { + "model-index": eval_results_to_model_index( + model_name=model_pretty_name, + eval_results=[ + EvalResult( + task_name=task_pretty_name, + task_type=task_id, + metric_name=metrics_pretty_name, + metric_type=metrics_id, + metric_value=metrics_value, + dataset_name=dataset_pretty_name, + dataset_type=dataset_id, + metric_config=metrics_config, + verified=metrics_verified, + verify_token=metrics_verification_token, + dataset_config=dataset_config, + dataset_split=dataset_split, + dataset_revision=dataset_revision, + ) + ], + ) + } + + +@validate_hf_hub_args +def metadata_update( + repo_id: str, + metadata: dict, + *, + repo_type: str | None = None, + overwrite: bool = False, + token: str | None = None, + commit_message: str | None = None, + commit_description: str | None = None, + revision: str | None = None, + create_pr: bool = False, + parent_commit: str | None = None, +) -> str: + """ + Updates the metadata in the README.md of a repository on the Hugging Face Hub. + If the README.md file doesn't exist yet, a new one is created with metadata and + the default ModelCard or DatasetCard template. For `space` repo, an error is thrown + as a Space cannot exist without a `README.md` file. + + Args: + repo_id (`str`): + The name of the repository. + metadata (`dict`): + A dictionary containing the metadata to be updated. + repo_type (`str`, *optional*): + Set to `"dataset"` or `"space"` if updating to a dataset or space, + `None` or `"model"` if updating to a model. Default is `None`. + overwrite (`bool`, *optional*, defaults to `False`): + If set to `True` an existing field can be overwritten, otherwise + attempting to overwrite an existing field will cause an error. + token (`str`, *optional*): + The Hugging Face authentication token. + commit_message (`str`, *optional*): + The summary / title / first line of the generated commit. Defaults to + `f"Update metadata with huggingface_hub"` + commit_description (`str` *optional*) + The description of the generated commit + revision (`str`, *optional*): + The git revision to commit from. Defaults to the head of the + `"main"` branch. + create_pr (`boolean`, *optional*): + Whether or not to create a Pull Request from `revision` with that commit. + Defaults to `False`. + parent_commit (`str`, *optional*): + The OID / SHA of the parent commit, as a hexadecimal string. Shorthands (7 first characters) are also supported. + If specified and `create_pr` is `False`, the commit will fail if `revision` does not point to `parent_commit`. + If specified and `create_pr` is `True`, the pull request will be created from `parent_commit`. + Specifying `parent_commit` ensures the repo has not changed before committing the changes, and can be + especially useful if the repo is updated / committed too concurrently. + Returns: + `str`: URL of the commit which updated the card metadata. + + Example: + ```python + >>> from huggingface_hub import metadata_update + >>> metadata = {'model-index': [{'name': 'RoBERTa fine-tuned on ReactionGIF', + ... 'results': [{'dataset': {'name': 'ReactionGIF', + ... 'type': 'julien-c/reactiongif'}, + ... 'metrics': [{'name': 'Recall', + ... 'type': 'recall', + ... 'value': 0.7762102282047272}], + ... 'task': {'name': 'Text Classification', + ... 'type': 'text-classification'}}]}]} + >>> url = metadata_update("hf-internal-testing/reactiongif-roberta-card", metadata) + + ``` + """ + commit_message = commit_message if commit_message is not None else "Update metadata with huggingface_hub" + + # Card class given repo_type + card_class: type[RepoCard] + if repo_type is None or repo_type == "model": + card_class = ModelCard + elif repo_type == "dataset": + card_class = DatasetCard + elif repo_type == "space": + card_class = RepoCard + else: + raise ValueError(f"Unknown repo_type: {repo_type}") + + # Either load repo_card from the Hub or create an empty one. + # NOTE: Will not create the repo if it doesn't exist. + try: + card = card_class.load(repo_id, token=token, repo_type=repo_type) + except EntryNotFoundError: + if repo_type == "space": + raise ValueError("Cannot update metadata on a Space that doesn't contain a `README.md` file.") + + # Initialize a ModelCard or DatasetCard from default template and no data. + # Cast to the concrete expected card type to satisfy type checkers. + card = card_class.from_template(CardData()) # type: ignore + + for key, value in metadata.items(): + if key == "model-index": + # if the new metadata doesn't include a name, either use existing one or repo name + if "name" not in value[0]: + value[0]["name"] = getattr(card, "model_name", repo_id) + model_name, new_results = model_index_to_eval_results(value) + if card.data.eval_results is None: + card.data.eval_results = new_results + card.data.model_name = model_name + else: + existing_results = card.data.eval_results + + # Iterate over new results + # Iterate over existing results + # If both results describe the same metric but value is different: + # If overwrite=True: overwrite the metric value + # Else: raise ValueError + # Else: append new result to existing ones. + for new_result in new_results: + result_found = False + for existing_result in existing_results: + if new_result.is_equal_except_value(existing_result): + if new_result != existing_result and not overwrite: + raise ValueError( + "You passed a new value for the existing metric" + f" 'name: {new_result.metric_name}, type: " + f"{new_result.metric_type}'. Set `overwrite=True`" + " to overwrite existing metrics." + ) + result_found = True + existing_result.metric_value = new_result.metric_value + if existing_result.verified is True: + existing_result.verify_token = new_result.verify_token + if not result_found: + card.data.eval_results.append(new_result) + else: + # Any metadata that is not a result metric + if card.data.get(key) is not None and not overwrite and card.data.get(key) != value: + raise ValueError( + f"You passed a new value for the existing meta data field '{key}'." + " Set `overwrite=True` to overwrite existing metadata." + ) + else: + card.data[key] = value + + return card.push_to_hub( + repo_id, + token=token, + repo_type=repo_type, + commit_message=commit_message, + commit_description=commit_description, + create_pr=create_pr, + revision=revision, + parent_commit=parent_commit, + ) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/repocard_data.py b/.venv/lib/python3.13/site-packages/huggingface_hub/repocard_data.py new file mode 100644 index 0000000000000000000000000000000000000000..51f40eb7758a4a8978541d3871e6b9e5e0f3ab88 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/repocard_data.py @@ -0,0 +1,775 @@ +import copy +from collections import defaultdict +from dataclasses import dataclass +from typing import Any + +from huggingface_hub.utils import logging, yaml_dump + + +logger = logging.get_logger(__name__) + + +@dataclass +class EvalResult: + """ + Flattened representation of individual evaluation results found in model-index of Model Cards. + + For more information on the model-index spec, see https://github.com/huggingface/hub-docs/blob/main/modelcard.md?plain=1. + + Args: + task_type (`str`): + The task identifier. Example: "image-classification". + dataset_type (`str`): + The dataset identifier. Example: "common_voice". Use dataset id from https://hf.co/datasets. + dataset_name (`str`): + A pretty name for the dataset. Example: "Common Voice (French)". + metric_type (`str`): + The metric identifier. Example: "wer". Use metric id from https://hf.co/metrics. + metric_value (`Any`): + The metric value. Example: 0.9 or "20.0 ± 1.2". + task_name (`str`, *optional*): + A pretty name for the task. Example: "Speech Recognition". + dataset_config (`str`, *optional*): + The name of the dataset configuration used in `load_dataset()`. + Example: fr in `load_dataset("common_voice", "fr")`. See the `datasets` docs for more info: + https://hf.co/docs/datasets/package_reference/loading_methods#datasets.load_dataset.name + dataset_split (`str`, *optional*): + The split used in `load_dataset()`. Example: "test". + dataset_revision (`str`, *optional*): + The revision (AKA Git Sha) of the dataset used in `load_dataset()`. + Example: 5503434ddd753f426f4b38109466949a1217c2bb + dataset_args (`dict[str, Any]`, *optional*): + The arguments passed during `Metric.compute()`. Example for `bleu`: `{"max_order": 4}` + metric_name (`str`, *optional*): + A pretty name for the metric. Example: "Test WER". + metric_config (`str`, *optional*): + The name of the metric configuration used in `load_metric()`. + Example: bleurt-large-512 in `load_metric("bleurt", "bleurt-large-512")`. + See the `datasets` docs for more info: https://huggingface.co/docs/datasets/v2.1.0/en/loading#load-configurations + metric_args (`dict[str, Any]`, *optional*): + The arguments passed during `Metric.compute()`. Example for `bleu`: max_order: 4 + verified (`bool`, *optional*): + Indicates whether the metrics originate from Hugging Face's [evaluation service](https://huggingface.co/spaces/autoevaluate/model-evaluator) or not. Automatically computed by Hugging Face, do not set. + verify_token (`str`, *optional*): + A JSON Web Token that is used to verify whether the metrics originate from Hugging Face's [evaluation service](https://huggingface.co/spaces/autoevaluate/model-evaluator) or not. + source_name (`str`, *optional*): + The name of the source of the evaluation result. Example: "Open LLM Leaderboard". + source_url (`str`, *optional*): + The URL of the source of the evaluation result. Example: "https://huggingface.co/spaces/open-llm-leaderboard/open_llm_leaderboard". + """ + + # Required + + # The task identifier + # Example: automatic-speech-recognition + task_type: str + + # The dataset identifier + # Example: common_voice. Use dataset id from https://hf.co/datasets + dataset_type: str + + # A pretty name for the dataset. + # Example: Common Voice (French) + dataset_name: str + + # The metric identifier + # Example: wer. Use metric id from https://hf.co/metrics + metric_type: str + + # Value of the metric. + # Example: 20.0 or "20.0 ± 1.2" + metric_value: Any + + # Optional + + # A pretty name for the task. + # Example: Speech Recognition + task_name: str | None = None + + # The name of the dataset configuration used in `load_dataset()`. + # Example: fr in `load_dataset("common_voice", "fr")`. + # See the `datasets` docs for more info: + # https://huggingface.co/docs/datasets/package_reference/loading_methods#datasets.load_dataset.name + dataset_config: str | None = None + + # The split used in `load_dataset()`. + # Example: test + dataset_split: str | None = None + + # The revision (AKA Git Sha) of the dataset used in `load_dataset()`. + # Example: 5503434ddd753f426f4b38109466949a1217c2bb + dataset_revision: str | None = None + + # The arguments passed during `Metric.compute()`. + # Example for `bleu`: max_order: 4 + dataset_args: dict[str, Any] | None = None + + # A pretty name for the metric. + # Example: Test WER + metric_name: str | None = None + + # The name of the metric configuration used in `load_metric()`. + # Example: bleurt-large-512 in `load_metric("bleurt", "bleurt-large-512")`. + # See the `datasets` docs for more info: https://huggingface.co/docs/datasets/v2.1.0/en/loading#load-configurations + metric_config: str | None = None + + # The arguments passed during `Metric.compute()`. + # Example for `bleu`: max_order: 4 + metric_args: dict[str, Any] | None = None + + # Indicates whether the metrics originate from Hugging Face's [evaluation service](https://huggingface.co/spaces/autoevaluate/model-evaluator) or not. Automatically computed by Hugging Face, do not set. + verified: bool | None = None + + # A JSON Web Token that is used to verify whether the metrics originate from Hugging Face's [evaluation service](https://huggingface.co/spaces/autoevaluate/model-evaluator) or not. + verify_token: str | None = None + + # The name of the source of the evaluation result. + # Example: Open LLM Leaderboard + source_name: str | None = None + + # The URL of the source of the evaluation result. + # Example: https://huggingface.co/spaces/open-llm-leaderboard/open_llm_leaderboard + source_url: str | None = None + + @property + def unique_identifier(self) -> tuple: + """Returns a tuple that uniquely identifies this evaluation.""" + return ( + self.task_type, + self.dataset_type, + self.dataset_config, + self.dataset_split, + self.dataset_revision, + ) + + def is_equal_except_value(self, other: "EvalResult") -> bool: + """ + Return True if `self` and `other` describe exactly the same metric but with a + different value. + """ + for key, _ in self.__dict__.items(): + if key == "metric_value": + continue + # For metrics computed by Hugging Face's evaluation service, `verify_token` is derived from `metric_value`, + # so we exclude it here in the comparison. + if key != "verify_token" and getattr(self, key) != getattr(other, key): + return False + return True + + def __post_init__(self) -> None: + if self.source_name is not None and self.source_url is None: + raise ValueError("If `source_name` is provided, `source_url` must also be provided.") + + +@dataclass +class CardData: + """Structure containing metadata from a RepoCard. + + [`CardData`] is the parent class of [`ModelCardData`] and [`DatasetCardData`]. + + Metadata can be exported as a dictionary or YAML. Export can be customized to alter the representation of the data + (example: flatten evaluation results). `CardData` behaves as a dictionary (can get, pop, set values) but do not + inherit from `dict` to allow this export step. + """ + + def __init__(self, ignore_metadata_errors: bool = False, **kwargs): + self.__dict__.update(kwargs) + + def to_dict(self): + """Converts CardData to a dict. + + Returns: + `dict`: CardData represented as a dictionary ready to be dumped to a YAML + block for inclusion in a README.md file. + """ + + data_dict = copy.deepcopy(self.__dict__) + self._to_dict(data_dict) + return {key: value for key, value in data_dict.items() if value is not None} + + def _to_dict(self, data_dict): + """Use this method in child classes to alter the dict representation of the data. Alter the dict in-place. + + Args: + data_dict (`dict`): The raw dict representation of the card data. + """ + pass + + def to_yaml(self, line_break=None, original_order: list[str] | None = None) -> str: + """Dumps CardData to a YAML block for inclusion in a README.md file. + + Args: + line_break (str, *optional*): + The line break to use when dumping to yaml. + original_order (`list[str]`, *optional*): + If provided, reorder the metadata fields to match this list before dumping. + Any keys not in `original_order` are appended after the listed keys, preserving + their existing relative order. Useful for round-tripping a YAML block without + shuffling its keys. + + Returns: + `str`: CardData represented as a YAML block. + """ + if original_order: + self.__dict__ = { + k: self.__dict__[k] + for k in original_order + list(set(self.__dict__.keys()) - set(original_order)) + if k in self.__dict__ + } + return yaml_dump(self.to_dict(), sort_keys=False, line_break=line_break).strip() + + def __repr__(self): + return repr(self.__dict__) + + def __str__(self): + return self.to_yaml() + + def get(self, key: str, default: Any = None) -> Any: + """Get value for a given metadata key.""" + value = self.__dict__.get(key) + return default if value is None else value + + def pop(self, key: str, default: Any = None) -> Any: + """Pop value for a given metadata key.""" + return self.__dict__.pop(key, default) + + def __getitem__(self, key: str) -> Any: + """Get value for a given metadata key.""" + return self.__dict__[key] + + def __setitem__(self, key: str, value: Any) -> None: + """Set value for a given metadata key.""" + self.__dict__[key] = value + + def __contains__(self, key: str) -> bool: + """Check if a given metadata key is set.""" + return key in self.__dict__ + + def __len__(self) -> int: + """Return the number of metadata keys set.""" + return len(self.__dict__) + + +def _validate_eval_results( + eval_results: EvalResult | list[EvalResult] | None, + model_name: str | None, +) -> list[EvalResult]: + if eval_results is None: + return [] + if isinstance(eval_results, EvalResult): + eval_results = [eval_results] + if not isinstance(eval_results, list) or not all(isinstance(r, EvalResult) for r in eval_results): + raise ValueError( + f"`eval_results` should be of type `EvalResult` or a list of `EvalResult`, got {type(eval_results)}." + ) + if model_name is None: + raise ValueError("Passing `eval_results` requires `model_name` to be set.") + return eval_results + + +class ModelCardData(CardData): + """Model Card Metadata that is used by Hugging Face Hub when included at the top of your README.md + + Args: + base_model (`str` or `list[str]`, *optional*): + The identifier of the base model from which the model derives. This is applicable for example if your model is a + fine-tune or adapter of an existing model. The value must be the ID of a model on the Hub (or a list of IDs + if your model derives from multiple models). Defaults to None. + datasets (`Union[str, list[str]]`, *optional*): + Dataset or list of datasets that were used to train this model. Should be a dataset ID + found on https://hf.co/datasets. Defaults to None. + eval_results (`Union[list[EvalResult], EvalResult]`, *optional*): + List of `huggingface_hub.EvalResult` that define evaluation results of the model. If provided, + `model_name` is used to as a name on PapersWithCode's leaderboards. Defaults to `None`. + language (`Union[str, list[str]]`, *optional*): + Language of model's training data or metadata. It must be an ISO 639-1, 639-2 or + 639-3 code (two/three letters), or a special value like "code", "multilingual". Defaults to `None`. + library_name (`str`, *optional*): + Name of library used by this model. Example: keras or any library from + https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/src/model-libraries.ts. + Defaults to None. + license (`str`, *optional*): + License of this model. Example: apache-2.0 or any license from + https://huggingface.co/docs/hub/repositories-licenses. Defaults to None. + license_name (`str`, *optional*): + Name of the license of this model. Defaults to None. To be used in conjunction with `license_link`. + Common licenses (Apache-2.0, MIT, CC-BY-SA-4.0) do not need a name. In that case, use `license` instead. + license_link (`str`, *optional*): + Link to the license of this model. Defaults to None. To be used in conjunction with `license_name`. + Common licenses (Apache-2.0, MIT, CC-BY-SA-4.0) do not need a link. In that case, use `license` instead. + metrics (`list[str]`, *optional*): + List of metrics used to evaluate this model. Should be a metric name that can be found + at https://hf.co/metrics. Example: 'accuracy'. Defaults to None. + model_name (`str`, *optional*): + A name for this model. It is used along with + `eval_results` to construct the `model-index` within the card's metadata. The name + you supply here is what will be used on PapersWithCode's leaderboards. If None is provided + then the repo name is used as a default. Defaults to None. + pipeline_tag (`str`, *optional*): + The pipeline tag associated with the model. Example: "text-classification". + tags (`list[str]`, *optional*): + List of tags to add to your model that can be used when filtering on the Hugging + Face Hub. Defaults to None. + ignore_metadata_errors (`str`): + If True, errors while parsing the metadata section will be ignored. Some information might be lost during + the process. Use it at your own risk. + kwargs (`dict`, *optional*): + Additional metadata that will be added to the model card. Defaults to None. + + Example: + ```python + >>> from huggingface_hub import ModelCardData + >>> card_data = ModelCardData( + ... language="en", + ... license="mit", + ... library_name="timm", + ... tags=['image-classification', 'resnet'], + ... ) + >>> card_data.to_dict() + {'language': 'en', 'license': 'mit', 'library_name': 'timm', 'tags': ['image-classification', 'resnet']} + + ``` + """ + + def __init__( + self, + *, + base_model: str | list[str] | None = None, + datasets: str | list[str] | None = None, + eval_results: list[EvalResult] | None = None, + language: str | list[str] | None = None, + library_name: str | None = None, + license: str | None = None, + license_name: str | None = None, + license_link: str | None = None, + metrics: list[str] | None = None, + model_name: str | None = None, + pipeline_tag: str | None = None, + tags: list[str] | None = None, + ignore_metadata_errors: bool = False, + **kwargs, + ): + self.base_model = base_model + self.datasets = datasets + self.eval_results = eval_results + self.language = language + self.library_name = library_name + self.license = license + self.license_name = license_name + self.license_link = license_link + self.metrics = metrics + self.model_name = model_name + self.pipeline_tag = pipeline_tag + self.tags = _to_unique_list(tags) + + model_index = kwargs.pop("model-index", None) + if model_index: + try: + model_name, eval_results = model_index_to_eval_results(model_index) + self.model_name = model_name + self.eval_results = eval_results + except (KeyError, TypeError) as error: + if ignore_metadata_errors: + logger.warning("Invalid model-index. Not loading eval results into CardData.") + else: + raise ValueError( + f"Invalid `model_index` in metadata cannot be parsed: {error.__class__} {error}. Pass" + " `ignore_metadata_errors=True` to ignore this error while loading a Model Card. Warning:" + " some information will be lost. Use it at your own risk." + ) + + super().__init__(**kwargs) + + if self.eval_results: + try: + self.eval_results = _validate_eval_results(self.eval_results, self.model_name) + except Exception as e: + if ignore_metadata_errors: + logger.warning(f"Failed to validate eval_results: {e}. Not loading eval results into CardData.") + else: + raise ValueError(f"Failed to validate eval_results: {e}") from e + + def _to_dict(self, data_dict): + """Format the internal data dict. In this case, we convert eval results to a valid model index""" + if self.eval_results is not None: + data_dict["model-index"] = eval_results_to_model_index(self.model_name, self.eval_results) # type: ignore + del data_dict["eval_results"], data_dict["model_name"] + + +class DatasetCardData(CardData): + """Dataset Card Metadata that is used by Hugging Face Hub when included at the top of your README.md + + Args: + language (`list[str]`, *optional*): + Language of dataset's data or metadata. It must be an ISO 639-1, 639-2 or + 639-3 code (two/three letters), or a special value like "code", "multilingual". + license (`Union[str, list[str]]`, *optional*): + License(s) of this dataset. Example: apache-2.0 or any license from + https://huggingface.co/docs/hub/repositories-licenses. + annotations_creators (`Union[str, list[str]]`, *optional*): + How the annotations for the dataset were created. + Options are: 'found', 'crowdsourced', 'expert-generated', 'machine-generated', 'no-annotation', 'other'. + language_creators (`Union[str, list[str]]`, *optional*): + How the text-based data in the dataset was created. + Options are: 'found', 'crowdsourced', 'expert-generated', 'machine-generated', 'other' + multilinguality (`Union[str, list[str]]`, *optional*): + Whether the dataset is multilingual. + Options are: 'monolingual', 'multilingual', 'translation', 'other'. + size_categories (`Union[str, list[str]]`, *optional*): + The number of examples in the dataset. Options are: 'n<1K', '1K1T', and 'other'. + source_datasets (`list[str]]`, *optional*): + Indicates whether the dataset is an original dataset or extended from another existing dataset. + Options are: 'original' and 'extended'. + task_categories (`Union[str, list[str]]`, *optional*): + What categories of task does the dataset support? + task_ids (`Union[str, list[str]]`, *optional*): + What specific tasks does the dataset support? + paperswithcode_id (`str`, *optional*): + ID of the dataset on PapersWithCode. + pretty_name (`str`, *optional*): + A more human-readable name for the dataset. (ex. "Cats vs. Dogs") + train_eval_index (`dict`, *optional*): + A dictionary that describes the necessary spec for doing evaluation on the Hub. + If not provided, it will be gathered from the 'train-eval-index' key of the kwargs. + config_names (`Union[str, list[str]]`, *optional*): + A list of the available dataset configs for the dataset. + """ + + def __init__( + self, + *, + language: str | list[str] | None = None, + license: str | list[str] | None = None, + annotations_creators: str | list[str] | None = None, + language_creators: str | list[str] | None = None, + multilinguality: str | list[str] | None = None, + size_categories: str | list[str] | None = None, + source_datasets: list[str] | None = None, + task_categories: str | list[str] | None = None, + task_ids: str | list[str] | None = None, + paperswithcode_id: str | None = None, + pretty_name: str | None = None, + train_eval_index: dict | None = None, + config_names: str | list[str] | None = None, + ignore_metadata_errors: bool = False, + **kwargs, + ): + self.annotations_creators = annotations_creators + self.language_creators = language_creators + self.language = language + self.license = license + self.multilinguality = multilinguality + self.size_categories = size_categories + self.source_datasets = source_datasets + self.task_categories = task_categories + self.task_ids = task_ids + self.paperswithcode_id = paperswithcode_id + self.pretty_name = pretty_name + self.config_names = config_names + + # TODO - maybe handle this similarly to EvalResult? + self.train_eval_index = train_eval_index or kwargs.pop("train-eval-index", None) + super().__init__(**kwargs) + + def _to_dict(self, data_dict): + data_dict["train-eval-index"] = data_dict.pop("train_eval_index") + + +class SpaceCardData(CardData): + """Space Card Metadata that is used by Hugging Face Hub when included at the top of your README.md + + To get an exhaustive reference of Spaces configuration, please visit https://huggingface.co/docs/hub/spaces-config-reference#spaces-configuration-reference. + + Args: + title (`str`, *optional*) + Title of the Space. + sdk (`str`, *optional*) + SDK of the Space (one of `gradio`, `streamlit`, `docker`, or `static`). + sdk_version (`str`, *optional*) + Version of the used SDK (if Gradio/Streamlit sdk). + python_version (`str`, *optional*) + Python version used in the Space (if Gradio/Streamlit sdk). + app_file (`str`, *optional*) + Path to your main application file (which contains either gradio or streamlit Python code, or static html code). + Path is relative to the root of the repository. + app_port (`str`, *optional*) + Port on which your application is running. Used only if sdk is `docker`. + license (`str`, *optional*) + License of this model. Example: apache-2.0 or any license from + https://huggingface.co/docs/hub/repositories-licenses. + duplicated_from (`str`, *optional*) + ID of the original Space if this is a duplicated Space. + models (list[`str`], *optional*) + List of models related to this Space. Should be a dataset ID found on https://hf.co/models. + datasets (`list[str]`, *optional*) + List of datasets related to this Space. Should be a dataset ID found on https://hf.co/datasets. + tags (`list[str]`, *optional*) + List of tags to add to your Space that can be used when filtering on the Hub. + ignore_metadata_errors (`str`): + If True, errors while parsing the metadata section will be ignored. Some information might be lost during + the process. Use it at your own risk. + kwargs (`dict`, *optional*): + Additional metadata that will be added to the space card. + + Example: + ```python + >>> from huggingface_hub import SpaceCardData + >>> card_data = SpaceCardData( + ... title="Dreambooth Training", + ... license="mit", + ... sdk="gradio", + ... duplicated_from="multimodalart/dreambooth-training" + ... ) + >>> card_data.to_dict() + {'title': 'Dreambooth Training', 'sdk': 'gradio', 'license': 'mit', 'duplicated_from': 'multimodalart/dreambooth-training'} + ``` + """ + + def __init__( + self, + *, + title: str | None = None, + sdk: str | None = None, + sdk_version: str | None = None, + python_version: str | None = None, + app_file: str | None = None, + app_port: int | None = None, + license: str | None = None, + duplicated_from: str | None = None, + models: list[str] | None = None, + datasets: list[str] | None = None, + tags: list[str] | None = None, + ignore_metadata_errors: bool = False, + **kwargs, + ): + self.title = title + self.sdk = sdk + self.sdk_version = sdk_version + self.python_version = python_version + self.app_file = app_file + self.app_port = app_port + self.license = license + self.duplicated_from = duplicated_from + self.models = models + self.datasets = datasets + self.tags = _to_unique_list(tags) + super().__init__(**kwargs) + + +def model_index_to_eval_results(model_index: list[dict[str, Any]]) -> tuple[str, list[EvalResult]]: + """Takes in a model index and returns the model name and a list of `huggingface_hub.EvalResult` objects. + + A detailed spec of the model index can be found here: + https://github.com/huggingface/hub-docs/blob/main/modelcard.md?plain=1 + + Args: + model_index (`list[dict[str, Any]]`): + A model index data structure, likely coming from a README.md file on the + Hugging Face Hub. + + Returns: + model_name (`str`): + The name of the model as found in the model index. This is used as the + identifier for the model on leaderboards like PapersWithCode. + eval_results (`list[EvalResult]`): + A list of `huggingface_hub.EvalResult` objects containing the metrics + reported in the provided model_index. + + Example: + ```python + >>> from huggingface_hub.repocard_data import model_index_to_eval_results + >>> # Define a minimal model index + >>> model_index = [ + ... { + ... "name": "my-cool-model", + ... "results": [ + ... { + ... "task": { + ... "type": "image-classification" + ... }, + ... "dataset": { + ... "type": "beans", + ... "name": "Beans" + ... }, + ... "metrics": [ + ... { + ... "type": "accuracy", + ... "value": 0.9 + ... } + ... ] + ... } + ... ] + ... } + ... ] + >>> model_name, eval_results = model_index_to_eval_results(model_index) + >>> model_name + 'my-cool-model' + >>> eval_results[0].task_type + 'image-classification' + >>> eval_results[0].metric_type + 'accuracy' + + ``` + """ + + eval_results = [] + for elem in model_index: + name = elem["name"] + results = elem["results"] + for result in results: + task_type = result["task"]["type"] + task_name = result["task"].get("name") + dataset_type = result["dataset"]["type"] + dataset_name = result["dataset"]["name"] + dataset_config = result["dataset"].get("config") + dataset_split = result["dataset"].get("split") + dataset_revision = result["dataset"].get("revision") + dataset_args = result["dataset"].get("args") + source_name = result.get("source", {}).get("name") + source_url = result.get("source", {}).get("url") + + for metric in result["metrics"]: + metric_type = metric["type"] + metric_value = metric["value"] + metric_name = metric.get("name") + metric_args = metric.get("args") + metric_config = metric.get("config") + verified = metric.get("verified") + verify_token = metric.get("verifyToken") + + eval_result = EvalResult( + task_type=task_type, # Required + dataset_type=dataset_type, # Required + dataset_name=dataset_name, # Required + metric_type=metric_type, # Required + metric_value=metric_value, # Required + task_name=task_name, + dataset_config=dataset_config, + dataset_split=dataset_split, + dataset_revision=dataset_revision, + dataset_args=dataset_args, + metric_name=metric_name, + metric_args=metric_args, + metric_config=metric_config, + verified=verified, + verify_token=verify_token, + source_name=source_name, + source_url=source_url, + ) + eval_results.append(eval_result) + return name, eval_results + + +def _remove_none(obj): + """ + Recursively remove `None` values from a dict. Borrowed from: https://stackoverflow.com/a/20558778 + """ + if isinstance(obj, (list, tuple, set)): + return type(obj)(_remove_none(x) for x in obj if x is not None) + elif isinstance(obj, dict): + return type(obj)((_remove_none(k), _remove_none(v)) for k, v in obj.items() if k is not None and v is not None) + else: + return obj + + +def eval_results_to_model_index(model_name: str, eval_results: list[EvalResult]) -> list[dict[str, Any]]: + """Takes in given model name and list of `huggingface_hub.EvalResult` and returns a + valid model-index that will be compatible with the format expected by the + Hugging Face Hub. + + Args: + model_name (`str`): + Name of the model (ex. "my-cool-model"). This is used as the identifier + for the model on leaderboards like PapersWithCode. + eval_results (`list[EvalResult]`): + List of `huggingface_hub.EvalResult` objects containing the metrics to be + reported in the model-index. + + Returns: + model_index (`list[dict[str, Any]]`): The eval_results converted to a model-index. + + Example: + ```python + >>> from huggingface_hub.repocard_data import eval_results_to_model_index, EvalResult + >>> # Define minimal eval_results + >>> eval_results = [ + ... EvalResult( + ... task_type="image-classification", # Required + ... dataset_type="beans", # Required + ... dataset_name="Beans", # Required + ... metric_type="accuracy", # Required + ... metric_value=0.9, # Required + ... ) + ... ] + >>> eval_results_to_model_index("my-cool-model", eval_results) + [{'name': 'my-cool-model', 'results': [{'task': {'type': 'image-classification'}, 'dataset': {'name': 'Beans', 'type': 'beans'}, 'metrics': [{'type': 'accuracy', 'value': 0.9}]}]}] + + ``` + """ + + # Metrics are reported on a unique task-and-dataset basis. + # Here, we make a map of those pairs and the associated EvalResults. + task_and_ds_types_map: dict[Any, list[EvalResult]] = defaultdict(list) + for eval_result in eval_results: + task_and_ds_types_map[eval_result.unique_identifier].append(eval_result) + + # Use the map from above to generate the model index data. + model_index_data: list[dict[str, Any]] = [] + for results in task_and_ds_types_map.values(): + # All items from `results` share same metadata + sample_result = results[0] + data: dict[str, Any] = { + "task": { + "type": sample_result.task_type, + "name": sample_result.task_name, + }, + "dataset": { + "name": sample_result.dataset_name, + "type": sample_result.dataset_type, + "config": sample_result.dataset_config, + "split": sample_result.dataset_split, + "revision": sample_result.dataset_revision, + "args": sample_result.dataset_args, + }, + "metrics": [ + { + "type": result.metric_type, + "value": result.metric_value, + "name": result.metric_name, + "config": result.metric_config, + "args": result.metric_args, + "verified": result.verified, + "verifyToken": result.verify_token, + } + for result in results + ], + } + if sample_result.source_url is not None: + source: dict[str, str] = { + "url": sample_result.source_url, + } + if sample_result.source_name is not None: + source["name"] = sample_result.source_name + data["source"] = source + model_index_data.append(data) + + # TODO - Check if there cases where this list is longer than one? + # Finally, the model index itself is list of dicts. + model_index = [ + { + "name": model_name, + "results": model_index_data, + } + ] + return _remove_none(model_index) + + +def _to_unique_list(tags: list[str] | None) -> list[str] | None: + if tags is None: + return tags + unique_tags = [] # make tags unique + keep order explicitly + for tag in tags: + if tag not in unique_tags: + unique_tags.append(tag) + return unique_tags diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/serialization/__init__.py b/.venv/lib/python3.13/site-packages/huggingface_hub/serialization/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6e624a754176079eb63540513297099025a0685c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/serialization/__init__.py @@ -0,0 +1,26 @@ +# Copyright 2024 The HuggingFace Team. All rights reserved. +# +# 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. +# ruff: noqa: F401 +"""Contains helpers to serialize tensors.""" + +from ._base import StateDictSplit, split_state_dict_into_shards_factory +from ._torch import ( + get_torch_storage_id, + get_torch_storage_size, + load_state_dict_from_file, + load_torch_model, + save_torch_model, + save_torch_state_dict, + split_torch_state_dict_into_shards, +) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/serialization/_base.py b/.venv/lib/python3.13/site-packages/huggingface_hub/serialization/_base.py new file mode 100644 index 0000000000000000000000000000000000000000..f58bcb1f4ed57706be7d62bd39729d50dc98a5c1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/serialization/_base.py @@ -0,0 +1,212 @@ +# Copyright 2024 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains helpers to split tensors into shards.""" + +from collections.abc import Callable +from dataclasses import dataclass, field +from typing import Any, TypeVar + +from .. import logging + + +TensorT = TypeVar("TensorT") +TensorSizeFn_T = Callable[[TensorT], int] +StorageIDFn_T = Callable[[TensorT], Any | None] + +MAX_SHARD_SIZE = "5GB" +SIZE_UNITS = { + "TB": 10**12, + "GB": 10**9, + "MB": 10**6, + "KB": 10**3, +} + + +logger = logging.get_logger(__file__) + + +@dataclass +class StateDictSplit: + is_sharded: bool = field(init=False) + metadata: dict[str, Any] + filename_to_tensors: dict[str, list[str]] + tensor_to_filename: dict[str, str] + + def __post_init__(self): + self.is_sharded = len(self.filename_to_tensors) > 1 + + +def split_state_dict_into_shards_factory( + state_dict: dict[str, TensorT], + *, + get_storage_size: TensorSizeFn_T, + filename_pattern: str, + get_storage_id: StorageIDFn_T = lambda tensor: None, + max_shard_size: int | str = MAX_SHARD_SIZE, +) -> StateDictSplit: + """ + Split a model state dictionary in shards so that each shard is smaller than a given size. + + The shards are determined by iterating through the `state_dict` in the order of its keys. There is no optimization + made to make each shard as close as possible to the maximum size passed. For example, if the limit is 10GB and we + have tensors of sizes [6GB, 6GB, 2GB, 6GB, 2GB, 2GB] they will get sharded as [6GB], [6+2GB], [6+2+2GB] and not + [6+2+2GB], [6+2GB], [6GB]. + + > [!WARNING] + > If one of the model's tensor is bigger than `max_shard_size`, it will end up in its own shard which will have a + > size greater than `max_shard_size`. + + Args: + state_dict (`dict[str, Tensor]`): + The state dictionary to save. + get_storage_size (`Callable[[Tensor], int]`): + A function that returns the size of a tensor when saved on disk in bytes. + get_storage_id (`Callable[[Tensor], Optional[Any]]`, *optional*): + A function that returns a unique identifier to a tensor storage. Multiple different tensors can share the + same underlying storage. This identifier is guaranteed to be unique and constant for this tensor's storage + during its lifetime. Two tensor storages with non-overlapping lifetimes may have the same id. + filename_pattern (`str`, *optional*): + The pattern to generate the files names in which the model will be saved. Pattern must be a string that + can be formatted with `filename_pattern.format(suffix=...)` and must contain the keyword `suffix` + max_shard_size (`int` or `str`, *optional*): + The maximum size of each shard, in bytes. Defaults to 5GB. + + Returns: + [`StateDictSplit`]: A `StateDictSplit` object containing the shards and the index to retrieve them. + """ + storage_id_to_tensors: dict[Any, list[str]] = {} + + shard_list: list[dict[str, TensorT]] = [] + current_shard: dict[str, TensorT] = {} + current_shard_size = 0 + total_size = 0 + + if isinstance(max_shard_size, str): + max_shard_size = parse_size_to_int(max_shard_size) + + for key, tensor in state_dict.items(): + # when bnb serialization is used the weights in the state dict can be strings + # check: https://github.com/huggingface/transformers/pull/24416 for more details + if isinstance(tensor, str): + logger.info("Skipping tensor %s as it is a string (bnb serialization)", key) + continue + + # If a `tensor` shares the same underlying storage as another tensor, we put `tensor` in the same `block` + storage_id = get_storage_id(tensor) # type: ignore[invalid-argument-type] + if storage_id is not None: + if storage_id in storage_id_to_tensors: + # We skip this tensor for now and will reassign to correct shard later + storage_id_to_tensors[storage_id].append(key) + continue + else: + # This is the first tensor with this storage_id, we create a new entry + # in the storage_id_to_tensors dict => we will assign the shard id later + storage_id_to_tensors[storage_id] = [key] + + # Compute tensor size + tensor_size = get_storage_size(tensor) # type: ignore[invalid-argument-type] + + # If this tensor is bigger than the maximal size, we put it in its own shard + if tensor_size > max_shard_size: + total_size += tensor_size + shard_list.append({key: tensor}) + continue + + # If this tensor is going to tip up over the maximal size, we split. + # Current shard already has some tensors, we add it to the list of shards and create a new one. + if current_shard_size + tensor_size > max_shard_size: + shard_list.append(current_shard) + current_shard = {} + current_shard_size = 0 + + # Add the tensor to the current shard + current_shard[key] = tensor + current_shard_size += tensor_size + total_size += tensor_size + + # Add the last shard + if len(current_shard) > 0: + shard_list.append(current_shard) + nb_shards = len(shard_list) + + # Loop over the tensors that share the same storage and assign them together + for storage_id, keys in storage_id_to_tensors.items(): + # Let's try to find the shard where the first tensor of this storage is and put all tensors in the same shard + for shard in shard_list: + if keys[0] in shard: + for key in keys: + shard[key] = state_dict[key] + break + + # If we only have one shard, we return it => no need to build the index + if nb_shards == 1: + filename = filename_pattern.format(suffix="") + # Use the keys from the shard itself rather than `state_dict` directly, so that tensors + # skipped above (e.g. string tensors from bnb serialization) are excluded from the index, + # consistently with the multi-shard path below. + keys = list(shard_list[0].keys()) + return StateDictSplit( + metadata={"total_size": total_size}, + filename_to_tensors={filename: keys}, + tensor_to_filename={key: filename for key in keys}, + ) + + # Now that each tensor is assigned to a shard, let's assign a filename to each shard + tensor_name_to_filename = {} + filename_to_tensors = {} + for idx, shard in enumerate(shard_list): + filename = filename_pattern.format(suffix=f"-{idx + 1:05d}-of-{nb_shards:05d}") + for key in shard: + tensor_name_to_filename[key] = filename + filename_to_tensors[filename] = list(shard.keys()) + + # Build the index and return + return StateDictSplit( + metadata={"total_size": total_size}, + filename_to_tensors=filename_to_tensors, + tensor_to_filename=tensor_name_to_filename, + ) + + +def parse_size_to_int(size_as_str: str) -> int: + """ + Parse a size expressed as a string with digits and unit (like `"5MB"`) to an integer (in bytes). + + Supported units are "TB", "GB", "MB", "KB". + + Args: + size_as_str (`str`): The size to convert. Will be directly returned if an `int`. + + Example: + + ```py + >>> parse_size_to_int("5MB") + 5000000 + ``` + """ + size_as_str = size_as_str.strip() + + # Parse unit + unit = size_as_str[-2:].upper() + if unit not in SIZE_UNITS: + raise ValueError(f"Unit '{unit}' not supported. Supported units are TB, GB, MB, KB. Got '{size_as_str}'.") + multiplier = SIZE_UNITS[unit] + + # Parse value + try: + value = float(size_as_str[:-2].strip()) + except ValueError as e: + raise ValueError(f"Could not parse the size value from '{size_as_str}': {e}") from e + + return int(value * multiplier) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/serialization/_dduf.py b/.venv/lib/python3.13/site-packages/huggingface_hub/serialization/_dduf.py new file mode 100644 index 0000000000000000000000000000000000000000..37e916d419d5a5934525bcb169fd5dae48d6389d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/serialization/_dduf.py @@ -0,0 +1,386 @@ +import json +import logging +import mmap +import os +import shutil +import zipfile +from collections.abc import Generator, Iterable +from contextlib import contextmanager +from dataclasses import dataclass, field +from pathlib import Path +from typing import Any + +from ..errors import DDUFCorruptedFileError, DDUFExportError, DDUFInvalidEntryNameError + + +logger = logging.getLogger(__name__) + +DDUF_ALLOWED_ENTRIES = { + # Allowed file extensions in a DDUF file + ".json", + ".model", + ".safetensors", + ".txt", +} + +DDUF_FOLDER_REQUIRED_ENTRIES = { + # Each folder must contain at least one of these entries + "config.json", + "tokenizer_config.json", + "preprocessor_config.json", + "scheduler_config.json", +} + + +@dataclass +class DDUFEntry: + """Object representing a file entry in a DDUF file. + + See [`read_dduf_file`] for how to read a DDUF file. + + Attributes: + filename (str): + The name of the file in the DDUF archive. + offset (int): + The offset of the file in the DDUF archive. + length (int): + The length of the file in the DDUF archive. + dduf_path (str): + The path to the DDUF archive (for internal use). + """ + + filename: str + length: int + offset: int + + dduf_path: Path = field(repr=False) + + @contextmanager + def as_mmap(self) -> Generator[bytes, None, None]: + """Open the file as a memory-mapped file. + + Useful to load safetensors directly from the file. + + Example: + ```py + >>> import safetensors.torch + >>> with entry.as_mmap() as mm: + ... tensors = safetensors.torch.load(mm) + ``` + """ + with self.dduf_path.open("rb") as f: + with mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_READ) as mm: + yield mm[self.offset : self.offset + self.length] + + def read_text(self, encoding: str = "utf-8") -> str: + """Read the file as text. + + Useful for '.txt' and '.json' entries. + + Example: + ```py + >>> import json + >>> index = json.loads(entry.read_text()) + ``` + """ + with self.dduf_path.open("rb") as f: + f.seek(self.offset) + return f.read(self.length).decode(encoding=encoding) + + +def read_dduf_file(dduf_path: os.PathLike | str) -> dict[str, DDUFEntry]: + """ + Read a DDUF file and return a dictionary of entries. + + Only the metadata is read, the data is not loaded in memory. + + Args: + dduf_path (`str` or `os.PathLike`): + The path to the DDUF file to read. + + Returns: + `dict[str, DDUFEntry]`: + A dictionary of [`DDUFEntry`] indexed by filename. + + Raises: + - [`DDUFCorruptedFileError`]: If the DDUF file is corrupted (i.e. doesn't follow the DDUF format). + + Example: + ```python + >>> import json + >>> import safetensors.torch + >>> from huggingface_hub import read_dduf_file + + # Read DDUF metadata + >>> dduf_entries = read_dduf_file("FLUX.1-dev.dduf") + + # Returns a mapping filename <> DDUFEntry + >>> dduf_entries["model_index.json"] + DDUFEntry(filename='model_index.json', offset=66, length=587) + + # Load model index as JSON + >>> json.loads(dduf_entries["model_index.json"].read_text()) + {'_class_name': 'FluxPipeline', '_diffusers_version': '0.32.0.dev0', '_name_or_path': 'black-forest-labs/FLUX.1-dev', ... + + # Load VAE weights using safetensors + >>> with dduf_entries["vae/diffusion_pytorch_model.safetensors"].as_mmap() as mm: + ... state_dict = safetensors.torch.load(mm) + ``` + """ + entries = {} + dduf_path = Path(dduf_path) + logger.info(f"Reading DDUF file {dduf_path}") + with zipfile.ZipFile(str(dduf_path), "r") as zf: + for info in zf.infolist(): + logger.debug(f"Reading entry {info.filename}") + if info.compress_type != zipfile.ZIP_STORED: + raise DDUFCorruptedFileError("Data must not be compressed in DDUF file.") + + try: + _validate_dduf_entry_name(info.filename) + except DDUFInvalidEntryNameError as e: + raise DDUFCorruptedFileError(f"Invalid entry name in DDUF file: {info.filename}") from e + + offset = _get_data_offset(zf, info) + + entries[info.filename] = DDUFEntry( + filename=info.filename, offset=offset, length=info.file_size, dduf_path=dduf_path + ) + + # Consistency checks on the DDUF file + if "model_index.json" not in entries: + raise DDUFCorruptedFileError("Missing required 'model_index.json' entry in DDUF file.") + index = json.loads(entries["model_index.json"].read_text()) + _validate_dduf_structure(index, entries.keys()) + + logger.info(f"Done reading DDUF file {dduf_path}. Found {len(entries)} entries") + return entries + + +def export_entries_as_dduf(dduf_path: str | os.PathLike, entries: Iterable[tuple[str, str | Path | bytes]]) -> None: + """Write a DDUF file from an iterable of entries. + + This is a lower-level helper than [`export_folder_as_dduf`] that allows more flexibility when serializing data. + In particular, you don't need to save the data on disk before exporting it in the DDUF file. + + Args: + dduf_path (`str` or `os.PathLike`): + The path to the DDUF file to write. + entries (`Iterable[tuple[str, Union[str, Path, bytes]]]`): + An iterable of entries to write in the DDUF file. Each entry is a tuple with the filename and the content. + The filename should be the path to the file in the DDUF archive. + The content can be a string or a pathlib.Path representing a path to a file on the local disk or directly the content as bytes. + + Raises: + - [`DDUFExportError`]: If anything goes wrong during the export (e.g. invalid entry name, missing 'model_index.json', etc.). + + Example: + ```python + # Export specific files from the local disk. + >>> from huggingface_hub import export_entries_as_dduf + >>> export_entries_as_dduf( + ... dduf_path="stable-diffusion-v1-4-FP16.dduf", + ... entries=[ # List entries to add to the DDUF file (here, only FP16 weights) + ... ("model_index.json", "path/to/model_index.json"), + ... ("vae/config.json", "path/to/vae/config.json"), + ... ("vae/diffusion_pytorch_model.fp16.safetensors", "path/to/vae/diffusion_pytorch_model.fp16.safetensors"), + ... ("text_encoder/config.json", "path/to/text_encoder/config.json"), + ... ("text_encoder/model.fp16.safetensors", "path/to/text_encoder/model.fp16.safetensors"), + ... # ... add more entries here + ... ] + ... ) + ``` + + ```python + # Export state_dicts one by one from a loaded pipeline + >>> from diffusers import DiffusionPipeline + >>> from typing import Generator, Tuple + >>> import safetensors.torch + >>> from huggingface_hub import export_entries_as_dduf + >>> pipe = DiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4") + ... # ... do some work with the pipeline + + >>> def as_entries(pipe: DiffusionPipeline) -> Generator[tuple[str, bytes], None, None]: + ... # Build a generator that yields the entries to add to the DDUF file. + ... # The first element of the tuple is the filename in the DDUF archive (must use UNIX separator!). The second element is the content of the file. + ... # Entries will be evaluated lazily when the DDUF file is created (only 1 entry is loaded in memory at a time) + ... yield "vae/config.json", pipe.vae.to_json_string().encode() + ... yield "vae/diffusion_pytorch_model.safetensors", safetensors.torch.save(pipe.vae.state_dict()) + ... yield "text_encoder/config.json", pipe.text_encoder.config.to_json_string().encode() + ... yield "text_encoder/model.safetensors", safetensors.torch.save(pipe.text_encoder.state_dict()) + ... # ... add more entries here + + >>> export_entries_as_dduf(dduf_path="stable-diffusion-v1-4.dduf", entries=as_entries(pipe)) + ``` + """ + logger.info(f"Exporting DDUF file '{dduf_path}'") + filenames = set() + index = None + with zipfile.ZipFile(str(dduf_path), "w", zipfile.ZIP_STORED) as archive: + for filename, content in entries: + if filename in filenames: + raise DDUFExportError(f"Can't add duplicate entry: {filename}") + filenames.add(filename) + + if filename == "model_index.json": + try: + index = json.loads(_load_content(content).decode()) + except json.JSONDecodeError as e: + raise DDUFExportError("Failed to parse 'model_index.json'.") from e + + try: + filename = _validate_dduf_entry_name(filename) + except DDUFInvalidEntryNameError as e: + raise DDUFExportError(f"Invalid entry name: {filename}") from e + logger.debug(f"Adding entry '{filename}' to DDUF file") + _dump_content_in_archive(archive, filename, content) + + # Consistency checks on the DDUF file + if index is None: + raise DDUFExportError("Missing required 'model_index.json' entry in DDUF file.") + try: + _validate_dduf_structure(index, filenames) + except DDUFCorruptedFileError as e: + raise DDUFExportError("Invalid DDUF file structure.") from e + + logger.info(f"Done writing DDUF file {dduf_path}") + + +def export_folder_as_dduf(dduf_path: str | os.PathLike, folder_path: str | os.PathLike) -> None: + """ + Export a folder as a DDUF file. + + AUses [`export_entries_as_dduf`] under the hood. + + Args: + dduf_path (`str` or `os.PathLike`): + The path to the DDUF file to write. + folder_path (`str` or `os.PathLike`): + The path to the folder containing the diffusion model. + + Example: + ```python + >>> from huggingface_hub import export_folder_as_dduf + >>> export_folder_as_dduf(dduf_path="FLUX.1-dev.dduf", folder_path="path/to/FLUX.1-dev") + ``` + """ + folder_path = Path(folder_path) + + def _iterate_over_folder() -> Iterable[tuple[str, Path]]: + for path in Path(folder_path).glob("**/*"): + if not path.is_file(): + continue + if path.suffix not in DDUF_ALLOWED_ENTRIES: + logger.debug(f"Skipping file '{path}' (file type not allowed)") + continue + path_in_archive = path.relative_to(folder_path) + if len(path_in_archive.parts) >= 3: + logger.debug(f"Skipping file '{path}' (nested directories not allowed)") + continue + yield path_in_archive.as_posix(), path + + export_entries_as_dduf(dduf_path, _iterate_over_folder()) + + +def _dump_content_in_archive(archive: zipfile.ZipFile, filename: str, content: str | os.PathLike | bytes) -> None: + with archive.open(filename, "w", force_zip64=True) as archive_fh: + if isinstance(content, (str, Path)): + content_path = Path(content) + with content_path.open("rb") as content_fh: + shutil.copyfileobj(content_fh, archive_fh, 1024 * 1024 * 8) # type: ignore[misc] + elif isinstance(content, bytes): + archive_fh.write(content) + else: + raise DDUFExportError(f"Invalid content type for {filename}. Must be str, Path or bytes.") + + +def _load_content(content: str | Path | bytes) -> bytes: + """Load the content of an entry as bytes. + + Used only for small checks (not to dump content into archive). + """ + if isinstance(content, (str, Path)): + return Path(content).read_bytes() + elif isinstance(content, bytes): + return content + else: + raise DDUFExportError(f"Invalid content type. Must be str, Path or bytes. Got {type(content)}.") + + +def _validate_dduf_entry_name(entry_name: str) -> str: + if "." + entry_name.split(".")[-1] not in DDUF_ALLOWED_ENTRIES: + raise DDUFInvalidEntryNameError(f"File type not allowed: {entry_name}") + if "\\" in entry_name: + raise DDUFInvalidEntryNameError(f"Entry names must use UNIX separators ('/'). Got {entry_name}.") + entry_name = entry_name.strip("/") + if entry_name.count("/") > 1: + raise DDUFInvalidEntryNameError(f"DDUF only supports 1 level of directory. Got {entry_name}.") + return entry_name + + +def _validate_dduf_structure(index: Any, entry_names: Iterable[str]) -> None: + """ + Consistency checks on the DDUF file structure. + + Rules: + - The 'model_index.json' entry is required and must contain a dictionary. + - Each folder name must correspond to an entry in 'model_index.json'. + - Each folder must contain at least a config file ('config.json', 'tokenizer_config.json', 'preprocessor_config.json', 'scheduler_config.json'). + + Args: + index (Any): + The content of the 'model_index.json' entry. + entry_names (Iterable[str]): + The list of entry names in the DDUF file. + + Raises: + - [`DDUFCorruptedFileError`]: If the DDUF file is corrupted (i.e. doesn't follow the DDUF format). + """ + if not isinstance(index, dict): + raise DDUFCorruptedFileError(f"Invalid 'model_index.json' content. Must be a dictionary. Got {type(index)}.") + + dduf_folders = {entry.split("/")[0] for entry in entry_names if "/" in entry} + for folder in dduf_folders: + if folder not in index: + raise DDUFCorruptedFileError(f"Missing required entry '{folder}' in 'model_index.json'.") + if not any(f"{folder}/{required_entry}" in entry_names for required_entry in DDUF_FOLDER_REQUIRED_ENTRIES): + raise DDUFCorruptedFileError( + f"Missing required file in folder '{folder}'. Must contains at least one of {DDUF_FOLDER_REQUIRED_ENTRIES}." + ) + + +def _get_data_offset(zf: zipfile.ZipFile, info: zipfile.ZipInfo) -> int: + """ + Calculate the data offset for a file in a ZIP archive. + + Args: + zf (`zipfile.ZipFile`): + The opened ZIP file. Must be opened in read mode. + info (`zipfile.ZipInfo`): + The file info. + + Returns: + int: The offset of the file data in the ZIP archive. + """ + if zf.fp is None: + raise DDUFCorruptedFileError("ZipFile object must be opened in read mode.") + + # Step 1: Get the local file header offset + header_offset = info.header_offset + + # Step 2: Read the local file header + zf.fp.seek(header_offset) + local_file_header = zf.fp.read(30) # Fixed-size part of the local header + + if len(local_file_header) < 30: + raise DDUFCorruptedFileError("Incomplete local file header.") + + # Step 3: Parse the header fields to calculate the start of file data + # Local file header: https://en.wikipedia.org/wiki/ZIP_(file_format)#File_headers + filename_len = int.from_bytes(local_file_header[26:28], "little") + extra_field_len = int.from_bytes(local_file_header[28:30], "little") + + # Data offset is after the fixed header, filename, and extra fields + data_offset = header_offset + 30 + filename_len + extra_field_len + + return data_offset diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/serialization/_torch.py b/.venv/lib/python3.13/site-packages/huggingface_hub/serialization/_torch.py new file mode 100644 index 0000000000000000000000000000000000000000..19516aa7feea7c206391dd3b9deecf6157b7e455 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/serialization/_torch.py @@ -0,0 +1,1046 @@ +# Copyright 2024 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains pytorch-specific helpers.""" + +import importlib +import importlib.util +import json +import os +import re +from collections import defaultdict, namedtuple +from collections.abc import Iterable +from functools import lru_cache +from pathlib import Path, PureWindowsPath +from typing import TYPE_CHECKING, Any, NamedTuple, Union + +from packaging import version + +from .. import constants, logging +from ._base import MAX_SHARD_SIZE, StateDictSplit, split_state_dict_into_shards_factory + + +logger = logging.get_logger(__file__) + +if TYPE_CHECKING: + import torch + +# SAVING + + +def save_torch_model( + model: "torch.nn.Module", + save_directory: str | Path, + *, + filename_pattern: str | None = None, + force_contiguous: bool = True, + max_shard_size: int | str = MAX_SHARD_SIZE, + metadata: dict[str, str] | None = None, + safe_serialization: bool = True, + is_main_process: bool = True, + shared_tensors_to_discard: list[str] | None = None, +): + """ + Saves a given torch model to disk, handling sharding and shared tensors issues. + + See also [`save_torch_state_dict`] to save a state dict with more flexibility. + + For more information about tensor sharing, check out [this guide](https://huggingface.co/docs/safetensors/torch_shared_tensors). + + The model state dictionary is split into shards so that each shard is smaller than a given size. The shards are + saved in the `save_directory` with the given `filename_pattern`. If the model is too big to fit in a single shard, + an index file is saved in the `save_directory` to indicate where each tensor is saved. This helper uses + [`split_torch_state_dict_into_shards`] under the hood. If `safe_serialization` is `True`, the shards are saved as + safetensors (the default). Otherwise, the shards are saved as pickle. + + Before saving the model, the `save_directory` is cleaned from any previous shard files. + + > [!WARNING] + > If one of the model's tensor is bigger than `max_shard_size`, it will end up in its own shard which will have a + > size greater than `max_shard_size`. + + > [!WARNING] + > If your model is a `transformers.PreTrainedModel`, you should pass `model._tied_weights_keys` as `shared_tensors_to_discard` to properly handle shared tensors saving. This ensures the correct duplicate tensors are discarded during saving. + + Args: + model (`torch.nn.Module`): + The model to save on disk. + save_directory (`str` or `Path`): + The directory in which the model will be saved. + filename_pattern (`str`, *optional*): + The pattern to generate the files names in which the model will be saved. Pattern must be a string that + can be formatted with `filename_pattern.format(suffix=...)` and must contain the keyword `suffix` + Defaults to `"model{suffix}.safetensors"` or `pytorch_model{suffix}.bin` depending on `safe_serialization` + parameter. + force_contiguous (`boolean`, *optional*): + Forcing the state_dict to be saved as contiguous tensors. This has no effect on the correctness of the + model, but it could potentially change performance if the layout of the tensor was chosen specifically for + that reason. Defaults to `True`. + max_shard_size (`int` or `str`, *optional*): + The maximum size of each shard, in bytes. Defaults to 5GB. + metadata (`dict[str, str]`, *optional*): + Extra information to save along with the model. Some metadata will be added for each dropped tensors. + This information will not be enough to recover the entire shared structure but might help understanding + things. + safe_serialization (`bool`, *optional*): + Whether to save as safetensors, which is the default behavior. If `False`, the shards are saved as pickle. + Safe serialization is recommended for security reasons. Saving as pickle is deprecated and will be removed + in a future version. + is_main_process (`bool`, *optional*): + Whether the process calling this is the main process or not. Useful when in distributed training like + TPUs and need to call this function from all processes. In this case, set `is_main_process=True` only on + the main process to avoid race conditions. Defaults to True. + shared_tensors_to_discard (`list[str]`, *optional*): + List of tensor names to drop when saving shared tensors. If not provided and shared tensors are + detected, it will drop the first name alphabetically. + + Example: + + ```py + >>> from huggingface_hub import save_torch_model + >>> model = ... # A PyTorch model + + # Save state dict to "path/to/folder". The model will be split into shards of 5GB each and saved as safetensors. + >>> save_torch_model(model, "path/to/folder") + + # Load model back + >>> from huggingface_hub import load_torch_model # TODO + >>> load_torch_model(model, "path/to/folder") + >>> + ``` + """ + save_torch_state_dict( + state_dict=model.state_dict(), + filename_pattern=filename_pattern, + force_contiguous=force_contiguous, + max_shard_size=max_shard_size, + metadata=metadata, + safe_serialization=safe_serialization, + save_directory=save_directory, + is_main_process=is_main_process, + shared_tensors_to_discard=shared_tensors_to_discard, + ) + + +def save_torch_state_dict( + state_dict: dict[str, "torch.Tensor"], + save_directory: str | Path, + *, + filename_pattern: str | None = None, + force_contiguous: bool = True, + max_shard_size: int | str = MAX_SHARD_SIZE, + metadata: dict[str, str] | None = None, + safe_serialization: bool = True, + is_main_process: bool = True, + shared_tensors_to_discard: list[str] | None = None, +) -> None: + """ + Save a model state dictionary to the disk, handling sharding and shared tensors issues. + + See also [`save_torch_model`] to directly save a PyTorch model. + + For more information about tensor sharing, check out [this guide](https://huggingface.co/docs/safetensors/torch_shared_tensors). + + The model state dictionary is split into shards so that each shard is smaller than a given size. The shards are + saved in the `save_directory` with the given `filename_pattern`. If the model is too big to fit in a single shard, + an index file is saved in the `save_directory` to indicate where each tensor is saved. This helper uses + [`split_torch_state_dict_into_shards`] under the hood. If `safe_serialization` is `True`, the shards are saved as + safetensors (the default). Otherwise, the shards are saved as pickle. + + Before saving the model, the `save_directory` is cleaned from any previous shard files. + + > [!WARNING] + > If one of the model's tensor is bigger than `max_shard_size`, it will end up in its own shard which will have a + > size greater than `max_shard_size`. + + > [!WARNING] + > If your model is a `transformers.PreTrainedModel`, you should pass `model._tied_weights_keys` as `shared_tensors_to_discard` to properly handle shared tensors saving. This ensures the correct duplicate tensors are discarded during saving. + + Args: + state_dict (`dict[str, torch.Tensor]`): + The state dictionary to save. + save_directory (`str` or `Path`): + The directory in which the model will be saved. + filename_pattern (`str`, *optional*): + The pattern to generate the files names in which the model will be saved. Pattern must be a string that + can be formatted with `filename_pattern.format(suffix=...)` and must contain the keyword `suffix` + Defaults to `"model{suffix}.safetensors"` or `pytorch_model{suffix}.bin` depending on `safe_serialization` + parameter. + force_contiguous (`boolean`, *optional*): + Forcing the state_dict to be saved as contiguous tensors. This has no effect on the correctness of the + model, but it could potentially change performance if the layout of the tensor was chosen specifically for + that reason. Defaults to `True`. + max_shard_size (`int` or `str`, *optional*): + The maximum size of each shard, in bytes. Defaults to 5GB. + metadata (`dict[str, str]`, *optional*): + Extra information to save along with the model. Some metadata will be added for each dropped tensors. + This information will not be enough to recover the entire shared structure but might help understanding + things. + safe_serialization (`bool`, *optional*): + Whether to save as safetensors, which is the default behavior. If `False`, the shards are saved as pickle. + Safe serialization is recommended for security reasons. Saving as pickle is deprecated and will be removed + in a future version. + is_main_process (`bool`, *optional*): + Whether the process calling this is the main process or not. Useful when in distributed training like + TPUs and need to call this function from all processes. In this case, set `is_main_process=True` only on + the main process to avoid race conditions. Defaults to True. + shared_tensors_to_discard (`list[str]`, *optional*): + List of tensor names to drop when saving shared tensors. If not provided and shared tensors are + detected, it will drop the first name alphabetically. + + Example: + + ```py + >>> from huggingface_hub import save_torch_state_dict + >>> model = ... # A PyTorch model + + # Save state dict to "path/to/folder". The model will be split into shards of 5GB each and saved as safetensors. + >>> state_dict = model_to_save.state_dict() + >>> save_torch_state_dict(state_dict, "path/to/folder") + ``` + """ + save_directory = str(save_directory) + + if filename_pattern is None: + filename_pattern = ( + constants.SAFETENSORS_WEIGHTS_FILE_PATTERN + if safe_serialization + else constants.PYTORCH_WEIGHTS_FILE_PATTERN + ) + + if metadata is None: + metadata = {} + if safe_serialization: + try: + from safetensors.torch import save_file as save_file_fn + except ImportError as e: + raise ImportError( + "Please install `safetensors` to use safe serialization. " + "You can install it with `pip install safetensors`." + ) from e + # Clean state dict for safetensors + state_dict = _clean_state_dict_for_safetensors( + state_dict, + metadata, + force_contiguous=force_contiguous, + shared_tensors_to_discard=shared_tensors_to_discard, + ) + else: + from torch import save as save_file_fn # type: ignore[assignment, no-redef] + + logger.warning( + "You are using unsafe serialization. Due to security reasons, it is recommended not to load " + "pickled models from untrusted sources. If you intend to share your model, we strongly recommend " + "using safe serialization by installing `safetensors` with `pip install safetensors`." + ) + # Split dict + state_dict_split = split_torch_state_dict_into_shards( + state_dict, filename_pattern=filename_pattern, max_shard_size=max_shard_size + ) + + # Only main process should clean up existing files to avoid race conditions in distributed environment + if is_main_process: + existing_files_regex = re.compile(filename_pattern.format(suffix=r"(-\d{5}-of-\d{5})?") + r"(\.index\.json)?") + for filename in os.listdir(save_directory): + if existing_files_regex.match(filename): + try: + logger.debug(f"Removing existing file '{filename}' from folder.") + os.remove(os.path.join(save_directory, filename)) + except Exception as e: + logger.warning( + f"Error when trying to remove existing '{filename}' from folder: {e}. Continuing..." + ) + + # Save each shard + per_file_metadata = {"format": "pt"} + if not state_dict_split.is_sharded: + per_file_metadata.update(metadata) + safe_file_kwargs = {"metadata": per_file_metadata} if safe_serialization else {} + for filename, tensors in state_dict_split.filename_to_tensors.items(): + shard = {tensor: state_dict[tensor] for tensor in tensors} + save_file_fn(shard, os.path.join(save_directory, filename), **safe_file_kwargs) # ty: ignore[invalid-argument-type] + logger.debug(f"Shard saved to {filename}") + + # Save the index (if any) + if state_dict_split.is_sharded: + index_path = filename_pattern.format(suffix="") + ".index.json" + index = { + "metadata": {**state_dict_split.metadata, **metadata}, + "weight_map": state_dict_split.tensor_to_filename, + } + with open(os.path.join(save_directory, index_path), "w") as f: + json.dump(index, f, indent=2) + logger.info( + f"The model is bigger than the maximum size per checkpoint ({max_shard_size}). " + f"Model weighs have been saved in {len(state_dict_split.filename_to_tensors)} checkpoint shards. " + f"You can find where each parameters has been saved in the index located at {index_path}." + ) + + logger.info(f"Model weights successfully saved to {save_directory}!") + + +def split_torch_state_dict_into_shards( + state_dict: dict[str, "torch.Tensor"], + *, + filename_pattern: str = constants.SAFETENSORS_WEIGHTS_FILE_PATTERN, + max_shard_size: int | str = MAX_SHARD_SIZE, +) -> StateDictSplit: + """ + Split a model state dictionary in shards so that each shard is smaller than a given size. + + The shards are determined by iterating through the `state_dict` in the order of its keys. There is no optimization + made to make each shard as close as possible to the maximum size passed. For example, if the limit is 10GB and we + have tensors of sizes [6GB, 6GB, 2GB, 6GB, 2GB, 2GB] they will get sharded as [6GB], [6+2GB], [6+2+2GB] and not + [6+2+2GB], [6+2GB], [6GB]. + + + > [!TIP] + > To save a model state dictionary to the disk, see [`save_torch_state_dict`]. This helper uses + > `split_torch_state_dict_into_shards` under the hood. + + > [!WARNING] + > If one of the model's tensor is bigger than `max_shard_size`, it will end up in its own shard which will have a + > size greater than `max_shard_size`. + + Args: + state_dict (`dict[str, torch.Tensor]`): + The state dictionary to save. + filename_pattern (`str`, *optional*): + The pattern to generate the files names in which the model will be saved. Pattern must be a string that + can be formatted with `filename_pattern.format(suffix=...)` and must contain the keyword `suffix` + Defaults to `"model{suffix}.safetensors"`. + max_shard_size (`int` or `str`, *optional*): + The maximum size of each shard, in bytes. Defaults to 5GB. + + Returns: + [`StateDictSplit`]: A `StateDictSplit` object containing the shards and the index to retrieve them. + + Example: + ```py + >>> import json + >>> import os + >>> from safetensors.torch import save_file as safe_save_file + >>> from huggingface_hub import split_torch_state_dict_into_shards + + >>> def save_state_dict(state_dict: dict[str, torch.Tensor], save_directory: str): + ... state_dict_split = split_torch_state_dict_into_shards(state_dict) + ... for filename, tensors in state_dict_split.filename_to_tensors.items(): + ... shard = {tensor: state_dict[tensor] for tensor in tensors} + ... safe_save_file( + ... shard, + ... os.path.join(save_directory, filename), + ... metadata={"format": "pt"}, + ... ) + ... if state_dict_split.is_sharded: + ... index = { + ... "metadata": state_dict_split.metadata, + ... "weight_map": state_dict_split.tensor_to_filename, + ... } + ... with open(os.path.join(save_directory, "model.safetensors.index.json"), "w") as f: + ... f.write(json.dumps(index, indent=2)) + ``` + """ + return split_state_dict_into_shards_factory( + state_dict, + max_shard_size=max_shard_size, + filename_pattern=filename_pattern, + get_storage_size=get_torch_storage_size, + get_storage_id=get_torch_storage_id, + ) + + +# LOADING + + +def load_torch_model( + model: "torch.nn.Module", + checkpoint_path: str | os.PathLike, + *, + strict: bool = False, + safe: bool = True, + weights_only: bool = False, + map_location: Union[str, "torch.device"] | None = None, + mmap: bool = False, + filename_pattern: str | None = None, +) -> NamedTuple: + """ + Load a checkpoint into a model, handling both sharded and non-sharded checkpoints. + + Args: + model (`torch.nn.Module`): + The model in which to load the checkpoint. + checkpoint_path (`str` or `os.PathLike`): + Path to either the checkpoint file or directory containing the checkpoint(s). + strict (`bool`, *optional*, defaults to `False`): + Whether to strictly enforce that the keys in the model state dict match the keys in the checkpoint. + safe (`bool`, *optional*, defaults to `True`): + If `safe` is True, the safetensors files will be loaded. If `safe` is False, the function + will first attempt to load safetensors files if they are available, otherwise it will fall back to loading + pickle files. `filename_pattern` parameter takes precedence over `safe` parameter. + weights_only (`bool`, *optional*, defaults to `False`): + If True, only loads the model weights without optimizer states and other metadata. + Only supported in PyTorch >= 1.13. + map_location (`str` or `torch.device`, *optional*): + A `torch.device` object, string or a dict specifying how to remap storage locations. It + indicates the location where all tensors should be loaded. + mmap (`bool`, *optional*, defaults to `False`): + Whether to use memory-mapped file loading. Memory mapping can improve loading performance + for large models in PyTorch >= 2.1.0 with zipfile-based checkpoints. + filename_pattern (`str`, *optional*): + The pattern to look for the index file. Pattern must be a string that + can be formatted with `filename_pattern.format(suffix=...)` and must contain the keyword `suffix` + Defaults to `"model{suffix}.safetensors"`. + Returns: + `NamedTuple`: A named tuple with `missing_keys` and `unexpected_keys` fields. + - `missing_keys` is a list of str containing the missing keys, i.e. keys that are in the model but not in the checkpoint. + - `unexpected_keys` is a list of str containing the unexpected keys, i.e. keys that are in the checkpoint but not in the model. + + Raises: + [`FileNotFoundError`](https://docs.python.org/3/library/exceptions.html#FileNotFoundError) + If the checkpoint file or directory does not exist. + [`ImportError`](https://docs.python.org/3/library/exceptions.html#ImportError) + If safetensors or torch is not installed when trying to load a .safetensors file or a PyTorch checkpoint respectively. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If the checkpoint path is invalid or if the checkpoint format cannot be determined. + + Example: + ```python + >>> from huggingface_hub import load_torch_model + >>> model = ... # A PyTorch model + >>> load_torch_model(model, "path/to/checkpoint") + ``` + """ + checkpoint_path = Path(checkpoint_path) + + if not checkpoint_path.exists(): + raise ValueError(f"Checkpoint path {checkpoint_path} does not exist") + # 1. Check if checkpoint is a single file + if checkpoint_path.is_file(): + state_dict = load_state_dict_from_file( + checkpoint_file=checkpoint_path, + map_location=map_location, + weights_only=weights_only, + ) + return model.load_state_dict(state_dict, strict=strict) + + # 2. If not, checkpoint_path is a directory + if filename_pattern is None: + filename_pattern = constants.SAFETENSORS_WEIGHTS_FILE_PATTERN + index_path = checkpoint_path / (filename_pattern.format(suffix="") + ".index.json") + # Only fallback to pickle format if safetensors index is not found and safe is False. + if not index_path.is_file() and not safe: + filename_pattern = constants.PYTORCH_WEIGHTS_FILE_PATTERN + + index_path = checkpoint_path / (filename_pattern.format(suffix="") + ".index.json") + + if index_path.is_file(): + return _load_sharded_checkpoint( + model=model, + save_directory=checkpoint_path, + strict=strict, + weights_only=weights_only, + filename_pattern=filename_pattern, + ) + + # Look for single model file + model_files = list(checkpoint_path.glob("*.safetensors" if safe else "*.bin")) + if len(model_files) == 1: + state_dict = load_state_dict_from_file( + checkpoint_file=model_files[0], + map_location=map_location, + weights_only=weights_only, + mmap=mmap, + ) + return model.load_state_dict(state_dict, strict=strict) + + raise ValueError( + f"Directory '{checkpoint_path}' does not contain a valid checkpoint. " + "Expected either a sharded checkpoint with an index file, or a single model file." + ) + + +def _load_sharded_checkpoint( + model: "torch.nn.Module", + save_directory: os.PathLike, + *, + strict: bool = False, + weights_only: bool = False, + filename_pattern: str = constants.SAFETENSORS_WEIGHTS_FILE_PATTERN, +) -> NamedTuple: + """ + Loads a sharded checkpoint into a model. This is the same as + [`torch.nn.Module.load_state_dict`](https://pytorch.org/docs/stable/generated/torch.nn.Module.html?highlight=load_state_dict#torch.nn.Module.load_state_dict) + but for a sharded checkpoint. Each shard is loaded one by one and removed from memory after being loaded into the model. + + Args: + model (`torch.nn.Module`): + The model in which to load the checkpoint. + save_directory (`str` or `os.PathLike`): + A path to a folder containing the sharded checkpoint. + strict (`bool`, *optional*, defaults to `False`): + Whether to strictly enforce that the keys in the model state dict match the keys in the sharded checkpoint. + weights_only (`bool`, *optional*, defaults to `False`): + If True, only loads the model weights without optimizer states and other metadata. + Only supported in PyTorch >= 1.13. + filename_pattern (`str`, *optional*, defaults to `"model{suffix}.safetensors"`): + The pattern to look for the index file. Pattern must be a string that + can be formatted with `filename_pattern.format(suffix=...)` and must contain the keyword `suffix` + Defaults to `"model{suffix}.safetensors"`. + + Returns: + `NamedTuple`: A named tuple with `missing_keys` and `unexpected_keys` fields, + - `missing_keys` is a list of str containing the missing keys + - `unexpected_keys` is a list of str containing the unexpected keys + """ + + # 1. Load and validate index file + # The index file contains mapping of parameter names to shard files + index_path = filename_pattern.format(suffix="") + ".index.json" + index_file = os.path.join(save_directory, index_path) + with open(index_file, encoding="utf-8") as f: + index = json.load(f) + + # 2. Validate shard filenames from the index + # This prevents path traversal attacks and extension confusion attacks + # (e.g. a safetensors index referencing .bin pickle files) + expected_extension = Path(filename_pattern.format(suffix="")).suffix # e.g. ".safetensors" + shard_files = list(set(index["weight_map"].values())) + for shard_file in shard_files: + # Reject anything that could escape `save_directory` on any host OS: + # POSIX absolute ("/tmp/x"), Windows drive ("C:x", "C:\\x"), UNC + # ("\\\\server\\share\\x"), rooted-without-drive ("\\x", "/x"), or + # ".." traversal — including "..\\x" which `os.path.isabs` never caught on POSIX. + # + # We parse with `PureWindowsPath` *regardless of host OS*: it treats both "/" and + # "\\" as separators and exposes `drive` / `root`, so a single check rejects a + # malicious index file on Linux too (e.g. if it's later opened on Windows). The + # only over-strict case is a POSIX filename like "a:foo" which would be parsed as + # drive "a:" — such names are never produced for safetensors shards and would + # break on Windows anyway, so rejecting them is fine. + win_path = PureWindowsPath(shard_file) + if win_path.drive or win_path.root or ".." in win_path.parts: + raise ValueError( + f"Invalid shard filename '{shard_file}' in index file '{index_file}'. " + "Shard filenames must be relative paths without '..' components." + ) + # Reject extension mismatch (e.g. .bin shard in a .safetensors index) + if not shard_file.endswith(expected_extension): + raise ValueError( + f"Invalid shard filename '{shard_file}' in index file '{index_file}'. " + f"Expected '{expected_extension}' extension to match the index format." + ) + + # 3. Validate keys if in strict mode + # This is done before loading any shards to fail fast + if strict: + _validate_keys_for_strict_loading(model, index["weight_map"].keys()) + + # 4. Load each shard using `load_state_dict` + # Get unique shard files (multiple parameters can be in same shard) + for shard_file in shard_files: + # Load shard into memory + shard_path = os.path.join(save_directory, shard_file) + state_dict = load_state_dict_from_file( + shard_path, + map_location="cpu", + weights_only=weights_only, + ) + # Update model with parameters from this shard + model.load_state_dict(state_dict, strict=strict) + # Explicitly remove the state dict from memory + del state_dict + + # 5. Return compatibility info + loaded_keys = set(index["weight_map"].keys()) + model_keys = set(model.state_dict().keys()) + return _IncompatibleKeys( + missing_keys=list(model_keys - loaded_keys), unexpected_keys=list(loaded_keys - model_keys) + ) + + +def load_state_dict_from_file( + checkpoint_file: str | os.PathLike, + map_location: Union[str, "torch.device"] | None = None, + weights_only: bool = False, + mmap: bool = False, +) -> dict[str, "torch.Tensor"] | Any: + """ + Loads a checkpoint file, handling both safetensors and pickle checkpoint formats. + + Args: + checkpoint_file (`str` or `os.PathLike`): + Path to the checkpoint file to load. Can be either a safetensors or pickle (`.bin`) checkpoint. + map_location (`str` or `torch.device`, *optional*): + A `torch.device` object, string or a dict specifying how to remap storage locations. It + indicates the location where all tensors should be loaded. + weights_only (`bool`, *optional*, defaults to `False`): + If True, only loads the model weights without optimizer states and other metadata. + Only supported for pickle (`.bin`) checkpoints with PyTorch >= 1.13. Has no effect when + loading safetensors files. + mmap (`bool`, *optional*, defaults to `False`): + Whether to use memory-mapped file loading. Memory mapping can improve loading performance + for large models in PyTorch >= 2.1.0 with zipfile-based checkpoints. Has no effect when + loading safetensors files, as the `safetensors` library uses memory mapping by default. + + Returns: + `Union[dict[str, "torch.Tensor"], Any]`: The loaded checkpoint. + - For safetensors files: always returns a dictionary mapping parameter names to tensors. + - For pickle files: returns any Python object that was pickled (commonly a state dict, but could be + an entire model, optimizer state, or any other Python object). + + Raises: + [`FileNotFoundError`](https://docs.python.org/3/library/exceptions.html#FileNotFoundError) + If the checkpoint file does not exist. + [`ImportError`](https://docs.python.org/3/library/exceptions.html#ImportError) + If safetensors or torch is not installed when trying to load a .safetensors file or a PyTorch checkpoint respectively. + [`OSError`](https://docs.python.org/3/library/exceptions.html#OSError) + If the checkpoint file format is invalid or if git-lfs files are not properly downloaded. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If the checkpoint file path is empty or invalid. + + Example: + ```python + >>> from huggingface_hub import load_state_dict_from_file + + # Load a PyTorch checkpoint + >>> state_dict = load_state_dict_from_file("path/to/model.bin", map_location="cpu") + >>> model.load_state_dict(state_dict) + + # Load a safetensors checkpoint + >>> state_dict = load_state_dict_from_file("path/to/model.safetensors") + >>> model.load_state_dict(state_dict) + ``` + """ + checkpoint_path = Path(checkpoint_file) + + # Check if file exists and is a regular file (not a directory) + if not checkpoint_path.is_file(): + raise FileNotFoundError( + f"No checkpoint file found at '{checkpoint_path}'. Please verify the path is correct and " + "the file has been properly downloaded." + ) + + # Load safetensors checkpoint + if checkpoint_path.suffix == ".safetensors": + try: + from safetensors import safe_open + from safetensors.torch import load_file + except ImportError as e: + raise ImportError( + "Please install `safetensors` to load safetensors checkpoint. " + "You can install it with `pip install safetensors`." + ) from e + + # Check format of the archive + with safe_open(checkpoint_file, framework="pt") as f: # type: ignore[attr-defined] + metadata = f.metadata() + # see comment: https://github.com/huggingface/transformers/blob/3d213b57fe74302e5902d68ed9478c3ad1aaa713/src/transformers/modeling_utils.py#L3966 + if metadata is not None and metadata.get("format") not in ["pt", "mlx"]: + raise OSError( + f"The safetensors archive passed at {checkpoint_file} does not contain the valid metadata. Make sure " + "you save your model with the `save_torch_model` method." + ) + device = str(map_location.type) if map_location is not None and hasattr(map_location, "type") else map_location + # meta device is not supported with safetensors, falling back to CPU + if device == "meta": + logger.warning("Meta device is not supported with safetensors. Falling back to CPU device.") + device = "cpu" + return load_file(checkpoint_file, device=device) # type: ignore[arg-type] + # Otherwise, load from pickle + try: + import torch + from torch import load + except ImportError as e: + raise ImportError( + "Please install `torch` to load torch tensors. You can install it with `pip install torch`." + ) from e + # Add additional kwargs, mmap is only supported in torch >= 2.1.0 + additional_kwargs = {} + if version.parse(torch.__version__) >= version.parse("2.1.0"): + additional_kwargs["mmap"] = mmap + + # weights_only is only supported in torch >= 1.13.0 + if version.parse(torch.__version__) >= version.parse("1.13.0"): + additional_kwargs["weights_only"] = weights_only + + return load( + checkpoint_file, + map_location=map_location, + **additional_kwargs, + ) + + +# HELPERS + + +def _validate_keys_for_strict_loading( + model: "torch.nn.Module", + loaded_keys: Iterable[str], +) -> None: + """ + Validate that model keys match loaded keys when strict loading is enabled. + + Args: + model: The PyTorch model being loaded + loaded_keys: The keys present in the checkpoint + + Raises: + RuntimeError: If there are missing or unexpected keys in strict mode + """ + loaded_keys_set = set(loaded_keys) + model_keys = set(model.state_dict().keys()) + missing_keys = model_keys - loaded_keys_set # Keys in model but not in checkpoint + unexpected_keys = loaded_keys_set - model_keys # Keys in checkpoint but not in model + + if missing_keys or unexpected_keys: + error_message = f"Error(s) in loading state_dict for {model.__class__.__name__}" + if missing_keys: + str_missing_keys = ",".join([f'"{k}"' for k in sorted(missing_keys)]) + error_message += f"\nMissing key(s): {str_missing_keys}." + if unexpected_keys: + str_unexpected_keys = ",".join([f'"{k}"' for k in sorted(unexpected_keys)]) + error_message += f"\nUnexpected key(s): {str_unexpected_keys}." + raise RuntimeError(error_message) + + +def _get_unique_id(tensor: "torch.Tensor") -> int | tuple[Any, ...]: + """Returns a unique id for plain tensor + or a (potentially nested) Tuple of unique id for the flattened Tensor + if the input is a wrapper tensor subclass Tensor + """ + + try: + from torch.distributed.tensor import DTensor + + if isinstance(tensor, DTensor): + local_tensor = tensor.to_local() + return local_tensor.storage().data_ptr() + except ImportError: + pass + + try: + # for torch 2.1 and above we can also handle tensor subclasses + from torch.utils._python_dispatch import is_traceable_wrapper_subclass + + if is_traceable_wrapper_subclass(tensor): + attrs, _ = tensor.__tensor_flatten__() # type: ignore[attr-defined] + return tuple(_get_unique_id(getattr(tensor, attr)) for attr in attrs) + + except ImportError: + # for torch version less than 2.1, we can fall back to original implementation + pass + + if tensor.device.type == "xla" and is_torch_tpu_available(): + # NOTE: xla tensors don't have storage + # use some other unique id to distinguish. + # this is a XLA tensor, it must be created using torch_xla's + # device. So the following import is safe: + import torch_xla # type: ignore[import] + + unique_id = torch_xla._XLAC._xla_get_tensor_id(tensor) + else: + unique_id = storage_ptr(tensor) + + return unique_id + + +def get_torch_storage_id(tensor: "torch.Tensor") -> tuple["torch.device", int | tuple[Any, ...], int] | None: + """ + Return unique identifier to a tensor storage. + + Multiple different tensors can share the same underlying storage. This identifier is + guaranteed to be unique and constant for this tensor's storage during its lifetime. Two tensor storages with + non-overlapping lifetimes may have the same id. + In the case of meta tensors, we return None since we can't tell if they share the same storage. + + Taken from https://github.com/huggingface/transformers/blob/1ecf5f7c982d761b4daaa96719d162c324187c64/src/transformers/pytorch_utils.py#L278. + """ + if tensor.device.type == "meta": + return None + else: + return tensor.device, _get_unique_id(tensor), get_torch_storage_size(tensor) + + +def get_torch_storage_size(tensor: "torch.Tensor") -> int: + """ + Taken from https://github.com/huggingface/safetensors/blob/08db34094e9e59e2f9218f2df133b7b4aaff5a99/bindings/python/py_src/safetensors/torch.py#L31C1-L41C59 + """ + try: + from torch.distributed.tensor import DTensor + + if isinstance(tensor, DTensor): + # this returns the size of the FULL tensor in bytes + return tensor.nbytes + except ImportError: + pass + + try: + # for torch 2.1 and above we can also handle tensor subclasses + from torch.utils._python_dispatch import is_traceable_wrapper_subclass + + if is_traceable_wrapper_subclass(tensor): + attrs, _ = tensor.__tensor_flatten__() # type: ignore[attr-defined] + return sum(get_torch_storage_size(getattr(tensor, attr)) for attr in attrs) + except ImportError: + # for torch version less than 2.1, we can fall back to original implementation + pass + + try: + return tensor.untyped_storage().nbytes() + except AttributeError: + # Fallback for torch==1.10 + try: + return tensor.storage().size() * _get_dtype_size(tensor.dtype) + except NotImplementedError: + # Fallback for meta storage + # On torch >=2.0 this is the tensor size + return tensor.nelement() * _get_dtype_size(tensor.dtype) + + +@lru_cache +def is_torch_tpu_available(check_device=True): + """ + Checks if `torch_xla` is installed and potentially if a TPU is in the environment + + Taken from https://github.com/huggingface/transformers/blob/1ecf5f7c982d761b4daaa96719d162c324187c64/src/transformers/utils/import_utils.py#L463. + """ + if importlib.util.find_spec("torch_xla") is not None: + if check_device: + # We need to check if `xla_device` can be found, will raise a RuntimeError if not + try: + import torch_xla.core.xla_model as xm # type: ignore[import] + + _ = xm.xla_device() + return True + except RuntimeError: + return False + return True + return False + + +def storage_ptr(tensor: "torch.Tensor") -> int | tuple[Any, ...]: + """ + Taken from https://github.com/huggingface/safetensors/blob/079781fd0dc455ba0fe851e2b4507c33d0c0d407/bindings/python/py_src/safetensors/torch.py#L11. + """ + try: + # for torch 2.1 and above we can also handle tensor subclasses + from torch.utils._python_dispatch import is_traceable_wrapper_subclass + + if is_traceable_wrapper_subclass(tensor): + return _get_unique_id(tensor) # type: ignore + except ImportError: + # for torch version less than 2.1, we can fall back to original implementation + pass + + try: + return tensor.untyped_storage().data_ptr() + except Exception: + # Fallback for torch==1.10 + try: + return tensor.storage().data_ptr() + except NotImplementedError: + # Fallback for meta storage + return 0 + + +def _clean_state_dict_for_safetensors( + state_dict: dict[str, "torch.Tensor"], + metadata: dict[str, str], + force_contiguous: bool = True, + shared_tensors_to_discard: list[str] | None = None, +): + """Remove shared tensors from state_dict and update metadata accordingly (for reloading). + + Warning: `state_dict` and `metadata` are mutated in-place! + + Taken from https://github.com/huggingface/safetensors/blob/079781fd0dc455ba0fe851e2b4507c33d0c0d407/bindings/python/py_src/safetensors/torch.py#L155. + """ + to_removes = _remove_duplicate_names(state_dict, discard_names=shared_tensors_to_discard) + for kept_name, to_remove_group in to_removes.items(): + for to_remove in to_remove_group: + if metadata is None: + metadata = {} + + if to_remove not in metadata: + # Do not override user data + metadata[to_remove] = kept_name + del state_dict[to_remove] + if force_contiguous: + state_dict = {k: v.contiguous() for k, v in state_dict.items()} + return state_dict + + +def _end_ptr(tensor: "torch.Tensor") -> int: + """ + Taken from https://github.com/huggingface/safetensors/blob/079781fd0dc455ba0fe851e2b4507c33d0c0d407/bindings/python/py_src/safetensors/torch.py#L23. + """ + if tensor.nelement(): + stop = tensor.view(-1)[-1].data_ptr() + _get_dtype_size(tensor.dtype) + else: + stop = tensor.data_ptr() + return stop + + +def _filter_shared_not_shared(tensors: list[set[str]], state_dict: dict[str, "torch.Tensor"]) -> list[set[str]]: + """ + Taken from https://github.com/huggingface/safetensors/blob/079781fd0dc455ba0fe851e2b4507c33d0c0d407/bindings/python/py_src/safetensors/torch.py#L44 + """ + filtered_tensors = [] + for shared in tensors: + if len(shared) < 2: + filtered_tensors.append(shared) + continue + + areas = [] + for name in shared: + tensor = state_dict[name] + areas.append((tensor.data_ptr(), _end_ptr(tensor), name)) + areas.sort() + + _, last_stop, last_name = areas[0] + filtered_tensors.append({last_name}) + for start, stop, name in areas[1:]: + if start >= last_stop: + filtered_tensors.append({name}) + else: + filtered_tensors[-1].add(name) + last_stop = stop + + return filtered_tensors + + +def _find_shared_tensors(state_dict: dict[str, "torch.Tensor"]) -> list[set[str]]: + """ + Taken from https://github.com/huggingface/safetensors/blob/079781fd0dc455ba0fe851e2b4507c33d0c0d407/bindings/python/py_src/safetensors/torch.py#L69. + """ + import torch + + tensors_dict = defaultdict(set) + for k, v in state_dict.items(): + if v.device != torch.device("meta") and storage_ptr(v) != 0 and get_torch_storage_size(v) != 0: + # Need to add device as key because of multiple GPU. + tensors_dict[(v.device, storage_ptr(v), get_torch_storage_size(v))].add(k) + tensors = list(sorted(tensors_dict.values())) + tensors = _filter_shared_not_shared(tensors, state_dict) + return tensors + + +def _is_complete(tensor: "torch.Tensor") -> bool: + """ + Taken from https://github.com/huggingface/safetensors/blob/079781fd0dc455ba0fe851e2b4507c33d0c0d407/bindings/python/py_src/safetensors/torch.py#L80 + """ + try: + # for torch 2.1 and above we can also handle tensor subclasses + from torch.utils._python_dispatch import is_traceable_wrapper_subclass + + if is_traceable_wrapper_subclass(tensor): + attrs, _ = tensor.__tensor_flatten__() # type: ignore[attr-defined] + return all(_is_complete(getattr(tensor, attr)) for attr in attrs) + except ImportError: + # for torch version less than 2.1, we can fall back to original implementation + pass + + return tensor.data_ptr() == storage_ptr(tensor) and tensor.nelement() * _get_dtype_size( + tensor.dtype + ) == get_torch_storage_size(tensor) + + +def _remove_duplicate_names( + state_dict: dict[str, "torch.Tensor"], + *, + preferred_names: list[str] | None = None, + discard_names: list[str] | None = None, +) -> dict[str, list[str]]: + """ + Taken from https://github.com/huggingface/safetensors/blob/079781fd0dc455ba0fe851e2b4507c33d0c0d407/bindings/python/py_src/safetensors/torch.py#L80 + """ + if preferred_names is None: + preferred_names = [] + unique_preferred_names = set(preferred_names) + if discard_names is None: + discard_names = [] + unique_discard_names = set(discard_names) + + shareds = _find_shared_tensors(state_dict) + to_remove = defaultdict(list) + for shared in shareds: + complete_names = {name for name in shared if _is_complete(state_dict[name])} + if not complete_names: + raise RuntimeError( + "Error while trying to find names to remove to save state dict, but found no suitable name to keep" + f" for saving amongst: {shared}. None is covering the entire storage. Refusing to save/load the model" + " since you could be storing much more memory than needed. Please refer to" + " https://huggingface.co/docs/safetensors/torch_shared_tensors for more information. Or open an" + " issue." + ) + + keep_name = sorted(list(complete_names))[0] + + # Mechanism to preferentially select keys to keep + # coming from the on-disk file to allow + # loading models saved with a different choice + # of keep_name + preferred = complete_names.difference(unique_discard_names) + if preferred: + keep_name = sorted(list(preferred))[0] + + if unique_preferred_names: + preferred = unique_preferred_names.intersection(complete_names) + if preferred: + keep_name = sorted(list(preferred))[0] + for name in sorted(shared): + if name != keep_name: + to_remove[keep_name].append(name) + return to_remove + + +@lru_cache +def _get_dtype_size(dtype: "torch.dtype") -> int: + """ + Taken from https://github.com/huggingface/safetensors/blob/08db34094e9e59e2f9218f2df133b7b4aaff5a99/bindings/python/py_src/safetensors/torch.py#L344 + """ + import torch + + # torch.float8 formats require 2.1; we do not support these dtypes on earlier versions + _float8_e4m3fn = getattr(torch, "float8_e4m3fn", None) + _float8_e5m2 = getattr(torch, "float8_e5m2", None) + _SIZE = { + torch.int64: 8, + torch.float32: 4, + torch.int32: 4, + torch.bfloat16: 2, + torch.float16: 2, + torch.int16: 2, + torch.uint8: 1, + torch.int8: 1, + torch.bool: 1, + torch.float64: 8, + _float8_e4m3fn: 1, + _float8_e5m2: 1, + } + return _SIZE[dtype] + + +class _IncompatibleKeys(namedtuple("IncompatibleKeys", ["missing_keys", "unexpected_keys"])): + """ + This is used to report missing and unexpected keys in the state dict. + Taken from https://github.com/pytorch/pytorch/blob/main/torch/nn/modules/module.py#L52. + + """ + + def __repr__(self) -> str: + if not self.missing_keys and not self.unexpected_keys: + return "" + return super().__repr__() + + __str__ = __repr__ diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/templates/datasetcard_template.md b/.venv/lib/python3.13/site-packages/huggingface_hub/templates/datasetcard_template.md new file mode 100644 index 0000000000000000000000000000000000000000..9af29ebbed93653ec74a8952e314e7554323ef15 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/templates/datasetcard_template.md @@ -0,0 +1,143 @@ +--- +# For reference on dataset card metadata, see the spec: https://github.com/huggingface/hub-docs/blob/main/datasetcard.md?plain=1 +# Doc / guide: https://huggingface.co/docs/hub/datasets-cards +{{ card_data }} +--- + +# Dataset Card for {{ pretty_name | default("Dataset Name", true) }} + + + +{{ dataset_summary | default("", true) }} + +## Dataset Details + +### Dataset Description + + + +{{ dataset_description | default("", true) }} + +- **Curated by:** {{ curators | default("[More Information Needed]", true)}} +- **Funded by [optional]:** {{ funded_by | default("[More Information Needed]", true)}} +- **Shared by [optional]:** {{ shared_by | default("[More Information Needed]", true)}} +- **Language(s) (NLP):** {{ language | default("[More Information Needed]", true)}} +- **License:** {{ license | default("[More Information Needed]", true)}} + +### Dataset Sources [optional] + + + +- **Repository:** {{ repo | default("[More Information Needed]", true)}} +- **Paper [optional]:** {{ paper | default("[More Information Needed]", true)}} +- **Demo [optional]:** {{ demo | default("[More Information Needed]", true)}} + +## Uses + + + +### Direct Use + + + +{{ direct_use | default("[More Information Needed]", true)}} + +### Out-of-Scope Use + + + +{{ out_of_scope_use | default("[More Information Needed]", true)}} + +## Dataset Structure + + + +{{ dataset_structure | default("[More Information Needed]", true)}} + +## Dataset Creation + +### Curation Rationale + + + +{{ curation_rationale_section | default("[More Information Needed]", true)}} + +### Source Data + + + +#### Data Collection and Processing + + + +{{ data_collection_and_processing_section | default("[More Information Needed]", true)}} + +#### Who are the source data producers? + + + +{{ source_data_producers_section | default("[More Information Needed]", true)}} + +### Annotations [optional] + + + +#### Annotation process + + + +{{ annotation_process_section | default("[More Information Needed]", true)}} + +#### Who are the annotators? + + + +{{ who_are_annotators_section | default("[More Information Needed]", true)}} + +#### Personal and Sensitive Information + + + +{{ personal_and_sensitive_information | default("[More Information Needed]", true)}} + +## Bias, Risks, and Limitations + + + +{{ bias_risks_limitations | default("[More Information Needed]", true)}} + +### Recommendations + + + +{{ bias_recommendations | default("Users should be made aware of the risks, biases and limitations of the dataset. More information needed for further recommendations.", true)}} + +## Citation [optional] + + + +**BibTeX:** + +{{ citation_bibtex | default("[More Information Needed]", true)}} + +**APA:** + +{{ citation_apa | default("[More Information Needed]", true)}} + +## Glossary [optional] + + + +{{ glossary | default("[More Information Needed]", true)}} + +## More Information [optional] + +{{ more_information | default("[More Information Needed]", true)}} + +## Dataset Card Authors [optional] + +{{ dataset_card_authors | default("[More Information Needed]", true)}} + +## Dataset Card Contact + +{{ dataset_card_contact | default("[More Information Needed]", true)}} diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/templates/modelcard_template.md b/.venv/lib/python3.13/site-packages/huggingface_hub/templates/modelcard_template.md new file mode 100644 index 0000000000000000000000000000000000000000..79ca15e4547debac763b390ef8e4b715e6f6403f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/templates/modelcard_template.md @@ -0,0 +1,200 @@ +--- +# For reference on model card metadata, see the spec: https://github.com/huggingface/hub-docs/blob/main/modelcard.md?plain=1 +# Doc / guide: https://huggingface.co/docs/hub/model-cards +{{ card_data }} +--- + +# Model Card for {{ model_id | default("Model ID", true) }} + + + +{{ model_summary | default("", true) }} + +## Model Details + +### Model Description + + + +{{ model_description | default("", true) }} + +- **Developed by:** {{ developers | default("[More Information Needed]", true)}} +- **Funded by [optional]:** {{ funded_by | default("[More Information Needed]", true)}} +- **Shared by [optional]:** {{ shared_by | default("[More Information Needed]", true)}} +- **Model type:** {{ model_type | default("[More Information Needed]", true)}} +- **Language(s) (NLP):** {{ language | default("[More Information Needed]", true)}} +- **License:** {{ license | default("[More Information Needed]", true)}} +- **Finetuned from model [optional]:** {{ base_model | default("[More Information Needed]", true)}} + +### Model Sources [optional] + + + +- **Repository:** {{ repo | default("[More Information Needed]", true)}} +- **Paper [optional]:** {{ paper | default("[More Information Needed]", true)}} +- **Demo [optional]:** {{ demo | default("[More Information Needed]", true)}} + +## Uses + + + +### Direct Use + + + +{{ direct_use | default("[More Information Needed]", true)}} + +### Downstream Use [optional] + + + +{{ downstream_use | default("[More Information Needed]", true)}} + +### Out-of-Scope Use + + + +{{ out_of_scope_use | default("[More Information Needed]", true)}} + +## Bias, Risks, and Limitations + + + +{{ bias_risks_limitations | default("[More Information Needed]", true)}} + +### Recommendations + + + +{{ bias_recommendations | default("Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations.", true)}} + +## How to Get Started with the Model + +Use the code below to get started with the model. + +{{ get_started_code | default("[More Information Needed]", true)}} + +## Training Details + +### Training Data + + + +{{ training_data | default("[More Information Needed]", true)}} + +### Training Procedure + + + +#### Preprocessing [optional] + +{{ preprocessing | default("[More Information Needed]", true)}} + + +#### Training Hyperparameters + +- **Training regime:** {{ training_regime | default("[More Information Needed]", true)}} + +#### Speeds, Sizes, Times [optional] + + + +{{ speeds_sizes_times | default("[More Information Needed]", true)}} + +## Evaluation + + + +### Testing Data, Factors & Metrics + +#### Testing Data + + + +{{ testing_data | default("[More Information Needed]", true)}} + +#### Factors + + + +{{ testing_factors | default("[More Information Needed]", true)}} + +#### Metrics + + + +{{ testing_metrics | default("[More Information Needed]", true)}} + +### Results + +{{ results | default("[More Information Needed]", true)}} + +#### Summary + +{{ results_summary | default("", true) }} + +## Model Examination [optional] + + + +{{ model_examination | default("[More Information Needed]", true)}} + +## Environmental Impact + + + +Carbon emissions can be estimated using the [Machine Learning Impact calculator](https://mlco2.github.io/impact#compute) presented in [Lacoste et al. (2019)](https://arxiv.org/abs/1910.09700). + +- **Hardware Type:** {{ hardware_type | default("[More Information Needed]", true)}} +- **Hours used:** {{ hours_used | default("[More Information Needed]", true)}} +- **Cloud Provider:** {{ cloud_provider | default("[More Information Needed]", true)}} +- **Compute Region:** {{ cloud_region | default("[More Information Needed]", true)}} +- **Carbon Emitted:** {{ co2_emitted | default("[More Information Needed]", true)}} + +## Technical Specifications [optional] + +### Model Architecture and Objective + +{{ model_specs | default("[More Information Needed]", true)}} + +### Compute Infrastructure + +{{ compute_infrastructure | default("[More Information Needed]", true)}} + +#### Hardware + +{{ hardware_requirements | default("[More Information Needed]", true)}} + +#### Software + +{{ software | default("[More Information Needed]", true)}} + +## Citation [optional] + + + +**BibTeX:** + +{{ citation_bibtex | default("[More Information Needed]", true)}} + +**APA:** + +{{ citation_apa | default("[More Information Needed]", true)}} + +## Glossary [optional] + + + +{{ glossary | default("[More Information Needed]", true)}} + +## More Information [optional] + +{{ more_information | default("[More Information Needed]", true)}} + +## Model Card Authors [optional] + +{{ model_card_authors | default("[More Information Needed]", true)}} + +## Model Card Contact + +{{ model_card_contact | default("[More Information Needed]", true)}} diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/__init__.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18965e574f3cf298c468a163d6d76cb08584bb64 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/__init__.py @@ -0,0 +1,133 @@ +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# 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 + +# ruff: noqa: F401 +from huggingface_hub.errors import ( + BadRequestError, + BucketNotFoundError, + CacheNotFound, + CorruptedCacheException, + DisabledRepoError, + EntryNotFoundError, + FileMetadataError, + GatedRepoError, + HfHubHTTPError, + HFValidationError, + JobNotFoundError, + LocalEntryNotFoundError, + LocalTokenNotFoundError, + NotASafetensorsRepoError, + OfflineModeIsEnabled, + RepositoryNotFoundError, + RevisionNotFoundError, + SafetensorsParsingError, +) + +from . import tqdm as _tqdm # _tqdm is the module +from ._auth import get_stored_tokens, get_token +from ._cache_assets import cached_assets_path +from ._cache_manager import ( + CachedFileInfo, + CachedIncompleteFileInfo, + CachedRepoInfo, + CachedRevisionInfo, + DeleteCacheStrategy, + HFCacheInfo, + _format_size, + scan_cache_dir, +) +from ._chunk_utils import chunk_iterable +from ._datetime import parse_datetime +from ._detect_agent import detect_agent, is_agent +from ._experimental import experimental +from ._fixes import SoftTemporaryDirectory, WeakFileLock, yaml_dump +from ._git_credential import list_credential_helpers, set_git_credential, unset_git_credential +from ._headers import build_hf_headers, get_token_to_send +from ._hf_uris import HfMount, HfUri, is_hf_uri, parse_hf_mount, parse_hf_uri +from ._http import ( + ASYNC_CLIENT_FACTORY_T, + CLIENT_FACTORY_T, + RateLimitInfo, + close_session, + fix_hf_endpoint_in_url, + get_async_session, + get_session, + hf_raise_for_status, + http_backoff, + http_stream_backoff, + parse_ratelimit_headers, + set_async_client_factory, + set_client_factory, +) +from ._pagination import paginate +from ._paths import DEFAULT_IGNORE_PATTERNS, FORBIDDEN_FOLDERS, filter_repo_objects +from ._runtime import ( + dump_environment_info, + get_aiohttp_version, + get_fastai_version, + get_fastapi_version, + get_fastcore_version, + get_gradio_version, + get_graphviz_version, + get_hf_hub_version, + get_jinja_version, + get_numpy_version, + get_pillow_version, + get_pydantic_version, + get_pydot_version, + get_python_version, + get_tensorboard_version, + get_tf_version, + get_torch_version, + installation_method, + is_aiohttp_available, + is_colab_enterprise, + is_fastai_available, + is_fastapi_available, + is_fastcore_available, + is_google_colab, + is_gradio_available, + is_graphviz_available, + is_jinja_available, + is_notebook, + is_numpy_available, + is_package_available, + is_pillow_available, + is_pydantic_available, + is_pydot_available, + is_safetensors_available, + is_tensorboard_available, + is_tf_available, + is_torch_available, +) +from ._safetensors import SafetensorsFileMetadata, SafetensorsRepoMetadata, TensorInfo +from ._subprocess import capture_output, run_interactive_subprocess, run_subprocess +from ._telemetry import send_telemetry +from ._terminal import ANSI, StatusLine, select_choice, tabulate +from ._typing import is_jsonable, is_simple_optional_type, unwrap_simple_optional_type +from ._validators import validate_hf_hub_args, validate_repo_id +from ._xet import ( + XetFileData, + XetTokenType, + parse_xet_file_data_from_response, +) +from .tqdm import ( + are_progress_bars_disabled, + disable_progress_bars, + enable_progress_bars, + is_tqdm_disabled, + silent_tqdm, + tqdm, + tqdm_stream_file, +) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_auth.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_auth.py new file mode 100644 index 0000000000000000000000000000000000000000..d1dba82be8e198693cca84b5bdd51c7c91d907d3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_auth.py @@ -0,0 +1,456 @@ +# Copyright 2023 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains a helper to get the token from machine (env variable, secret or config file).""" + +import configparser +import io +import logging +import os +import time +import warnings +from pathlib import Path +from threading import Lock +from typing import TypedDict + +from .. import constants +from ..errors import DeviceCodeError, OAuthErrorCode, OIDCError +from ._fixes import WeakFileLock +from ._oauth_device import refresh_access_token +from ._runtime import is_colab_enterprise, is_google_colab + + +_SECRET_FILE_MODE = 0o600 +_SECRET_DIR_MODE = 0o700 + + +def _write_secret(path: Path, content: str) -> None: + """Write content to file, restricting both the file and its parent directory to owner-only on POSIX systems.""" + path.parent.mkdir(parents=True, exist_ok=True, mode=_SECRET_DIR_MODE) + fd = os.open(str(path), os.O_WRONLY | os.O_CREAT | os.O_TRUNC, _SECRET_FILE_MODE) + with os.fdopen(fd, "w") as f: + f.write(content) + try: + path.chmod(_SECRET_FILE_MODE) + path.parent.chmod(_SECRET_DIR_MODE) + except (OSError, NotImplementedError): + # Windows does not support POSIX modes; chmod() will raise. Best-effort. + pass + + +_IS_GOOGLE_COLAB_CHECKED = False +_GOOGLE_COLAB_SECRET_LOCK = Lock() +_GOOGLE_COLAB_SECRET: str | None = None + +logger = logging.getLogger(__name__) + + +def get_token() -> str | None: + """ + Get token if user is logged in. + + Note: in most cases, you should use [`huggingface_hub.utils.build_hf_headers`] instead. This method is only useful + if you want to retrieve the token for other purposes than sending an HTTP request. + + If `HF_OIDC_RESOURCE` is set (Trusted Publishers, typically in CI), a short-lived token obtained via OIDC token + exchange takes precedence. Otherwise the token is retrieved from the `HF_TOKEN` environment variable, then from the + token file in the Hugging Face home folder. Returns None if user is not logged in. To log in, use [`login`] or + `hf auth login`. + + OAuth tokens obtained with the browser-based login come with a refresh token: when such a token is close to + expiry, it is transparently refreshed and persisted before being returned. + + Note: if `HF_OIDC_RESOURCE` is set but the OIDC token exchange fails, this raises instead of returning `None`, + opting into OIDC is explicit, so a failure surfaces as a clear error rather than a silent fallback. + + Returns: + `str` or `None`: The token, `None` if it doesn't exist. + """ + return ( + _get_token_from_oidc() + or _get_token_from_environment() + or _get_token_from_file_refreshed() + or _get_token_from_google_colab() + ) + + +def _get_token_from_google_colab() -> str | None: + """Get token from Google Colab secrets vault using `google.colab.userdata.get(...)`. + + Token is read from the vault only once per session and then stored in a global variable to avoid re-requesting + access to the vault. + """ + # If it's not a Google Colab or it's Colab Enterprise, fallback to environment variable or token file authentication + if not is_google_colab() or is_colab_enterprise(): + return None + + # `google.colab.userdata` is not thread-safe + # This can lead to a deadlock if multiple threads try to access it at the same time + # (typically when using `snapshot_download`) + # => use a lock + # See https://github.com/huggingface/huggingface_hub/issues/1952 for more details. + with _GOOGLE_COLAB_SECRET_LOCK: + global _GOOGLE_COLAB_SECRET + global _IS_GOOGLE_COLAB_CHECKED + + if _IS_GOOGLE_COLAB_CHECKED: # request access only once + return _GOOGLE_COLAB_SECRET + + try: + from google.colab import userdata # type: ignore + from google.colab.errors import Error as ColabError # type: ignore + except ImportError: + return None + + try: + token = userdata.get("HF_TOKEN") + _GOOGLE_COLAB_SECRET = _clean_token(token) + except userdata.NotebookAccessError: + # Means the user has a secret call `HF_TOKEN` and got a popup "please grand access to HF_TOKEN" and refused it + # => warn user but ignore error => do not re-request access to user + warnings.warn( + "\nAccess to the secret `HF_TOKEN` has not been granted on this notebook." + "\nYou will not be requested again." + "\nPlease restart the session if you want to be prompted again." + ) + _GOOGLE_COLAB_SECRET = None + except userdata.SecretNotFoundError: + # No `HF_TOKEN` secret defined: simply not logged in via the Colab vault. Not worth a + # warning now that `login()` is the primary flow (it would even fire during `login()` + # itself, telling the user to set up a secret while they are busy authenticating). + logger.info( + "The secret `HF_TOKEN` does not exist in your Colab secrets. Run `huggingface_hub.login()` to" + " authenticate (recommended but still optional to access public models or datasets)." + ) + _GOOGLE_COLAB_SECRET = None + except ColabError as e: + # Something happen but we don't know what => recommend to open a GitHub issue + warnings.warn(f"\nError while fetching `HF_TOKEN` secret value from your vault: '{str(e)}'.") + _GOOGLE_COLAB_SECRET = None + + _IS_GOOGLE_COLAB_CHECKED = True + return _GOOGLE_COLAB_SECRET + + +def _get_token_from_environment() -> str | None: + # `HF_TOKEN` has priority (keep `HUGGING_FACE_HUB_TOKEN` for backward compatibility) + return _clean_token(os.environ.get("HF_TOKEN") or os.environ.get("HUGGING_FACE_HUB_TOKEN")) + + +def _get_token_from_file() -> str | None: + try: + return _clean_token(Path(constants.HF_TOKEN_PATH).read_text()) + except FileNotFoundError: + return None + + +class _OidcTokenCache(TypedDict): + resource: str + token: str + expires_at: float # monotonic clock value after which the cached token must be re-exchanged + + +# Cache for the OIDC-exchanged token: re-exchanging on every `get_token()` call would be wasteful, +# and re-exchanging shortly before expiry transparently keeps long-running jobs authenticated. +_OIDC_TOKEN_LOCK = Lock() +_OIDC_TOKEN_CACHE: _OidcTokenCache | None = None +_OIDC_REFRESH_MARGIN = 300 # re-exchange this many seconds before the token actually expires + + +def _get_token_from_oidc() -> str | None: + """Get a short-lived OIDC token in CI (Trusted Publishers). + + Enabled by setting `HF_OIDC_RESOURCE`, which scopes the token to a repo or user. + The ID token is read from `HF_OIDC_ID_TOKEN` if available, or minted from a supported CI provider (e.g. GitHub Actions). + + Returns `None` when OIDC is not enabled. + If enabled, any failure is raised explicitly rather than falling back silently. + + See `huggingface_hub._oidc` and https://huggingface.co/docs/hub/trusted-publishers. + """ + resource = os.environ.get("HF_OIDC_RESOURCE") + if not resource: + return None + + from .._oidc import detect_provider, oidc_login + + global _OIDC_TOKEN_CACHE + with _OIDC_TOKEN_LOCK: + now = time.monotonic() + if ( + _OIDC_TOKEN_CACHE is not None + and _OIDC_TOKEN_CACHE["resource"] == resource + and now < _OIDC_TOKEN_CACHE["expires_at"] + ): + return _OIDC_TOKEN_CACHE["token"] + + # An explicit id token (any provider) takes precedence; otherwise mint from a detected one. + subject_token = os.environ.get("HF_OIDC_ID_TOKEN") or None + if subject_token is None and detect_provider() is None: + raise OIDCError( + "HF_OIDC_RESOURCE is set but no OIDC id token is available: not running in a supported " + "CI provider (github) and HF_OIDC_ID_TOKEN is not set. Set HF_OIDC_ID_TOKEN to the id " + "token minted by your CI provider, or unset HF_OIDC_RESOURCE." + ) + + result = oidc_login(resource=resource, subject_token=subject_token) + token = result["access_token"] + expires_in = int(result.get("expires_in", 3600)) + # A pre-supplied HF_OIDC_ID_TOKEN can't be re-minted, so refreshing early is pointless (the id + # token is likely already expired by then): cache for the full lifetime. Only the auto-minted + # path can refresh, so only it gets the safety margin. + margin = 0 if subject_token is not None else _OIDC_REFRESH_MARGIN + _OIDC_TOKEN_CACHE = { + "resource": resource, + "token": token, + "expires_at": now + max(expires_in - margin, 0), + } + return token + + +class _OAuthRefreshCache(TypedDict): + file_token: str # token as read from HF_TOKEN_PATH (cache key) + resolved_token: str # token to return (refreshed, or identical if no refresh was needed) + recheck_at: float # wall-clock timestamp after which the expiry must be re-evaluated + + +# Cache the refresh decision in-process: `get_token()` is called on every HTTP request and must not +# re-read the stored tokens file (let alone hit the network) each time. +_OAUTH_REFRESH_LOCK = Lock() +_OAUTH_REFRESH_CACHE: _OAuthRefreshCache | None = None +_OAUTH_REFRESH_MARGIN = 24 * 3600 # refresh when less than 1 day of validity remains +_OAUTH_RECHECK_INTERVAL = 300 # re-check interval when there is no metadata or the refresh failed +_OAUTH_REFRESH_WARNED = False # warn at most once per process on refresh failure + + +def _get_token_from_file_refreshed() -> str | None: + """Get the token from `HF_TOKEN_PATH`, transparently refreshing it if close to expiry.""" + token = _get_token_from_file() + if token is None: + return None + return _refresh_oauth_token_if_needed(token) + + +def _refresh_oauth_token_if_needed(token: str) -> str: + """Refresh an OAuth access token if it is close to expiry. Best-effort: never raises. + + OAuth tokens obtained with the browser-based login are stored with a `refresh_token` and an + `expires_at` timestamp (see `_save_token`). When the active token is one of them and about to + expire, exchange the refresh token for a new access token and persist it. Any other token is + returned unchanged. + """ + global _OAUTH_REFRESH_CACHE + with _OAUTH_REFRESH_LOCK: + now = time.time() + cache = _OAUTH_REFRESH_CACHE + if cache is not None and cache["file_token"] == token and now < cache["recheck_at"]: + return cache["resolved_token"] + + token_name, fields = next( + ((name, fields) for name, fields in _read_stored_tokens_full().items() if fields.get("hf_token") == token), + (None, {}), + ) + refresh_token = fields.get("refresh_token") + expires_at = _parse_expires_at(fields) + if token_name is None or refresh_token is None or expires_at is None: + # `token` may have just been replaced by a concurrent refresh (in which case it no + # longer appears in the stored tokens): serve the fresh file token without caching. + current_file_token = _get_token_from_file() + if current_file_token is not None and current_file_token != token: + return current_file_token + # Not a refreshable OAuth token (or its metadata was lost): nothing to do. + _OAUTH_REFRESH_CACHE = { + "file_token": token, + "resolved_token": token, + "recheck_at": now + _OAUTH_RECHECK_INTERVAL, + } + return token + + if expires_at - _OAUTH_REFRESH_MARGIN > now: + _OAUTH_REFRESH_CACHE = { + "file_token": token, + "resolved_token": token, + "recheck_at": expires_at - _OAUTH_REFRESH_MARGIN, + } + return token + + try: + # Cross-process file lock: if the server rotates refresh tokens, two processes + # refreshing concurrently would invalidate each other's refresh token. + with WeakFileLock(constants.HF_STORED_TOKENS_PATH + ".lock", timeout=30): + # Re-read under the lock: another process may have refreshed in the meantime. + fields = _read_stored_tokens_full().get(token_name, {}) + if fields.get("hf_token") != token: + # Another process already refreshed this token: adopt its result. + new_token = fields.get("hf_token") or token + new_expires_at = _parse_expires_at(fields) + else: + response = refresh_access_token(refresh_token) + new_token = response["access_token"] + new_expires_at = int(now) + int(response["expires_in"]) if "expires_in" in response else None + _save_token( + token=new_token, + token_name=token_name, + # The server may rotate the refresh token; keep the old one if it doesn't. + refresh_token=response.get("refresh_token") or refresh_token, + expires_at=new_expires_at, + ) + # Update the active token file, unless another process switched to a different token meanwhile. + if _get_token_from_file() == token: + _write_secret(Path(constants.HF_TOKEN_PATH), new_token) + logger.info(f"Access token `{token_name}` has been refreshed.") + except Exception as e: + if isinstance(e, DeviceCodeError) and e.error_code == OAuthErrorCode.INVALID_GRANT: + # Refresh token expired or revoked: retrying is pointless, a re-login is required. + # Warned unconditionally (the inf recheck guarantees it fires at most once): an + # earlier transient warning must not suppress this actionable message. + logger.warning( + "Your Hugging Face access token has expired and could not be refreshed " + f"(session expired or revoked). Run `hf auth login` to re-authenticate. ({e})" + ) + recheck_at = float("inf") + else: + # Transient failure (offline, server error, ...): retry later. + _warn_refresh_failure_once(f"Could not refresh your Hugging Face access token: {e}. Will retry later.") + recheck_at = now + _OAUTH_RECHECK_INTERVAL + # Return the existing token: if it's truly expired, the API will reject it with a clear error. + _OAUTH_REFRESH_CACHE = {"file_token": token, "resolved_token": token, "recheck_at": recheck_at} + return token + + _OAUTH_REFRESH_CACHE = { + "file_token": new_token, + "resolved_token": new_token, + # The floor guards against a token lifetime shorter than the refresh margin, which + # would otherwise put `recheck_at` in the past and trigger a refresh on every call. + "recheck_at": max( + now + _OAUTH_RECHECK_INTERVAL, + new_expires_at - _OAUTH_REFRESH_MARGIN if new_expires_at else 0, + ), + } + return new_token + + +def _warn_refresh_failure_once(message: str) -> None: + global _OAUTH_REFRESH_WARNED + if not _OAUTH_REFRESH_WARNED: + logger.warning(message) + _OAUTH_REFRESH_WARNED = True + + +def _parse_expires_at(fields: dict[str, str]) -> int | None: + """Parse the `expires_at` field of a stored-tokens section, `None` if missing or corrupt.""" + try: + return int(fields["expires_at"]) + except (KeyError, ValueError): + return None + + +def get_stored_tokens() -> dict[str, str]: + """ + Returns the parsed INI file containing the access tokens. + The file is located at `HF_STORED_TOKENS_PATH`, defaulting to `~/.cache/huggingface/stored_tokens`. + If the file does not exist, an empty dictionary is returned. + + Returns: `dict[str, str]` + Key is the token name and value is the token. + """ + return {token_name: fields.get("hf_token", "") for token_name, fields in _read_stored_tokens_full().items()} + + +def _read_stored_tokens_full() -> dict[str, dict[str, str]]: + """Read all sections of the stored tokens INI file, with all their fields. + + Beside `hf_token`, sections for OAuth tokens also carry `refresh_token` and `expires_at` + (unix timestamp), used by [`get_token`] to transparently refresh them. + """ + tokens_path = Path(constants.HF_STORED_TOKENS_PATH) + if not tokens_path.exists(): + return {} + # interpolation=None: token values are opaque strings, a `%` must not be interpreted. + config = configparser.ConfigParser(interpolation=None) + try: + config.read(tokens_path) + return {token_name: dict(config.items(token_name)) for token_name in config.sections()} + except configparser.Error as e: + logger.error(f"Error parsing stored tokens file: {e}") + return {} + + +def _save_stored_tokens_full(stored_tokens: dict[str, dict[str, str]]) -> None: + """Write all sections and their fields to the stored tokens INI file.""" + config = configparser.ConfigParser(interpolation=None) + for token_name in sorted(stored_tokens.keys()): + config.add_section(token_name) + for key, value in stored_tokens[token_name].items(): + config.set(token_name, key, value) + + buf = io.StringIO() + config.write(buf) + _write_secret(Path(constants.HF_STORED_TOKENS_PATH), buf.getvalue()) + + +def _get_token_by_name(token_name: str) -> str | None: + """ + Get the token by name. + + Args: + token_name (`str`): + The name of the token to get. + + Returns: + `str` or `None`: The token, `None` if it doesn't exist. + + """ + stored_tokens = get_stored_tokens() + if token_name not in stored_tokens: + return None + return _clean_token(stored_tokens[token_name]) + + +def _save_token( + token: str, token_name: str, *, refresh_token: str | None = None, expires_at: int | None = None +) -> None: + """ + Save the given token. + + If the stored tokens file does not exist, it will be created. + Args: + token (`str`): + The token to save. + token_name (`str`): + The name of the token. + refresh_token (`str`, *optional*): + OAuth refresh token used to renew the access token when it expires. + expires_at (`int`, *optional*): + Unix timestamp at which the access token expires. + """ + stored_tokens = _read_stored_tokens_full() + fields = {"hf_token": token} + if refresh_token is not None: + fields["refresh_token"] = refresh_token + if expires_at is not None: + fields["expires_at"] = str(expires_at) + # Replace the whole section: re-logging in under the same name must drop stale metadata. + stored_tokens[token_name] = fields + _save_stored_tokens_full(stored_tokens) + logger.info(f"The token `{token_name}` has been saved to {constants.HF_STORED_TOKENS_PATH}") + + +def _clean_token(token: str | None) -> str | None: + """Clean token by removing trailing and leading spaces and newlines. + + If token is an empty string, return None. + """ + if token is None: + return None + return token.replace("\r", "").replace("\n", "").strip() or None diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_cache_assets.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_cache_assets.py new file mode 100644 index 0000000000000000000000000000000000000000..01263873715c56d8331200b47a4608a1b1135ab7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_cache_assets.py @@ -0,0 +1,133 @@ +# Copyright 2019-present, the HuggingFace Inc. team. +# +# 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. +from pathlib import Path + +from ..constants import HF_ASSETS_CACHE + + +def cached_assets_path( + library_name: str, + namespace: str = "default", + subfolder: str = "default", + *, + assets_dir: str | Path | None = None, +) -> Path: + """Return a folder path to cache arbitrary files. + + `huggingface_hub` provides a canonical folder path to store assets. This is the + recommended way to integrate cache in a downstream library as it will benefit from + the builtins tools to scan and delete the cache properly. + + The distinction is made between files cached from the Hub and assets. Files from the + Hub are cached in a git-aware manner and entirely managed by `huggingface_hub`. See + [related documentation](https://huggingface.co/docs/huggingface_hub/how-to-cache). + All other files that a downstream library caches are considered to be "assets" + (files downloaded from external sources, extracted from a .tar archive, preprocessed + for training,...). + + Once the folder path is generated, it is guaranteed to exist and to be a directory. + The path is based on 3 levels of depth: the library name, a namespace and a + subfolder. Those 3 levels grants flexibility while allowing `huggingface_hub` to + expect folders when scanning/deleting parts of the assets cache. Within a library, + it is expected that all namespaces share the same subset of subfolder names but this + is not a mandatory rule. The downstream library has then full control on which file + structure to adopt within its cache. Namespace and subfolder are optional (would + default to a `"default/"` subfolder) but library name is mandatory as we want every + downstream library to manage its own cache. + + Expected tree: + ```text + assets/ + └── datasets/ + │ ├── SQuAD/ + │ │ ├── downloaded/ + │ │ ├── extracted/ + │ │ └── processed/ + │ ├── Helsinki-NLP--tatoeba_mt/ + │ ├── downloaded/ + │ ├── extracted/ + │ └── processed/ + └── transformers/ + ├── default/ + │ ├── something/ + ├── bert-base-cased/ + │ ├── default/ + │ └── training/ + hub/ + └── models--julien-c--EsperBERTo-small/ + ├── blobs/ + │ ├── (...) + │ ├── (...) + ├── refs/ + │ └── (...) + └── [ 128] snapshots/ + ├── 2439f60ef33a0d46d85da5001d52aeda5b00ce9f/ + │ ├── (...) + └── bbc77c8132af1cc5cf678da3f1ddf2de43606d48/ + └── (...) + ``` + + + Args: + library_name (`str`): + Name of the library that will manage the cache folder. Example: `"dataset"`. + namespace (`str`, *optional*, defaults to "default"): + Namespace to which the data belongs. Example: `"SQuAD"`. + subfolder (`str`, *optional*, defaults to "default"): + Subfolder in which the data will be stored. Example: `extracted`. + assets_dir (`str`, `Path`, *optional*): + Path to the folder where assets are cached. This must not be the same folder + where Hub files are cached. Defaults to `HF_HOME / "assets"` if not provided. + Can also be set with `HF_ASSETS_CACHE` environment variable. + + Returns: + Path to the cache folder (`Path`). + + Example: + ```py + >>> from huggingface_hub import cached_assets_path + + >>> cached_assets_path(library_name="datasets", namespace="SQuAD", subfolder="download") + PosixPath('/home/wauplin/.cache/huggingface/extra/datasets/SQuAD/download') + + >>> cached_assets_path(library_name="datasets", namespace="SQuAD", subfolder="extracted") + PosixPath('/home/wauplin/.cache/huggingface/extra/datasets/SQuAD/extracted') + + >>> cached_assets_path(library_name="datasets", namespace="Helsinki-NLP/tatoeba_mt") + PosixPath('/home/wauplin/.cache/huggingface/extra/datasets/Helsinki-NLP--tatoeba_mt/default') + + >>> cached_assets_path(library_name="datasets", assets_dir="/tmp/tmp123456") + PosixPath('/tmp/tmp123456/datasets/default/default') + ``` + """ + # Resolve assets_dir + if assets_dir is None: + assets_dir = HF_ASSETS_CACHE + assets_dir = Path(assets_dir).expanduser().resolve() + + # Avoid names that could create path issues + for part in (" ", "/", "\\"): + library_name = library_name.replace(part, "--") + namespace = namespace.replace(part, "--") + subfolder = subfolder.replace(part, "--") + + # Path to subfolder is created + path = assets_dir / library_name / namespace / subfolder + try: + path.mkdir(exist_ok=True, parents=True) + except (FileExistsError, NotADirectoryError): + raise ValueError(f"Corrupted assets folder: cannot create directory because of an existing file ({path}).") + + # Return + return path diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_cache_manager.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_cache_manager.py new file mode 100644 index 0000000000000000000000000000000000000000..5684cf0d286a21eec8c8f0197572f7d885f5838a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_cache_manager.py @@ -0,0 +1,890 @@ +# Copyright 2022-present, the HuggingFace Inc. team. +# +# 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. +"""Contains utilities to manage the HF cache directory.""" + +import os +import shutil +from collections import defaultdict +from dataclasses import dataclass +from pathlib import Path +from typing import Literal + +from huggingface_hub.errors import CacheNotFound, CorruptedCacheException + +from ..constants import HF_HUB_CACHE +from . import logging +from ._parsing import format_timesince +from ._terminal import tabulate + + +logger = logging.get_logger(__name__) + +REPO_TYPE_T = Literal["model", "dataset", "space"] + +# List of OS-created helper files that need to be ignored +FILES_TO_IGNORE = [".DS_Store", "Thumbs.db", "desktop.ini"] + + +@dataclass(frozen=True) +class CachedFileInfo: + """Frozen data structure holding information about a single cached file. + + Args: + file_name (`str`): + Name of the file. Example: `config.json`. + file_path (`Path`): + Path of the file in the `snapshots` directory. The file path is a symlink + referring to a blob in the `blobs` folder. + blob_path (`Path`): + Path of the blob file. This is equivalent to `file_path.resolve()`. + size_on_disk (`int`): + Size of the blob file in bytes. + blob_last_accessed (`float`): + Timestamp of the last time the blob file has been accessed (from any + revision). + blob_last_modified (`float`): + Timestamp of the last time the blob file has been modified/created. + + > [!WARNING] + > `blob_last_accessed` and `blob_last_modified` reliability can depend on the OS you + > are using. See [python documentation](https://docs.python.org/3/library/os.html#os.stat_result) + > for more details. + """ + + file_name: str + file_path: Path + blob_path: Path + size_on_disk: int + + blob_last_accessed: float + blob_last_modified: float + + @property + def blob_last_accessed_str(self) -> str: + """ + (property) Timestamp of the last time the blob file has been accessed (from any + revision), returned as a human-readable string. + + Example: "2 weeks ago". + """ + return format_timesince(self.blob_last_accessed) + + @property + def blob_last_modified_str(self) -> str: + """ + (property) Timestamp of the last time the blob file has been modified, returned + as a human-readable string. + + Example: "2 weeks ago". + """ + return format_timesince(self.blob_last_modified) + + @property + def size_on_disk_str(self) -> str: + """ + (property) Size of the blob file as a human-readable string. + + Example: "42.2K". + """ + return _format_size(self.size_on_disk) + + +@dataclass(frozen=True) +class CachedRevisionInfo: + """Frozen data structure holding information about a revision. + + A revision correspond to a folder in the `snapshots` folder and is populated with + the exact tree structure as the repo on the Hub but contains only symlinks. A + revision can be either referenced by 1 or more `refs` or be "detached" (no refs). + + Args: + commit_hash (`str`): + Hash of the revision (unique). + Example: `"9338f7b671827df886678df2bdd7cc7b4f36dffd"`. + snapshot_path (`Path`): + Path to the revision directory in the `snapshots` folder. It contains the + exact tree structure as the repo on the Hub. + files: (`frozenset[CachedFileInfo]`): + Set of [`~CachedFileInfo`] describing all files contained in the snapshot. + refs (`frozenset[str]`): + Set of `refs` pointing to this revision. If the revision has no `refs`, it + is considered detached. + Example: `{"main", "2.4.0"}` or `{"refs/pr/1"}`. + size_on_disk (`int`): + Sum of the blob file sizes that are symlink-ed by the revision. + last_modified (`float`): + Timestamp of the last time the revision has been created/modified. + + > [!WARNING] + > `last_accessed` cannot be determined correctly on a single revision as blob files + > are shared across revisions. + + > [!WARNING] + > `size_on_disk` is not necessarily the sum of all file sizes because of possible + > duplicated files. Besides, only blobs are taken into account, not the (negligible) + > size of folders and symlinks. + """ + + commit_hash: str + snapshot_path: Path + size_on_disk: int + files: frozenset[CachedFileInfo] + refs: frozenset[str] + + last_modified: float + + @property + def last_modified_str(self) -> str: + """ + (property) Timestamp of the last time the revision has been modified, returned + as a human-readable string. + + Example: "2 weeks ago". + """ + return format_timesince(self.last_modified) + + @property + def size_on_disk_str(self) -> str: + """ + (property) Sum of the blob file sizes as a human-readable string. + + Example: "42.2K". + """ + return _format_size(self.size_on_disk) + + @property + def nb_files(self) -> int: + """ + (property) Total number of files in the revision. + """ + return len(self.files) + + +@dataclass(frozen=True) +class CachedRepoInfo: + """Frozen data structure holding information about a cached repository. + + Args: + repo_id (`str`): + Repo id of the repo on the Hub. Example: `"google/fleurs"`. + repo_type (`Literal["dataset", "model", "space"]`): + Type of the cached repo. + repo_path (`Path`): + Local path to the cached repo. + size_on_disk (`int`): + Sum of the blob file sizes in the cached repo. + nb_files (`int`): + Total number of blob files in the cached repo. + revisions (`frozenset[CachedRevisionInfo]`): + Set of [`~CachedRevisionInfo`] describing all revisions cached in the repo. + last_accessed (`float`): + Timestamp of the last time a blob file of the repo has been accessed. + last_modified (`float`): + Timestamp of the last time a blob file of the repo has been modified/created. + + > [!WARNING] + > `size_on_disk` is not necessarily the sum of all revisions sizes because of + > duplicated files. Besides, only blobs are taken into account, not the (negligible) + > size of folders and symlinks. + + > [!WARNING] + > `last_accessed` and `last_modified` reliability can depend on the OS you are using. + > See [python documentation](https://docs.python.org/3/library/os.html#os.stat_result) + > for more details. + """ + + repo_id: str + repo_type: REPO_TYPE_T + repo_path: Path + size_on_disk: int + nb_files: int + revisions: frozenset[CachedRevisionInfo] + + last_accessed: float + last_modified: float + + @property + def last_accessed_str(self) -> str: + """ + (property) Last time a blob file of the repo has been accessed, returned as a + human-readable string. + + Example: "2 weeks ago". + """ + return format_timesince(self.last_accessed) + + @property + def last_modified_str(self) -> str: + """ + (property) Last time a blob file of the repo has been modified, returned as a + human-readable string. + + Example: "2 weeks ago". + """ + return format_timesince(self.last_modified) + + @property + def size_on_disk_str(self) -> str: + """ + (property) Sum of the blob file sizes as a human-readable string. + + Example: "42.2K". + """ + return _format_size(self.size_on_disk) + + @property + def cache_id(self) -> str: + """Canonical `type/id` identifier used across cache tooling.""" + return f"{self.repo_type}/{self.repo_id}" + + @property + def refs(self) -> dict[str, CachedRevisionInfo]: + """ + (property) Mapping between `refs` and revision data structures. + """ + return {ref: revision for revision in self.revisions for ref in revision.refs} + + +@dataclass(frozen=True) +class DeleteCacheStrategy: + """Frozen data structure holding the strategy to delete cached revisions. + + This object is not meant to be instantiated programmatically but to be returned by + [`~utils.HFCacheInfo.delete_revisions`]. See documentation for usage example. + + Args: + expected_freed_size (`float`): + Expected freed size once strategy is executed. + blobs (`frozenset[Path]`): + Set of blob file paths to be deleted. + refs (`frozenset[Path]`): + Set of reference file paths to be deleted. + repos (`frozenset[Path]`): + Set of entire repo paths to be deleted. + snapshots (`frozenset[Path]`): + Set of snapshots to be deleted (directory of symlinks). + """ + + expected_freed_size: int + blobs: frozenset[Path] + refs: frozenset[Path] + repos: frozenset[Path] + snapshots: frozenset[Path] + + @property + def expected_freed_size_str(self) -> str: + """ + (property) Expected size that will be freed as a human-readable string. + + Example: "42.2K". + """ + return _format_size(self.expected_freed_size) + + def execute(self) -> None: + """Execute the defined strategy. + + > [!WARNING] + > If this method is interrupted, the cache might get corrupted. Deletion order is + > implemented so that references and symlinks are deleted before the actual blob + > files. + + > [!WARNING] + > This method is irreversible. If executed, cached files are erased and must be + > downloaded again. + """ + # Deletion order matters. Blobs are deleted in last so that the user can't end + # up in a state where a `ref`` refers to a missing snapshot or a snapshot + # symlink refers to a deleted blob. + + # Delete entire repos + for path in self.repos: + _try_delete_path(path, path_type="repo") + + # Delete snapshot directories + for path in self.snapshots: + _try_delete_path(path, path_type="snapshot") + + # Delete refs files + for path in self.refs: + _try_delete_path(path, path_type="ref") + + # Delete blob files + for path in self.blobs: + _try_delete_path(path, path_type="blob") + + logger.info(f"Cache deletion done. Saved {self.expected_freed_size_str}.") + + +@dataclass(frozen=True) +class CachedIncompleteFileInfo: + """Frozen data structure holding information about a single incomplete download. + + Interrupted downloads leave `//blobs/.incomplete` files behind. + These are not part of any committed revision, so they are surfaced separately by + [`scan_cache_dir`]. + + Args: + file_path (`Path`): + Path of the `.incomplete` file in the `blobs` folder. + size_on_disk (`int`): + Size of the partially-downloaded file in bytes. + """ + + file_path: Path + size_on_disk: int + + +@dataclass(frozen=True) +class HFCacheInfo: + """Frozen data structure holding information about the entire cache-system. + + This data structure is returned by [`scan_cache_dir`] and is immutable. + + Args: + size_on_disk (`int`): + Sum of all valid repo sizes in the cache-system. + repos (`frozenset[CachedRepoInfo]`): + Set of [`~CachedRepoInfo`] describing all valid cached repos found on the + cache-system while scanning. + incomplete_files (`frozenset[CachedIncompleteFileInfo]`): + Set of [`~CachedIncompleteFileInfo`] describing orphaned `*.incomplete` + files left behind by interrupted downloads. + warnings (`list[CorruptedCacheException]`): + List of [`~CorruptedCacheException`] that occurred while scanning the cache. + Those exceptions are captured so that the scan can continue. Corrupted repos + are skipped from the scan. + + > [!WARNING] + > Here `size_on_disk` is equal to the sum of all repo sizes (only blobs). However if + > some cached repos are corrupted, their sizes are not taken into account. + """ + + size_on_disk: int + repos: frozenset[CachedRepoInfo] + incomplete_files: frozenset[CachedIncompleteFileInfo] + warnings: list[CorruptedCacheException] + + @property + def size_on_disk_str(self) -> str: + """ + (property) Sum of all valid repo sizes in the cache-system as a human-readable + string. + + Example: "42.2K". + """ + return _format_size(self.size_on_disk) + + @property + def incomplete_size_on_disk(self) -> int: + """(property) Sum of all incomplete download sizes in bytes.""" + return sum(file.size_on_disk for file in self.incomplete_files) + + def delete_revisions(self, *revisions: str) -> DeleteCacheStrategy: + """Prepare the strategy to delete one or more revisions cached locally. + + Input revisions can be any revision hash. If a revision hash is not found in the + local cache, a warning is thrown but no error is raised. Revisions can be from + different cached repos since hashes are unique across repos, + + Examples: + ```py + >>> from huggingface_hub import scan_cache_dir + >>> cache_info = scan_cache_dir() + >>> delete_strategy = cache_info.delete_revisions( + ... "81fd1d6e7847c99f5862c9fb81387956d99ec7aa" + ... ) + >>> print(f"Will free {delete_strategy.expected_freed_size_str}.") + Will free 7.9K. + >>> delete_strategy.execute() + Cache deletion done. Saved 7.9K. + ``` + + ```py + >>> from huggingface_hub import scan_cache_dir + >>> scan_cache_dir().delete_revisions( + ... "81fd1d6e7847c99f5862c9fb81387956d99ec7aa", + ... "e2983b237dccf3ab4937c97fa717319a9ca1a96d", + ... "6c0e6080953db56375760c0471a8c5f2929baf11", + ... ).execute() + Cache deletion done. Saved 8.6G. + ``` + + > [!WARNING] + > `delete_revisions` returns a [`~utils.DeleteCacheStrategy`] object that needs to + > be executed. The [`~utils.DeleteCacheStrategy`] is not meant to be modified but + > allows having a dry run before actually executing the deletion. + """ + hashes_to_delete: set[str] = set(revisions) + + repos_with_revisions: dict[CachedRepoInfo, set[CachedRevisionInfo]] = defaultdict(set) + + for repo in self.repos: + for revision in repo.revisions: + if revision.commit_hash in hashes_to_delete: + repos_with_revisions[repo].add(revision) + hashes_to_delete.remove(revision.commit_hash) + + if len(hashes_to_delete) > 0: + logger.warning(f"Revision(s) not found - cannot delete them: {', '.join(hashes_to_delete)}") + + delete_strategy_blobs: set[Path] = set() + delete_strategy_refs: set[Path] = set() + delete_strategy_repos: set[Path] = set() + delete_strategy_snapshots: set[Path] = set() + delete_strategy_expected_freed_size = 0 + + for affected_repo, revisions_to_delete in repos_with_revisions.items(): + other_revisions = affected_repo.revisions - revisions_to_delete + + # If no other revisions, it means all revisions are deleted + # -> delete the entire cached repo + if len(other_revisions) == 0: + delete_strategy_repos.add(affected_repo.repo_path) + delete_strategy_expected_freed_size += affected_repo.size_on_disk + continue + + # Some revisions of the repo will be deleted but not all. We need to filter + # which blob files will not be linked anymore. + for revision_to_delete in revisions_to_delete: + # Snapshot dir + delete_strategy_snapshots.add(revision_to_delete.snapshot_path) + + # Refs dir + for ref in revision_to_delete.refs: + delete_strategy_refs.add(affected_repo.repo_path / "refs" / ref) + + # Blobs dir + for file in revision_to_delete.files: + if file.blob_path not in delete_strategy_blobs: + is_file_alone = True + for revision in other_revisions: + for rev_file in revision.files: + if file.blob_path == rev_file.blob_path: + is_file_alone = False + break + if not is_file_alone: + break + + # Blob file not referenced by remaining revisions -> delete + if is_file_alone: + delete_strategy_blobs.add(file.blob_path) + delete_strategy_expected_freed_size += file.size_on_disk + + # Return the strategy instead of executing it. + return DeleteCacheStrategy( + blobs=frozenset(delete_strategy_blobs), + refs=frozenset(delete_strategy_refs), + repos=frozenset(delete_strategy_repos), + snapshots=frozenset(delete_strategy_snapshots), + expected_freed_size=delete_strategy_expected_freed_size, + ) + + def export_as_table(self, *, verbosity: int = 0) -> str: + """Generate a table from the [`HFCacheInfo`] object. + + Pass `verbosity=0` to get a table with a single row per repo, with columns + "repo_id", "repo_type", "size_on_disk", "nb_files", "last_accessed", "last_modified", "refs", "local_path". + + Pass `verbosity=1` to get a table with a row per repo and revision (thus multiple rows can appear for a single repo), with columns + "repo_id", "repo_type", "revision", "size_on_disk", "nb_files", "last_modified", "refs", "local_path". + + Example: + ```py + >>> from huggingface_hub.utils import scan_cache_dir + + >>> hf_cache_info = scan_cache_dir() + HFCacheInfo(...) + + >>> print(hf_cache_info.export_as_table()) + REPO ID REPO TYPE SIZE ON DISK NB FILES LAST_ACCESSED LAST_MODIFIED REFS LOCAL PATH + --------------------------------------------------- --------- ------------ -------- ------------- ------------- ---- -------------------------------------------------------------------------------------------------- + roberta-base model 2.7M 5 1 day ago 1 week ago main ~/.cache/huggingface/hub/models--roberta-base + suno/bark model 8.8K 1 1 week ago 1 week ago main ~/.cache/huggingface/hub/models--suno--bark + t5-base model 893.8M 4 4 days ago 7 months ago main ~/.cache/huggingface/hub/models--t5-base + t5-large model 3.0G 4 5 weeks ago 5 months ago main ~/.cache/huggingface/hub/models--t5-large + + >>> print(hf_cache_info.export_as_table(verbosity=1)) + REPO ID REPO TYPE REVISION SIZE ON DISK NB FILES LAST_MODIFIED REFS LOCAL PATH + --------------------------------------------------- --------- ---------------------------------------- ------------ -------- ------------- ---- ----------------------------------------------------------------------------------------------------------------------------------------------------- + roberta-base model e2da8e2f811d1448a5b465c236feacd80ffbac7b 2.7M 5 1 week ago main ~/.cache/huggingface/hub/models--roberta-base/snapshots/e2da8e2f811d1448a5b465c236feacd80ffbac7b + suno/bark model 70a8a7d34168586dc5d028fa9666aceade177992 8.8K 1 1 week ago main ~/.cache/huggingface/hub/models--suno--bark/snapshots/70a8a7d34168586dc5d028fa9666aceade177992 + t5-base model a9723ea7f1b39c1eae772870f3b547bf6ef7e6c1 893.8M 4 7 months ago main ~/.cache/huggingface/hub/models--t5-base/snapshots/a9723ea7f1b39c1eae772870f3b547bf6ef7e6c1 + t5-large model 150ebc2c4b72291e770f58e6057481c8d2ed331a 3.0G 4 5 months ago main ~/.cache/huggingface/hub/models--t5-large/snapshots/150ebc2c4b72291e770f58e6057481c8d2ed331a + ``` + + Args: + verbosity (`int`, *optional*): + The verbosity level. Defaults to 0. + + Returns: + `str`: The table as a string. + """ + if verbosity == 0: + return tabulate( + rows=[ + [ + repo.repo_id, + repo.repo_type, + f"{repo.size_on_disk_str:>12}", + repo.nb_files, + repo.last_accessed_str, + repo.last_modified_str, + ", ".join(sorted(repo.refs)), + str(repo.repo_path), + ] + for repo in sorted(self.repos, key=lambda repo: repo.repo_path) + ], + headers=[ + "REPO ID", + "REPO TYPE", + "SIZE ON DISK", + "NB FILES", + "LAST_ACCESSED", + "LAST_MODIFIED", + "REFS", + "LOCAL PATH", + ], + ) + else: + return tabulate( + rows=[ + [ + repo.repo_id, + repo.repo_type, + revision.commit_hash, + f"{revision.size_on_disk_str:>12}", + revision.nb_files, + revision.last_modified_str, + ", ".join(sorted(revision.refs)), + str(revision.snapshot_path), + ] + for repo in sorted(self.repos, key=lambda repo: repo.repo_path) + for revision in sorted(repo.revisions, key=lambda revision: revision.commit_hash) + ], + headers=[ + "REPO ID", + "REPO TYPE", + "REVISION", + "SIZE ON DISK", + "NB FILES", + "LAST_MODIFIED", + "REFS", + "LOCAL PATH", + ], + ) + + +def scan_cache_dir(cache_dir: str | Path | None = None) -> HFCacheInfo: + """Scan the entire HF cache-system and return a [`~HFCacheInfo`] structure. + + Use `scan_cache_dir` in order to programmatically scan your cache-system. The cache + will be scanned repo by repo. If a repo is corrupted, a [`~CorruptedCacheException`] + will be thrown internally but captured and returned in the [`~HFCacheInfo`] + structure. Only valid repos get a proper report. + + ```py + >>> from huggingface_hub import scan_cache_dir + + >>> hf_cache_info = scan_cache_dir() + HFCacheInfo( + size_on_disk=3398085269, + repos=frozenset({ + CachedRepoInfo( + repo_id='t5-small', + repo_type='model', + repo_path=PosixPath(...), + size_on_disk=970726914, + nb_files=11, + revisions=frozenset({ + CachedRevisionInfo( + commit_hash='d78aea13fa7ecd06c29e3e46195d6341255065d5', + size_on_disk=970726339, + snapshot_path=PosixPath(...), + files=frozenset({ + CachedFileInfo( + file_name='config.json', + size_on_disk=1197 + file_path=PosixPath(...), + blob_path=PosixPath(...), + ), + CachedFileInfo(...), + ... + }), + ), + CachedRevisionInfo(...), + ... + }), + ), + CachedRepoInfo(...), + ... + }), + warnings=[ + CorruptedCacheException("Snapshots dir doesn't exist in cached repo: ..."), + CorruptedCacheException(...), + ... + ], + ) + ``` + + You can also print a detailed report directly from the `hf` command line using: + ```text + > hf cache ls + ID SIZE LAST_ACCESSED LAST_MODIFIED REFS + --------------------------- -------- ------------- ------------- ----------- + dataset/nyu-mll/glue 157.4M 2 days ago 2 days ago main script + model/LiquidAI/LFM2-VL-1.6B 3.2G 4 days ago 4 days ago main + model/microsoft/UserLM-8b 32.1G 4 days ago 4 days ago main + + Done in 0.0s. Scanned 6 repo(s) for a total of 3.4G. + Got 1 warning(s) while scanning. Use -vvv to print details. + ``` + + Args: + cache_dir (`str` or `Path`, `optional`): + Cache directory to cache. Defaults to the default HF cache directory. + + > [!WARNING] + > Raises: + > + > `CacheNotFound` + > If the cache directory does not exist. + > + > [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + > If the cache directory is a file, instead of a directory. + + Returns: a [`~HFCacheInfo`] object. + """ + if cache_dir is None: + cache_dir = HF_HUB_CACHE + + cache_dir = Path(cache_dir).expanduser().resolve() + if not cache_dir.exists(): + raise CacheNotFound( + f"Cache directory not found: {cache_dir}. Please use `cache_dir` argument or set `HF_HUB_CACHE` environment variable.", + cache_dir=cache_dir, + ) + + if cache_dir.is_file(): + raise ValueError( + f"Scan cache expects a directory but found a file: {cache_dir}. Please use `cache_dir` argument or set `HF_HUB_CACHE` environment variable." + ) + + repos: set[CachedRepoInfo] = set() + warnings: list[CorruptedCacheException] = [] + for repo_path in cache_dir.iterdir(): + if repo_path.name in FILES_TO_IGNORE: + continue + if repo_path.name == ".locks": # skip './.locks/' folder + continue + if repo_path.name == "CACHEDIR.TAG": # skip CACHEDIR.TAG file + continue + try: + repos.add(_scan_cached_repo(repo_path)) + except CorruptedCacheException as e: + warnings.append(e) + + return HFCacheInfo( + repos=frozenset(repos), + size_on_disk=sum(repo.size_on_disk for repo in repos), + incomplete_files=_scan_incomplete_files(cache_dir), + warnings=warnings, + ) + + +def _scan_incomplete_files(cache_dir: Path) -> frozenset[CachedIncompleteFileInfo]: + """Find orphaned `*.incomplete` partial-download files in the cache. + + Interrupted downloads leave `//blobs/.incomplete` files behind. + These are not part of any committed revision, so they are reported separately in the + [`~HFCacheInfo`] returned by [`scan_cache_dir`]. + """ + files: set[CachedIncompleteFileInfo] = set() + for path in cache_dir.glob("*/blobs/*.incomplete"): + try: + size_on_disk = path.stat().st_size + except OSError: + continue + files.add(CachedIncompleteFileInfo(file_path=path, size_on_disk=size_on_disk)) + return frozenset(files) + + +def _scan_cached_repo(repo_path: Path) -> CachedRepoInfo: + """Scan a single cache repo and return information about it. + + Any unexpected behavior will raise a [`~CorruptedCacheException`]. + """ + if not repo_path.is_dir(): + raise CorruptedCacheException(f"Repo path is not a directory: {repo_path}") + + if "--" not in repo_path.name: + raise CorruptedCacheException(f"Repo path is not a valid HuggingFace cache directory: {repo_path}") + + repo_type, repo_id = repo_path.name.split("--", maxsplit=1) + repo_type = repo_type[:-1] # "models" -> "model" + repo_id = repo_id.replace("--", "/") # google/fleurs -> "google/fleurs" + + if repo_type not in {"dataset", "model", "space"}: + raise CorruptedCacheException( + f"Repo type must be `dataset`, `model` or `space`, found `{repo_type}` ({repo_path})." + ) + + blob_stats: dict[Path, os.stat_result] = {} # Key is blob_path, value is blob stats + + snapshots_path = repo_path / "snapshots" + refs_path = repo_path / "refs" + + if not snapshots_path.exists() or not snapshots_path.is_dir(): + raise CorruptedCacheException(f"Snapshots dir doesn't exist in cached repo: {snapshots_path}") + + # Scan over `refs` directory + + # key is revision hash, value is set of refs + refs_by_hash: dict[str, set[str]] = defaultdict(set) + if refs_path.exists(): + # Example of `refs` directory + # ── refs + # ├── main + # └── refs + # └── pr + # └── 1 + if refs_path.is_file(): + raise CorruptedCacheException(f"Refs directory cannot be a file: {refs_path}") + + for ref_path in refs_path.glob("**/*"): + # glob("**/*") iterates over all files and directories -> skip directories + if ref_path.is_dir() or ref_path.name in FILES_TO_IGNORE: + continue + + ref_name = str(ref_path.relative_to(refs_path)) + with ref_path.open() as f: + commit_hash = f.read() + + refs_by_hash[commit_hash].add(ref_name) + + # Scan snapshots directory + cached_revisions: set[CachedRevisionInfo] = set() + for revision_path in snapshots_path.iterdir(): + # Ignore OS-created helper files + if revision_path.name in FILES_TO_IGNORE: + continue + if revision_path.is_file(): + raise CorruptedCacheException(f"Snapshots folder corrupted. Found a file: {revision_path}") + + cached_files = set() + for file_path in revision_path.glob("**/*"): + # glob("**/*") iterates over all files and directories -> skip directories + if file_path.is_dir(): + continue + + blob_path = Path(file_path).resolve() + if not blob_path.exists(): + raise CorruptedCacheException(f"Blob missing (broken symlink): {blob_path}") + + if blob_path not in blob_stats: + blob_stats[blob_path] = blob_path.stat() + + cached_files.add( + CachedFileInfo( + file_name=file_path.name, + file_path=file_path, + size_on_disk=blob_stats[blob_path].st_size, + blob_path=blob_path, + blob_last_accessed=blob_stats[blob_path].st_atime, + blob_last_modified=blob_stats[blob_path].st_mtime, + ) + ) + + # Last modified is either the last modified blob file or the revision folder + # itself if it is empty + if len(cached_files) > 0: + revision_last_modified = max(blob_stats[file.blob_path].st_mtime for file in cached_files) + else: + revision_last_modified = revision_path.stat().st_mtime + + cached_revisions.add( + CachedRevisionInfo( + commit_hash=revision_path.name, + files=frozenset(cached_files), + refs=frozenset(refs_by_hash.pop(revision_path.name, set())), + size_on_disk=sum( + blob_stats[blob_path].st_size for blob_path in {file.blob_path for file in cached_files} + ), + snapshot_path=revision_path, + last_modified=revision_last_modified, + ) + ) + + # Check that all refs referred to an existing revision + if len(refs_by_hash) > 0: + raise CorruptedCacheException( + f"Reference(s) refer to missing commit hashes: {dict(refs_by_hash)} ({repo_path})." + ) + + # Last modified is either the last modified blob file or the repo folder itself if + # no blob files has been found. Same for last accessed. + if len(blob_stats) > 0: + repo_last_accessed = max(stat.st_atime for stat in blob_stats.values()) + repo_last_modified = max(stat.st_mtime for stat in blob_stats.values()) + else: + repo_stats = repo_path.stat() + repo_last_accessed = repo_stats.st_atime + repo_last_modified = repo_stats.st_mtime + + # Build and return frozen structure + return CachedRepoInfo( + nb_files=len(blob_stats), + repo_id=repo_id, + repo_path=repo_path, + repo_type=repo_type, # type: ignore + revisions=frozenset(cached_revisions), + size_on_disk=sum(stat.st_size for stat in blob_stats.values()), + last_accessed=repo_last_accessed, + last_modified=repo_last_modified, + ) + + +def _format_size(num: int) -> str: + """Format size in bytes into a human-readable string. + + Taken from https://stackoverflow.com/a/1094933 + """ + num_f = float(num) + for unit in ["", "K", "M", "G", "T", "P", "E", "Z"]: + if abs(num_f) < 1000.0: + return f"{num_f:3.1f}{unit}" + num_f /= 1000.0 + return f"{num_f:.1f}Y" + + +def _try_delete_path(path: Path, path_type: str) -> None: + """Try to delete a local file or folder. + + If the path does not exist, error is logged as a warning and then ignored. + + Args: + path (`Path`) + Path to delete. Can be a file or a folder. + path_type (`str`) + What path are we deleting ? Only for logging purposes. Example: "snapshot". + """ + logger.info(f"Delete {path_type}: {path}") + try: + if path.is_file(): + os.remove(path) + else: + shutil.rmtree(path) + except FileNotFoundError: + logger.warning(f"Couldn't delete {path_type}: file not found ({path})", exc_info=True) + except PermissionError: + logger.warning(f"Couldn't delete {path_type}: permission denied ({path})", exc_info=True) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_chunk_utils.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_chunk_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..081d6e32b0ccc1e123b8f0719ae307eeb7b46133 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_chunk_utils.py @@ -0,0 +1,64 @@ +# Copyright 2022-present, the HuggingFace Inc. team. +# +# 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. +"""Contains a utility to iterate by chunks over an iterator.""" + +import itertools +from collections.abc import Iterable +from typing import TypeVar + + +T = TypeVar("T") + + +def chunk_iterable(iterable: Iterable[T], chunk_size: int) -> Iterable[Iterable[T]]: + """Iterates over an iterator chunk by chunk. + + Taken from https://stackoverflow.com/a/8998040. + See also https://github.com/huggingface/huggingface_hub/pull/920#discussion_r938793088. + + Args: + iterable (`Iterable`): + The iterable on which we want to iterate. + chunk_size (`int`): + Size of the chunks. Must be a strictly positive integer (e.g. >0). + + Example: + + ```python + >>> from huggingface_hub.utils import chunk_iterable + + >>> for items in chunk_iterable(range(17), chunk_size=8): + ... print(items) + # [0, 1, 2, 3, 4, 5, 6, 7] + # [8, 9, 10, 11, 12, 13, 14, 15] + # [16] # smaller last chunk + ``` + + Raises: + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If `chunk_size` <= 0. + + > [!WARNING] + > The last chunk can be smaller than `chunk_size`. + """ + if not isinstance(chunk_size, int) or chunk_size <= 0: + raise ValueError("`chunk_size` must be a strictly positive integer (>0).") + + iterator = iter(iterable) + while True: + try: + next_item = next(iterator) + except StopIteration: + return + yield itertools.chain((next_item,), itertools.islice(iterator, chunk_size - 1)) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_datetime.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_datetime.py new file mode 100644 index 0000000000000000000000000000000000000000..44961712a959d8be370b7e3adcd2ef298f27c108 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_datetime.py @@ -0,0 +1,66 @@ +# Copyright 2022-present, the HuggingFace Inc. team. +# +# 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. +"""Contains utilities to handle datetimes in Huggingface Hub.""" + +from datetime import datetime, timezone + + +def parse_datetime(date_string: str) -> datetime: + """ + Parses a date_string returned from the server to a datetime object. + + This parser is a weak-parser is the sense that it handles only a single format of + date_string. It is expected that the server format will never change. The + implementation depends only on the standard lib to avoid an external dependency + (python-dateutil). See full discussion about this decision on PR: + https://github.com/huggingface/huggingface_hub/pull/999. + + Example: + ```py + > parse_datetime('2022-08-19T07:19:38.123Z') + datetime.datetime(2022, 8, 19, 7, 19, 38, 123000, tzinfo=timezone.utc) + ``` + + Args: + date_string (`str`): + A string representing a datetime returned by the Hub server. + String is expected to follow '%Y-%m-%dT%H:%M:%S.%fZ' pattern. + + Returns: + A python datetime object. + + Raises: + :class:`ValueError`: + If `date_string` cannot be parsed. + """ + try: + # Normalize the string to always have 6 digits of fractional seconds + if date_string.endswith("Z"): + # Case 1: No decimal point (e.g., "2024-11-16T00:27:02Z") + if "." not in date_string: + # No fractional seconds - insert .000000 + date_string = date_string[:-1] + ".000000Z" + # Case 2: Has decimal point (e.g., "2022-08-19T07:19:38.123456789Z") + else: + # Get the fractional and base parts + base, fraction = date_string[:-1].split(".") + # fraction[:6] takes first 6 digits and :0<6 pads with zeros if less than 6 digits + date_string = f"{base}.{fraction[:6]:0<6}Z" + + return datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%S.%fZ").replace(tzinfo=timezone.utc) + except ValueError as e: + raise ValueError( + f"Cannot parse '{date_string}' as a datetime. Date string is expected to" + " follow '%Y-%m-%dT%H:%M:%S.%fZ' pattern." + ) from e diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_deprecation.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_deprecation.py new file mode 100644 index 0000000000000000000000000000000000000000..99df8405958f565e6bdf8aaa61e0042d685c4e77 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_deprecation.py @@ -0,0 +1,136 @@ +import warnings +from collections.abc import Iterable +from functools import wraps +from inspect import Parameter, signature + + +def _deprecate_positional_args(*, version: str): + """Decorator for methods that issues warnings for positional arguments. + Using the keyword-only argument syntax in pep 3102, arguments after the + * will issue a warning when passed as a positional argument. + + Args: + version (`str`): + The version when positional arguments will result in error. + """ + + def _inner_deprecate_positional_args(f): + sig = signature(f) + kwonly_args = [] + all_args = [] + for name, param in sig.parameters.items(): + if param.kind == Parameter.POSITIONAL_OR_KEYWORD: + all_args.append(name) + elif param.kind == Parameter.KEYWORD_ONLY: + kwonly_args.append(name) + + @wraps(f) + def inner_f(*args, **kwargs): + extra_args = len(args) - len(all_args) + if extra_args <= 0: + return f(*args, **kwargs) + # extra_args > 0 + args_msg = [ + f"{name}='{arg}'" if isinstance(arg, str) else f"{name}={arg}" + for name, arg in zip(kwonly_args[:extra_args], args[-extra_args:]) + ] + args_msg = ", ".join(args_msg) + warnings.warn( + f"Deprecated positional argument(s) used in '{f.__name__}': pass" + f" {args_msg} as keyword args. From version {version} passing these" + " as positional arguments will result in an error,", + FutureWarning, + ) + kwargs.update(zip(sig.parameters, args)) + return f(**kwargs) + + return inner_f + + return _inner_deprecate_positional_args + + +def _deprecate_arguments( + *, + version: str, + deprecated_args: Iterable[str], + custom_message: str | None = None, +): + """Decorator to issue warnings when using deprecated arguments. + + TODO: could be useful to be able to set a custom error message. + + Args: + version (`str`): + The version when deprecated arguments will result in error. + deprecated_args (`list[str]`): + List of the arguments to be deprecated. + custom_message (`str`, *optional*): + Warning message that is raised. If not passed, a default warning message + will be created. + """ + + def _inner_deprecate_positional_args(f): + sig = signature(f) + + @wraps(f) + def inner_f(*args, **kwargs): + # Check for used deprecated arguments + used_deprecated_args = [] + for _, parameter in zip(args, sig.parameters.values()): + if parameter.name in deprecated_args: + used_deprecated_args.append(parameter.name) + for kwarg_name, kwarg_value in kwargs.items(): + if ( + # If argument is deprecated but still used + kwarg_name in deprecated_args + # And then the value is not the default value + and kwarg_value != sig.parameters[kwarg_name].default + ): + used_deprecated_args.append(kwarg_name) + + # Warn and proceed + if len(used_deprecated_args) > 0: + message = ( + f"Deprecated argument(s) used in '{f.__name__}':" + f" {', '.join(used_deprecated_args)}. Will not be supported from" + f" version '{version}'." + ) + if custom_message is not None: + message += "\n\n" + custom_message + warnings.warn(message, FutureWarning) + return f(*args, **kwargs) + + return inner_f + + return _inner_deprecate_positional_args + + +def _deprecate_method(*, version: str, message: str | None = None): + """Decorator to issue warnings when using a deprecated method. + + Args: + version (`str`): + The version when deprecated arguments will result in error. + message (`str`, *optional*): + Warning message that is raised. If not passed, a default warning message + will be created. + """ + + def _inner_deprecate_method(f): + name = f.__name__ + if name == "__init__": + name = f.__qualname__.split(".")[0] # class name instead of method name + + @wraps(f) + def inner_f(*args, **kwargs): + warning_message = ( + f"'{name}' (from '{f.__module__}') is deprecated and will be removed from version '{version}'." + ) + if message is not None: + warning_message += " " + message + warnings.warn(warning_message, FutureWarning) + return f(*args, **kwargs) + + return inner_f + + return _inner_deprecate_method diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_detect_agent.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_detect_agent.py new file mode 100644 index 0000000000000000000000000000000000000000..fb2661bc2288fdbcea44de7023b2dd8268c6d215 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_detect_agent.py @@ -0,0 +1,204 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""Detect whether the process is being invoked by an AI coding agent. + +Detection is based on environment variables that AI agents set in their shell +sessions. `AI_AGENT` and `AGENT` are treated as a universal standard (any +tool can set its harness id there); the remaining checks are tool-specific and +ordered by priority (first match wins). + +The list of known harnesses is maintained on the Hub and exposed at +`{ENDPOINT}/api/agent-harnesses`. We fetch it at most once a day and cache it +locally so the list can be updated without requiring a new client release. + +Detection is entirely best-effort: there is no hardcoded list of harnesses. When +the registry cannot be fetched (and no cached copy is available), detection simply +reports "no agent". Any error while fetching/reading the registry is swallowed — +detection must never make a process fail. + +More details: https://huggingface.co/docs/hub/agents-overview#register-your-agent-harness +""" + +import json +import os +import time +from pathlib import Path +from typing import Optional, TypedDict + +from .. import constants +from . import logging + + +logger = logging.get_logger(__name__) + +# Refresh the cached registry at most once every 24 hours. +_REGISTRY_TTL_SECONDS = 24 * 3600 + +# Short timeout: fetching the registry is best-effort telemetry, never block the caller for long. +_REGISTRY_FETCH_TIMEOUT = 3 + + +class HarnessInfo(TypedDict, total=False): + """A single harness entry. `envVars` maps an env var name to a match pattern (see `_env_vars_match`).""" + + envVars: dict[str, str] + + +class Registry(TypedDict): + """The agent harness registry, as served by `{ENDPOINT}/api/agent-harnesses`.""" + + standardEnvVars: list[str] + harnesses: dict[str, HarnessInfo] + + +# Empty registry: detection is disabled (no agent ever detected). Used when the +# Hub is unreachable and no cached copy is available. +_EMPTY_REGISTRY: Registry = {"standardEnvVars": [], "harnesses": {}} + +# In-process cache of the resolved registry. Populated lazily on first detection. +_registry: Registry | None = None + + +def detect_agent() -> Optional[str]: + """Return the id of the detected AI agent harness or `None`. + + Harnesses are checked in registry order; for each one we match its env var + pattern(s) and, failing that, the standard `AI_AGENT` / `AGENT` vars + against the harness id. The first match wins. When a standard var is set to + an unrecognized value, `"unknown"` is returned. + """ + registry = _get_registry() + standard_vars = registry.get("standardEnvVars") or [] + harnesses = registry.get("harnesses") or {} + + for harness_id, info in harnesses.items(): + env_vars = (info or {}).get("envVars") + if env_vars and _env_vars_match(env_vars): + return harness_id + for var in standard_vars: + if os.environ.get(var, "").strip() == harness_id: + return harness_id + + # No harness matched but a standard var is set => unrecognized agent. + lowercased_harnesses = {k.lower() for k in harnesses.keys()} + for var in standard_vars: + if value := os.environ.get(var, "").strip().lower(): + if value in lowercased_harnesses: + return value + return "unknown" + + return None + + +def is_agent() -> bool: + """Return `True` if the process is being invoked by an AI coding agent.""" + return detect_agent() is not None + + +def _env_vars_match(env_vars: dict[str, str]) -> bool: + """Return `True` if any `(var, pattern)` from the harness matches the environment. + + Supported patterns: + - `"*"`: the variable is set to any non-empty value + - `""`: the variable equals this exact value + """ + for var, pattern in env_vars.items(): + value = os.environ.get(var) + if not value: + continue + if pattern == "*": + return True + if value == pattern: + return True + return False + + +def _get_registry() -> Registry: + """Return the harness registry, loading (and caching in-process) on first call. + + Best-effort: any unexpected error degrades to an empty registry so detection + never raises. + """ + global _registry + if _registry is None: + try: + _registry = _load_registry() + except Exception: + logger.debug("Could not resolve agent harnesses registry.", exc_info=True) + _registry = _EMPTY_REGISTRY + return _registry + + +def _load_registry() -> Registry: + """Resolve the registry from the local cache or the Hub. + + No hardcoded list: if the Hub is unreachable and no cached copy exists, an + empty registry is returned (i.e. no agent is detected). + """ + path = constants.AGENT_HARNESSES_PATH + + # 1. Use the cached file if it was refreshed within the last 24 hours. + if cached := _read_cached_registry(path, max_age=_REGISTRY_TTL_SECONDS): + return cached + + # 2. Otherwise refresh it from the Hub and persist it for next time. + if (fetched := _fetch_registry()) is not None: + _write_cached_registry(path, fetched) + return fetched + + # 3. Fetch failed: reuse a stale cache if available, else give up (no detection). + if stale := _read_cached_registry(path, max_age=None): + return stale + return _EMPTY_REGISTRY + + +def _read_cached_registry(path: str, max_age: int | None) -> Registry | None: + """Return the cached registry, or `None` if missing/stale/unreadable.""" + try: + if not os.path.exists(path): + return None + if max_age is not None and (time.time() - os.path.getmtime(path)) >= max_age: + return None + with open(path, encoding="utf-8") as f: + return json.load(f) + except Exception: + logger.debug("Could not read cached agent harnesses registry.", exc_info=True) + return None + + +def _write_cached_registry(path: str, registry: Registry) -> None: + try: + Path(path).parent.mkdir(parents=True, exist_ok=True) + with open(path, "w", encoding="utf-8") as f: + json.dump(registry, f) + except Exception: + logger.debug("Could not cache agent harnesses registry.", exc_info=True) + + +def _fetch_registry() -> Registry | None: + """Fetch the registry from the Hub. Returns `None` when offline or on any error.""" + if constants.HF_HUB_OFFLINE: + return None + try: + from ._http import get_session + + response = get_session().get( + f"{constants.ENDPOINT}/api/agent-harnesses", + timeout=_REGISTRY_FETCH_TIMEOUT, + ) + response.raise_for_status() + return response.json() + except Exception: + logger.debug("Could not fetch agent harnesses registry from the Hub.", exc_info=True) + return None diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_dotenv.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_dotenv.py new file mode 100644 index 0000000000000000000000000000000000000000..dd6de0ce23f9c24137a65c5e9ac7728da3073a27 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_dotenv.py @@ -0,0 +1,68 @@ +# AI-generated module (ChatGPT) +import re + + +# Escape sequences expanded inside quoted values. Double-quoted values additionally +# expand "\$" to "$"; single-quoted values keep it verbatim. +_ESCAPES = {"n": "\n", "t": "\t", '"': '"', "\\": "\\"} +_DOUBLE_QUOTE_ESCAPES = {**_ESCAPES, "$": "$"} + + +def _unescape(value: str, escapes: dict[str, str]) -> str: + r"""Expand backslash escapes in a single left-to-right pass. + + Processing in one pass (rather than chained `str.replace` calls) ensures an escaped + backslash (`\\`) is consumed as a unit and cannot merge with the following character, + e.g. `\\n` is a backslash followed by `n`, not a newline. Unknown escapes are kept as-is. + """ + return re.sub(r"\\(.)", lambda match: escapes.get(match.group(1), match.group(0)), value) + + +def load_dotenv(dotenv_str: str, environ: dict[str, str] | None = None) -> dict[str, str]: + """ + Parse a DOTENV-format string and return a dictionary of key-value pairs. + Handles quoted values, comments, export keyword, and blank lines. + """ + env: dict[str, str] = {} + line_pattern = re.compile( + r""" + ^\s* + (?:export[^\S\n]+)? # optional export + ([A-Za-z_][A-Za-z0-9_]*) # key + [^\S\n]*(=)?[^\S\n]* + ( # value group + (?: + '(?:\\'|[^'])*' # single-quoted value + | \"(?:\\\"|[^\"])*\" # double-quoted value + | [^#\n\r]+? # unquoted value + ) + )? + [^\S\n]*(?:\#.*)?$ # optional inline comment + """, + re.VERBOSE, + ) + + for line in dotenv_str.splitlines(): + line = line.strip() + if not line or line.startswith("#"): + continue # Skip comments and empty lines + + match = line_pattern.match(line) + if match: + key = match.group(1) + val = None + if match.group(2): # if there is '=' + raw_val = match.group(3) or "" + val = raw_val.strip() + # Remove surrounding quotes if quoted + if (val.startswith('"') and val.endswith('"')) or (val.startswith("'") and val.endswith("'")): + escapes = _DOUBLE_QUOTE_ESCAPES if raw_val.startswith('"') else _ESCAPES + val = _unescape(val[1:-1], escapes) + elif environ is not None: + # Get it from the current environment + val = environ.get(key) + + if val is not None: + env[key] = val + + return env diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_experimental.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_experimental.py new file mode 100644 index 0000000000000000000000000000000000000000..82753e1fe052639ee9f4cc7adcbbe2ffb595c88b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_experimental.py @@ -0,0 +1,67 @@ +# Copyright 2023-present, the HuggingFace Inc. team. +# +# 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. +"""Contains utilities to flag a feature as "experimental" in Huggingface Hub.""" + +import warnings +from collections.abc import Callable +from functools import wraps + +from .. import constants + + +def experimental(fn: Callable) -> Callable: + """Decorator to flag a feature as experimental. + + An experimental feature triggers a warning when used as it might be subject to breaking changes without prior notice + in the future. + + Warnings can be disabled by setting `HF_HUB_DISABLE_EXPERIMENTAL_WARNING=1` as environment variable. + + Args: + fn (`Callable`): + The function to flag as experimental. + + Returns: + `Callable`: The decorated function. + + Example: + + ```python + >>> from huggingface_hub.utils import experimental + + >>> @experimental + ... def my_function(): + ... print("Hello world!") + + >>> my_function() + UserWarning: 'my_function' is experimental and might be subject to breaking changes in the future without prior + notice. You can disable this warning by setting `HF_HUB_DISABLE_EXPERIMENTAL_WARNING=1` as environment variable. + Hello world! + ``` + """ + # For classes, put the "experimental" around the "__new__" method => __new__ will be removed in warning message + name = fn.__qualname__[: -len(".__new__")] if fn.__qualname__.endswith(".__new__") else fn.__qualname__ + + @wraps(fn) + def _inner_fn(*args, **kwargs): + if not constants.HF_HUB_DISABLE_EXPERIMENTAL_WARNING: + warnings.warn( + f"'{name}' is experimental and might be subject to breaking changes in the future without prior notice." + " You can disable this warning by setting `HF_HUB_DISABLE_EXPERIMENTAL_WARNING=1` as environment" + " variable.", + UserWarning, + ) + return fn(*args, **kwargs) + + return _inner_fn diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_fixes.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_fixes.py new file mode 100644 index 0000000000000000000000000000000000000000..b4f755fcc0aebc229dbf75c7d0ea51a50c91afff --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_fixes.py @@ -0,0 +1,123 @@ +import contextlib +import os +import shutil +import stat +import tempfile +import time +from collections.abc import Callable, Generator +from functools import partial +from pathlib import Path + +import yaml +from filelock import BaseFileLock, FileLock, SoftFileLock, Timeout + +from .. import constants +from . import logging + + +logger = logging.get_logger(__name__) + +# Wrap `yaml.dump` to set `allow_unicode=True` by default. +# +# Example: +# ```py +# >>> yaml.dump({"emoji": "👀", "some unicode": "日本か"}) +# 'emoji: "\\U0001F440"\nsome unicode: "\\u65E5\\u672C\\u304B"\n' +# +# >>> yaml_dump({"emoji": "👀", "some unicode": "日本か"}) +# 'emoji: "👀"\nsome unicode: "日本か"\n' +# ``` +yaml_dump: Callable[..., str] = partial(yaml.dump, stream=None, allow_unicode=True) # type: ignore + + +@contextlib.contextmanager +def SoftTemporaryDirectory( + suffix: str | None = None, + prefix: str | None = None, + dir: Path | str | None = None, + **kwargs, +) -> Generator[Path, None, None]: + """ + Context manager to create a temporary directory and safely delete it. + + If tmp directory cannot be deleted normally, we set the WRITE permission and retry. + If cleanup still fails, we give up but don't raise an exception. This is equivalent + to `tempfile.TemporaryDirectory(..., ignore_cleanup_errors=True)` introduced in + Python 3.10. + + See https://www.scivision.dev/python-tempfile-permission-error-windows/. + """ + tmpdir = tempfile.TemporaryDirectory(prefix=prefix, suffix=suffix, dir=dir, **kwargs) + yield Path(tmpdir.name).resolve() + + try: + # First once with normal cleanup + shutil.rmtree(tmpdir.name) + except Exception: + # If failed, try to set write permission and retry + try: + shutil.rmtree(tmpdir.name, onerror=_set_write_permission_and_retry) + except Exception: + pass + + # And finally, cleanup the tmpdir. + # If it fails again, give up but do not throw error + try: + tmpdir.cleanup() + except Exception: + pass + + +def _set_write_permission_and_retry(func, path, excinfo): + os.chmod(path, stat.S_IWRITE) + func(path) + + +@contextlib.contextmanager +def WeakFileLock(lock_file: str | Path, *, timeout: float | None = None) -> Generator[BaseFileLock, None, None]: + """A filelock with some custom logic. + + This filelock is weaker than the default filelock in that: + 1. It won't raise an exception if release fails. + 2. It will default to a SoftFileLock if the filesystem does not support flock. + 3. Lock files are created with mode 0o664 (group-writable) instead of the default 0o644. + This allows multiple users sharing a cache directory to wait for locks. + + An INFO log message is emitted every 10 seconds if the lock is not acquired immediately. + If a timeout is provided, a `filelock.Timeout` exception is raised if the lock is not acquired within the timeout. + """ + log_interval = constants.FILELOCK_LOG_EVERY_SECONDS + lock = FileLock(lock_file, timeout=log_interval, mode=0o664) + start_time = time.time() + + while True: + elapsed_time = time.time() - start_time + if timeout is not None and elapsed_time >= timeout: + raise Timeout(str(lock_file)) + + try: + lock.acquire(timeout=min(log_interval, timeout - elapsed_time) if timeout else log_interval) + except Timeout: + logger.info( + f"Still waiting to acquire lock on {lock_file} (elapsed: {time.time() - start_time:.1f} seconds)" + ) + except NotImplementedError as e: + if "use SoftFileLock instead" in str(e): + logger.warning( + "FileSystem does not appear to support flock. Falling back to SoftFileLock for %s", lock_file + ) + lock = SoftFileLock(lock_file, timeout=log_interval) + continue + else: + break + + try: + yield lock + finally: + try: + lock.release() + except OSError: + try: + Path(lock_file).unlink() + except OSError: + pass diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_git_credential.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_git_credential.py new file mode 100644 index 0000000000000000000000000000000000000000..8ef2b2dce55c1274d89dc9e34beaf92d0989f8e3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_git_credential.py @@ -0,0 +1,119 @@ +# Copyright 2022-present, the HuggingFace Inc. team. +# +# 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. +"""Contains utilities to manage Git credentials.""" + +import re +import subprocess + +from ..constants import ENDPOINT +from ._subprocess import run_interactive_subprocess, run_subprocess + + +GIT_CREDENTIAL_REGEX = re.compile( + r""" + ^\s* # start of line + credential\.helper # credential.helper value + \s*=\s* # separator + ([\w\-\/]+) # the helper name or absolute path (group 1) + (\s|$) # whitespace or end of line + """, + flags=re.MULTILINE | re.IGNORECASE | re.VERBOSE, +) + + +def list_credential_helpers(folder: str | None = None) -> list[str]: + """Return the list of git credential helpers configured. + + See https://git-scm.com/docs/gitcredentials. + + Credentials are saved in all configured helpers (store, cache, macOS keychain,...). + Calls "`git credential approve`" internally. See https://git-scm.com/docs/git-credential. + + Args: + folder (`str`, *optional*): + The folder in which to check the configured helpers. + """ + try: + output = run_subprocess("git config --list", folder=folder).stdout + parsed = _parse_credential_output(output) + return parsed + except subprocess.CalledProcessError as exc: + raise OSError(exc.stderr) + + +def set_git_credential(token: str, username: str = "hf_user", folder: str | None = None) -> None: + """Save a username/token pair in git credential for HF Hub registry. + + Credentials are saved in all configured helpers (store, cache, macOS keychain,...). + Calls "`git credential approve`" internally. See https://git-scm.com/docs/git-credential. + + Args: + username (`str`, defaults to `"hf_user"`): + A git username. Defaults to `"hf_user"`, the default user used in the Hub. + token (`str`, defaults to `"hf_user"`): + A git password. In practice, the User Access Token for the Hub. + See https://huggingface.co/settings/tokens. + folder (`str`, *optional*): + The folder in which to check the configured helpers. + """ + with run_interactive_subprocess("git credential approve", folder=folder) as ( + stdin, + _, + ): + stdin.write(f"url={ENDPOINT}\nusername={username.lower()}\npassword={token}\n\n") + stdin.flush() + + +def unset_git_credential(username: str = "hf_user", folder: str | None = None) -> None: + """Erase credentials from git credential for HF Hub registry. + + Credentials are erased from the configured helpers (store, cache, macOS + keychain,...), if any. If `username` is not provided, any credential configured for + HF Hub endpoint is erased. + Calls "`git credential erase`" internally. See https://git-scm.com/docs/git-credential. + + Args: + username (`str`, defaults to `"hf_user"`): + A git username. Defaults to `"hf_user"`, the default user used in the Hub. + folder (`str`, *optional*): + The folder in which to check the configured helpers. + """ + with run_interactive_subprocess("git credential reject", folder=folder) as ( + stdin, + _, + ): + standard_input = f"url={ENDPOINT}\n" + if username is not None: + standard_input += f"username={username.lower()}\n" + standard_input += "\n" + + stdin.write(standard_input) + stdin.flush() + + +def _parse_credential_output(output: str) -> list[str]: + """Parse the output of `git credential fill` to extract the password. + + Args: + output (`str`): + The output of `git credential fill`. + """ + # NOTE: If user has set a helper for a custom URL, it will not be caught here. + # Example: `credential.https://huggingface.co.helper=store` + # See: https://github.com/huggingface/huggingface_hub/pull/1138#discussion_r1013324508 + return sorted( # Sort for nice printing + { # Might have some duplicates + match[0] for match in GIT_CREDENTIAL_REGEX.findall(output) + } + ) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_headers.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_headers.py new file mode 100644 index 0000000000000000000000000000000000000000..aa6867401da47688c66cc1183e04d3facb708262 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_headers.py @@ -0,0 +1,208 @@ +# Copyright 2022-present, the HuggingFace Inc. team. +# +# 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. +"""Contains utilities to handle headers to send in calls to Huggingface Hub.""" + +from huggingface_hub.errors import LocalTokenNotFoundError + +from .. import constants +from ._auth import get_token +from ._detect_agent import detect_agent +from ._runtime import ( + get_hf_hub_version, + get_python_version, + get_torch_version, + is_torch_available, +) +from ._validators import validate_hf_hub_args + + +@validate_hf_hub_args +def build_hf_headers( + *, + token: bool | str | None = None, + library_name: str | None = None, + library_version: str | None = None, + user_agent: dict | str | None = None, + headers: dict[str, str] | None = None, +) -> dict[str, str]: + """ + Build headers dictionary to send in a HF Hub call. + + By default, authorization token is always provided either from argument (explicit + use) or retrieved from the cache (implicit use). To explicitly avoid sending the + token to the Hub, set `token=False` or set the `HF_HUB_DISABLE_IMPLICIT_TOKEN` + environment variable. + + In case of an API call that requires write access, an error is thrown if token is + `None` or token is an organization token (starting with `"api_org***"`). + + In addition to the auth header, a user-agent is added to provide information about + the installed packages (versions of python, huggingface_hub, torch). + + Args: + token (`str`, `bool`, *optional*): + The token to be sent in authorization header for the Hub call: + - if a string, it is used as the Hugging Face token + - if `True`, the token is read from the machine (cache or env variable) + - if `False`, authorization header is not set + - if `None`, the token is read from the machine only except if + `HF_HUB_DISABLE_IMPLICIT_TOKEN` env variable is set. + library_name (`str`, *optional*): + The name of the library that is making the HTTP request. Will be added to + the user-agent header. + library_version (`str`, *optional*): + The version of the library that is making the HTTP request. Will be added + to the user-agent header. + user_agent (`str`, `dict`, *optional*): + The user agent info in the form of a dictionary or a single string. It will + be completed with information about the installed packages. + headers (`dict`, *optional*): + Additional headers to include in the request. Those headers take precedence + over the ones generated by this function. + + Returns: + A `dict` of headers to pass in your API call. + + Example: + ```py + >>> build_hf_headers(token="hf_***") # explicit token + {"authorization": "Bearer hf_***", "user-agent": ""} + + >>> build_hf_headers(token=True) # explicitly use cached token + {"authorization": "Bearer hf_***",...} + + >>> build_hf_headers(token=False) # explicitly don't use cached token + {"user-agent": ...} + + >>> build_hf_headers() # implicit use of the cached token + {"authorization": "Bearer hf_***",...} + + # HF_HUB_DISABLE_IMPLICIT_TOKEN=True # to set as env variable + >>> build_hf_headers() # token is not sent + {"user-agent": ...} + + >>> build_hf_headers(library_name="transformers", library_version="1.2.3") + {"authorization": ..., "user-agent": "transformers/1.2.3; hf_hub/0.10.2; python/3.10.4; tensorflow/1.55"} + ``` + + Raises: + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If organization token is passed and "write" access is required. + [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) + If "write" access is required but token is not passed and not saved locally. + [`EnvironmentError`](https://docs.python.org/3/library/exceptions.html#EnvironmentError) + If `token=True` but token is not saved locally. + """ + # Get auth token to send + token_to_send = get_token_to_send(token) + + # Combine headers + hf_headers = { + "user-agent": _http_user_agent( + library_name=library_name, + library_version=library_version, + user_agent=user_agent, + ) + } + if token_to_send is not None: + hf_headers["authorization"] = f"Bearer {token_to_send}" + if headers is not None: + hf_headers.update(headers) + return hf_headers + + +def get_token_to_send(token: bool | str | None) -> str | None: + """Select the token to send from either `token` or the cache.""" + # Case token is explicitly provided + if isinstance(token, str): + return token + + # Case token is explicitly forbidden + if token is False: + return None + + # Case token is explicitly required + if token is True: + cached_token = get_token() + if cached_token is None: + raise LocalTokenNotFoundError( + "Token is required (`token=True`), but no token found. You" + " need to provide a token or be logged in to Hugging Face with" + " `hf auth login` or `huggingface_hub.login`. See" + " https://huggingface.co/settings/tokens." + ) + return cached_token + + # Case implicit use of the token is forbidden by env variable. Checked before resolving the + # cached token: `get_token()` may refresh an OAuth token (network call + file writes), which + # must not happen when the resolved token wouldn't be used anyway. + if constants.HF_HUB_DISABLE_IMPLICIT_TOKEN: + return None + + # Otherwise: we use the cached token as the user has not explicitly forbidden it + return get_token() + + +def _http_user_agent( + *, + library_name: str | None = None, + library_version: str | None = None, + user_agent: dict | str | None = None, +) -> str: + """Format a user-agent string containing information about the installed packages. + + Args: + library_name (`str`, *optional*): + The name of the library that is making the HTTP request. + library_version (`str`, *optional*): + The version of the library that is making the HTTP request. + user_agent (`str`, `dict`, *optional*): + The user agent info in the form of a dictionary or a single string. + + Returns: + The formatted user-agent string. + """ + if library_name is not None: + ua = f"{library_name}/{library_version}" + else: + ua = "unknown/None" + ua += f"; hf_hub/{get_hf_hub_version()}" + ua += f"; python/{get_python_version()}" + + if not constants.HF_HUB_DISABLE_TELEMETRY: + if is_torch_available(): + ua += f"; torch/{get_torch_version()}" + + agent = detect_agent() + if agent: + ua += f"; agent/{agent}" + + if isinstance(user_agent, dict): + ua += "; " + "; ".join(f"{k}/{v}" for k, v in user_agent.items()) + elif isinstance(user_agent, str): + ua += "; " + user_agent + + # Retrieve user-agent origin headers from environment variable + origin = constants.HF_HUB_USER_AGENT_ORIGIN + if origin is not None: + ua += "; origin/" + origin + + return _deduplicate_user_agent(ua) + + +def _deduplicate_user_agent(user_agent: str) -> str: + """Deduplicate redundant information in the generated user-agent.""" + # Split around ";" > Strip whitespaces > Store as dict keys (ensure unicity) > format back as string + # Order is implicitly preserved by dictionary structure (see https://stackoverflow.com/a/53657523). + return "; ".join({key.strip(): None for key in user_agent.split(";")}.keys()) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_hf_uris.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_hf_uris.py new file mode 100644 index 0000000000000000000000000000000000000000..a678c3e1c753ea97ee42794e1b7d6d00040089d7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_hf_uris.py @@ -0,0 +1,642 @@ +# Copyright 2026-present, the HuggingFace Inc. team. +# +# 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. +"""Centralized parser for Hugging Face Hub URIs ('hf://...') and mount specifications. + +A HF URI is a URI-like string that identifies a location on the Hugging Face +Hub: a model/dataset/space/kernel repository, a bucket, optionally a revision, +and optionally a path inside the repo or bucket. + +Canonical syntax: + +``` +hf://[/][@][/] +``` + +For convenience, [`parse_hf_uri`] also accepts Hugging Face **web URLs** (the +ones you copy-paste from your browser), e.g. +'https://huggingface.co/datasets/my-org/my-dataset/blob/main/train.csv'. They are +normalized to the canonical 'hf://' form before parsing. Only unambiguous URLs +(repository / bucket pages and file/folder viewer routes) are accepted; any other +route is rejected rather than guessed. + +A HF mount wraps a HF URI with a local mount path and an optional ':ro'/':rw' +flag (used by Spaces and Jobs volumes): + +``` +hf://[/][@][/]:[:ro|:rw] +``` + +See 'docs/source/en/package_reference/hf_uris.md' for the full grammar and examples. +""" + +import functools +import re +from dataclasses import dataclass, field +from urllib.parse import quote, unquote, urlsplit + +from huggingface_hub import constants +from huggingface_hub.errors import HfUriError, HFValidationError + +from ._validators import validate_repo_id + + +# Inverse map (singular -> plural URI prefix). Built once from the canonical +# 'constants.HF_URI_TYPE_PREFIXES' and used to render URIs. +_TYPE_TO_PREFIX: dict[str, str] = {v: k for k, v in constants.HF_URI_TYPE_PREFIXES.items()} + +# Special revisions that contain a '/'. They take precedence when splitting +# the part after '@' into '/'. Matches 'refs/pr/N' +# (Pull Request refs) and 'refs/convert/' (e.g. parquet conversions). +# The conversion name allows the typical git ref characters '[a-zA-Z0-9_.-]' +# so names like 'parquet-v2' or 'duckdb.v1' round-trip correctly. +_SPECIAL_REFS_REVISION_REGEX = re.compile(r"^refs/(?:convert/[\w.-]+|pr/\d+)") + +# Same as constants.HfUriType, but as a set of strings for easy lookup.) +_VALID_URI_TYPES: frozenset[str] = frozenset(constants.HF_URI_TYPE_PREFIXES.values()) + + +# Web-viewer routes that point at a file or folder and that map cleanly onto a +# '/' pair. Other routes (commit, commits, discussions, settings, +# edit, ...) do not identify a Hub location and are rejected by the URL parser. +_URL_REPO_LOCATION_ACTIONS: frozenset[str] = frozenset({"blame", "blob", "raw", "resolve", "tree"}) +# Bucket web routes that point at a file or folder. Buckets are not versioned, so +# these are followed directly by '' (no revision segment). +_URL_BUCKET_LOCATION_ACTIONS: frozenset[str] = frozenset({"resolve", "tree"}) + + +@dataclass(frozen=True) +class HfUri: + """Parsed representation of a Hugging Face Hub URI ('hf://...'). + + Attributes: + type (`str`): + One of 'model', 'dataset', 'space', 'kernel' or 'bucket'. + id (`str`): + The repository id ('namespace/name', e.g. 'my-org/my-model') for repo URIs, or the bucket id ('namespace/name') for bucket URIs. + revision (`str`, *optional*): + The revision specified after '@' in the URI, URL-decoded. 'None' if no revision was specified, or for bucket URIs (which + never carry a revision). Special refs like 'refs/pr/10' and 'refs/convert/parquet' are preserved as-is. + path_in_repo (`str`): + The path inside the repo or bucket. Empty string if the URI points at the root. + """ + + type: constants.HfUriType + id: str + revision: str | None = None + path_in_repo: str = "" + _raw: str | None = field(repr=False, hash=False, compare=False, default=None) + + def __post_init__(self) -> None: + uri = self._raw or "" # For error messages + + # Check valid URI type + if self.type not in _VALID_URI_TYPES: + raise HfUriError(uri=uri, msg=f"Invalid type '{self.type}'. Must be one of {sorted(_VALID_URI_TYPES)}.") + + # Check valid ID + if not self.id or self.id.count("/") != 1: + raise HfUriError(uri=uri, msg=f"Id must be 'namespace/name', got '{self.id}'.") + if self.type != "bucket": + try: + validate_repo_id(self.id) + except HFValidationError as e: + raise HfUriError(uri=uri, msg=str(e)) from e + + # Check valid revision + if self.revision is not None and not self.revision: + raise HfUriError(uri=uri, msg="Revision must not be an empty string.") + if self.type == "bucket" and self.revision is not None: + raise HfUriError(uri=uri, msg="Bucket URIs do not support a revision.") + + # Check valid path in repo + if self.path_in_repo: + if self.path_in_repo.startswith("/") or "//" in self.path_in_repo: + raise HfUriError(uri=uri, msg=f"Path must not contain empty segments (got '{self.path_in_repo}').") + + @property + def is_bucket(self) -> bool: + """True if this URI points at a bucket.""" + return self.type == "bucket" + + @property + def is_repo(self) -> bool: + """True if this URI points at a repository (model, dataset, space or kernel).""" + return self.type != "bucket" + + def to_uri(self) -> str: + """Render the URI as a canonical 'hf://' string. + + The type prefix is always written explicitly (e.g. 'hf://models/my-org/my-model'). + """ + parts: list[str] = [constants.HF_PROTOCOL, _TYPE_TO_PREFIX[self.type], "/", self.id] + if self.revision is not None: + # Encode '/' as '%2F' for revisions that would otherwise be split as '/' + # at parse time. Special refs ('refs/pr/N', 'refs/convert/') are kept verbatim + # because the parser matches them eagerly. + revision = self.revision + if "/" in revision and _SPECIAL_REFS_REVISION_REGEX.fullmatch(revision) is None: + revision = revision.replace("/", "%2F") + parts.append(f"@{revision}") + if self.path_in_repo: + parts.append(f"/{self.path_in_repo}") + return "".join(parts) + + def to_url(self, endpoint: str | None = None) -> str: + """Render the URI as a Hugging Face **web URL** (the kind you open in a browser). + + This is the inverse of parsing a URL with [`parse_hf_uri`]. The returned URL points at: + + - the repository / bucket landing page when no path or revision is set; + - the folder viewer ('/tree/') when only a revision is set; + - the file viewer ('/blob//') for repository files (revision defaults to 'main'); + - the tree route ('/tree/') for bucket files (buckets are not versioned). + + Args: + endpoint (`str`, *optional*): + Base endpoint to use. Defaults to 'constants.ENDPOINT' (i.e. 'https://huggingface.co'). + + Returns: + `str`: the web URL. + + Example: + ```py + >>> from huggingface_hub import parse_hf_uri + >>> parse_hf_uri("hf://datasets/my-org/my-dataset@v1/train.csv").to_url() + 'https://huggingface.co/datasets/my-org/my-dataset/blob/v1/train.csv' + ``` + """ + base = (endpoint or constants.ENDPOINT).rstrip("/") + # Percent-encode characters that would otherwise break the URL (spaces, '#', '?', ...), + # keeping '/' as the path separator. This is the inverse of the decoding done when parsing. + path = quote(self.path_in_repo, safe="/") + + if self.type == "bucket": + url = f"{base}/buckets/{self.id}" + if path: + url += f"/tree/{path}" + return url + + # Models live at the root ('hf.co/'); other repos are namespaced by their plural prefix. + url = f"{base}/{self.id}" if self.type == "model" else f"{base}/{_TYPE_TO_PREFIX[self.type]}/{self.id}" + revision = self.revision + # Percent-encode the branch/tag name so it stays a single, URL-safe segment: a '/' would + # otherwise open a new path segment and '#'/'?' would be read as a fragment/query when the + # URL is opened or parsed back. This mirrors the decoding done when parsing. Special refs + # ('refs/pr/N', 'refs/convert/') are used verbatim by the Hub web routes. + if revision is not None and _SPECIAL_REFS_REVISION_REGEX.fullmatch(revision) is None: + revision = quote(revision, safe="") + if path: + url += f"/blob/{revision or constants.DEFAULT_REVISION}/{path}" + elif revision is not None: + url += f"/tree/{revision}" + return url + + +@dataclass(frozen=True) +class HfMount: + """A HF URI paired with a local mount path and optional read-only flag. + + Used by Spaces and Jobs to describe volume mounts. The full syntax is: + + ``` + hf://[/][@][/]:[:ro|:rw] + ``` + + Attributes: + source ([`HfUri`]): + The parsed HF URI identifying the Hub resource to mount. + mount_path (`str`): + The local mount path (always starts with '/'). + read_only (`bool`, *optional*): + True if the mount ends with ':ro', False if it ends with ':rw', 'None' if no flag was provided. + """ + + source: HfUri + mount_path: str + read_only: bool | None = None + _raw: str | None = field(repr=False, hash=False, compare=False, default=None) + + def __post_init__(self) -> None: + raw = self._raw or "" + if not self.mount_path.startswith("/") or self.mount_path == "/": + raise HfUriError( + uri=raw, + msg=f"Mount path must be a non-empty absolute path starting with '/', got '{self.mount_path}'.", + ) + + def to_uri(self) -> str: + """Render the mount as a canonical 'hf://' string. + + Example: 'hf://models/my-org/my-model:/data:ro' + """ + parts = [self.source.to_uri(), ":", self.mount_path] + if self.read_only is not None: + parts.append(":ro" if self.read_only else ":rw") + return "".join(parts) + + +def is_hf_uri(uri: str) -> bool: + """Check if a string is a valid HF URI ('hf://...') or a recognized Hugging Face web URL.""" + try: + parse_hf_uri(uri) + return True + except HfUriError: + return False + + +@functools.lru_cache +def parse_hf_uri(uri: str, endpoint: str | None = None) -> HfUri: + """Parse a Hugging Face Hub URI ('hf://...') or a Hugging Face web URL. + + A HF URI is a URI-like string identifying a location on the Hugging Face Hub. The full grammar is: + + ``` + hf://[/][@][/] + ``` + + For convenience, Hugging Face **web URLs** (the ones you copy-paste from the website) are also + accepted and normalized to the canonical 'hf://' form, e.g. + 'https://huggingface.co/datasets/my-org/my-dataset/blob/main/train.csv'. Only unambiguous URLs + (repository / bucket pages and file/folder viewer routes) are accepted; any other route is rejected. + + See 'docs/source/en/package_reference/hf_uris.md' for the full specification. + + Args: + uri (`str`): + The URI to parse. Must start with 'hf://', or be a Hugging Face URL (e.g. 'https://huggingface.co/...'). + endpoint (`str`, *optional*): + A custom Hub endpoint (e.g. a self-hosted or proxied Hub like 'https://hub.my-company.com' or + 'http://localhost:8080/hf'). When provided, web URLs on that endpoint are recognized in addition to + the default Hugging Face hosts. Has no effect on 'hf://' URIs. + + Returns: + [`HfUri`]: the parsed URI. + + Raises: + [`HfUriError`]: + If the URI is malformed (missing prefix, invalid type, missing id, unsupported URL route, etc.). + + Examples: + ```py + >>> from huggingface_hub.utils import parse_hf_uri + >>> parse_hf_uri("hf://my-org/my-model") + HfUri(type='model', id='my-org/my-model', revision=None, path_in_repo='') + >>> parse_hf_uri("hf://datasets/my-org/my-dataset@refs/pr/3/train.json") + HfUri(type='dataset', id='my-org/my-dataset', revision='refs/pr/3', path_in_repo='train.json') + >>> parse_hf_uri("https://huggingface.co/datasets/my-org/my-dataset/blob/main/train.csv") + HfUri(type='dataset', id='my-org/my-dataset', revision='main', path_in_repo='train.csv') + ``` + """ + raw = uri + if uri.startswith(constants.HF_PROTOCOL): + body = uri[len(constants.HF_PROTOCOL) :] + if not body: + raise HfUriError(uri, f"Empty body after '{constants.HF_PROTOCOL}'.") + elif _looks_like_hf_url(uri, endpoint=endpoint): + body = _url_to_uri_body(uri, endpoint=endpoint) + else: + raise HfUriError( + uri, + f"Must start with '{constants.HF_PROTOCOL}' or be a Hugging Face URL (e.g. 'https://huggingface.co/...'). " + f"Expected format: {constants.HF_PROTOCOL}[/][@][/]", + ) + + type_, location = _split_type(body, raw=raw) + + if type_ == "bucket": + return _parse_bucket_body(location, type_, raw=raw) + return _parse_repo_body(location, type_, raw=raw) + + +def _endpoint_host_and_path(endpoint: str | None) -> tuple[str | None, str]: + """Return the lowercased host and stripped path prefix of a custom Hub 'endpoint'. + + E.g. 'https://hub.my-company.com' -> ('hub.my-company.com', '') and a self-hosted + 'http://localhost:8080/hf' -> ('localhost', 'hf'). Returns '(None, "")' when 'endpoint' is None. + """ + if endpoint is None: + return None, "" + # Prefix '//' for scheme-less endpoints so 'urlsplit' populates 'netloc' instead of 'path'. + parsed = urlsplit(endpoint if "://" in endpoint else "//" + endpoint) + host = parsed.hostname.lower() if parsed.hostname else None + return host, parsed.path.strip("/") + + +def _recognized_hosts(endpoint: str | None) -> frozenset[str]: + """The set of hosts whose web URLs can be parsed: the default Hugging Face hosts plus 'endpoint'.""" + host, _ = _endpoint_host_and_path(endpoint) + return constants.HF_URL_HOSTS | {host} if host else constants.HF_URL_HOSTS + + +def _looks_like_hf_url(uri: str, endpoint: str | None = None) -> bool: + """Return True if 'uri' looks like a (possibly scheme-less) Hugging Face web URL.""" + lowered = uri.lower() + if lowered.startswith(("http://", "https://")): + return True + # Scheme-less host (e.g. 'huggingface.co/org/model'). + return any(lowered == host or lowered.startswith(host + "/") for host in _recognized_hosts(endpoint)) + + +def _decode_url_path_segment(segment: str) -> str: + """Percent-decode a single URL path segment (e.g. 'file%20name.txt' -> 'file name.txt'). + + A decoded '/' is re-encoded as '%2F' so the segment stays atomic when the normalized body is + re-split by the shared parser. This decodes ordinary path characters (spaces, '#', ...) that + browsers encode, while keeping '%2F'-encoded revisions (e.g. 'feature%2Ffoo') intact. + """ + return unquote(segment).replace("/", "%2F") + + +def _url_to_uri_body(url: str, endpoint: str | None = None) -> str: + """Normalize a Hugging Face web URL into the body of a 'hf://' URI (everything after 'hf://'). + + The returned string is fed back into the regular URI parsing logic, so all validation + (repo id, revision, empty path segments, ...) is shared with the canonical 'hf://' path. + Only unambiguous URLs are accepted: any unrecognized route raises [`HfUriError`]. When 'endpoint' + is provided, URLs on that custom Hub host are recognized too (and its path prefix is stripped). + """ + raw = url + # Prefix '//' for scheme-less inputs so 'urlsplit' populates 'netloc' instead of 'path'. + parsed = urlsplit(url if "://" in url else "//" + url) + host = (parsed.hostname or "").lower() + if host not in _recognized_hosts(endpoint): + raise HfUriError( + uri=raw, + msg=f"Unrecognized host '{host or url}'. Expected a Hugging Face URL (e.g. 'https://huggingface.co/...').", + ) + + # Query string and fragment are intentionally dropped (e.g. '?download=true'). + path = parsed.path + # For a self-hosted endpoint with a path prefix (e.g. 'http://localhost:8080/hf'), drop it so the + # remaining segments are '[/]/[/...]' just like on the public Hub. + endpoint_host, endpoint_path = _endpoint_host_and_path(endpoint) + if endpoint_path and host == endpoint_host: + prefix = "/" + endpoint_path + if path == prefix or path.startswith(prefix + "/"): + path = path[len(prefix) :] + segments = [segment for segment in path.split("/") if segment] + if not segments: + raise HfUriError(uri=raw, msg=f"Missing repository or bucket identifier in URL '{url}'.") + + # Optional type prefix ('datasets', 'spaces', 'kernels', 'buckets', 'models'). + type_prefix: str | None = None + if segments[0] in constants.HF_URI_TYPE_PREFIXES: + type_prefix = segments[0] + segments = segments[1:] + + # Everything in the web UI is namespaced ('/'); a single segment is a user or + # organization page (or a listing page), which we cannot map to a repository -> reject. + if len(segments) < 2: + raise HfUriError( + uri=raw, + msg=( + f"Cannot parse URL '{url}': expected a '/' repository or bucket. " + "User/organization pages and single-segment URLs are not supported." + ), + ) + repo_id = f"{segments[0]}/{segments[1]}" + rest = segments[2:] + + if type_prefix == "buckets": + if not rest: + return f"buckets/{repo_id}" + action, *tail = rest + if action not in _URL_BUCKET_LOCATION_ACTIONS: + raise HfUriError(uri=raw, msg=f"Cannot parse bucket URL '{url}': unsupported '/{action}/' route.") + path = "/".join(_decode_url_path_segment(segment) for segment in tail) + return f"buckets/{repo_id}/{path}" if path else f"buckets/{repo_id}" + + prefix = f"{type_prefix}/" if type_prefix else "" + if not rest: + return f"{prefix}{repo_id}" + action, *tail = rest + if action not in _URL_REPO_LOCATION_ACTIONS: + raise HfUriError( + uri=raw, + msg=( + f"Cannot parse URL '{url}': unsupported '/{action}/' route. " + "Only repository pages and file/folder viewer routes (blob, resolve, raw, tree, ...) can be parsed." + ), + ) + if not tail: + # e.g. '.../tree' with nothing after -> repository root. + return f"{prefix}{repo_id}" + # 'tail' is '/'; reuse the canonical '@/' splitting logic + # (special refs, URL-encoded slashes, ...) by handing it back to the URI parser. Each segment + # is percent-decoded first so file names with spaces, '#', ... resolve correctly; the revision + # segment's '%2F' survives (re-encoded by '_decode_url_path_segment') and is decoded downstream. + decoded = "/".join(_decode_url_path_segment(segment) for segment in tail) + return f"{prefix}{repo_id}@{decoded}" + + +def parse_hf_mount(mount_str: str) -> HfMount: + """Parse a HF mount specification ('hf://...:[:ro|:rw]'). + + A mount specification is a HF URI followed by a local mount path and an optional read-only/read-write flag. + The full grammar is: + + ``` + hf://[/][@][/]:[:ro|:rw] + ``` + + See 'docs/source/en/package_reference/hf_uris.md' for the full specification. + + Args: + mount_str (`str`): + The mount string to parse. Must start with 'hf://' and contain a ':' segment. + + Returns: + [`HfMount`]: the parsed mount. + + Raises: + [`HfUriError`]: + If the mount string is malformed (missing mount path, invalid URI, etc.). + + Examples: + ```py + >>> from huggingface_hub.utils import parse_hf_mount + >>> parse_hf_mount("hf://my-org/my-model:/data:ro") + HfMount(source=HfUri(type='model', id='my-org/my-model', revision=None, path_in_repo=''), mount_path='/data', read_only=True) + >>> parse_hf_mount("hf://buckets/my-org/my-bucket/sub/dir:/mnt:rw") + HfMount(source=HfUri(type='bucket', id='my-org/my-bucket', revision=None, path_in_repo='sub/dir'), mount_path='/mnt', read_only=False) + ``` + """ + if not mount_str.startswith(constants.HF_PROTOCOL): + raise HfUriError( + uri=mount_str, + msg=f"Must start with '{constants.HF_PROTOCOL}'.", + ) + + raw = mount_str + body = mount_str[len(constants.HF_PROTOCOL) :] + if not body: + raise HfUriError(uri=raw, msg=f"Empty body after '{constants.HF_PROTOCOL}'.") + + location, mount_path, read_only = _split_mount(body, raw=raw) + + if mount_path is None: + raise HfUriError(uri=raw, msg="Missing mount path. Expected ':' (e.g. 'hf://org/model:/data').") + + # Re-assemble the URI part and parse it + uri_str = constants.HF_PROTOCOL + location + try: + source = parse_hf_uri(uri_str) + except HfUriError as e: + raise HfUriError(uri=raw, msg=e.msg) from e + + return HfMount(source=source, mount_path=mount_path, read_only=read_only, _raw=raw) + + +def _split_mount(body: str, *, raw: str) -> tuple[str, str | None, bool | None]: + """Split the ':[:ro|:rw]' suffix from 'body'. + + Returns '(location, mount_path, read_only)' where 'mount_path' is 'None' if no mount segment is present. + """ + if body.endswith(":ro"): + read_only, body = True, body.removesuffix(":ro") + elif body.endswith(":rw"): + read_only, body = False, body.removesuffix(":rw") + else: + read_only = None + + # Mount paths always start with '/', so the delimiter is ':/'. + # We use rfind() because the mount segment is always trailing + idx = body.rfind(":/") + if idx == -1: + if read_only is not None: + raise HfUriError( + uri=raw, + msg="':ro'/':rw' suffix is only valid when a mount path is provided (e.g. 'hf://...:/:ro').", + ) + return body, None, None + + location = body[:idx] + mount_path = body[idx + 1 :] # includes the leading '/' + if not location: + raise HfUriError(uri=raw, msg="Missing location before mount path.") + return location, mount_path, read_only + + +def _split_type(location: str, *, raw: str) -> tuple[constants.HfUriType, str]: + """Detect the (optional) type prefix and return '(type, remaining_location)'. + + A missing type prefix defaults to 'model'. Singular forms ('model/', 'dataset/', etc.) are explicitly rejected with a helpful error. + """ + slash_idx = location.find("/") + if slash_idx == -1: + # Single segment, no prefix. Reject if it looks like a bare type name. + if location in constants.HF_URI_TYPE_PREFIXES: + raise HfUriError( + uri=raw, + msg=f"Missing identifier after '{location}'. Expected '{constants.HF_PROTOCOL}{location}/'.", + ) + if (singular_plural := _TYPE_TO_PREFIX.get(location)) is not None: + raise HfUriError( + uri=raw, + msg=f"Type prefix must be plural. Did you mean '{constants.HF_PROTOCOL}{singular_plural}/...'?", + ) + return "model", location + + first = location[:slash_idx] + rest = location[slash_idx + 1 :] + if first in constants.HF_URI_TYPE_PREFIXES: + return constants.HF_URI_TYPE_PREFIXES[first], rest + if (singular_plural := _TYPE_TO_PREFIX.get(first)) is not None: + raise HfUriError( + uri=raw, msg=f"Type prefix must be plural, got '{first}/'. Did you mean '{singular_plural}/'?" + ) + return "model", location + + +def _parse_bucket_body( + location: str, + type_: constants.HfUriType, + *, + raw: str, +) -> HfUri: + """Parse the body of a bucket URI: 'namespace/name[/path]'.""" + location = location.strip("/") + parts = location.split("/", 2) + if len(parts) < 2 or not parts[0] or not parts[1]: + raise HfUriError(uri=raw, msg=f"Bucket id must be 'namespace/name', got '{location}'.") + bucket_id = f"{parts[0]}/{parts[1]}" + if "@" in bucket_id: + raise HfUriError(uri=raw, msg="Bucket URIs do not support a revision marker ('@').") + path_in_bucket = parts[2] if len(parts) >= 3 else "" + return HfUri( + type=type_, + id=bucket_id, + revision=None, + path_in_repo=path_in_bucket, + _raw=raw, + ) + + +def _parse_repo_body( + location: str, + type_: constants.HfUriType, + *, + raw: str, +) -> HfUri: + """Parse the body of a repo URI: '[@][/]'.""" + location = location.strip("/") + if not location: + raise HfUriError(uri=raw, msg="Missing repository id.") + + # The '@' separates the repo_id from the revision, but only when it + # appears right after 'namespace/name' (at most one '/' before it). + # An '@' deeper in the path (e.g. in a filename like 'file@1.txt') is literal. + at_idx = location.find("@") + revision: str | None + + if at_idx == -1 or location[:at_idx].count("/") > 1: + # No '@' at all, or the '@' is past the repo_id portion (in a filename). + revision = None + parts = location.split("/", 2) + if len(parts) < 2: + raise HfUriError(uri=raw, msg=f"Repository id must be 'namespace/name', got '{location}'. ") + repo_id = f"{parts[0]}/{parts[1]}" + path_in_repo = parts[2] if len(parts) > 2 else "" + else: + repo_id = location[:at_idx] + rev_and_path = location[at_idx + 1 :] + if not repo_id: + raise HfUriError(uri=raw, msg="Missing repository id before '@'.") + if repo_id.count("/") != 1: + raise HfUriError(uri=raw, msg=f"Repository id must be 'namespace/name', got '{repo_id}'.") + # Special refs like 'refs/pr/10' contain '/' and must be matched eagerly, + # otherwise we would split them at the first '/' and treat the rest as a path. + match = _SPECIAL_REFS_REVISION_REGEX.match(rev_and_path) + if match is not None: + revision = match.group() + path_in_repo = rev_and_path[len(revision) :].removeprefix("/") + else: + slash_idx = rev_and_path.find("/") + if slash_idx == -1: + revision = rev_and_path + path_in_repo = "" + else: + revision = rev_and_path[:slash_idx] + path_in_repo = rev_and_path[slash_idx + 1 :] + revision = unquote(revision) + if not revision: + raise HfUriError(uri=raw, msg="Empty revision after '@'.") + + return HfUri( + type=type_, + id=repo_id, + revision=revision, + path_in_repo=path_in_repo, + _raw=raw, + ) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_http.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_http.py new file mode 100644 index 0000000000000000000000000000000000000000..270f08dfafd615825b8c843c91621fa50762bd51 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_http.py @@ -0,0 +1,1161 @@ +# Copyright 2022-present, the HuggingFace Inc. team. +# +# 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. +"""Contains utilities to handle HTTP requests in huggingface_hub.""" + +import atexit +import io +import json +import os +import re +import threading +import time +import uuid +from collections.abc import Callable, Generator, Mapping +from contextlib import contextmanager +from dataclasses import dataclass +from shlex import quote +from typing import Any, TypeVar +from urllib.parse import urlparse + +import httpx + +from huggingface_hub.errors import OfflineModeIsEnabled + +from .. import constants +from ..errors import ( + BadRequestError, + BucketNotFoundError, + DisabledRepoError, + GatedRepoError, + HfHubHTTPError, + JobNotFoundError, + RemoteEntryNotFoundError, + RepositoryNotFoundError, + RevisionNotFoundError, +) +from . import logging +from ._lfs import SliceFileObj +from ._typing import HTTP_METHOD_T + + +logger = logging.get_logger(__name__) + + +@dataclass(frozen=True) +class RateLimitInfo: + """ + Parsed rate limit information from HTTP response headers. + + Attributes: + resource_type (`str`): The type of resource being rate limited. + remaining (`int`): The number of requests remaining in the current window. + reset_in_seconds (`int`): The number of seconds until the rate limit resets. + limit (`int`, *optional*): The maximum number of requests allowed in the current window. + window_seconds (`int`, *optional*): The number of seconds in the current window. + + """ + + resource_type: str + remaining: int + reset_in_seconds: int + limit: int | None = None + window_seconds: int | None = None + + +# Regex patterns for parsing rate limit headers +# e.g.: "api";r=0;t=55 --> resource_type="api", r=0, t=55 +_RATELIMIT_REGEX = re.compile(r"\"(?P\w+)\"\s*;\s*r\s*=\s*(?P\d+)\s*;\s*t\s*=\s*(?P\d+)") +# e.g.: "fixed window";"api";q=500;w=300 --> q=500, w=300 +_RATELIMIT_POLICY_REGEX = re.compile(r"q\s*=\s*(?P\d+).*?w\s*=\s*(?P\d+)") + + +def parse_ratelimit_headers(headers: Mapping[str, str]) -> RateLimitInfo | None: + """Parse rate limit information from HTTP response headers. + + Follows IETF draft: https://www.ietf.org/archive/id/draft-ietf-httpapi-ratelimit-headers-09.html + Only a subset is implemented. + + Example: + ```python + >>> from huggingface_hub.utils import parse_ratelimit_headers + >>> headers = { + ... "ratelimit": '"api";r=0;t=55', + ... "ratelimit-policy": '"fixed window";"api";q=500;w=300', + ... } + >>> info = parse_ratelimit_headers(headers) + >>> info.remaining + 0 + >>> info.reset_in_seconds + 55 + ``` + """ + + ratelimit: str | None = None + policy: str | None = None + for key in headers: + lower_key = key.lower() + if lower_key == "ratelimit": + ratelimit = headers[key] + elif lower_key == "ratelimit-policy": + policy = headers[key] + + if not ratelimit: + return None + + match = _RATELIMIT_REGEX.search(ratelimit) + if not match: + return None + + resource_type = match.group("resource_type") + remaining = int(match.group("r")) + reset_in_seconds = int(match.group("t")) + + limit: int | None = None + window_seconds: int | None = None + + if policy: + policy_match = _RATELIMIT_POLICY_REGEX.search(policy) + if policy_match: + limit = int(policy_match.group("q")) + window_seconds = int(policy_match.group("w")) + + return RateLimitInfo( + resource_type=resource_type, + remaining=remaining, + reset_in_seconds=reset_in_seconds, + limit=limit, + window_seconds=window_seconds, + ) + + +def _parse_retry_after(headers: Mapping[str, str]) -> int | None: + """Parse the standard `Retry-After` HTTP header into a number of seconds to wait. + + The `Retry-After` header can be either a non-negative number of seconds (delay-seconds) + or an HTTP-date after which to retry. We handle only the delay-seconds case. + + See https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Retry-After. + """ + value: str | None = None + for key in headers: + if key.lower() == "retry-after": + value = headers[key] + break + + if value is None: + return None + value = value.strip() + if not value: + return None + + if value.isdigit(): + return int(value) # e.g. "Retry-After: 120" + return None # e.g. "Retry-After: Wed, 21 Oct 2015 07:28:00 GMT" - not supported + + +# When raising an error, we include the request id in the error message for easier debugging. +# Request ID is sourced from headers in order of precedence: "X-Request-Id", "X-Amzn-Trace-Id", "X-Amz-Cf-Id". +X_REQUEST_ID = "x-request-id" +X_AMZN_TRACE_ID = "X-Amzn-Trace-Id" +X_AMZ_CF_ID = "x-amz-cf-id" + +REPO_API_REGEX = re.compile( + r""" + # staging or production endpoint + ^https://[^/]+ + ( + # on /api/repo_type/repo_id + /api/(models|datasets|spaces)/(.+) + | + # or /repo_id/resolve/revision/... + /(.+)/resolve/(.+) + ) + """, + flags=re.VERBOSE, +) + +BUCKET_API_REGEX = re.compile( + r""" + # staging or production endpoint + ^https?://[^/]+ + # on /api/buckets/... + /api/buckets/ + """, + flags=re.VERBOSE, +) + +# Regex to extract the job_id from a (scheduled) job API URL. +# Matches /api/jobs/{namespace}/{job_id}[/...] and /api/scheduled-jobs/{namespace}/{job_id}[/...]. +_JOB_ID_FROM_URL_REGEX = re.compile(r"^https?://[^/]+/api/(?:scheduled-jobs|jobs)/[^/]+/([^/?]+)") + +# Regex to extract repo_type and repo_id from API URLs. +# Captures: group(1) = repo_type plural (models/datasets/spaces), group(2) = first path segment, group(3) = optional second segment. +_REPO_ID_FROM_URL_REGEX = re.compile(r"^https?://[^/]+/api/(models|datasets|spaces)/([^/]+)(?:/([^/]+))?") + +# Regex to extract bucket_id (namespace/name) from bucket API URLs. +_BUCKET_ID_FROM_URL_REGEX = re.compile(r"^https?://[^/]+/api/buckets/([^/]+/[^/]+)") + +# Sub-paths that follow a repo_id in API URLs (not part of the repo name). +_REPO_URL_SUBPATHS = {"resolve", "tree", "blob", "raw", "refs", "commit", "discussions", "settings", "revision"} + + +def _parse_repo_info_from_url(url: str) -> tuple[str | None, str | None]: + """Extract (repo_type, repo_id) from an API URL. + + Returns canonical repo_type values: "model", "dataset", "space" (or None). + + Examples: + >>> _parse_repo_info_from_url("https://huggingface.co/api/models/user/repo") + ("model", "user/repo") + >>> _parse_repo_info_from_url("https://huggingface.co/api/datasets/user/repo/resolve/main/data.csv") + ("dataset", "user/repo") + >>> _parse_repo_info_from_url("https://huggingface.co/api/models/bert-base-cased/resolve/main/config.json") + ("model", "bert-base-cased") + """ + match = _REPO_ID_FROM_URL_REGEX.search(url) + if not match: + return None, None + repo_type = constants.REPO_TYPES_MAPPING.get(match.group(1)) + first, second = match.group(2), match.group(3) + if second and second not in _REPO_URL_SUBPATHS: + repo_id = f"{first}/{second}" + else: + repo_id = first + return repo_type, repo_id + + +def _parse_bucket_id_from_url(url: str) -> str | None: + """Extract bucket_id (namespace/name) from a bucket API URL.""" + match = _BUCKET_ID_FROM_URL_REGEX.search(url) + return match.group(1) if match else None + + +def _parse_job_id_from_url(url: str) -> str | None: + """Extract the job_id from a (scheduled) job API URL, if present.""" + match = _JOB_ID_FROM_URL_REGEX.search(url) + return match.group(1) if match else None + + +def hf_request_event_hook(request: httpx.Request) -> None: + """ + Event hook that will be used to make HTTP requests to the Hugging Face Hub. + + What it does: + - Block requests if offline mode is enabled + - Add a request ID to the request headers + - Log the request if debug mode is enabled + """ + if constants.is_offline_mode(): + raise OfflineModeIsEnabled( + f"Cannot reach {request.url}: offline mode is enabled. To disable it, please unset the `HF_HUB_OFFLINE` environment variable." + ) + + # Add random request ID => easier for server-side debugging + if X_AMZN_TRACE_ID not in request.headers: + request.headers[X_AMZN_TRACE_ID] = request.headers.get(X_REQUEST_ID) or str(uuid.uuid4()) + request_id = request.headers.get(X_AMZN_TRACE_ID) + + # Debug log + logger.debug( + "Request %s: %s %s (authenticated: %s)", + request_id, + request.method, + request.url, + request.headers.get("authorization") is not None, + ) + if constants.HF_DEBUG: + logger.debug("Send: %s", _curlify(request)) + + return request_id + + +async def async_hf_request_event_hook(request: httpx.Request) -> None: + """ + Async version of `hf_request_event_hook`. + """ + return hf_request_event_hook(request) + + +async def async_hf_response_event_hook(response: httpx.Response) -> None: + if response.status_code >= 400: + # If response will raise, read content from stream to have it available when raising the exception + # If content-length is not set or is too large, skip reading the content to avoid OOM + if "Content-length" in response.headers: + try: + length = int(response.headers["Content-length"]) + except ValueError: + return + + if length < 1_000_000: + await response.aread() + + +def default_client_factory() -> httpx.Client: + """ + Factory function to create a `httpx.Client` with the default transport. + """ + return httpx.Client( + event_hooks={"request": [hf_request_event_hook]}, + follow_redirects=True, + timeout=None, + ) + + +def default_async_client_factory() -> httpx.AsyncClient: + """ + Factory function to create a `httpx.AsyncClient` with the default transport. + """ + return httpx.AsyncClient( + event_hooks={"request": [async_hf_request_event_hook], "response": [async_hf_response_event_hook]}, + follow_redirects=True, + timeout=None, + ) + + +CLIENT_FACTORY_T = Callable[[], httpx.Client] +ASYNC_CLIENT_FACTORY_T = Callable[[], httpx.AsyncClient] + +_CLIENT_LOCK = threading.Lock() +_GLOBAL_CLIENT_FACTORY: CLIENT_FACTORY_T = default_client_factory +_GLOBAL_ASYNC_CLIENT_FACTORY: ASYNC_CLIENT_FACTORY_T = default_async_client_factory +_GLOBAL_CLIENT: httpx.Client | None = None + + +def set_client_factory(client_factory: CLIENT_FACTORY_T) -> None: + """ + Set the HTTP client factory to be used by `huggingface_hub`. + + The client factory is a method that returns a `httpx.Client` object. On the first call to [`get_session`] the client factory + will be used to create a new `httpx.Client` object that will be shared between all calls made by `huggingface_hub`. + + This can be useful if you are running your scripts in a specific environment requiring custom configuration (e.g. custom proxy or certifications). + + Use [`get_session`] to get a correctly configured `httpx.Client`. + """ + global _GLOBAL_CLIENT_FACTORY + with _CLIENT_LOCK: + close_session() + _GLOBAL_CLIENT_FACTORY = client_factory + + +def set_async_client_factory(async_client_factory: ASYNC_CLIENT_FACTORY_T) -> None: + """ + Set the HTTP async client factory to be used by `huggingface_hub`. + + The async client factory is a method that returns a `httpx.AsyncClient` object. + This can be useful if you are running your scripts in a specific environment requiring custom configuration (e.g. custom proxy or certifications). + Use [`get_async_client`] to get a correctly configured `httpx.AsyncClient`. + + > [!WARNING] + > Contrary to the `httpx.Client` that is shared between all calls made by `huggingface_hub`, the `httpx.AsyncClient` is not shared. + > It is recommended to use an async context manager to ensure the client is properly closed when the context is exited. + """ + global _GLOBAL_ASYNC_CLIENT_FACTORY + _GLOBAL_ASYNC_CLIENT_FACTORY = async_client_factory + + +def get_session() -> httpx.Client: + """ + Get a `httpx.Client` object, using the transport factory from the user. + + This client is shared between all calls made by `huggingface_hub`. Therefore you should not close it manually. + + Use [`set_client_factory`] to customize the `httpx.Client`. + """ + global _GLOBAL_CLIENT + if _GLOBAL_CLIENT is None: + with _CLIENT_LOCK: + _GLOBAL_CLIENT = _GLOBAL_CLIENT_FACTORY() + return _GLOBAL_CLIENT + + +def get_async_session() -> httpx.AsyncClient: + """ + Return a `httpx.AsyncClient` object, using the transport factory from the user. + + Use [`set_async_client_factory`] to customize the `httpx.AsyncClient`. + + > [!WARNING] + > Contrary to the `httpx.Client` that is shared between all calls made by `huggingface_hub`, the `httpx.AsyncClient` is not shared. + > It is recommended to use an async context manager to ensure the client is properly closed when the context is exited. + """ + return _GLOBAL_ASYNC_CLIENT_FACTORY() + + +def close_session() -> None: + """ + Close the global `httpx.Client` used by `huggingface_hub`. + + If a Client is closed, it will be recreated on the next call to [`get_session`]. + + Can be useful if e.g. an SSL certificate has been updated. + """ + global _GLOBAL_CLIENT + client = _GLOBAL_CLIENT + + # First, set global client to None + _GLOBAL_CLIENT = None + + # Then, close the clients + if client is not None: + try: + client.close() + except Exception as e: + logger.warning(f"Error closing client: {e}") + + +atexit.register(close_session) +if hasattr(os, "register_at_fork"): + os.register_at_fork(after_in_child=close_session) + + +_DEFAULT_RETRY_ON_EXCEPTIONS: tuple[type[Exception], ...] = ( + httpx.TimeoutException, + httpx.NetworkError, + httpx.RemoteProtocolError, +) +_DEFAULT_RETRY_ON_STATUS_CODES: tuple[int, ...] = (408, 429, 500, 502, 503, 504) + + +def _http_backoff_base( + method: HTTP_METHOD_T, + url: str, + *, + max_retries: int = 5, + base_wait_time: float = 1, + max_wait_time: float = 8, + retry_on_exceptions: type[Exception] | tuple[type[Exception], ...] = _DEFAULT_RETRY_ON_EXCEPTIONS, + retry_on_status_codes: int | tuple[int, ...] = _DEFAULT_RETRY_ON_STATUS_CODES, + stream: bool = False, + **kwargs, +) -> Generator[httpx.Response, None, None]: + """Internal implementation of HTTP backoff logic shared between `http_backoff` and `http_stream_backoff`.""" + if isinstance(retry_on_exceptions, type): # Tuple from single exception type + retry_on_exceptions = (retry_on_exceptions,) + + if isinstance(retry_on_status_codes, int): # Tuple from single status code + retry_on_status_codes = (retry_on_status_codes,) + + nb_tries = 0 + sleep_time = base_wait_time + ratelimit_reset: int | None = None # seconds to wait for rate limit reset if 429 response + + # If `data` is used and is a file object (or any IO), it will be consumed on the + # first HTTP request. We need to save the initial position so that the full content + # of the file is re-sent on http backoff. See warning tip in docstring. + io_obj_initial_pos = None + if "data" in kwargs and isinstance(kwargs["data"], (io.IOBase, SliceFileObj)): + io_obj_initial_pos = kwargs["data"].tell() + + client = get_session() + while True: + nb_tries += 1 + ratelimit_reset = None + try: + # If `data` is used and is a file object (or any IO), set back cursor to + # initial position. + if io_obj_initial_pos is not None: + kwargs["data"].seek(io_obj_initial_pos) + + # Perform request and handle response + def _should_retry(response: httpx.Response) -> bool: + """Handle response and return True if should retry, False if should return/yield.""" + nonlocal ratelimit_reset + + if response.status_code not in retry_on_status_codes: + return False # Success, don't retry + + # Wrong status code returned (HTTP 503 for instance) + logger.warning(f"HTTP Error {response.status_code} thrown while requesting {method} {url}") + if nb_tries > max_retries: + hf_raise_for_status(response) # Will raise uncaught exception + # Return/yield response to avoid infinite loop in the corner case where the + # user ask for retry on a status code that doesn't raise_for_status. + return False # Don't retry, return/yield response + + # Check 'ratelimit' and `Retry-After` headers. + if ( + response.status_code == 429 + and (ratelimit_info := parse_ratelimit_headers(response.headers)) is not None + ): + ratelimit_reset = ratelimit_info.reset_in_seconds + elif (retry_after := _parse_retry_after(response.headers)) is not None: + ratelimit_reset = retry_after + + return True # Should retry + + if stream: + with client.stream(method=method, url=url, **kwargs) as response: + if not _should_retry(response): + yield response + return + else: + response = client.request(method=method, url=url, **kwargs) + if not _should_retry(response): + yield response + return + + except retry_on_exceptions as err: + logger.warning(f"'{err}' thrown while requesting {method} {url}") + + if isinstance(err, httpx.ConnectError): + close_session() # In case of SSLError it's best to close the shared httpx.Client objects + + if nb_tries > max_retries: + raise err + + if ratelimit_reset is not None: + actual_sleep = float(ratelimit_reset) + 1 # +1s to avoid rounding issues + logger.warning(f"Rate limited. Waiting {actual_sleep}s before retry [Retry {nb_tries}/{max_retries}].") + else: + actual_sleep = sleep_time + logger.warning(f"Retrying in {actual_sleep}s [Retry {nb_tries}/{max_retries}].") + + time.sleep(actual_sleep) + + # Update sleep time for next retry + sleep_time = min(max_wait_time, sleep_time * 2) # Exponential backoff + + +def http_backoff( + method: HTTP_METHOD_T, + url: str, + *, + max_retries: int = 5, + base_wait_time: float = 1, + max_wait_time: float = 8, + retry_on_exceptions: type[Exception] | tuple[type[Exception], ...] = _DEFAULT_RETRY_ON_EXCEPTIONS, + retry_on_status_codes: int | tuple[int, ...] = _DEFAULT_RETRY_ON_STATUS_CODES, + **kwargs, +) -> httpx.Response: + """Wrapper around httpx to retry calls on an endpoint, with exponential backoff. + + Endpoint call is retried on exceptions (ex: connection timeout, proxy error,...) + and/or on specific status codes (ex: service unavailable). If the call failed more + than `max_retries`, the exception is thrown or `raise_for_status` is called on the + response object. + + Re-implement mechanisms from the `backoff` library to avoid adding an external + dependencies to `hugging_face_hub`. See https://github.com/litl/backoff. + + Args: + method (`Literal["GET", "OPTIONS", "HEAD", "POST", "PUT", "PATCH", "DELETE"]`): + HTTP method to perform. + url (`str`): + The URL of the resource to fetch. + max_retries (`int`, *optional*, defaults to `5`): + Maximum number of retries, defaults to 5. Set to `0` to disable retries. + base_wait_time (`float`, *optional*, defaults to `1`): + Duration (in seconds) to wait before retrying the first time. + Wait time between retries then grows exponentially, capped by + `max_wait_time`. + max_wait_time (`float`, *optional*, defaults to `8`): + Maximum duration (in seconds) to wait before retrying. + retry_on_exceptions (`type[Exception]` or `tuple[type[Exception]]`, *optional*): + Define which exceptions must be caught to retry the request. Can be a single type or a tuple of types. + By default, retry on `httpx.TimeoutException`, `httpx.NetworkError` and `httpx.RemoteProtocolError`. + retry_on_status_codes (`int` or `tuple[int]`, *optional*, defaults to `(429, 500, 502, 503, 504)`): + Define on which status codes the request must be retried. By default, retries + on rate limit (429) and server errors (5xx). + **kwargs (`dict`, *optional*): + kwargs to pass to `httpx.request`. + + Example: + ``` + >>> from huggingface_hub.utils import http_backoff + + # Same usage as "httpx.request". + >>> response = http_backoff("GET", "https://www.google.com") + >>> response.raise_for_status() + + # If you expect a Gateway Timeout from time to time + >>> http_backoff("PUT", upload_url, data=data, retry_on_status_codes=504) + >>> response.raise_for_status() + ``` + + > [!WARNING] + > When using `requests` it is possible to stream data by passing an iterator to the + > `data` argument. On http backoff this is a problem as the iterator is not reset + > after a failed call. This issue is mitigated for file objects or any IO streams + > by saving the initial position of the cursor (with `data.tell()`) and resetting the + > cursor between each call (with `data.seek()`). For arbitrary iterators, http backoff + > will fail. If this is a hard constraint for you, please let us know by opening an + > issue on [Github](https://github.com/huggingface/huggingface_hub). + """ + return next( + _http_backoff_base( + method=method, + url=url, + max_retries=max_retries, + base_wait_time=base_wait_time, + max_wait_time=max_wait_time, + retry_on_exceptions=retry_on_exceptions, + retry_on_status_codes=retry_on_status_codes, + stream=False, + **kwargs, + ) + ) + + +@contextmanager +def http_stream_backoff( + method: HTTP_METHOD_T, + url: str, + *, + max_retries: int = 5, + base_wait_time: float = 1, + max_wait_time: float = 8, + retry_on_exceptions: type[Exception] | tuple[type[Exception], ...] = _DEFAULT_RETRY_ON_EXCEPTIONS, + retry_on_status_codes: int | tuple[int, ...] = _DEFAULT_RETRY_ON_STATUS_CODES, + **kwargs, +) -> Generator[httpx.Response, None, None]: + """Wrapper around httpx to retry calls on an endpoint, with exponential backoff. + + Endpoint call is retried on exceptions (ex: connection timeout, proxy error,...) + and/or on specific status codes (ex: service unavailable). If the call failed more + than `max_retries`, the exception is thrown or `raise_for_status` is called on the + response object. + + Re-implement mechanisms from the `backoff` library to avoid adding an external + dependencies to `hugging_face_hub`. See https://github.com/litl/backoff. + + Args: + method (`Literal["GET", "OPTIONS", "HEAD", "POST", "PUT", "PATCH", "DELETE"]`): + HTTP method to perform. + url (`str`): + The URL of the resource to fetch. + max_retries (`int`, *optional*, defaults to `5`): + Maximum number of retries, defaults to 5. Set to `0` to disable retries. + base_wait_time (`float`, *optional*, defaults to `1`): + Duration (in seconds) to wait before retrying the first time. + Wait time between retries then grows exponentially, capped by + `max_wait_time`. + max_wait_time (`float`, *optional*, defaults to `8`): + Maximum duration (in seconds) to wait before retrying. + retry_on_exceptions (`type[Exception]` or `tuple[type[Exception]]`, *optional*): + Define which exceptions must be caught to retry the request. Can be a single type or a tuple of types. + By default, retry on `httpx.TimeoutException`, `httpx.NetworkError` and `httpx.RemoteProtocolError`. + retry_on_status_codes (`int` or `tuple[int]`, *optional*, defaults to `(429, 500, 502, 503, 504)`): + Define on which status codes the request must be retried. By default, retries + on rate limit (429) and server errors (5xx). + **kwargs (`dict`, *optional*): + kwargs to pass to `httpx.request`. + + Example: + ``` + >>> from huggingface_hub.utils import http_stream_backoff + + # Same usage as "httpx.stream". + >>> with http_stream_backoff("GET", "https://www.google.com") as response: + ... for chunk in response.iter_bytes(): + ... print(chunk) + + # If you expect a Gateway Timeout from time to time + >>> with http_stream_backoff("PUT", upload_url, data=data, retry_on_status_codes=504) as response: + ... response.raise_for_status() + ``` + + > [!WARNING] + > When using `httpx` it is possible to stream data by passing an iterator to the + > `data` argument. On http backoff this is a problem as the iterator is not reset + > after a failed call. This issue is mitigated for file objects or any IO streams + > by saving the initial position of the cursor (with `data.tell()`) and resetting the + > cursor between each call (with `data.seek()`). For arbitrary iterators, http backoff + > will fail. If this is a hard constraint for you, please let us know by opening an + > issue on [Github](https://github.com/huggingface/huggingface_hub). + """ + yield from _http_backoff_base( + method=method, + url=url, + max_retries=max_retries, + base_wait_time=base_wait_time, + max_wait_time=max_wait_time, + retry_on_exceptions=retry_on_exceptions, + retry_on_status_codes=retry_on_status_codes, + stream=True, + **kwargs, + ) + + +def _httpx_follow_relative_redirects_with_backoff( + method: HTTP_METHOD_T, url: str, *, retry_on_errors: bool = False, **httpx_kwargs +) -> httpx.Response: + """Perform an HTTP request with backoff and follow relative redirects only. + + Used to fetch HEAD /resolve on repo or bucket files. + + This is useful to follow a redirection to a renamed repository without following redirection to a CDN. + + A backoff mechanism retries the HTTP call on errors (429, 5xx, timeout, network errors). + + Args: + method (`str`): + HTTP method, such as 'GET' or 'HEAD'. + url (`str`): + The URL of the resource to fetch. + retry_on_errors (`bool`, *optional*, defaults to `False`): + Whether to retry on errors. If False, no retry is performed (fast fallback to local cache). + If True, uses default retry behavior (429, 5xx, timeout, network errors). + **httpx_kwargs (`dict`, *optional*): + Params to pass to `httpx.request`. + """ + # if `retry_on_errors=False`, disable all retries for fast fallback to cache + no_retry_kwargs: dict[str, Any] = ( + {} if retry_on_errors else {"retry_on_exceptions": (), "retry_on_status_codes": ()} + ) + + while True: + response = http_backoff( + method=method, + url=url, + **httpx_kwargs, + follow_redirects=False, + **no_retry_kwargs, + ) + hf_raise_for_status(response) + + # Check if response is a relative redirect + if 300 <= response.status_code <= 399: + parsed_target = urlparse(response.headers["Location"]) + if parsed_target.netloc == "": + # Relative redirect -> update URL and retry + url = urlparse(url)._replace(path=parsed_target.path).geturl() + continue + + # Break if no relative redirect + break + + return response + + +def fix_hf_endpoint_in_url(url: str, endpoint: str | None) -> str: + """Replace the default endpoint in a URL by a custom one. + + This is useful when using a proxy and the Hugging Face Hub returns a URL with the default endpoint. + """ + endpoint = endpoint.rstrip("/") if endpoint else constants.ENDPOINT + # check if a proxy has been set => if yes, update the returned URL to use the proxy + if endpoint not in (constants._HF_DEFAULT_ENDPOINT, constants._HF_DEFAULT_STAGING_ENDPOINT): + url = url.replace(constants._HF_DEFAULT_ENDPOINT, endpoint) + url = url.replace(constants._HF_DEFAULT_STAGING_ENDPOINT, endpoint) + return url + + +def hf_raise_for_status(response: httpx.Response, endpoint_name: str | None = None) -> None: + """ + Internal version of `response.raise_for_status()` that will refine a potential HTTPError. + Raised exception will be an instance of [`~errors.HfHubHTTPError`]. + + This helper is meant to be the unique method to raise_for_status when making a call to the Hugging Face Hub. + + Args: + response (`Response`): + Response from the server. + endpoint_name (`str`, *optional*): + Name of the endpoint that has been called. If provided, the error message will be more complete. + + > [!WARNING] + > Raises when the request has failed: + > + > - [`~utils.RepositoryNotFoundError`] + > If the repository to download from cannot be found. This may be because it + > doesn't exist, because `repo_type` is not set correctly, or because the repo + > is `private` and you do not have access. + > - [`~utils.GatedRepoError`] + > If the repository exists but is gated and the user is not on the authorized + > list. + > - [`~utils.RevisionNotFoundError`] + > If the repository exists but the revision couldn't be found. + > - [`~utils.EntryNotFoundError`] + > If the repository exists but the entry (e.g. the requested file) couldn't be + > find. + > - [`~utils.BadRequestError`] + > If request failed with a HTTP 400 BadRequest error. + > - [`~utils.HfHubHTTPError`] + > If request failed for a reason not listed above. + """ + try: + _warn_on_warning_headers(response) + except Exception: + # Never raise on warning parsing + logger.debug("Failed to parse warning headers", exc_info=True) + + try: + response.raise_for_status() + except httpx.HTTPStatusError as e: + if response.status_code // 100 == 3: + return # Do not raise on redirects to stay consistent with `requests` + + error_code = response.headers.get("X-Error-Code") + error_message = response.headers.get("X-Error-Message") + + # Parse repo info from request URL (used to enrich errors below) + request_url = ( + str(response.request.url) if response.request is not None and response.request.url is not None else None + ) + repo_type, repo_id = _parse_repo_info_from_url(request_url) if request_url else (None, None) + + if error_code == "RevisionNotFound": + message = f"{response.status_code} Client Error." + "\n\n" + f"Revision Not Found for url: {response.url}." + raise _format(RevisionNotFoundError, message, response, repo_type=repo_type, repo_id=repo_id) from e + + elif error_code == "EntryNotFound": + message = f"{response.status_code} Client Error." + "\n\n" + f"Entry Not Found for url: {response.url}." + raise _format(RemoteEntryNotFoundError, message, response, repo_type=repo_type, repo_id=repo_id) from e + + elif error_code == "GatedRepo": + message = ( + f"{response.status_code} Client Error." + "\n\n" + f"Cannot access gated repo for url {response.url}." + ) + raise _format(GatedRepoError, message, response, repo_type=repo_type, repo_id=repo_id) from e + + elif error_message == "Access to this resource is disabled.": + message = ( + f"{response.status_code} Client Error." + + "\n\n" + + f"Cannot access repository for url {response.url}." + + "\n" + + "Access to this resource is disabled." + ) + raise _format(DisabledRepoError, message, response) from e + + elif ( + error_code == "RepoNotFound" + and request_url is not None + and BUCKET_API_REGEX.search(request_url) is not None + ): + message = ( + f"{response.status_code} Client Error." + + "\n\n" + + f"Bucket Not Found for url: {response.url}." + + "\nPlease make sure you specified the correct bucket id (namespace/name)." + + "\nIf the bucket is private, make sure you are authenticated and your token has the required permissions." + ) + raise _format( + BucketNotFoundError, message, response, bucket_id=_parse_bucket_id_from_url(request_url) + ) from e + + elif ( + response.status_code == 404 + and request_url is not None + and (job_id := _parse_job_id_from_url(request_url)) is not None + ): + message = ( + f"{response.status_code} Client Error." + + "\n\n" + + f"Job Not Found for url: {response.url}." + + "\nPlease make sure you specified the correct job ID and namespace." + ) + raise _format(JobNotFoundError, message, response, job_id=job_id) from e + + elif error_code == "RepoNotFound" or ( + response.status_code == 401 + and error_message != "Invalid credentials in Authorization header" + and request_url is not None + and REPO_API_REGEX.search(request_url) is not None + ): + # 401 is misleading as it is returned for: + # - private and gated repos if user is not authenticated + # - missing repos + # => for now, we process them as `RepoNotFound` anyway. + # See https://gist.github.com/Wauplin/46c27ad266b15998ce56a6603796f0b9 + message = ( + f"{response.status_code} Client Error." + + "\n\n" + + f"Repository Not Found for url: {response.url}." + + "\nPlease make sure you specified the correct `repo_id` and" + " `repo_type`.\nIf you are trying to access a private or gated repo," + " make sure you are authenticated and your token has the required permissions." + + "\nFor more details, see https://huggingface.co/docs/huggingface_hub/authentication" + ) + raise _format(RepositoryNotFoundError, message, response, repo_type=repo_type, repo_id=repo_id) from e + + elif response.status_code == 400: + message = ( + f"\n\nBad request for {endpoint_name} endpoint:" if endpoint_name is not None else "\n\nBad request:" + ) + raise _format(BadRequestError, message, response) from e + + elif response.status_code == 403: + message = ( + f"\n\n{response.status_code} Forbidden: {error_message}." + + f"\nCannot access content at: {response.url}." + + "\nMake sure your token has the correct permissions." + ) + raise _format(HfHubHTTPError, message, response) from e + + elif response.status_code == 429: + ratelimit_info = parse_ratelimit_headers(response.headers) + if ratelimit_info is not None: + message = ( + f"\n\n429 Too Many Requests: you have reached your '{ratelimit_info.resource_type}' rate limit." + ) + message += f"\nRetry after {ratelimit_info.reset_in_seconds} seconds" + if ratelimit_info.limit is not None and ratelimit_info.window_seconds is not None: + message += ( + f" ({ratelimit_info.remaining}/{ratelimit_info.limit} requests remaining" + f" in current {ratelimit_info.window_seconds}s window)." + ) + else: + message += "." + message += f"\nUrl: {response.url}." + else: + message = f"\n\n429 Too Many Requests for url: {response.url}." + raise _format(HfHubHTTPError, message, response) from e + + elif response.status_code == 416: + range_header = response.request.headers.get("Range") + message = f"{e}. Requested range: {range_header}. Content-Range: {response.headers.get('Content-Range')}." + raise _format(HfHubHTTPError, message, response) from e + + # Convert `HTTPError` into a `HfHubHTTPError` to display request information + # as well (request id and/or server error message) + raise _format(HfHubHTTPError, str(e), response) from e + + +_WARNED_TOPICS = set() + + +def _warn_on_warning_headers(response: httpx.Response) -> None: + """ + Emit warnings if warning headers are present in the HTTP response. + + Expected header format: 'X-HF-Warning: topic; message' + + Only the first warning for each topic will be shown. Topic is optional and can be empty. Note that several warning + headers can be present in a single response. + + Args: + response (`httpx.Response`): + The HTTP response to check for warning headers. + """ + server_warnings = response.headers.get_list("X-HF-Warning") + for server_warning in server_warnings: + topic, message = server_warning.split(";", 1) if ";" in server_warning else ("", server_warning) + topic = topic.strip() + if topic not in _WARNED_TOPICS: + message = message.strip() + if message: + _WARNED_TOPICS.add(topic) + logger.warning(message) + + +_HfHubHTTPErrorT = TypeVar("_HfHubHTTPErrorT", bound=HfHubHTTPError) + + +def _format( + error_type: type[_HfHubHTTPErrorT], custom_message: str, response: httpx.Response, **attrs: Any +) -> _HfHubHTTPErrorT: + server_errors = [] + + # Retrieve server error from header + from_headers = response.headers.get("X-Error-Message") + if from_headers is not None: + server_errors.append(from_headers) + + # Retrieve server error from body + try: + # Case errors are returned in a JSON format + try: + data = response.json() + except httpx.ResponseNotRead: + try: + response.read() # In case of streaming response, we need to read the response first + data = response.json() + except RuntimeError: + # In case of async streaming response, we can't read the stream here. + # In practice if user is using the default async client from `get_async_client`, the stream will have + # already been read in the async event hook `async_hf_response_event_hook`. + # + # Here, we are skipping reading the response to avoid RuntimeError but it happens only if async + stream + used httpx.AsyncClient directly. + data = {} + + error = data.get("error") + error_description = data.get("error_description") + if error is not None: + if isinstance(error, list): + # Case {'error': ['my error 1', 'my error 2']} + server_errors.extend(error) + elif error_description is not None: + # OAuth-style case {'error': 'invalid_grant', 'error_description': 'my description'} + server_errors.append(f"{error}: {error_description}") + else: + # Case {'error': 'my error'} + server_errors.append(error) + elif error_description is not None: + # Case {'error_description': 'my description'} (no 'error' field) + server_errors.append(error_description) + + errors = data.get("errors") + if errors is not None: + # Case {'errors': [{'message': 'my error 1'}, {'message': 'my error 2'}]} + for error in errors: + if "message" in error: + server_errors.append(error["message"]) + + except json.JSONDecodeError: + # If content is not JSON and not HTML, append the text + content_type = response.headers.get("Content-Type", "") + if response.text and "html" not in content_type.lower(): + server_errors.append(response.text) + + # Strip all server messages + server_errors = [str(line).strip() for line in server_errors if str(line).strip()] + + # Deduplicate server messages (keep order) + # taken from https://stackoverflow.com/a/17016257 + server_errors = list(dict.fromkeys(server_errors)) + + # Format server error + server_message = "\n".join(server_errors) + + # Add server error to custom message + final_error_message = custom_message + if server_message and server_message.lower() not in custom_message.lower(): + if "\n\n" in custom_message: + final_error_message += "\n" + server_message + else: + final_error_message += "\n\n" + server_message + + # Prepare Request ID message + request_id = "" + request_id_message = "" + for header, label in ( + (X_REQUEST_ID, "Request ID"), + (X_AMZN_TRACE_ID, "Amzn Trace ID"), + (X_AMZ_CF_ID, "Amz CF ID"), + ): + value = response.headers.get(header) + if value: + request_id = str(value) + request_id_message = f" ({label}: {value})" + break + + # Add Request ID + if request_id and request_id.lower() not in final_error_message.lower(): + if "\n" in final_error_message: + newline_index = final_error_message.index("\n") + final_error_message = ( + final_error_message[:newline_index] + request_id_message + final_error_message[newline_index:] + ) + else: + final_error_message += request_id_message + + # Return + err = error_type(final_error_message.strip(), response=response, server_message=server_message or None) + for k, v in attrs.items(): + setattr(err, k, v) + return err + + +# Request-body fields that carry credentials; redacted from debug-log curl commands (HF_DEBUG). +_SENSITIVE_BODY_KEYS = ("subject_token", "access_token", "refresh_token", "client_secret", "device_code") +_SENSITIVE_BODY_PATTERNS = [ + pattern + for key in _SENSITIVE_BODY_KEYS + for pattern in ( + (re.compile(rf'("{key}"\s*:\s*")[^"]*(")'), r"\1\2"), # JSON + (re.compile(rf"(^|&)({key}=)[^&]*"), r"\1\2"), # application/x-www-form-urlencoded + ) +] + + +def _redact_sensitive_body(body: str) -> str: + """Redact OAuth credential values from a JSON or form-urlencoded request body string.""" + for pattern, replacement in _SENSITIVE_BODY_PATTERNS: + body = pattern.sub(replacement, body) + return body + + +def _curlify(request: httpx.Request) -> str: + """Convert a `httpx.Request` into a curl command (str). + + Used for debug purposes only. + + Implementation vendored from https://github.com/ofw/curlify/blob/master/curlify.py. + MIT License Copyright (c) 2016 Egor. + """ + parts: list[tuple[Any, Any]] = [ + ("curl", None), + ("-X", request.method), + ] + + for k, v in sorted(request.headers.items()): + if k.lower() == "authorization": + v = "" # Hide authorization header, no matter its value (can be Bearer, Key, etc.) + parts += [("-H", f"{k}: {v}")] + + body: str | None = None + try: + if request.content is not None: + body = request.content.decode("utf-8", errors="ignore") + if len(body) > 1000: + body = f"{body[:1000]} ... [truncated]" + body = _redact_sensitive_body(body) + except httpx.RequestNotRead: + body = "" + if body is not None: + parts += [("-d", body.replace("\n", ""))] + + parts += [(None, request.url)] + + flat_parts = [] + for k, v in parts: + if k: + flat_parts.append(quote(str(k))) + if v: + flat_parts.append(quote(str(v))) + + return " ".join(flat_parts) + + +# Regex to parse HTTP Range header +RANGE_REGEX = re.compile(r"^\s*bytes\s*=\s*(\d*)\s*-\s*(\d*)\s*$", re.IGNORECASE) + + +def _adjust_range_header(original_range: str | None, resume_size: int) -> str | None: + """ + Adjust HTTP Range header to account for resume position. + """ + if not original_range: + return f"bytes={resume_size}-" + + if "," in original_range: + raise ValueError(f"Multiple ranges detected - {original_range!r}, not supported yet.") + + match = RANGE_REGEX.match(original_range) + if not match: + raise RuntimeError(f"Invalid range format - {original_range!r}.") + start, end = match.groups() + + if not start: + if not end: + raise RuntimeError(f"Invalid range format - {original_range!r}.") + + new_suffix = int(end) - resume_size + new_range = f"bytes=-{new_suffix}" + if new_suffix <= 0: + raise RuntimeError(f"Empty new range - {new_range!r}.") + return new_range + + start = int(start) + new_start = start + resume_size + if end: + end = int(end) + new_range = f"bytes={new_start}-{end}" + if new_start > end: + raise RuntimeError(f"Empty new range - {new_range!r}.") + return new_range + + return f"bytes={new_start}-" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_lfs.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_lfs.py new file mode 100644 index 0000000000000000000000000000000000000000..78c5d49b23f4363904600ddc808a8b29095a65f8 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_lfs.py @@ -0,0 +1,109 @@ +# Copyright 2019-present, the HuggingFace Inc. team. +# +# 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. +"""Git LFS related utilities""" + +import io +import os +from contextlib import AbstractContextManager +from typing import BinaryIO + + +class SliceFileObj(AbstractContextManager): + """ + Utility context manager to read a *slice* of a seekable file-like object as a seekable, file-like object. + + This is NOT thread safe + + Inspired by stackoverflow.com/a/29838711/593036 + + Credits to @julien-c + + Args: + fileobj (`BinaryIO`): + A file-like object to slice. MUST implement `tell()` and `seek()` (and `read()` of course). + `fileobj` will be reset to its original position when exiting the context manager. + seek_from (`int`): + The start of the slice (offset from position 0 in bytes). + read_limit (`int`): + The maximum number of bytes to read from the slice. + + Attributes: + previous_position (`int`): + The previous position + + Examples: + + Reading 200 bytes with an offset of 128 bytes from a file (ie bytes 128 to 327): + ```python + >>> with open("path/to/file", "rb") as file: + ... with SliceFileObj(file, seek_from=128, read_limit=200) as fslice: + ... fslice.read(...) + ``` + + Reading a file in chunks of 512 bytes + ```python + >>> import os + >>> chunk_size = 512 + >>> file_size = os.getsize("path/to/file") + >>> with open("path/to/file", "rb") as file: + ... for chunk_idx in range(ceil(file_size / chunk_size)): + ... with SliceFileObj(file, seek_from=chunk_idx * chunk_size, read_limit=chunk_size) as fslice: + ... chunk = fslice.read(...) + + ``` + """ + + def __init__(self, fileobj: BinaryIO, seek_from: int, read_limit: int): + self.fileobj = fileobj + self.seek_from = seek_from + self.read_limit = read_limit + + def __enter__(self): + self._previous_position = self.fileobj.tell() + end_of_stream = self.fileobj.seek(0, os.SEEK_END) + self._len = min(self.read_limit, end_of_stream - self.seek_from) + # ^^ The actual number of bytes that can be read from the slice + self.fileobj.seek(self.seek_from, io.SEEK_SET) + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.fileobj.seek(self._previous_position, io.SEEK_SET) + + def read(self, n: int = -1): + pos = self.tell() + if pos >= self._len: + return b"" + remaining_amount = self._len - pos + data = self.fileobj.read(remaining_amount if n < 0 else min(n, remaining_amount)) + return data + + def tell(self) -> int: + return self.fileobj.tell() - self.seek_from + + def seek(self, offset: int, whence: int = os.SEEK_SET) -> int: + start = self.seek_from + end = start + self._len + if whence in (os.SEEK_SET, os.SEEK_END): + offset = start + offset if whence == os.SEEK_SET else end + offset + offset = max(start, min(offset, end)) + whence = os.SEEK_SET + elif whence == os.SEEK_CUR: + cur_pos = self.fileobj.tell() + offset = max(start - cur_pos, min(offset, end - cur_pos)) + else: + raise ValueError(f"whence value {whence} is not supported") + return self.fileobj.seek(offset, whence) - self.seek_from + + def __iter__(self): + yield self.read(n=4 * 1024 * 1024) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_oauth_device.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_oauth_device.py new file mode 100644 index 0000000000000000000000000000000000000000..e626d0c28a34170ce6035ed26b732d4c733e1f0a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_oauth_device.py @@ -0,0 +1,197 @@ +# Copyright 2026 The HuggingFace Team. All rights reserved. +# +# 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. +"""Device Code OAuth (RFC 8628) for browser-based login, plus access token refresh. + +The flow: the client requests a device code, displays a URL and a short user code, the user +authorizes in a browser, and the client polls ``POST {ENDPOINT}/oauth/token`` until a token is +issued. Access tokens may come with a refresh token, used to renew them transparently (see +``utils/_auth.py::get_token``). + +This module is self-contained protocol logic: no printing, no persistence. Interactive flows +live in ``_login.py`` (human/library) and ``cli/auth.py`` (machine-readable event stream). +""" + +import time +from collections.abc import Callable +from typing import TypedDict, cast + +import httpx + +from .. import constants +from ..errors import DeviceCodeError, OAuthErrorCode +from ._http import get_session, hf_raise_for_status + + +_DEVICE_CODE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code" +_REFRESH_TOKEN_GRANT_TYPE = "refresh_token" + + +class DeviceCodeInfo(TypedDict): + device_code: str + user_code: str + verification_uri: str + verification_uri_complete: str # falls back to verification_uri if the server omits it + interval: int + expires_in: int + + +class OAuthTokenResponse(TypedDict, total=False): + access_token: str + refresh_token: str + expires_in: int + token_type: str + + +def request_device_code() -> DeviceCodeInfo: + """Request a device code from the Hub's OAuth device authorization endpoint. + + The returned dict is normalized: `interval`, `expires_in` and `verification_uri_complete` + are always set (server values, or sensible defaults). + + Raises: + [`DeviceCodeError`]: If the request fails. + """ + try: + response = get_session().post( + f"{constants.ENDPOINT}/oauth/device", + data={"client_id": constants.DEVICE_CODE_OAUTH_CLIENT_ID}, + timeout=constants.HF_HUB_DOWNLOAD_TIMEOUT, + ) + hf_raise_for_status(response) + except httpx.HTTPError as e: + raise DeviceCodeError(f"Failed to request device code from {constants.ENDPOINT}/oauth/device: {e}") from e + info = response.json() + # `interval` is optional per RFC 8628 (5s is the spec-mandated fallback); `expires_in` is + # required but defaulted defensively so polling stays bounded if a server omits it. + info.setdefault("interval", 5) + info.setdefault("expires_in", 900) + if not info.get("verification_uri_complete"): + info["verification_uri_complete"] = info["verification_uri"] + return cast(DeviceCodeInfo, info) + + +def poll_device_token( + device_info: DeviceCodeInfo, *, on_pending: Callable[[], None] | None = None +) -> OAuthTokenResponse: + """Poll the token endpoint until the user authorizes the device. + + Args: + device_info (`DeviceCodeInfo`): + The device authorization response from [`request_device_code`]. + on_pending (`Callable`, *optional*): + Called after each "authorization pending" response (e.g. to print a progress dot). + + Returns: + `OAuthTokenResponse`: the full token response: `access_token`, and optionally + `refresh_token` and `expires_in`. + + Raises: + [`DeviceCodeError`]: If authorization is denied, the device code expires, or the server + returns an unexpected OAuth error. + """ + interval = device_info["interval"] + deadline = time.monotonic() + device_info["expires_in"] + while time.monotonic() < deadline: + # Inconclusive responses (network blip, 5xx, gateway error page, rate limiting) must not + # abort the login: keep polling until the device code expires (RFC 8628 section 3.5). + # The deadline bounds the total wait even if the endpoint is genuinely broken. + data = None + try: + response = get_session().post( + f"{constants.ENDPOINT}/oauth/token", + data={ + "grant_type": _DEVICE_CODE_GRANT_TYPE, + "device_code": device_info["device_code"], + "client_id": constants.DEVICE_CODE_OAUTH_CLIENT_ID, + }, + timeout=constants.HF_HUB_DOWNLOAD_TIMEOUT, + ) + if response.status_code < 500: + data = response.json() + except (httpx.HTTPError, ValueError): + pass + + if data is not None: + if "access_token" in data: + return cast(OAuthTokenResponse, data) + + match data.get("error"): + case None: + pass # JSON without an OAuth `error` field (proxy error page, ...): transient + case OAuthErrorCode.AUTHORIZATION_PENDING: + if on_pending is not None: + on_pending() + case OAuthErrorCode.SLOW_DOWN: + interval += 5 + case OAuthErrorCode.EXPIRED_TOKEN: + raise DeviceCodeError( + "Device code expired. Please try again.", error_code=OAuthErrorCode.EXPIRED_TOKEN + ) + case OAuthErrorCode.ACCESS_DENIED: + raise DeviceCodeError( + "Authorization was denied. Please try again.", error_code=OAuthErrorCode.ACCESS_DENIED + ) + case error: + raise DeviceCodeError( + f"OAuth error: {error} - {data.get('error_description', '')}", error_code=error + ) + + time.sleep(interval) + + raise DeviceCodeError("Device code expired (timeout). Please try again.", error_code=OAuthErrorCode.EXPIRED_TOKEN) + + +def refresh_access_token(refresh_token: str) -> OAuthTokenResponse: + """Exchange a refresh token for a new access token. + + Returns: + `OAuthTokenResponse`: the full token response: `access_token`, and optionally a rotated + `refresh_token` and `expires_in`. + + Raises: + [`DeviceCodeError`]: If the server rejects the refresh (`error_code="invalid_grant"` when + the refresh token is expired or revoked) or returns an unexpected response. + """ + try: + response = get_session().post( + f"{constants.ENDPOINT}/oauth/token", + data={ + "grant_type": _REFRESH_TOKEN_GRANT_TYPE, + "refresh_token": refresh_token, + "client_id": constants.DEVICE_CODE_OAUTH_CLIENT_ID, + }, + # An explicit timeout is critical here: this runs inside `get_token()`, so a hung + # request would otherwise block every Hub call in the process. + timeout=constants.HF_HUB_DOWNLOAD_TIMEOUT, + ) + except httpx.HTTPError as e: + raise DeviceCodeError(f"Failed to refresh access token: {e}") from e + data = _parse_token_response(response) + if "access_token" in data: + return cast(OAuthTokenResponse, data) + error = data.get("error") + raise DeviceCodeError( + f"Failed to refresh access token: {error or response.status_code} - {data.get('error_description', '')}", + error_code=error, + ) + + +def _parse_token_response(response: httpx.Response) -> dict: + try: + return response.json() + except ValueError as e: + raise DeviceCodeError( + f"Failed to parse response from {constants.ENDPOINT}/oauth/token " + f"(status {response.status_code}): {response.text[:500]}" + ) from e diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_pagination.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_pagination.py new file mode 100644 index 0000000000000000000000000000000000000000..4e04f664edee574fc72b935a4472c4b102019045 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_pagination.py @@ -0,0 +1,52 @@ +# Copyright 2022-present, the HuggingFace Inc. team. +# +# 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. +"""Contains utilities to handle pagination on Huggingface Hub.""" + +from collections.abc import Iterable +from typing import Any + +import httpx + +from . import get_session, hf_raise_for_status, http_backoff, logging + + +logger = logging.get_logger(__name__) + + +def paginate(path: str, params: dict | list[tuple[str, Any]], headers: dict, timeout: float | None = None) -> Iterable: + """Fetch a list of models/datasets/spaces and paginate through results. + + This is using the same "Link" header format as GitHub. + See: + - https://requests.readthedocs.io/en/latest/api/#requests.Response.links + - https://docs.github.com/en/rest/guides/traversing-with-pagination#link-header + """ + session = get_session() + r = session.get(path, params=params, headers=headers, timeout=timeout) + hf_raise_for_status(r) + yield from r.json() + + # Follow pages + # Next link already contains query params + next_page = _get_next_page(r) + while next_page is not None: + logger.debug(f"Pagination detected. Requesting next page: {next_page}") + r = http_backoff("GET", next_page, headers=headers, timeout=timeout) + hf_raise_for_status(r) + yield from r.json() + next_page = _get_next_page(r) + + +def _get_next_page(response: httpx.Response) -> str | None: + return response.links.get("next", {}).get("url") diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_parsing.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_parsing.py new file mode 100644 index 0000000000000000000000000000000000000000..eeddee70f6416da25abaef8cb78ca2a5905b89a9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_parsing.py @@ -0,0 +1,116 @@ +# Copyright 2025-present, the HuggingFace Inc. team. +# +# 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. +"""Parsing helpers shared across modules.""" + +import re +import time + + +RE_NUMBER_WITH_UNIT = re.compile(r"(\d+)([a-z]+)", re.IGNORECASE) + +BYTE_UNITS: dict[str, int] = { + "k": 1_000, + "kb": 1_000, + "m": 1_000_000, + "mb": 1_000_000, + "g": 1_000_000_000, + "gb": 1_000_000_000, + "t": 1_000_000_000_000, + "tb": 1_000_000_000_000, + "p": 1_000_000_000_000_000, + "pb": 1_000_000_000_000_000, +} + +TIME_UNITS: dict[str, int] = { + "s": 1, + "m": 60, + "h": 60 * 60, + "d": 24 * 60 * 60, + "w": 7 * 24 * 60 * 60, + "mo": 30 * 24 * 60 * 60, + "y": 365 * 24 * 60 * 60, +} + + +def parse_size(value: str) -> int: + """Parse a size expressed as a string with digits and unit (like `"10MB"`) to an integer (in bytes).""" + return _parse_with_unit(value, BYTE_UNITS) + + +def parse_duration(value: str) -> int: + """Parse a duration expressed as a string with digits and unit (like `"10s"`) to an integer (in seconds).""" + return _parse_with_unit(value, TIME_UNITS) + + +def _parse_with_unit(value: str, units: dict[str, int]) -> int: + """Parse a numeric value with optional unit.""" + stripped = value.strip() + if not stripped: + raise ValueError("Value cannot be empty.") + try: + return int(value) + except ValueError: + pass + + match = RE_NUMBER_WITH_UNIT.fullmatch(stripped) + if not match: + raise ValueError(f"Invalid value '{value}'. Must match pattern '\\d+[a-z]+' or be a plain number.") + + number = int(match.group(1)) + unit = match.group(2).lower() + + if unit not in units: + raise ValueError(f"Unknown unit '{unit}'. Must be one of {list(units.keys())}.") + + return number * units[unit] + + +def format_duration(secs: int | None) -> str: + """Format a duration in seconds as a short human-readable string (e.g. `"1m 32s"`, `"2h 15m"`, `"45s"`). + + Returns `"--"` when `secs` is `None` so it can be used directly as a CLI table cell. + """ + if secs is None: + return "--" + secs = int(secs) + if secs < 60: + return f"{secs}s" + if secs < 3600: + return f"{secs // 60}m {secs % 60}s" + return f"{secs // 3600}h {(secs % 3600) // 60}m" + + +def format_timesince(ts: float) -> str: + """Format timestamp in seconds into a human-readable string, relative to now. + + Vaguely inspired by Django's `timesince` formatter. + """ + _TIMESINCE_CHUNKS = ( + # Label, divider, max value + ("second", 1, 60), + ("minute", 60, 60), + ("hour", 60 * 60, 24), + ("day", 60 * 60 * 24, 6), + ("week", 60 * 60 * 24 * 7, 6), + ("month", 60 * 60 * 24 * 30, 11), + ("year", 60 * 60 * 24 * 365, None), + ) + delta = time.time() - ts + if delta < 20: + return "a few seconds ago" + for label, divider, max_value in _TIMESINCE_CHUNKS: # noqa: B007 + value = round(delta / divider) + if max_value is not None and value <= max_value: + break + return f"{value} {label}{'s' if value > 1 else ''} ago" diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_paths.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_paths.py new file mode 100644 index 0000000000000000000000000000000000000000..f1420f98642515d6394e72bbab15b7c0ccecbd7b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_paths.py @@ -0,0 +1,155 @@ +# Copyright 2022-present, the HuggingFace Inc. team. +# +# 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. +"""Contains utilities to handle paths in Huggingface Hub.""" + +from collections.abc import Callable, Generator, Iterable +from fnmatch import fnmatchcase +from pathlib import Path +from typing import TypeVar + + +T = TypeVar("T") + +# Always ignore `.git` and `.cache/huggingface` folders in commits +DEFAULT_IGNORE_PATTERNS = [ + ".git", + ".git/*", + "*/.git", + "**/.git/**", + ".cache/huggingface", + ".cache/huggingface/*", + "*/.cache/huggingface", + "**/.cache/huggingface/**", +] +# Forbidden to commit these folders +FORBIDDEN_FOLDERS = [".git", ".cache"] + + +def filter_repo_objects( + items: Iterable[T], + *, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + key: Callable[[T], str] | None = None, +) -> Generator[T, None, None]: + """Filter repo objects based on an allowlist and a denylist. + + Input must be a list of paths (`str` or `Path`) or a list of arbitrary objects. + In the later case, `key` must be provided and specifies a function of one argument + that is used to extract a path from each element in iterable. + + Patterns are Standard Wildcards (globbing patterns), NOT regular expressions. The pattern matching is based on + Python's `fnmatch.fnmatchcase`, so it is case-sensitive on every platform. Backslashes are treated as path separators + and normalized to forward slashes in both patterns and paths before matching, so patterns built with `os.path.join` + on Windows work as expected. + + Note that it matches `*` across path boundaries, unlike traditional Unix shell globbing. For example, `"data/*.json"` + will match both `data/file.json` and `data/subdir/file.json`. + + See https://docs.python.org/3/library/fnmatch.html for more details. + + Args: + items (`Iterable`): + List of items to filter. + allow_patterns (`str` or `list[str]`, *optional*): + Patterns constituting the allowlist. If provided, item paths must match at + least one pattern from the allowlist. + ignore_patterns (`str` or `list[str]`, *optional*): + Patterns constituting the denylist. If provided, item paths must not match + any patterns from the denylist. + key (`Callable[[T], str]`, *optional*): + Single-argument function to extract a path from each item. If not provided, + the `items` must already be `str` or `Path`. + + Returns: + Filtered list of objects, as a generator. + + Raises: + :class:`ValueError`: + If `key` is not provided and items are not `str` or `Path`. + + Example usage with paths: + ```python + >>> # Filter only PDFs that are not hidden. + >>> list(filter_repo_objects( + ... ["aaa.pdf", "bbb.jpg", ".ccc.pdf", ".ddd.png"], + ... allow_patterns=["*.pdf"], + ... ignore_patterns=[".*"], + ... )) + ["aaa.pdf"] + ``` + + Example usage with objects: + ```python + >>> list(filter_repo_objects( + ... [ + ... CommitOperationAdd(path_or_fileobj="/tmp/aaa.pdf", path_in_repo="aaa.pdf") + ... CommitOperationAdd(path_or_fileobj="/tmp/bbb.jpg", path_in_repo="bbb.jpg") + ... CommitOperationAdd(path_or_fileobj="/tmp/.ccc.pdf", path_in_repo=".ccc.pdf") + ... CommitOperationAdd(path_or_fileobj="/tmp/.ddd.png", path_in_repo=".ddd.png") + ... ], + ... allow_patterns=["*.pdf"], + ... ignore_patterns=[".*"], + ... key=lambda x: x.path_in_repo + ... )) + [CommitOperationAdd(path_or_fileobj="/tmp/aaa.pdf", path_in_repo="aaa.pdf")] + ``` + """ + if isinstance(allow_patterns, str): + allow_patterns = [allow_patterns] + + if isinstance(ignore_patterns, str): + ignore_patterns = [ignore_patterns] + + if allow_patterns is not None: + allow_patterns = [_add_wildcard_to_directories(_normalize_separators(p)) for p in allow_patterns] + if ignore_patterns is not None: + ignore_patterns = [_add_wildcard_to_directories(_normalize_separators(p)) for p in ignore_patterns] + + if key is None: + + def _identity(item: T) -> str: + if isinstance(item, str): + return item + if isinstance(item, Path): + return str(item) + raise ValueError(f"Please provide `key` argument in `filter_repo_objects`: `{item}` is not a string.") + + key = _identity # Items must be `str` or `Path`, otherwise raise ValueError + + for item in items: + path = _normalize_separators(key(item)) + + # Skip if there's an allowlist and path doesn't match any + if allow_patterns is not None and not any(fnmatchcase(path, r) for r in allow_patterns): + continue + + # Skip if there's a denylist and path matches any + if ignore_patterns is not None and any(fnmatchcase(path, r) for r in ignore_patterns): + continue + + yield item + + +def _normalize_separators(value: str | Path) -> str: + # Repo paths always use `/` and `\` is not an fnmatch escape character, so treating backslashes as path separators + # (e.g. patterns built with `os.path.join` on Windows) is safe. + # `value` can be a `Path` if a custom `key` returns one; coerce to `str` first. + return str(value).replace("\\", "/") + + +def _add_wildcard_to_directories(pattern: str) -> str: + if pattern.endswith("/"): + return pattern + "*" + return pattern diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_runtime.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_runtime.py new file mode 100644 index 0000000000000000000000000000000000000000..f29de42c998b94e60c167018e9a27eb3f50f8c57 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_runtime.py @@ -0,0 +1,445 @@ +# Copyright 2022-present, the HuggingFace Inc. team. +# +# 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. +"""Check presence of installed packages at runtime.""" + +import importlib.metadata +import importlib.util +import os +import platform +import sys +import warnings +from pathlib import Path +from typing import Any, Literal + +from .. import __version__, constants + + +_PY_VERSION: str = sys.version.split()[0].rstrip("+") + +_package_versions = {} + +_CANDIDATES = { + "aiohttp": {"aiohttp"}, + "fastai": {"fastai"}, + "fastapi": {"fastapi"}, + "fastcore": {"fastcore"}, + "gradio": {"gradio"}, + "graphviz": {"graphviz"}, + "hf_xet": {"hf_xet"}, + "jinja": {"Jinja2"}, + "httpx": {"httpx"}, + "keras": {"keras"}, + "numpy": {"numpy"}, + "pillow": {"Pillow"}, + "pydantic": {"pydantic"}, + "pydot": {"pydot"}, + "safetensors": {"safetensors"}, + "tensorboard": {"tensorboardX"}, + "tensorflow": ( + "tensorflow", + "tensorflow-cpu", + "tensorflow-gpu", + "tf-nightly", + "tf-nightly-cpu", + "tf-nightly-gpu", + "intel-tensorflow", + "intel-tensorflow-avx512", + "tensorflow-rocm", + "tensorflow-macos", + ), + "torch": {"torch"}, +} + +# Check once at runtime +for candidate_name, package_names in _CANDIDATES.items(): + _package_versions[candidate_name] = "N/A" + for name in package_names: + try: + _package_versions[candidate_name] = importlib.metadata.version(name) + break + except importlib.metadata.PackageNotFoundError: + pass + + +def _get_version(package_name: str) -> str: + return _package_versions.get(package_name, "N/A") + + +def is_package_available(package_name: str) -> bool: + return _get_version(package_name) != "N/A" + + +# Python +def get_python_version() -> str: + return _PY_VERSION + + +# Huggingface Hub +def get_hf_hub_version() -> str: + return __version__ + + +# aiohttp +def is_aiohttp_available() -> bool: + return is_package_available("aiohttp") + + +def get_aiohttp_version() -> str: + return _get_version("aiohttp") + + +# FastAI +def is_fastai_available() -> bool: + return is_package_available("fastai") + + +def get_fastai_version() -> str: + return _get_version("fastai") + + +# FastAPI +def is_fastapi_available() -> bool: + return is_package_available("fastapi") + + +def get_fastapi_version() -> str: + return _get_version("fastapi") + + +# Fastcore +def is_fastcore_available() -> bool: + return is_package_available("fastcore") + + +def get_fastcore_version() -> str: + return _get_version("fastcore") + + +# FastAI +def is_gradio_available() -> bool: + return is_package_available("gradio") + + +def get_gradio_version() -> str: + return _get_version("gradio") + + +# Graphviz +def is_graphviz_available() -> bool: + return is_package_available("graphviz") + + +def get_graphviz_version() -> str: + return _get_version("graphviz") + + +# httpx +def is_httpx_available() -> bool: + return is_package_available("httpx") + + +def get_httpx_version() -> str: + return _get_version("httpx") + + +# xet +def is_xet_available() -> bool: + # since hf_xet is automatically used if available, allow explicit disabling via environment variable + if constants.HF_HUB_DISABLE_XET: + return False + + return is_package_available("hf_xet") + + +def get_xet_version() -> str: + return _get_version("hf_xet") + + +# keras +def is_keras_available() -> bool: + return is_package_available("keras") + + +def get_keras_version() -> str: + return _get_version("keras") + + +# Numpy +def is_numpy_available() -> bool: + return is_package_available("numpy") + + +def get_numpy_version() -> str: + return _get_version("numpy") + + +# Jinja +def is_jinja_available() -> bool: + return is_package_available("jinja") + + +def get_jinja_version() -> str: + return _get_version("jinja") + + +# Pillow +def is_pillow_available() -> bool: + return is_package_available("pillow") + + +def get_pillow_version() -> str: + return _get_version("pillow") + + +# Pydantic +def is_pydantic_available() -> bool: + if not is_package_available("pydantic"): + return False + # For Pydantic, we add an extra check to test whether it is correctly installed or not. If both pydantic 2.x and + # typing_extensions<=4.5.0 are installed, then pydantic will fail at import time. This should not happen when + # it is installed with `pip install huggingface_hub[inference]` but it can happen when it is installed manually + # by the user in an environment that we don't control. + # + # Usually we won't need to do this kind of check on optional dependencies. However, pydantic is a special case + # as it is automatically imported when doing `from huggingface_hub import ...` even if the user doesn't use it. + # + # See https://github.com/huggingface/huggingface_hub/pull/1829 for more details. + try: + from pydantic import validator # noqa: F401 + except ImportError: + # Example: "ImportError: cannot import name 'TypeAliasType' from 'typing_extensions'" + warnings.warn( + "Pydantic is installed but cannot be imported. Please check your installation. `huggingface_hub` will " + "default to not using Pydantic. Error message: '{e}'" + ) + return False + return True + + +def get_pydantic_version() -> str: + return _get_version("pydantic") + + +# Pydot +def is_pydot_available() -> bool: + return is_package_available("pydot") + + +def get_pydot_version() -> str: + return _get_version("pydot") + + +# Tensorboard +def is_tensorboard_available() -> bool: + return is_package_available("tensorboard") + + +def get_tensorboard_version() -> str: + return _get_version("tensorboard") + + +# Tensorflow +def is_tf_available() -> bool: + return is_package_available("tensorflow") + + +def get_tf_version() -> str: + return _get_version("tensorflow") + + +# Torch +def is_torch_available() -> bool: + return is_package_available("torch") + + +def get_torch_version() -> str: + return _get_version("torch") + + +# Safetensors +def is_safetensors_available() -> bool: + return is_package_available("safetensors") + + +# Shell-related helpers +try: + # Set to `True` if script is running in a Google Colab notebook. + # If running in Google Colab, git credential store is set globally which makes the + # warning disappear. See https://github.com/huggingface/huggingface_hub/issues/1043 + # + # Taken from https://stackoverflow.com/a/63519730. + _is_google_colab = "google.colab" in str(get_ipython()) # type: ignore # noqa: F821 +except NameError: + _is_google_colab = False + + +def is_notebook() -> bool: + """Return `True` if code is executed in a notebook (Jupyter, Colab, QTconsole). + + Taken from https://stackoverflow.com/a/39662359. + Adapted to make it work with Google colab as well. + """ + try: + shell_class = get_ipython().__class__ # type: ignore # noqa: F821 + for parent_class in shell_class.__mro__: # e.g. "is subclass of" + if parent_class.__name__ == "ZMQInteractiveShell": + return True # Jupyter notebook, Google colab or qtconsole + return False + except NameError: + return False # Probably standard Python interpreter + + +def is_google_colab() -> bool: + """Return `True` if code is executed in a Google colab. + + Taken from https://stackoverflow.com/a/63519730. + """ + return _is_google_colab + + +def is_colab_enterprise() -> bool: + """Return `True` if code is executed in a Google Colab Enterprise environment.""" + return os.environ.get("VERTEX_PRODUCT") == "COLAB_ENTERPRISE" + + +# Check how huggingface_hub has been installed + + +def installation_method() -> Literal["brew", "hf_installer", "pip", "unknown"]: + """Return the installation method of the current environment. + + - "hf_installer" if installed via the official installer script + - "brew" if installed via Homebrew + - "pip" if pip is available (default fallback for standard Python environments) + - "unknown" otherwise + """ + # hf_installer check must come first: the installer creates a venv using the + # system Python, which may be Homebrew's. Checking brew first would false-positive + # when the resolved sys.executable points to /opt/homebrew/... inside a venv. + if _is_hf_installer_installation(): + return "hf_installer" + if _is_brew_installation(): + return "brew" + if _is_pip_available(): + return "pip" + return "unknown" + + +def _is_brew_installation() -> bool: + """Check if running from a Homebrew installation. + + Homebrew installs the `hf` formula into a Cellar directory and creates a + libexec virtualenv at e.g. /opt/homebrew/Cellar/hf/0.30.0/libexec/. + We check `sys.prefix` (the venv/prefix root) for "/Cellar/hf/" rather + than checking `sys.executable` — the latter resolves to Homebrew's Python + (e.g. /opt/homebrew/Cellar/python@3.12/...) even for non-brew installs + when the system Python happens to come from Homebrew. + """ + prefix = str(Path(sys.prefix).resolve()) + return "/Cellar/hf/" in prefix + + +def _is_hf_installer_installation() -> bool: + """Return `True` if the current environment was set up via the official hf installer script. + + i.e. using one of + curl -LsSf https://hf.co/cli/install.sh | bash + powershell -ExecutionPolicy ByPass -c "irm https://hf.co/cli/install.ps1 | iex" + """ + venv = sys.prefix # points to venv root if active + marker = Path(venv) / ".hf_installer_marker" + return marker.exists() + + +def _is_pip_available() -> bool: + """Return `True` if pip is importable in the current environment.""" + return importlib.util.find_spec("pip") is not None + + +def dump_environment_info() -> dict[str, Any]: + """Dump information about the machine to help debugging issues. + + Similar helper exist in: + - `datasets` (https://github.com/huggingface/datasets/blob/main/src/datasets/commands/env.py) + - `diffusers` (https://github.com/huggingface/diffusers/blob/main/src/diffusers/commands/env.py) + - `transformers` (https://github.com/huggingface/transformers/blob/main/src/transformers/commands/env.py) + """ + from huggingface_hub import get_token, whoami + from huggingface_hub.utils import is_agent, list_credential_helpers + + token = get_token() + + # Generic machine info + info: dict[str, Any] = { + "huggingface_hub version": get_hf_hub_version(), + "Platform": platform.platform(), + "Python version": get_python_version(), + } + + # Interpreter info + try: + shell_class = get_ipython().__class__ # type: ignore # noqa: F821 + info["Running in iPython ?"] = "Yes" + info["iPython shell"] = shell_class.__name__ + except NameError: + info["Running in iPython ?"] = "No" + info["Running in notebook ?"] = "Yes" if is_notebook() else "No" + info["Running in Google Colab ?"] = "Yes" if is_google_colab() else "No" + info["Running in Google Colab Enterprise ?"] = "Yes" if is_colab_enterprise() else "No" + # Login info + info["Token path ?"] = constants.HF_TOKEN_PATH + info["Has saved token ?"] = token is not None + if token is not None: + try: + info["Who am I ?"] = whoami()["name"] + except Exception: + pass + + try: + info["Configured git credential helpers"] = ", ".join(list_credential_helpers()) + except Exception: + pass + + info["Run by AI agent ?"] = "Yes" if is_agent() else "No" + + # How huggingface_hub has been installed? + info["Installation method"] = installation_method() + + # Installed dependencies + info["httpx"] = get_httpx_version() + info["hf_xet"] = get_xet_version() + info["gradio"] = get_gradio_version() + info["tensorboard"] = get_tensorboard_version() + + # Environment variables + info["ENDPOINT"] = constants.ENDPOINT + info["HF_HUB_CACHE"] = constants.HF_HUB_CACHE + info["HF_ASSETS_CACHE"] = constants.HF_ASSETS_CACHE + info["HF_TOKEN_PATH"] = constants.HF_TOKEN_PATH + info["HF_STORED_TOKENS_PATH"] = constants.HF_STORED_TOKENS_PATH + info["HF_HUB_OFFLINE"] = constants.HF_HUB_OFFLINE + info["HF_HUB_DISABLE_TELEMETRY"] = constants.HF_HUB_DISABLE_TELEMETRY + info["HF_HUB_DISABLE_PROGRESS_BARS"] = constants.HF_HUB_DISABLE_PROGRESS_BARS + info["HF_HUB_DISABLE_SYMLINKS"] = constants.HF_HUB_DISABLE_SYMLINKS + info["HF_HUB_DISABLE_SYMLINKS_WARNING"] = constants.HF_HUB_DISABLE_SYMLINKS_WARNING + info["HF_HUB_DISABLE_EXPERIMENTAL_WARNING"] = constants.HF_HUB_DISABLE_EXPERIMENTAL_WARNING + info["HF_HUB_DISABLE_IMPLICIT_TOKEN"] = constants.HF_HUB_DISABLE_IMPLICIT_TOKEN + info["HF_HUB_DISABLE_XET"] = constants.HF_HUB_DISABLE_XET + info["HF_HUB_ETAG_TIMEOUT"] = constants.HF_HUB_ETAG_TIMEOUT + info["HF_HUB_DOWNLOAD_TIMEOUT"] = constants.HF_HUB_DOWNLOAD_TIMEOUT + info["HF_XET_HIGH_PERFORMANCE"] = constants.HF_XET_HIGH_PERFORMANCE + + print("\nCopy-and-paste the text below in your GitHub issue.\n") + print("\n".join([f"- {prop}: {val}" for prop, val in info.items()]) + "\n") + return info diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_safetensors.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_safetensors.py new file mode 100644 index 0000000000000000000000000000000000000000..8e4d0adbc1907cc9a9be6aafef1e9826bd6f97be --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_safetensors.py @@ -0,0 +1,111 @@ +import functools +import operator +from collections import defaultdict +from dataclasses import dataclass, field +from typing import Literal + + +FILENAME_T = str +TENSOR_NAME_T = str +DTYPE_T = Literal["F64", "F32", "F16", "BF16", "I64", "I32", "I16", "I8", "U8", "BOOL"] + + +@dataclass +class TensorInfo: + """Information about a tensor. + + For more details regarding the safetensors format, check out https://huggingface.co/docs/safetensors/index#format. + + Attributes: + dtype (`str`): + The data type of the tensor ("F64", "F32", "F16", "BF16", "I64", "I32", "I16", "I8", "U8", "BOOL"). + shape (`list[int]`): + The shape of the tensor. + data_offsets (`tuple[int, int]`): + The offsets of the data in the file as a tuple `[BEGIN, END]`. + parameter_count (`int`): + The number of parameters in the tensor. + """ + + dtype: DTYPE_T + shape: list[int] + data_offsets: tuple[int, int] + parameter_count: int = field(init=False) + + def __post_init__(self) -> None: + # Taken from https://stackoverflow.com/a/13840436 + try: + self.parameter_count = functools.reduce(operator.mul, self.shape) + except TypeError: + self.parameter_count = 1 # scalar value has no shape + + +@dataclass +class SafetensorsFileMetadata: + """Metadata for a Safetensors file hosted on the Hub. + + This class is returned by [`parse_safetensors_file_metadata`]. + + For more details regarding the safetensors format, check out https://huggingface.co/docs/safetensors/index#format. + + Attributes: + metadata (`dict`): + The metadata contained in the file. + tensors (`dict[str, TensorInfo]`): + A map of all tensors. Keys are tensor names and values are information about the corresponding tensor, as a + [`TensorInfo`] object. + parameter_count (`dict[str, int]`): + A map of the number of parameters per data type. Keys are data types and values are the number of parameters + of that data type. + """ + + metadata: dict[str, str] + tensors: dict[TENSOR_NAME_T, TensorInfo] + parameter_count: dict[DTYPE_T, int] = field(init=False) + + def __post_init__(self) -> None: + parameter_count: dict[DTYPE_T, int] = defaultdict(int) + for tensor in self.tensors.values(): + parameter_count[tensor.dtype] += tensor.parameter_count + self.parameter_count = dict(parameter_count) + + +@dataclass +class SafetensorsRepoMetadata: + """Metadata for a Safetensors repo. + + A repo is considered to be a Safetensors repo if it contains either a 'model.safetensors' weight file (non-shared + model) or a 'model.safetensors.index.json' index file (sharded model) at its root. + + This class is returned by [`get_safetensors_metadata`]. + + For more details regarding the safetensors format, check out https://huggingface.co/docs/safetensors/index#format. + + Attributes: + metadata (`dict`, *optional*): + The metadata contained in the 'model.safetensors.index.json' file, if it exists. Only populated for sharded + models. + sharded (`bool`): + Whether the repo contains a sharded model or not. + weight_map (`dict[str, str]`): + A map of all weights. Keys are tensor names and values are filenames of the files containing the tensors. + files_metadata (`dict[str, SafetensorsFileMetadata]`): + A map of all files metadata. Keys are filenames and values are the metadata of the corresponding file, as + a [`SafetensorsFileMetadata`] object. + parameter_count (`dict[str, int]`): + A map of the number of parameters per data type. Keys are data types and values are the number of parameters + of that data type. + """ + + metadata: dict | None + sharded: bool + weight_map: dict[TENSOR_NAME_T, FILENAME_T] # tensor name -> filename + files_metadata: dict[FILENAME_T, SafetensorsFileMetadata] # filename -> metadata + parameter_count: dict[DTYPE_T, int] = field(init=False) + + def __post_init__(self) -> None: + parameter_count: dict[DTYPE_T, int] = defaultdict(int) + for file_metadata in self.files_metadata.values(): + for dtype, nb_parameters_ in file_metadata.parameter_count.items(): + parameter_count[dtype] += nb_parameters_ + self.parameter_count = dict(parameter_count) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_subprocess.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_subprocess.py new file mode 100644 index 0000000000000000000000000000000000000000..e648e11146ecaa18bdb736bafedaf6cb6d8c15ff --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_subprocess.py @@ -0,0 +1,143 @@ +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# 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 +"""Contains utilities to easily handle subprocesses in `huggingface_hub`.""" + +import os +import subprocess +import sys +from collections.abc import Generator +from contextlib import contextmanager +from io import StringIO +from pathlib import Path +from typing import IO + +from .logging import get_logger + + +logger = get_logger(__name__) + + +@contextmanager +def capture_output() -> Generator[StringIO, None, None]: + """Capture output that is printed to terminal. + + Taken from https://stackoverflow.com/a/34738440 + + Example: + ```py + >>> with capture_output() as output: + ... print("hello world") + >>> assert output.getvalue() == "hello world\n" + ``` + """ + output = StringIO() + previous_output = sys.stdout + sys.stdout = output + try: + yield output + finally: + sys.stdout = previous_output + + +def run_subprocess( + command: str | list[str], + folder: str | Path | None = None, + check=True, + **kwargs, +) -> subprocess.CompletedProcess: + """ + Method to run subprocesses. Calling this will capture the `stderr` and `stdout`, + please call `subprocess.run` manually in case you would like for them not to + be captured. + + Args: + command (`str` or `list[str]`): + The command to execute as a string or list of strings. + folder (`str`, *optional*): + The folder in which to run the command. Defaults to current working + directory (from `os.getcwd()`). + check (`bool`, *optional*, defaults to `True`): + Setting `check` to `True` will raise a `subprocess.CalledProcessError` + when the subprocess has a non-zero exit code. + kwargs (`dict[str]`): + Keyword arguments to be passed to the `subprocess.run` underlying command. + + Returns: + `subprocess.CompletedProcess`: The completed process. + """ + if isinstance(command, str): + command = command.split() + + if isinstance(folder, Path): + folder = str(folder) + + return subprocess.run( + command, + capture_output=True, + check=check, + encoding="utf-8", + errors="replace", # if not utf-8, replace char by � + cwd=folder or os.getcwd(), + **kwargs, + ) + + +@contextmanager +def run_interactive_subprocess( + command: str | list[str], + folder: str | Path | None = None, + **kwargs, +) -> Generator[tuple[IO[str], IO[str]], None, None]: + """Run a subprocess in an interactive mode in a context manager. + + Args: + command (`str` or `list[str]`): + The command to execute as a string or list of strings. + folder (`str`, *optional*): + The folder in which to run the command. Defaults to current working + directory (from `os.getcwd()`). + kwargs (`dict[str]`): + Keyword arguments to be passed to the `subprocess.run` underlying command. + + Returns: + `tuple[IO[str], IO[str]]`: A tuple with `stdin` and `stdout` to interact + with the process (input and output are utf-8 encoded). + + Example: + ```python + with _interactive_subprocess("git credential-store get") as (stdin, stdout): + # Write to stdin + stdin.write("url=hf.co\nusername=obama\n".encode("utf-8")) + stdin.flush() + + # Read from stdout + output = stdout.read().decode("utf-8") + ``` + """ + if isinstance(command, str): + command = command.split() + + with subprocess.Popen( + command, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + encoding="utf-8", + errors="replace", # if not utf-8, replace char by � + cwd=folder or os.getcwd(), + **kwargs, + ) as process: + assert process.stdin is not None, "subprocess is opened as subprocess.PIPE" + assert process.stdout is not None, "subprocess is opened as subprocess.PIPE" + yield process.stdin, process.stdout diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_telemetry.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_telemetry.py new file mode 100644 index 0000000000000000000000000000000000000000..a97bae52111902e0b1ffb5fdcdb91ae07396f3f2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_telemetry.py @@ -0,0 +1,125 @@ +from queue import Queue +from threading import Lock, Thread +from urllib.parse import quote + +from .. import constants, logging +from . import build_hf_headers, get_session, hf_raise_for_status + + +logger = logging.get_logger(__name__) + +# Telemetry is sent by a separate thread to avoid blocking the main thread. +# A daemon thread is started once and consume tasks from the _TELEMETRY_QUEUE. +# If the thread stops for some reason -shouldn't happen-, we restart a new one. +_TELEMETRY_THREAD: Thread | None = None +_TELEMETRY_THREAD_LOCK = Lock() # Lock to avoid starting multiple threads in parallel +_TELEMETRY_QUEUE: Queue = Queue() + + +def send_telemetry( + topic: str, + *, + library_name: str | None = None, + library_version: str | None = None, + user_agent: dict | str | None = None, +) -> None: + """ + Sends telemetry that helps track usage of different HF libraries. + + This usage data helps us debug issues and prioritize new features. However, we understand that not everyone wants + to share additional information, and we respect your privacy. You can disable telemetry collection by setting the + `HF_HUB_DISABLE_TELEMETRY=1` as environment variable. Telemetry is also disabled in offline mode (i.e. when setting + `HF_HUB_OFFLINE=1`). + + Telemetry collection is run in a separate thread to minimize impact for the user. + + Args: + topic (`str`): + Name of the topic that is monitored. The topic is directly used to build the URL. If you want to monitor + subtopics, just use "/" separation. Examples: "gradio", "transformers/examples",... + library_name (`str`, *optional*): + The name of the library that is making the HTTP request. Will be added to the user-agent header. + library_version (`str`, *optional*): + The version of the library that is making the HTTP request. Will be added to the user-agent header. + user_agent (`str`, `dict`, *optional*): + The user agent info in the form of a dictionary or a single string. It will be completed with information about the installed packages. + + Example: + ```py + >>> from huggingface_hub.utils import send_telemetry + + # Send telemetry without library information + >>> send_telemetry("ping") + + # Send telemetry to subtopic with library information + >>> send_telemetry("gradio/local_link", library_name="gradio", library_version="3.22.1") + + # Send telemetry with additional data + >>> send_telemetry( + ... topic="examples", + ... library_name="transformers", + ... library_version="4.26.0", + ... user_agent={"pipeline": "text_classification", "framework": "flax"}, + ... ) + ``` + """ + if constants.is_offline_mode() or constants.HF_HUB_DISABLE_TELEMETRY: + return + + _start_telemetry_thread() # starts thread only if doesn't exist yet + _TELEMETRY_QUEUE.put( + {"topic": topic, "library_name": library_name, "library_version": library_version, "user_agent": user_agent} + ) + + +def _start_telemetry_thread(): + """Start a daemon thread to consume tasks from the telemetry queue. + + If the thread is interrupted, start a new one. + """ + with _TELEMETRY_THREAD_LOCK: # avoid to start multiple threads if called concurrently + global _TELEMETRY_THREAD + if _TELEMETRY_THREAD is None or not _TELEMETRY_THREAD.is_alive(): + _TELEMETRY_THREAD = Thread(target=_telemetry_worker, daemon=True) + _TELEMETRY_THREAD.start() + + +def _telemetry_worker(): + """Wait for a task and consume it.""" + while True: + kwargs = _TELEMETRY_QUEUE.get() + _send_telemetry_in_thread(**kwargs) + _TELEMETRY_QUEUE.task_done() + + +def _send_telemetry_in_thread( + topic: str, + *, + library_name: str | None = None, + library_version: str | None = None, + user_agent: dict | str | None = None, +) -> None: + """Contains the actual data sending data to the Hub. + + This function is called directly in gradio's analytics because + it is not possible to send telemetry from a daemon thread. + + See here: https://github.com/gradio-app/gradio/pull/8180 + + Please do not rename or remove this function. + """ + path = "/".join(quote(part) for part in topic.split("/") if len(part) > 0) + try: + r = get_session().head( + f"{constants.ENDPOINT}/api/telemetry/{path}", + headers=build_hf_headers( + token=False, # no need to send a token for telemetry + library_name=library_name, + library_version=library_version, + user_agent=user_agent, + ), + ) + hf_raise_for_status(r) + except Exception as e: + # We don't want to error in case of connection errors of any kind. + logger.debug(f"Error while sending telemetry: {e}") diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_terminal.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_terminal.py new file mode 100644 index 0000000000000000000000000000000000000000..051713fb8bfafb8654efc5952b844bb218757173 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_terminal.py @@ -0,0 +1,262 @@ +# Copyright 2025 The HuggingFace Team. All rights reserved. +# +# 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. +"""Contains utilities to print stuff to the terminal (styling, helpers).""" + +import ctypes +import os +import shutil +import sys +from contextlib import contextmanager + +from ._detect_agent import is_agent + + +if sys.platform == "win32": + import msvcrt +else: + import select + import termios + import tty + + +class StatusLine: + """Minimal TTY status line for sync progress (stderr, single-line overwrite).""" + + def __init__(self, enabled: bool = True): + self._active = enabled and sys.stderr.isatty() + + def update(self, msg: str) -> None: + if not self._active: + return + width = shutil.get_terminal_size().columns + if len(msg) > width - 1: + msg = msg[: width - 4] + "..." + sys.stderr.write(f"\r\033[K\033[90m{msg}\033[0m") + sys.stderr.flush() + + def done(self, msg: str) -> None: + if not self._active: + return + width = shutil.get_terminal_size().columns + if len(msg) > width - 1: + msg = msg[: width - 4] + "..." + sys.stderr.write(f"\r\033[K\033[90m{msg}\033[0m\n") + sys.stderr.flush() + + +class ANSI: + """ + Helper for en.wikipedia.org/wiki/ANSI_escape_code + """ + + _blue = "\u001b[34m" + _bold = "\u001b[1m" + _gray = "\u001b[90m" + _green = "\u001b[32m" + _red = "\u001b[31m" + _reset = "\u001b[0m" + _underline = "\u001b[4m" + _yellow = "\u001b[33m" + + @classmethod + def blue(cls, s: str) -> str: + return cls._format(s, cls._blue) + + @classmethod + def bold(cls, s: str) -> str: + return cls._format(s, cls._bold) + + @classmethod + def gray(cls, s: str) -> str: + return cls._format(s, cls._gray) + + @classmethod + def green(cls, s: str) -> str: + return cls._format(s, cls._green) + + @classmethod + def red(cls, s: str) -> str: + return cls._format(s, cls._bold + cls._red) + + @classmethod + def underline(cls, s: str) -> str: + return cls._format(s, cls._underline) + + @classmethod + def yellow(cls, s: str) -> str: + return cls._format(s, cls._yellow) + + @classmethod + def _format(cls, s: str, code: str) -> str: + if os.environ.get("NO_COLOR") or is_agent(): + # See https://no-color.org/ + return s + return f"{code}{s}{cls._reset}" + + +def select_choice(prompt: str, choices: list[str]) -> int: + """Single-choice interactive prompt. Returns the index of the selected choice. + + On a TTY, renders an arrow-key menu (Up/Down to move, Enter to confirm, 1-9 to pick + directly, Ctrl+C to abort). Falls back to a numbered `input()` prompt when raw + keyboard input is not available. Callers are responsible for not prompting at all in + non-interactive contexts. + """ + if not choices: + raise ValueError("select_choice() requires at least one choice.") + if _supports_raw_keyboard(): + return _select_with_arrows(prompt, choices) + return _select_with_numbers(prompt, choices) + + +def _supports_raw_keyboard() -> bool: + if not (sys.stdin and sys.stdin.isatty() and sys.stdout.isatty()): + return False + if sys.platform == "win32": + return _enable_windows_vt_processing() + return True + + +def _enable_windows_vt_processing() -> bool: + """Enable VT escape-sequence processing on the Windows console (off by default in legacy + cmd.exe/PowerShell windows, where the menu would otherwise render as literal `←[K` garbage).""" + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 + STD_OUTPUT_HANDLE = -11 + try: + kernel32 = ctypes.windll.kernel32 # type: ignore[attr-defined] + handle = kernel32.GetStdHandle(STD_OUTPUT_HANDLE) + mode = ctypes.c_uint32() + if not kernel32.GetConsoleMode(handle, ctypes.byref(mode)): + return False + return bool(kernel32.SetConsoleMode(handle, mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING)) + except Exception: + return False + + +@contextmanager +def _raw_terminal(): + """Put the terminal in cbreak mode (read keypresses without Enter). No-op on Windows.""" + if sys.platform == "win32": + yield + return + + fd = sys.stdin.fileno() + old_settings = termios.tcgetattr(fd) + try: + tty.setcbreak(fd) + yield + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + + +def _read_key() -> str: + """Read one keypress, normalizing arrow keys to "up"/"down".""" + if sys.platform == "win32": + char = msvcrt.getwch() + if char in ("\x00", "\xe0"): # arrow keys come as a two-character sequence + return {"H": "up", "P": "down"}.get(msvcrt.getwch(), "") + return char + + # Read the file descriptor directly: `sys.stdin.read(1)` would buffer the whole escape + # sequence internally, making the fd look empty to `select()` below. + fd = sys.stdin.fileno() + char = os.read(fd, 1) + # Disambiguate a bare Escape from an escape sequence (e.g. "\x1b[A" for Up). + if char == b"\x1b" and select.select([fd], [], [], 0.05)[0]: + if os.read(fd, 1) == b"[" and select.select([fd], [], [], 0.05)[0]: + return {b"A": "up", b"B": "down"}.get(os.read(fd, 1), "") + return "" + return char.decode(errors="replace") + + +def _select_with_arrows(prompt: str, choices: list[str]) -> int: + selected = 0 + print(ANSI.bold(f"? {prompt}") + ANSI.gray(" [Use arrows, Enter to confirm]")) + + def render() -> None: + for i, choice in enumerate(choices): + line = ANSI.green("> ") + ANSI.bold(choice) if i == selected else " " + choice + sys.stdout.write(f"\r\x1b[K{line}\n") + sys.stdout.flush() + + try: + sys.stdout.write("\x1b[?25l") # hide cursor + render() + with _raw_terminal(): + while True: + key = _read_key() + if key == "\x03": + # Ctrl+C: POSIX cbreak keeps ISIG so it never reaches here, but on Windows + # msvcrt.getwch() returns the raw character instead of raising. + raise KeyboardInterrupt + if key == "up": + selected = (selected - 1) % len(choices) + elif key == "down": + selected = (selected + 1) % len(choices) + elif key.isdecimal() and 1 <= int(key) <= len(choices): + selected = int(key) - 1 + break + elif key in ("\r", "\n"): + break + else: + continue + sys.stdout.write(f"\x1b[{len(choices)}A") # move back to the first option line + render() + finally: + sys.stdout.write("\x1b[?25h") # show cursor + sys.stdout.flush() + + # Collapse the menu into a single "? prompt answer" summary line, like gh does. + sys.stdout.write(f"\x1b[{len(choices) + 1}A\r\x1b[J") + print(ANSI.bold(f"? {prompt} ") + ANSI.green(choices[selected])) + return selected + + +def _select_with_numbers(prompt: str, choices: list[str]) -> int: + print(f"? {prompt}") + for i, choice in enumerate(choices, start=1): + print(f" {i}. {choice}") + while True: + raw = input("Choice [1]: ").strip() + if not raw: + return 0 + if raw.isdecimal() and 1 <= int(raw) <= len(choices): + return int(raw) - 1 + print(f"Invalid choice. Enter a number between 1 and {len(choices)}.") + + +def tabulate( + rows: list[list[str | int]], + headers: list[str], + alignments: dict[str, str] | None = None, +) -> str: + """ + Inspired by: + + - stackoverflow.com/a/8356620/593036 + - stackoverflow.com/questions/9535954/printing-lists-as-tabular-data + """ + _ALIGN_MAP = {"left": "<", "right": ">"} + for row in rows: + if len(row) < len(headers): + raise IndexError(f"Row has {len(row)} values but expected {len(headers)} (headers: {headers})") + col_widths = [max(len(str(x)) for x in col) for col in zip(*rows, headers)] + col_aligns = [_ALIGN_MAP.get((alignments or {}).get(h, "left"), "<") for h in headers] + row_format = " ".join(f"{{:{a}{w}}}" for a, w in zip(col_aligns, col_widths)) + lines = [] + lines.append(row_format.format(*headers)) + lines.append(row_format.format(*["-" * w for w in col_widths])) + for row in rows: + lines.append(row_format.format(*row)) + return "\n".join(lines) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_typing.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_typing.py new file mode 100644 index 0000000000000000000000000000000000000000..20db0e2d3ae9ae30a2a8a641e82a7869738fe2a9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_typing.py @@ -0,0 +1,91 @@ +# Copyright 2022-present, the HuggingFace Inc. team. +# +# 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. +"""Handle typing imports based on system compatibility.""" + +from collections.abc import Callable +from types import UnionType +from typing import Any, Literal, TypeVar, Union, get_args, get_origin + + +UNION_TYPES: list[Any] = [Union, UnionType] + + +HTTP_METHOD_T = Literal["GET", "OPTIONS", "HEAD", "POST", "PUT", "PATCH", "DELETE"] + +# type hint meaning "function signature not changed by decorator" +CallableT = TypeVar("CallableT", bound=Callable) + +_JSON_SERIALIZABLE_TYPES = (int, float, str, bool, type(None)) + + +def is_jsonable(obj: Any, _visited: set[int] | None = None) -> bool: + """Check if an object is JSON serializable. + + This is a weak check, as it does not check for the actual JSON serialization, but only for the types of the object. + It works correctly for basic use cases but do not guarantee an exhaustive check. + + Object is considered to be recursively json serializable if: + - it is an instance of int, float, str, bool, or NoneType + - it is a list or tuple and all its items are json serializable + - it is a dict and all its keys are strings and all its values are json serializable + + Uses a visited set to avoid infinite recursion on circular references. If object has already been visited, it is + considered not json serializable. + """ + # Initialize visited set to track object ids and detect circular references + if _visited is None: + _visited = set() + + # Detect circular reference + obj_id = id(obj) + if obj_id in _visited: + return False + + # Add current object to visited before recursive checks + _visited.add(obj_id) + try: + if isinstance(obj, _JSON_SERIALIZABLE_TYPES): + return True + if isinstance(obj, (list, tuple)): + return all(is_jsonable(item, _visited) for item in obj) + if isinstance(obj, dict): + return all( + isinstance(key, _JSON_SERIALIZABLE_TYPES) and is_jsonable(value, _visited) + for key, value in obj.items() + ) + if hasattr(obj, "__json__"): + return True + return False + except RecursionError: + return False + finally: + # Remove the object id from visited to avoid side‑effects for other branches + _visited.discard(obj_id) + + +def is_simple_optional_type(type_: type) -> bool: + """Check if a type is optional, i.e. Optional[Type] or Union[Type, None] or Type | None, where Type is a non-composite type.""" + if get_origin(type_) in UNION_TYPES: + union_args = get_args(type_) + if len(union_args) == 2 and type(None) in union_args: + return True + return False + + +def unwrap_simple_optional_type(optional_type: type) -> type: + """Unwraps a simple optional type, i.e. returns Type from Optional[Type].""" + for arg in get_args(optional_type): + if arg is not type(None): + return arg + raise ValueError(f"'{optional_type}' is not an optional type") diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_validators.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_validators.py new file mode 100644 index 0000000000000000000000000000000000000000..59c02dad4d08d8838b84ed2cda7634108a5ff1a2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_validators.py @@ -0,0 +1,210 @@ +# Copyright 2022-present, the HuggingFace Inc. team. +# +# 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. +"""Contains utilities to validate argument values in `huggingface_hub`.""" + +import inspect +import re +import warnings +from functools import wraps +from itertools import chain +from typing import Any + +from huggingface_hub.errors import HFValidationError + +from ._typing import CallableT + + +REPO_ID_REGEX = re.compile( + r""" + ^ + (\b[\w\-.]+\b/)? # optional namespace (username or organization) + \b # starts with a word boundary + [\w\-.]{1,96} # repo_name: alphanumeric + . _ - + \b # ends with a word boundary + $ + """, + flags=re.VERBOSE, +) + + +def validate_hf_hub_args(fn: CallableT) -> CallableT: + """Validate values received as argument for any public method of `huggingface_hub`. + + The goal of this decorator is to harmonize validation of arguments reused + everywhere. By default, all defined validators are tested. + + Validators: + - [`~utils.validate_repo_id`]: `repo_id` must be `"repo_name"` + or `"namespace/repo_name"`. Namespace is a username or an organization. + - [`~utils.smoothly_deprecate_legacy_arguments`]: Ignore `proxies` when downloading files (should be set globally). + + Example: + ```py + >>> from huggingface_hub.utils import validate_hf_hub_args + + >>> @validate_hf_hub_args + ... def my_cool_method(repo_id: str): + ... print(repo_id) + + >>> my_cool_method(repo_id="valid_repo_id") + valid_repo_id + + >>> my_cool_method("other..repo..id") + huggingface_hub.utils._validators.HFValidationError: Cannot have -- or .. in repo_id: 'other..repo..id'. + + >>> my_cool_method(repo_id="other..repo..id") + huggingface_hub.utils._validators.HFValidationError: Cannot have -- or .. in repo_id: 'other..repo..id'. + ``` + + Raises: + [`~utils.HFValidationError`]: + If an input is not valid. + """ + # TODO: add an argument to opt-out validation for specific argument? + signature = inspect.signature(fn) + + @wraps(fn) + def _inner_fn(*args, **kwargs): + for arg_name, arg_value in chain( + zip(signature.parameters, args), # Args values + kwargs.items(), # Kwargs values + ): + if arg_name in ["repo_id", "from_id", "to_id"]: + validate_repo_id(arg_value) + + kwargs = smoothly_deprecate_legacy_arguments(fn_name=fn.__name__, kwargs=kwargs) + + return fn(*args, **kwargs) + + return _inner_fn # type: ignore + + +def validate_repo_id(repo_id: str | None) -> None: + """Validate `repo_id` is valid. + + This is not meant to replace the proper validation made on the Hub but rather to + avoid local inconsistencies whenever possible (example: passing `repo_type` in the + `repo_id` is forbidden). + + Rules: + - Between 1 and 96 characters. + - Either "repo_name" or "namespace/repo_name" + - [a-zA-Z0-9] or "-", "_", "." + - "--" and ".." are forbidden + + Valid: `"foo"`, `"foo/bar"`, `"123"`, `"Foo-BAR_foo.bar123"` + + Not valid: `"datasets/foo/bar"`, `".repo_id"`, `"foo--bar"`, `"foo.git"` + + Example: + ```py + >>> from huggingface_hub.utils import validate_repo_id + >>> validate_repo_id(repo_id="valid_repo_id") + >>> validate_repo_id(repo_id="other..repo..id") + huggingface_hub.utils._validators.HFValidationError: Cannot have -- or .. in repo_id: 'other..repo..id'. + ``` + + Discussed in https://github.com/huggingface/huggingface_hub/issues/1008. + In moon-landing (internal repository): + - https://github.com/huggingface/moon-landing/blob/main/server/lib/Names.ts#L27 + - https://github.com/huggingface/moon-landing/blob/main/server/views/components/NewRepoForm/NewRepoForm.svelte#L138 + """ + if repo_id is None: + # Repo id is not always required + return + + if not isinstance(repo_id, str): + # Typically, a Path is not a repo_id + raise HFValidationError(f"Repo id must be a string, not {type(repo_id)}: '{repo_id}'.") + + if repo_id.count("/") > 1: + raise HFValidationError( + "Repo id must be in the form 'repo_name' or 'namespace/repo_name':" + f" '{repo_id}'. Use `repo_type` argument if needed." + ) + + if not REPO_ID_REGEX.match(repo_id): + raise HFValidationError( + "Repo id must use alphanumeric chars, '-', '_' or '.'." + " The name cannot start or end with '-' or '.' and the maximum length is 96:" + f" '{repo_id}'." + ) + + if "--" in repo_id or ".." in repo_id: + raise HFValidationError(f"Cannot have -- or .. in repo_id: '{repo_id}'.") + + if repo_id.endswith(".git"): + raise HFValidationError(f"Repo_id cannot end by '.git': '{repo_id}'.") + + +def smoothly_deprecate_legacy_arguments(fn_name: str, kwargs: dict[str, Any]) -> dict[str, Any]: + """Smoothly deprecate legacy arguments in the `huggingface_hub` codebase. + + This function ignores some deprecated arguments from the kwargs and warns the user they are ignored. + The goal is to avoid breaking existing code while guiding the user to the new way of doing things. + + List of deprecated arguments: + - `proxies`: + To set up proxies, user must either use the HTTP_PROXY environment variable or configure the `httpx.Client` + manually using the [`set_client_factory`] function. + + In huggingface_hub 0.x, `proxies` was a dictionary directly passed to `requests.request`. + In huggingface_hub 1.x, we migrated to `httpx` which does not support `proxies` the same way. + In particular, it is not possible to configure proxies on a per-request basis. The solution is to configure + it globally using the [`set_client_factory`] function or using the HTTP_PROXY environment variable. + + For more details, see: + - https://www.python-httpx.org/advanced/proxies/ + - https://www.python-httpx.org/compatibility/#proxy-keys. + + - `resume_download`: deprecated without replacement. `huggingface_hub` always resumes downloads whenever possible. + - `force_filename`: deprecated without replacement. Filename is always the same as on the Hub. + - `local_dir_use_symlinks`: deprecated without replacement. Downloading to a local directory does not use symlinks anymore. + """ + new_kwargs = kwargs.copy() # do not mutate input ! + + # proxies + proxies = new_kwargs.pop("proxies", None) # remove from kwargs + if proxies is not None: + warnings.warn( + f"The `proxies` argument is ignored in `{fn_name}`. To set up proxies, use the HTTP_PROXY / HTTPS_PROXY" + " environment variables or configure the `httpx.Client` manually using `huggingface_hub.set_client_factory`." + " See https://www.python-httpx.org/advanced/proxies/ for more details." + ) + + # resume_download + resume_download = new_kwargs.pop("resume_download", None) # remove from kwargs + if resume_download is not None: + warnings.warn( + f"The `resume_download` argument is deprecated and ignored in `{fn_name}`. Downloads always resume" + " whenever possible." + ) + + # force_filename + force_filename = new_kwargs.pop("force_filename", None) # remove from kwargs + if force_filename is not None: + warnings.warn( + f"The `force_filename` argument is deprecated and ignored in `{fn_name}`. Filename is always the same " + "as on the Hub." + ) + + # local_dir_use_symlinks + local_dir_use_symlinks = new_kwargs.pop("local_dir_use_symlinks", None) # remove from kwargs + if local_dir_use_symlinks is not None: + warnings.warn( + f"The `local_dir_use_symlinks` argument is deprecated and ignored in `{fn_name}`. Downloading to a local" + " directory does not use symlinks anymore." + ) + + return new_kwargs diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_verification.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_verification.py new file mode 100644 index 0000000000000000000000000000000000000000..1c01f97a4cb79959a628b95b2b03624bff364485 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_verification.py @@ -0,0 +1,167 @@ +import re +from dataclasses import dataclass +from pathlib import Path +from typing import TYPE_CHECKING, Literal, TypedDict + +from .. import constants +from ..file_download import repo_folder_name +from .sha import git_hash, sha_fileobj + + +if TYPE_CHECKING: + from ..hf_api import RepoFile + +# using fullmatch for clarity and strictness +_REGEX_COMMIT_HASH = re.compile(r"^[0-9a-f]{40}$") + + +# Typed structure describing a checksum mismatch +class Mismatch(TypedDict): + path: str + expected: str + actual: str + algorithm: str + + +HashAlgo = Literal["sha256", "git-sha1"] + + +@dataclass(frozen=True) +class FolderVerification: + revision: str + checked_count: int + mismatches: list[Mismatch] + missing_paths: list[str] + extra_paths: list[str] + verified_path: Path + + +def collect_local_files(root: Path) -> dict[str, Path]: + """ + Return a mapping of repo-relative path -> absolute path for all files under `root`. + """ + return {p.relative_to(root).as_posix(): p for p in root.rglob("*") if p.is_file()} + + +def _resolve_commit_hash_from_cache(storage_folder: Path, revision: str | None) -> str: + """ + Resolve a commit hash from a cache repo folder and an optional revision. + """ + if revision and _REGEX_COMMIT_HASH.fullmatch(revision): + return revision + + refs_dir = storage_folder / "refs" + snapshots_dir = storage_folder / "snapshots" + + if revision: + ref_path = refs_dir / revision + if ref_path.is_file(): + return ref_path.read_text(encoding="utf-8").strip() + raise ValueError(f"Revision '{revision}' could not be resolved in cache (expected file '{ref_path}').") + + # No revision provided: try common defaults + main_ref = refs_dir / "main" + if main_ref.is_file(): + return main_ref.read_text(encoding="utf-8").strip() + + if not snapshots_dir.is_dir(): + raise ValueError(f"Cache repo is missing snapshots directory: {snapshots_dir}. Provide --revision explicitly.") + + candidates = [p.name for p in snapshots_dir.iterdir() if p.is_dir() and _REGEX_COMMIT_HASH.fullmatch(p.name)] + if len(candidates) == 1: + return candidates[0] + + raise ValueError( + "Ambiguous cached revision: multiple snapshots found and no refs to disambiguate. Please pass --revision." + ) + + +def compute_file_hash(path: Path, algorithm: HashAlgo) -> str: + """ + Compute the checksum of a local file using the requested algorithm. + """ + + with path.open("rb") as stream: + if algorithm == "sha256": + return sha_fileobj(stream).hex() + if algorithm == "git-sha1": + return git_hash(stream.read()) + raise ValueError(f"Unsupported hash algorithm: {algorithm}") + + +def verify_maps( + *, + remote_by_path: dict[str, "RepoFile"], + local_by_path: dict[str, Path], + revision: str, + verified_path: Path, +) -> FolderVerification: + """Compare remote entries and local files and return a verification result.""" + remote_paths = set(remote_by_path) + local_paths = set(local_by_path) + + missing = sorted(remote_paths - local_paths) + extra = sorted(local_paths - remote_paths) + both = sorted(remote_paths & local_paths) + + mismatches: list[Mismatch] = [] + + for rel_path in both: + remote_entry = remote_by_path[rel_path] + local_path = local_by_path[rel_path] + + lfs = getattr(remote_entry, "lfs", None) + lfs_sha = getattr(lfs, "sha256", None) if lfs is not None else None + if lfs_sha is None and isinstance(lfs, dict): + lfs_sha = lfs.get("sha256") + if lfs_sha: + algorithm: HashAlgo = "sha256" + expected = str(lfs_sha).lower() + else: + blob_id = remote_entry.blob_id # type: ignore + algorithm = "git-sha1" + expected = str(blob_id).lower() + + actual = compute_file_hash(local_path, algorithm) + + if actual != expected: + mismatches.append(Mismatch(path=rel_path, expected=expected, actual=actual, algorithm=algorithm)) + + return FolderVerification( + revision=revision, + checked_count=len(both), + mismatches=mismatches, + missing_paths=missing, + extra_paths=extra, + verified_path=verified_path, + ) + + +def resolve_local_root( + *, + repo_id: str, + repo_type: str, + revision: str | None, + cache_dir: Path | None, + local_dir: Path | None, +) -> tuple[Path, str]: + """ + Resolve the root directory to scan locally and the remote revision to verify. + """ + if local_dir is not None: + root = Path(local_dir).expanduser().resolve() + if not root.is_dir(): + raise ValueError(f"Local directory does not exist or is not a directory: {root}") + return root, (revision or constants.DEFAULT_REVISION) + + cache_root = Path(cache_dir or constants.HF_HUB_CACHE).expanduser().resolve() + storage_folder = cache_root / repo_folder_name(repo_id=repo_id, repo_type=repo_type) + if not storage_folder.exists(): + raise ValueError( + f"Repo is not present in cache: {storage_folder}. Use 'hf download' first or pass --local-dir." + ) + commit = _resolve_commit_hash_from_cache(storage_folder, revision) + snapshot_dir = storage_folder / "snapshots" / commit + if not snapshot_dir.is_dir(): + raise ValueError(f"Snapshot directory does not exist for revision '{commit}': {snapshot_dir}.") + return snapshot_dir, commit diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_xet.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_xet.py new file mode 100644 index 0000000000000000000000000000000000000000..58102ae537c180fe11f1624dc7d948c68cc863e0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_xet.py @@ -0,0 +1,172 @@ +import os +import threading +from dataclasses import dataclass +from enum import Enum + +import httpx + +from .. import constants +from . import validate_hf_hub_args + + +class XetTokenType(str, Enum): + READ = "read" + WRITE = "write" + + +@dataclass(frozen=True) +class XetFileData: + file_hash: str + refresh_route: str + + +def parse_xet_file_data_from_response(response: httpx.Response, endpoint: str | None = None) -> XetFileData | None: + """ + Parse XET file metadata from an HTTP response. + + This function extracts XET file metadata from the HTTP headers or HTTP links + of a given response object. If the required metadata is not found, it returns `None`. + + Args: + response (`httpx.Response`): + The HTTP response object containing headers dict and links dict to extract the XET metadata from. + Returns: + `Optional[XetFileData]`: + An instance of `XetFileData` containing the file hash and refresh route if the metadata + is found. Returns `None` if the required metadata is missing. + """ + if response is None: + return None + try: + file_hash = response.headers[constants.HUGGINGFACE_HEADER_X_XET_HASH] + + if constants.HUGGINGFACE_HEADER_LINK_XET_AUTH_KEY in response.links: + refresh_route = response.links[constants.HUGGINGFACE_HEADER_LINK_XET_AUTH_KEY]["url"] + else: + refresh_route = response.headers[constants.HUGGINGFACE_HEADER_X_XET_REFRESH_ROUTE] + except KeyError: + return None + endpoint = endpoint if endpoint is not None else constants.ENDPOINT + if refresh_route.startswith(constants.HUGGINGFACE_CO_URL_HOME): + refresh_route = refresh_route.replace(constants.HUGGINGFACE_CO_URL_HOME.rstrip("/"), endpoint.rstrip("/")) + return XetFileData( + file_hash=file_hash, + refresh_route=refresh_route, + ) + + +@validate_hf_hub_args +def xet_connection_info_refresh_url( + *, + token_type: XetTokenType, + repo_id: str, + repo_type: str, + revision: str | None = None, + endpoint: str | None = None, +) -> str: + """ + Build the URL used to fetch or refresh a Xet access token for a given repo. + Args: + token_type (`XetTokenType`): + Type of the token to request: `"read"` or `"write"`. + repo_id (`str`): + A namespace (user or an organization) and a repo name separated by a `/`. + repo_type (`str`): + Type of the repo (e.g. `"model"`, `"dataset"`, `"space"`, `"bucket"`). + revision (`str`, `optional`): + The revision of the repo to get the token for. + endpoint (`str`, `optional`): + The endpoint to use for the request. Defaults to the Hub endpoint. + Returns: + `str`: + The fully-qualified URL of the token refresh endpoint. + """ + endpoint = endpoint if endpoint is not None else constants.ENDPOINT + url = f"{endpoint}/api/{repo_type}s/{repo_id}/xet-{token_type.value}-token" + if repo_type != "bucket" or revision is not None: + # On "bucket" repo type, the revision never needed => don't use it + # Otherwise, use the revision. + # Note: when creating a PR on a git-based repo, user needs write access but they don't know the revision in advance. + # => pass "/None" in URL and server will return a token for PR refs. + url += f"/{revision}" + return url + + +class XetSessionHolder: + """Holds an optional XetSession; supports safe re-creation after sigint_abort or fork. + + Thread-safe: a ``threading.Lock`` guards all state mutations, which matters + for free-threaded Python (3.14t) where multiple threads can race on ``get()`` + or ``sigint_abort()`` without the GIL serialising them. + """ + + def __init__(self): + self._lock = threading.Lock() + self._session = None + self._session_pid: int | None = None + + def get(self): + """Return the current session, creating one if needed. + + Fork-safe: if the current process PID differs from the PID that created + the session (i.e. we are in a forked child), the old session is discarded + and a fresh session is created for this process. + """ + with self._lock: + current_pid = os.getpid() + + if self._session is not None and self._session_pid != current_pid: + # Fork detected. Discard the parent's session; the Rust Drop will + # call discard_runtime() (std::mem::forget) rather than the normal + # shutdown path, so this returns immediately without blocking. + self._session = None + + if self._session is None: + from hf_xet import XetSession + + self._session = XetSession() + self._session_pid = current_pid + + return self._session + + def sigint_abort(self): + """Abort the current session and clear it so the next get() creates a fresh one.""" + with self._lock: + if self._session is not None: + try: + self._session.sigint_abort() + except Exception: + pass + self._session = None + self._session_pid = None + + +_GLOBAL_XET_HOLDER = XetSessionHolder() + + +def get_xet_session(): + """Return the global :class:`hf_xet.XetSession`, creating it on first call. + + The session is shared across all calls within a process, just as the HTTP + client returned by :func:`~huggingface_hub.utils._http.get_session` is shared. + It is created lazily and is fork-safe and thread-safe. + """ + return _GLOBAL_XET_HOLDER.get() + + +def xet_headers_without_auth(headers: dict[str, str]) -> dict[str, str]: + """Return a copy of headers with the authorization header removed. + + Xet storage requests use a short-lived xet access token for auth, so the + Hub authorization header must not be forwarded to xet storage endpoints. + """ + return {key: value for key, value in headers.items() if key.lower() != "authorization"} + + +def abort_xet_session(): + """Abort the global xet session after a KeyboardInterrupt. + + Cancels any in-flight Rust operation and clears the session so the next + call to :func:`get_xet_session` starts fresh (notebook-friendly). + """ + _GLOBAL_XET_HOLDER.sigint_abort() diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_xet_progress_reporting.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_xet_progress_reporting.py new file mode 100644 index 0000000000000000000000000000000000000000..0198dd63a9b481c20062772610cb761b5e25ac03 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_xet_progress_reporting.py @@ -0,0 +1,343 @@ +from collections import OrderedDict +from typing import Any + +from . import is_google_colab, is_notebook +from .tqdm import _create_progress_bar, tqdm + + +def _format_speed_postfix(speed: float | None) -> str: + s = tqdm.format_sizeof(speed) if speed is not None else "???" + return f"{s}B/s ".rjust(10, " ") + + +# Transfer byte count is hard to predict (dedup/compression), so we omit a total and show bytes only. +XET_TRANSFER_BAR_FORMAT = "{desc}: {bar}| {n_fmt:>5}B{postfix:>12}" +XET_BYTES_BAR_FORMAT = "{l_bar}{bar}| {n_fmt:>5}B / {total_fmt:>5}B{postfix:>12}" + + +def _set_monotonic_total(bar, total: int | None) -> None: + if total is None or not hasattr(bar, "total"): + return + bar.total = max(bar.total or 0, total) + + +def _update_transfer_bar(bar, inc: int) -> None: + """Update the transfer bar and grow its hidden total so the bar graphic advances. + + Network bytes are hard to predict (dedup/compression), so the display omits a denominator. + tqdm still needs an internal total for the bar width — seeded from file size when known, + then expanded here if bytes received exceed that estimate. + """ + n_after = getattr(bar, "n", 0) + inc + current_total = getattr(bar, "total", 0) or 0 + if n_after > 0 and current_total < n_after: + bar.total = max(current_total, int(n_after * 1.25) + 1) + bar.update(inc) + + +def _finish_transfer_bar(bar) -> None: + """Snap the transfer bar to 100% when downloading stops. + + Transfer totals are seeded from file size, but actual network bytes are often lower. + Set ``total = n`` so the bar fills completely instead of stopping partway. + """ + n = getattr(bar, "n", 0) + if n > 0 and hasattr(bar, "total") and bar.total != n: + bar.total = n + bar.refresh() + + +class XetDownloadProgressReporter: + """Dual progress bars for Xet downloads: network transfer and file reconstruction. + + ``total_transfer_bytes_completed`` tracks bytes received from the network (updated continuously). + ``total_bytes_completed`` tracks bytes written to disk (updated after buffered chunks are flushed). + Showing both bars gives responsive feedback on slow connections where reconstruction lags behind transfer. + """ + + def __init__( + self, + *, + reconstruction_desc: str, + transfer_desc: str = "Downloading bytes", + total: int | None = None, + log_level: int, + name: str | None = None, + tqdm_class: type | None = None, + external_reconstruction_bar: Any | None = None, + position: int = 0, + ): + self._prev_bytes_completed = 0 + self._prev_transfer_bytes_completed = 0 + + cls = tqdm_class or tqdm + routes_transfer_via_reconstruction = external_reconstruction_bar is not None and callable( + getattr(external_reconstruction_bar, "update_transfer", None) + ) + uses_aggregated_tqdm_class = external_reconstruction_bar is None and callable( + getattr(cls, "update_transfer", None) + ) + + if external_reconstruction_bar is not None: + self.reconstruction_bar = external_reconstruction_bar + self._owns_reconstruction_bar = False + else: + self.reconstruction_bar = _create_progress_bar( + cls=cls, # ty: ignore[invalid-argument-type] + log_level=log_level, + name=name, + desc=reconstruction_desc, + total=total, + unit="B", + unit_scale=True, + position=position + 1, + bar_format=XET_BYTES_BAR_FORMAT, + leave=True, + ) + self._owns_reconstruction_bar = True + + if routes_transfer_via_reconstruction or uses_aggregated_tqdm_class: + self.transfer_bar = self.reconstruction_bar + self._owns_transfer_bar = False + elif external_reconstruction_bar is not None: + self.transfer_bar = None + self._owns_transfer_bar = False + else: + self.transfer_bar = _create_progress_bar( + cls=tqdm, + log_level=log_level, + name=f"{name}.transfer" if name else None, + desc=transfer_desc, + total=total, + unit="B", + unit_scale=True, + position=position, + bar_format=XET_TRANSFER_BAR_FORMAT, + leave=True, + ) + self._owns_transfer_bar = True + + @property + def _aggregated(self) -> bool: + return self.transfer_bar is not None and self.transfer_bar is self.reconstruction_bar + + def update_progress(self, group_report, _item_reports: dict | None = None) -> None: + bytes_inc = max(0, group_report.total_bytes_completed - self._prev_bytes_completed) + transfer_inc = max(0, group_report.total_transfer_bytes_completed - self._prev_transfer_bytes_completed) + self._prev_bytes_completed = group_report.total_bytes_completed + self._prev_transfer_bytes_completed = group_report.total_transfer_bytes_completed + + if bytes_inc > 0: + self.reconstruction_bar.update(bytes_inc) + self.reconstruction_bar.set_postfix_str( + _format_speed_postfix(group_report.total_bytes_completion_rate), refresh=False + ) + + if transfer_inc > 0 and self.transfer_bar is not None: + if self._aggregated: + self.reconstruction_bar.update_transfer(transfer_inc) + self.reconstruction_bar.set_transfer_postfix_str( + _format_speed_postfix(group_report.total_transfer_bytes_completion_rate), refresh=False + ) + else: + _update_transfer_bar(self.transfer_bar, transfer_inc) + self.transfer_bar.set_postfix_str( + _format_speed_postfix(group_report.total_transfer_bytes_completion_rate), refresh=False + ) + + if group_report.total_bytes: + _set_monotonic_total(self.reconstruction_bar, group_report.total_bytes) + + def close(self) -> None: + """Close bars owned by this reporter. + + Standalone downloads finish the transfer bar first (snap hidden total to ``n``), then close it. + Aggregated and external bars (e.g. snapshot ``_AggregatedTqdm`` or a reused ``_tqdm_bar``) are left + open — their parent caller owns their lifecycle. + """ + if self.transfer_bar is not None and self._owns_transfer_bar: + _finish_transfer_bar(self.transfer_bar) + if hasattr(self.transfer_bar, "close"): + self.transfer_bar.close() + if self._owns_reconstruction_bar and hasattr(self.reconstruction_bar, "close"): + self.reconstruction_bar.close() + + def __enter__(self) -> "XetDownloadProgressReporter": + return self + + def __exit__(self, *args) -> None: + self.close() + + +class XetUploadProgressReporter: + """ + Reports on progress for Xet uploads. + + Shows summary progress bars when running in notebooks or GUIs, and detailed per-file progress in console environments. + """ + + def __init__(self, n_lines: int = 10, description_width: int = 30, total_files: int | None = None): + self.n_lines = n_lines + self.description_width = description_width + self.total_files = total_files + + self.per_file_progress = is_google_colab() or not is_notebook() + + self.tqdm_settings = { + "unit": "B", + "unit_scale": True, + "leave": True, + "unit_divisor": 1000, + "nrows": n_lines + 3 if self.per_file_progress else 3, + "miniters": 1, + "bar_format": XET_BYTES_BAR_FORMAT, + } + + # Overall progress bars + self.data_processing_bar = tqdm( + total=0, desc=self.format_desc("Processing Files (0 / 0)", False), position=0, **self.tqdm_settings + ) + + self.upload_bar = tqdm( + total=0, desc=self.format_desc("New Data Upload", False), position=1, **self.tqdm_settings + ) + + self.known_items: set[str] = set() + self.completed_items: set[str] = set() + + # Track previous absolute values to compute increments + self._prev_bytes_completed: int = 0 + self._prev_transfer_bytes_completed: int = 0 + + # Item bars (scrolling view) + self.item_state: OrderedDict[str, Any] = OrderedDict() + self.current_bars: list = [None] * self.n_lines + + def format_desc(self, name: str, indent: bool) -> str: + """ + if name is longer than width characters, prints ... at the start and then the last width-3 characters of the name, otherwise + the whole name right justified into description_width characters. Also adds some padding. + """ + + if not self.per_file_progress: + # Here we just use the defaults. + return name + + padding = " " if indent else "" + width = self.description_width - len(padding) + + if len(name) > width: + name = f"...{name[-(width - 3) :]}" + + return f"{padding}{name.ljust(width)}" + + def reset_for_next_commit(self): + """Reset per-commit state so the reporter can be reused across multiple upload commits.""" + self._prev_bytes_completed = 0 + self._prev_transfer_bytes_completed = 0 + self.known_items.clear() + self.completed_items.clear() + self.item_state.clear() + + def update_progress(self, group_report, item_reports: dict): + # Update all the per-item values. + for item in item_reports.values(): + item_name = item.item_name + + self.known_items.add(item_name) + + # Only care about items where the processing has already started. + if item.bytes_completed == 0: + continue + + # Overwrite the existing value in there. + self.item_state[item_name] = item + + bar_idx = 0 + new_completed = [] + + # Now, go through and update all the bars + for name, item in self.item_state.items(): + # Is this ready to be removed on the next update? + if item.bytes_completed == item.total_bytes: + self.completed_items.add(name) + new_completed.append(name) + + # If we're only showing summary information, then don't update the individual bars + if not self.per_file_progress: + continue + + # If we've run out of bars to use, then collapse the last ones together. + if bar_idx >= len(self.current_bars): + bar = self.current_bars[-1] + in_final_bar_mode = True + final_bar_aggregation_count = bar_idx + 1 - len(self.current_bars) + else: + bar = self.current_bars[bar_idx] + in_final_bar_mode = False + + if bar is None: + self.current_bars[bar_idx] = tqdm( + desc=self.format_desc(name, True), + position=2 + bar_idx, # Set to the position past the initial bars. + total=item.total_bytes, + initial=item.bytes_completed, + **self.tqdm_settings, + ) + + elif in_final_bar_mode: + bar.n += item.bytes_completed + bar.total += item.total_bytes + bar.set_description(self.format_desc(f"[+ {final_bar_aggregation_count} files]", True), refresh=False) + else: + bar.set_description(self.format_desc(name, True), refresh=False) + bar.n = item.bytes_completed + bar.total = item.total_bytes + + bar_idx += 1 + + # Remove all the completed ones from the ordered dictionary + for name in new_completed: + # Only remove ones from consideration to make room for more items coming in. + if len(self.item_state) <= self.n_lines: + break + + del self.item_state[name] + + if self.per_file_progress: + # Now manually refresh each of the bars + for bar in self.current_bars: + if bar: + bar.refresh() + + # Update overall bars + bytes_inc = max(0, group_report.total_bytes_completed - self._prev_bytes_completed) + transfer_inc = max(0, group_report.total_transfer_bytes_completed - self._prev_transfer_bytes_completed) + self._prev_bytes_completed = group_report.total_bytes_completed + self._prev_transfer_bytes_completed = group_report.total_transfer_bytes_completed + + self.data_processing_bar.total = group_report.total_bytes + total_files_count = self.total_files if self.total_files is not None else len(self.known_items) + self.data_processing_bar.set_description( + self.format_desc(f"Processing Files ({len(self.completed_items)} / {total_files_count})", False), + refresh=False, + ) + self.data_processing_bar.set_postfix_str( + _format_speed_postfix(group_report.total_bytes_completion_rate), refresh=False + ) + self.data_processing_bar.update(bytes_inc) + + self.upload_bar.total = group_report.total_transfer_bytes + self.upload_bar.set_postfix_str( + _format_speed_postfix(group_report.total_transfer_bytes_completion_rate), refresh=False + ) + self.upload_bar.update(transfer_inc) + + def close(self): + self.data_processing_bar.close() + self.upload_bar.close() + + if self.per_file_progress: + for bar in self.current_bars: + if bar: + bar.close() diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/endpoint_helpers.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/endpoint_helpers.py new file mode 100644 index 0000000000000000000000000000000000000000..85cd86011b78bcdc57034aeebc3c01e9e721ab50 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/endpoint_helpers.py @@ -0,0 +1,66 @@ +# 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. +""" +Helpful utility functions and classes in relation to exploring API endpoints +with the aim for a user-friendly interface. +""" + +import math +import re +from typing import TYPE_CHECKING + +from ..repocard_data import ModelCardData + + +if TYPE_CHECKING: + from ..hf_api import ModelInfo + + +def _is_emission_within_threshold(model_info: "ModelInfo", minimum_threshold: float, maximum_threshold: float) -> bool: + """Checks if a model's emission is within a given threshold. + + Args: + model_info (`ModelInfo`): + A model info object containing the model's emission information. + minimum_threshold (`float`): + A minimum carbon threshold to filter by, such as 1. + maximum_threshold (`float`): + A maximum carbon threshold to filter by, such as 10. + + Returns: + `bool`: Whether the model's emission is within the given threshold. + """ + if minimum_threshold is None and maximum_threshold is None: + raise ValueError("Both `minimum_threshold` and `maximum_threshold` cannot both be `None`") + if minimum_threshold is None: + minimum_threshold = -1 + if maximum_threshold is None: + maximum_threshold = math.inf + + card_data = getattr(model_info, "card_data", None) + if card_data is None or not isinstance(card_data, (dict, ModelCardData)): + return False + + # Get CO2 emission metadata + emission = card_data.get("co2_eq_emissions", None) + if isinstance(emission, dict): + emission = emission["emissions"] + if not emission: + return False + + # Filter out if value is missing or out of range + matched = re.search(r"\d+\.\d+|\d+", str(emission)) + if matched is None: + return False + + emission_value = float(matched.group(0)) + return minimum_threshold <= emission_value <= maximum_threshold diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/insecure_hashlib.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/insecure_hashlib.py new file mode 100644 index 0000000000000000000000000000000000000000..639e04460b0338d4642ea522490bedf038bfb557 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/insecure_hashlib.py @@ -0,0 +1,32 @@ +# Taken from https://github.com/mlflow/mlflow/pull/10119 +# +# DO NOT use this function for security purposes (e.g., password hashing). +# +# In Python >= 3.9, insecure hashing algorithms such as MD5 fail in FIPS-compliant +# environments unless `usedforsecurity=False` is explicitly passed. +# +# References: +# - https://github.com/mlflow/mlflow/issues/9905 +# - https://github.com/mlflow/mlflow/pull/10119 +# - https://docs.python.org/3/library/hashlib.html +# - https://github.com/huggingface/transformers/pull/27038 +# +# Usage: +# ```python +# # Use +# from huggingface_hub.utils.insecure_hashlib import sha256 +# # instead of +# from hashlib import sha256 +# +# # Use +# from huggingface_hub.utils import insecure_hashlib +# # instead of +# import hashlib +# ``` +import functools +import hashlib + + +md5 = functools.partial(hashlib.md5, usedforsecurity=False) +sha1 = functools.partial(hashlib.sha1, usedforsecurity=False) +sha256 = functools.partial(hashlib.sha256, usedforsecurity=False) diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/logging.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/logging.py new file mode 100644 index 0000000000000000000000000000000000000000..48d6317fa7e6ad6083c6a4d486f0cab456d0c1da --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/logging.py @@ -0,0 +1,183 @@ +# Copyright 2020 Optuna, Hugging Face +# +# 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. +"""Logging utilities.""" + +import logging +import os +from logging import ( + CRITICAL, # NOQA + DEBUG, # NOQA + ERROR, # NOQA + FATAL, # NOQA + INFO, # NOQA + NOTSET, # NOQA + WARN, # NOQA + WARNING, # NOQA +) + +from .. import constants + + +log_levels = { + "debug": logging.DEBUG, + "info": logging.INFO, + "warning": logging.WARNING, + "error": logging.ERROR, + "critical": logging.CRITICAL, +} + +_default_log_level = logging.WARNING + + +def _get_library_name() -> str: + return __name__.split(".")[0] + + +def _get_library_root_logger() -> logging.Logger: + return logging.getLogger(_get_library_name()) + + +def _get_default_logging_level(): + """ + If `HF_HUB_VERBOSITY` env var is set to one of the valid choices return that as the new default level. If it is not + - fall back to `_default_log_level` + """ + env_level_str = os.getenv("HF_HUB_VERBOSITY", None) + if env_level_str: + if env_level_str in log_levels: + return log_levels[env_level_str] + else: + logging.getLogger().warning( + f"Unknown option HF_HUB_VERBOSITY={env_level_str}, has to be one of: {', '.join(log_levels.keys())}" + ) + return _default_log_level + + +def _configure_library_root_logger() -> None: + library_root_logger = _get_library_root_logger() + library_root_logger.addHandler(logging.StreamHandler()) + library_root_logger.setLevel(_get_default_logging_level()) + + +def _reset_library_root_logger() -> None: + library_root_logger = _get_library_root_logger() + library_root_logger.setLevel(logging.NOTSET) + + +def get_logger(name: str | None = None) -> logging.Logger: + """ + Returns a logger with the specified name. This function is not supposed + to be directly accessed by library users. + + Args: + name (`str`, *optional*): + The name of the logger to get, usually the filename + + Example: + + ```python + >>> from huggingface_hub import get_logger + + >>> logger = get_logger(__file__) + >>> logger.set_verbosity_info() + ``` + """ + + if name is None: + name = _get_library_name() + + return logging.getLogger(name) + + +def get_verbosity() -> int: + """Return the current level for the HuggingFace Hub's root logger. + + Returns: + Logging level, e.g., `huggingface_hub.logging.DEBUG` and + `huggingface_hub.logging.INFO`. + + > [!TIP] + > HuggingFace Hub has following logging levels: + > + > - `huggingface_hub.logging.CRITICAL`, `huggingface_hub.logging.FATAL` + > - `huggingface_hub.logging.ERROR` + > - `huggingface_hub.logging.WARNING`, `huggingface_hub.logging.WARN` + > - `huggingface_hub.logging.INFO` + > - `huggingface_hub.logging.DEBUG` + """ + return _get_library_root_logger().getEffectiveLevel() + + +def set_verbosity(verbosity: int) -> None: + """ + Sets the level for the HuggingFace Hub's root logger. + + Args: + verbosity (`int`): + Logging level, e.g., `huggingface_hub.logging.DEBUG` and + `huggingface_hub.logging.INFO`. + """ + _get_library_root_logger().setLevel(verbosity) + + +def set_verbosity_info(): + """ + Sets the verbosity to `logging.INFO`. + """ + return set_verbosity(INFO) + + +def set_verbosity_warning(): + """ + Sets the verbosity to `logging.WARNING`. + """ + return set_verbosity(WARNING) + + +def set_verbosity_debug(): + """ + Sets the verbosity to `logging.DEBUG`. + """ + return set_verbosity(DEBUG) + + +def set_verbosity_error(): + """ + Sets the verbosity to `logging.ERROR`. + """ + return set_verbosity(ERROR) + + +def disable_propagation() -> None: + """ + Disable propagation of the library log outputs. Note that log propagation is + disabled by default. + """ + _get_library_root_logger().propagate = False + + +def enable_propagation() -> None: + """ + Enable propagation of the library log outputs. Please disable the + HuggingFace Hub's default handler to prevent double logging if the root + logger has been configured. + """ + _get_library_root_logger().propagate = True + + +_configure_library_root_logger() + +if constants.HF_DEBUG: + # If `HF_DEBUG` environment variable is set, set the verbosity of `huggingface_hub` logger to `DEBUG`. + set_verbosity_debug() diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/sha.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/sha.py new file mode 100644 index 0000000000000000000000000000000000000000..dc2f8f614c9ec02579153eb3308603f7ff24adef --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/sha.py @@ -0,0 +1,64 @@ +"""Utilities to efficiently compute the SHA 256 hash of a bunch of bytes.""" + +from typing import BinaryIO + +from .insecure_hashlib import sha1, sha256 + + +def sha_fileobj(fileobj: BinaryIO, chunk_size: int | None = None) -> bytes: + """ + Computes the sha256 hash of the given file object, by chunks of size `chunk_size`. + + Args: + fileobj (file-like object): + The File object to compute sha256 for, typically obtained with `open(path, "rb")` + chunk_size (`int`, *optional*): + The number of bytes to read from `fileobj` at once, defaults to 1MB. + + Returns: + `bytes`: `fileobj`'s sha256 hash as bytes + """ + chunk_size = chunk_size if chunk_size is not None else 1024 * 1024 + + sha = sha256() + while True: + chunk = fileobj.read(chunk_size) + sha.update(chunk) + if not chunk: + break + return sha.digest() + + +def git_hash(data: bytes) -> str: + """ + Computes the git-sha1 hash of the given bytes, using the same algorithm as git. + + This is equivalent to running `git hash-object`. See https://git-scm.com/docs/git-hash-object + for more details. + + Note: this method is valid for regular files. For LFS files, the proper git hash is supposed to be computed on the + pointer file content, not the actual file content. However, for simplicity, we directly compare the sha256 of + the LFS file content when we want to compare LFS files. + + Args: + data (`bytes`): + The data to compute the git-hash for. + + Returns: + `str`: the git-hash of `data` as an hexadecimal string. + + Example: + ```python + >>> from huggingface_hub.utils.sha import git_hash + >>> git_hash(b"Hello, World!") + 'b45ef6fec89518d314f546fd6c3025367b721684' + ``` + """ + # Taken from https://gist.github.com/msabramo/763200 + # Note: no need to optimize by reading the file in chunks as we're not supposed to hash huge files (5MB maximum). + sha = sha1() + sha.update(b"blob ") + sha.update(str(len(data)).encode()) + sha.update(b"\0") + sha.update(data) + return sha.hexdigest() diff --git a/.venv/lib/python3.13/site-packages/huggingface_hub/utils/tqdm.py b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/tqdm.py new file mode 100644 index 0000000000000000000000000000000000000000..615becc0c13aaa40cc8df1c9f0f37d78bea33154 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/huggingface_hub/utils/tqdm.py @@ -0,0 +1,372 @@ +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# 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 +"""Utility helpers to handle progress bars in `huggingface_hub`. + +Example: + 1. Use `huggingface_hub.utils.tqdm` as you would use `tqdm.tqdm` or `tqdm.auto.tqdm`. + 2. To disable progress bars, either use `disable_progress_bars()` helper or set the + environment variable `HF_HUB_DISABLE_PROGRESS_BARS` to 1. + 3. To re-enable progress bars, use `enable_progress_bars()`. + 4. To check whether progress bars are disabled, use `are_progress_bars_disabled()`. + +NOTE: Environment variable `HF_HUB_DISABLE_PROGRESS_BARS` has the priority. + +Example: + ```py + >>> from huggingface_hub.utils import are_progress_bars_disabled, disable_progress_bars, enable_progress_bars, tqdm + + # Disable progress bars globally + >>> disable_progress_bars() + + # Use as normal `tqdm` + >>> for _ in tqdm(range(5)): + ... pass + + # Still not showing progress bars, as `disable=False` is overwritten to `True`. + >>> for _ in tqdm(range(5), disable=False): + ... pass + + >>> are_progress_bars_disabled() + True + + # Re-enable progress bars globally + >>> enable_progress_bars() + + # Progress bar will be shown ! + >>> for _ in tqdm(range(5)): + ... pass + 100%|███████████████████████████████████████| 5/5 [00:00<00:00, 117817.53it/s] + ``` + +Group-based control: + ```python + # Disable progress bars for a specific group + >>> disable_progress_bars("peft.foo") + + # Check state of different groups + >>> assert not are_progress_bars_disabled("peft")) + >>> assert not are_progress_bars_disabled("peft.something") + >>> assert are_progress_bars_disabled("peft.foo")) + >>> assert are_progress_bars_disabled("peft.foo.bar")) + + # Enable progress bars for a subgroup + >>> enable_progress_bars("peft.foo.bar") + + # Check if enabling a subgroup affects the parent group + >>> assert are_progress_bars_disabled("peft.foo")) + >>> assert not are_progress_bars_disabled("peft.foo.bar")) + + # No progress bar for `name="peft.foo"` + >>> for _ in tqdm(range(5), name="peft.foo"): + ... pass + + # Progress bar will be shown for `name="peft.foo.bar"` + >>> for _ in tqdm(range(5), name="peft.foo.bar"): + ... pass + 100%|███████████████████████████████████████| 5/5 [00:00<00:00, 117817.53it/s] + + ``` +""" + +import io +import logging +import os +import threading +import warnings +from collections.abc import Iterator +from contextlib import contextmanager, nullcontext +from pathlib import Path +from typing import ContextManager + +from tqdm.auto import tqdm as old_tqdm + +from ..constants import HF_HUB_DISABLE_PROGRESS_BARS + + +# The `HF_HUB_DISABLE_PROGRESS_BARS` environment variable can be True, False, or not set (None), +# allowing for control over progress bar visibility. When set, this variable takes precedence +# over programmatic settings, dictating whether progress bars should be shown or hidden globally. +# Essentially, the environment variable's setting overrides any code-based configurations. +# +# If `HF_HUB_DISABLE_PROGRESS_BARS` is not defined (None), it implies that users can manage +# progress bar visibility through code. By default, progress bars are turned on. + +progress_bar_states: dict[str, bool] = {} + + +class disable_progress_bars: + """ + Disable progress bars either globally or for a specified group. + + This function updates the state of progress bars based on a group name. + If no group name is provided, all progress bars are disabled. The operation + respects the `HF_HUB_DISABLE_PROGRESS_BARS` environment variable's setting. + + Works as both a regular call and a context manager: + disable_progress_bars() # disables until enable_progress_bars() + with disable_progress_bars(): # disables for the block, re-enables on exit + ... + + Args: + name (`str`, *optional*): + The name of the group for which to disable the progress bars. If None, + progress bars are disabled globally. + + Raises: + Warning: If the environment variable precludes changes. + """ + + def __init__(self, name: str | None = None) -> None: + self.name = name + + if HF_HUB_DISABLE_PROGRESS_BARS is False: + warnings.warn( + "Cannot disable progress bars: environment variable `HF_HUB_DISABLE_PROGRESS_BARS=0` is set and has priority." + ) + self._should_reenable = False + return + + self._should_reenable = not are_progress_bars_disabled(name) + if name is None: + progress_bar_states.clear() + progress_bar_states["_global"] = False + else: + keys_to_remove = [key for key in progress_bar_states if key.startswith(f"{name}.")] + for key in keys_to_remove: + del progress_bar_states[key] + progress_bar_states[name] = False + + def __enter__(self) -> "disable_progress_bars": + return self + + def __exit__(self, *exc) -> None: + if self._should_reenable: + enable_progress_bars(self.name) + + +def enable_progress_bars(name: str | None = None) -> None: + """ + Enable progress bars either globally or for a specified group. + + This function sets the progress bars to enabled for the specified group or globally + if no group is specified. The operation is subject to the `HF_HUB_DISABLE_PROGRESS_BARS` + environment setting. + + Args: + name (`str`, *optional*): + The name of the group for which to enable the progress bars. If None, + progress bars are enabled globally. + + Raises: + Warning: If the environment variable precludes changes. + """ + if HF_HUB_DISABLE_PROGRESS_BARS is True: + warnings.warn( + "Cannot enable progress bars: environment variable `HF_HUB_DISABLE_PROGRESS_BARS=1` is set and has priority." + ) + return + + if name is None: + progress_bar_states.clear() + progress_bar_states["_global"] = True + else: + keys_to_remove = [key for key in progress_bar_states if key.startswith(f"{name}.")] + for key in keys_to_remove: + del progress_bar_states[key] + progress_bar_states[name] = True + + +def are_progress_bars_disabled(name: str | None = None) -> bool: + """ + Check if progress bars are disabled globally or for a specific group. + + This function returns whether progress bars are disabled for a given group or globally. + It checks the `HF_HUB_DISABLE_PROGRESS_BARS` environment variable first, then the programmatic + settings. + + Args: + name (`str`, *optional*): + The group name to check; if None, checks the global setting. + + Returns: + `bool`: True if progress bars are disabled, False otherwise. + """ + if HF_HUB_DISABLE_PROGRESS_BARS is True: + return True + + if name is None: + return not progress_bar_states.get("_global", True) + + while name: + if name in progress_bar_states: + return not progress_bar_states[name] + name = ".".join(name.split(".")[:-1]) + + return not progress_bar_states.get("_global", True) + + +def is_tqdm_disabled(log_level: int) -> bool | None: + """ + Determine if tqdm progress bars should be disabled based on logging level and environment settings. + + see https://github.com/huggingface/huggingface_hub/pull/2000 and https://github.com/huggingface/huggingface_hub/pull/2698. + """ + if log_level == logging.NOTSET: + return True + if os.getenv("TQDM_POSITION") == "-1": + return False + return None + + +class tqdm(old_tqdm): + """ + Class to override `disable` argument in case progress bars are globally disabled. + + Taken from https://github.com/tqdm/tqdm/issues/619#issuecomment-619639324. + """ + + def __init__(self, *args, **kwargs): + name = kwargs.pop("name", None) # do not pass `name` to `tqdm` + if are_progress_bars_disabled(name): + kwargs["disable"] = True + super().__init__(*args, **kwargs) + + def __delattr__(self, attr: str) -> None: + """Fix for https://github.com/huggingface/huggingface_hub/issues/1603""" + try: + super().__delattr__(attr) + except AttributeError: + if attr != "_lock": + raise + + +# Prevent tqdm's default multiprocessing write-lock from spawning a resource +# tracker subprocess via fork_exec(). That path fails when stderr has an invalid +# fd (e.g. Textual TUIs that return -1 from sys.stderr.fileno()). Inter-process +# bar coordination on the HF subclass is not a supported use case. See #4065. +tqdm.set_lock(threading.RLock()) + + +class silent_tqdm: + """Fake tqdm object that does nothing.""" + + def __init__(self, *args, **kwargs): + pass + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + pass + + def update(self, n: int | float | None = 1) -> None: + pass + + +@contextmanager +def tqdm_stream_file(path: Path | str) -> Iterator[io.BufferedReader]: + """ + Open a file as binary and wrap the `read` method to display a progress bar when it's streamed. + + First implemented in `transformers` in 2019 but removed when switched to git-lfs. Used in `huggingface_hub` to show + progress bar when uploading an LFS file to the Hub. See github.com/huggingface/transformers/pull/2078#discussion_r354739608 + for implementation details. + + Note: currently implementation handles only files stored on disk as it is the most common use case. Could be + extended to stream any `BinaryIO` object but we might have to debug some corner cases. + + Example: + ```py + >>> with tqdm_stream_file("config.json") as f: + >>> httpx.put(url, data=f) + config.json: 100%|█████████████████████████| 8.19k/8.19k [00:02<00:00, 3.72kB/s] + ``` + """ + if isinstance(path, str): + path = Path(path) + + with path.open("rb") as f: + total_size = path.stat().st_size + pbar = tqdm( + unit="B", + unit_scale=True, + total=total_size, + initial=0, + desc=path.name, + ) + + f_read = f.read + + def _inner_read(size: int | None = -1) -> bytes: + data = f_read(size) + pbar.update(len(data)) + return data + + f.read = _inner_read # type: ignore + + yield f + + pbar.close() + + +def _create_progress_bar(*, cls: type[old_tqdm], log_level: int, name: str | None = None, **kwargs) -> old_tqdm: + """Create a progress bar. + + For our `tqdm` subclass (or subclasses of it): respects all disable signals + (`HF_HUB_DISABLE_PROGRESS_BARS`, `disable_progress_bars()`, log level) and uses + `disable=None` for TTY auto-detection (see https://github.com/huggingface/huggingface_hub/pull/2000), + unless `TQDM_POSITION=-1` forces bars on (https://github.com/huggingface/huggingface_hub/pull/2698). + + For other classes: does not inject `disable` or `name`. the custom class is fully + responsible for its own behavior. Vanilla tqdm defaults to `disable=False` (bar shows). + Omits `name` which vanilla tqdm rejects with `TqdmKeyError`. See https://github.com/huggingface/huggingface_hub/issues/4050. + """ + # issubclass() crashes on non-class callables (e.g. functools.partial), guard with isinstance. + if not (isinstance(cls, type) and issubclass(cls, tqdm)): + return cls(**kwargs) # type: ignore[return-value] + + # HF subclass: keep the historical log-level / TTY behavior. Group-based + # disabling is already handled in `tqdm.__init__`. + disable = is_tqdm_disabled(log_level) + return cls(disable=disable, name=name, **kwargs) # type: ignore[return-value] + + +def _get_progress_bar_context( + *, + desc: str, + log_level: int, + total: int | None = None, + initial: int = 0, + unit: str = "B", + unit_scale: bool = True, + name: str | None = None, + tqdm_class: type[old_tqdm] | None = None, + _tqdm_bar: tqdm | None = None, +) -> ContextManager[tqdm]: + if _tqdm_bar is not None: + return nullcontext(_tqdm_bar) + # ^ `contextlib.nullcontext` mimics a context manager that does nothing + # Makes it easier to use the same code path for both cases but in the later + # case, the progress bar is not closed when exiting the context manager. + + return _create_progress_bar( # type: ignore + cls=tqdm_class or tqdm, + log_level=log_level, + name=name, + unit=unit, + unit_scale=unit_scale, + total=total, + initial=initial, + desc=desc, + ) diff --git a/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/INSTALLER b/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/METADATA b/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..6c4bf89b25c79af2e9ecdc22c5ddb802effa85bc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/METADATA @@ -0,0 +1,155 @@ +Metadata-Version: 2.4 +Name: idna +Version: 3.18 +Summary: Internationalized Domain Names in Applications (IDNA) +Author-email: Kim Davies +Requires-Python: >=3.9 +Description-Content-Type: text/markdown +License-Expression: BSD-3-Clause +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +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 :: 3.14 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Internet :: Name Service (DNS) +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Utilities +License-File: LICENSE.md +Requires-Dist: ruff >= 0.6.2 ; extra == "all" +Requires-Dist: mypy >= 1.11.2 ; extra == "all" +Requires-Dist: pytest >= 8.3.2 ; extra == "all" +Project-URL: Changelog, https://github.com/kjd/idna/blob/master/HISTORY.md +Project-URL: Issue tracker, https://github.com/kjd/idna/issues +Project-URL: Source, https://github.com/kjd/idna +Provides-Extra: all + +# Internationalized Domain Names in Applications (IDNA) + +Support for [Internationalized Domain Names in Applications +(IDNA)](https://tools.ietf.org/html/rfc5891) and [Unicode IDNA +Compatibility Processing](https://unicode.org/reports/tr46/). It +supersedes the standard library's `encodings.idna`, which only +implements the 2003 specification, offering broader script coverage and +limiting domains with known security vulnerabilities. + +## Usage + +Package may be installed from [PyPI](https://pypi.org/project/idna/) via +the typical methods (e.g. `python3 -m pip install idna`) + +For typical usage, the `encode` and `decode` functions will take a +domain name argument and perform a conversion to ASCII-compatible encoding +(known as A-labels), or to Unicode strings (known as U-labels) +respectively. + +```pycon +>>> import idna +>>> idna.encode('ドメイン.テスト') +b'xn--eckwd4c7c.xn--zckzah' +>>> print(idna.decode('xn--eckwd4c7c.xn--zckzah')) +ドメイン.テスト +``` + +Conversions can be applied at a per-label basis using the `ulabel` or +`alabel` functions for specialized use cases. + + +### Compatibility Mapping (UTS #46) + +This library provides support for [Unicode IDNA Compatibility +Processing](https://unicode.org/reports/tr46/) which normalizes input from +different potential ways a user may input a domain prior to performing the IDNA +conversion operations. This functionality, known as a +[mapping](https://tools.ietf.org/html/rfc5895), is considered by the +specification to be a local user-interface issue distinct from IDNA +conversion functionality. + +For example, "Königsgäßchen" is not a permissible label as capital letters +are not allowed. UTS 46 will convert this into lower case prior to applying +the IDNA conversion. + +```pycon +>>> import idna +>>> idna.encode('Königsgäßchen') +... +idna.core.InvalidCodepoint: Codepoint U+004B at position 1 of 'Königsgäßchen' not allowed +>>> idna.encode('Königsgäßchen', uts46=True) +b'xn--knigsgchen-b4a3dun' +>>> idna.decode('xn--knigsgchen-b4a3dun') +'königsgäßchen' +``` + +When performing a decode operation for display purposes, `decode()` +accepts a `display=True` argument that leaves any `xn--` label that +fails to decode unchanged. This is useful for user interface display +where a domain is in use, the A-label form can be presented when it +is not a valid IDN. + + +## Exceptions + +All errors raised during conversion derive from the `idna.IDNAError` +base class. The more specific exceptions are: + +* `idna.IDNABidiError` — raised when a label contains an illegal + combination of left-to-right and right-to-left characters. +* `idna.InvalidCodepoint` — raised when a label contains a codepoint + that is INVALID for IDNA. +* `idna.InvalidCodepointContext` — raised when a CONTEXTO or CONTEXTJ + codepoint appears in a position whose contextual requirements are + not satisfied. + + +## Command-line tool + +The package supports command-line usage to convert domain names +between their Unicode and ASCII-compatible forms. It can be run either +as a module (`python3 -m idna`) or, once installed (such as with `uv +tool` or `pipx`), via the `idna` script: + +```bash +$ uv tool install idna +$ idna xn--e1afmkfd.xn--p1ai +пример.рф +$ idna пример.рф +xn--e1afmkfd.xn--p1ai +``` + +Mode can be specified with `-e`/`--encode` or `-d`/`--decode`, otherwise +it will be chosen automatically based on the first input. Multiple +domains can be supplied either as arguments or through standard input. +UTS #46 mapping is applied by default, which lets the tool accept +inputs that aren't strictly valid IDNA 2008 by normalising them first, +pass `--strict` to disable UTS #46. + +Conversion failures are reported on stderr together with the +offending input; processing continues with the remaining domains and +the tool exits with a non-zero status if any conversion failed. + + +## Additional Notes + +* **Version support**. This library supports Python 3.9 and higher. + As this library serves as a low-level toolkit for a variety of + applications, we strive to support all versions of Python that are + not beyond end-of-life. + +* **Emoji**. It is an occasional request to support emoji domains in + this library. Encoding of symbols like emoji is expressly prohibited by + the IDNA technical standard, and emoji domains are broadly phased + out across the domain industry due to associated security risks. + +* **Regenerating lookup tables**. The IDNA and UTS 46 functionality + relies upon pre-calculated lookup tables, generated using the + `idna-data` script in [`tools/`](tools/README.md). + diff --git a/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/RECORD b/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..053005c803c48e8f8c20b540fe76dd932313babf --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/RECORD @@ -0,0 +1,28 @@ +../../../bin/idna,sha256=vAPCwf2K_JkAWkobiOoZGvhWxjMz__nDvJBRR-tgCDU,186 +idna-3.18.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +idna-3.18.dist-info/METADATA,sha256=Rt_m5axGLQ9oDs2avPZugptqIzSCS02eOXmzETXK8oE,6119 +idna-3.18.dist-info/RECORD,, +idna-3.18.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82 +idna-3.18.dist-info/entry_points.txt,sha256=7H3nGOHap3jnLE5e7q7Ywr9Vq8axB7WIj5-C_4N2vhw,38 +idna-3.18.dist-info/licenses/LICENSE.md,sha256=GppPDj1HmickDd1ZqRN6ZqtKD539yMphiMwL_YUYfwQ,1541 +idna/__init__.py,sha256=MPqNDLZbXqGaNdXxAFhiqFPKEQXju2jNQhCey6-5eJM,868 +idna/__main__.py,sha256=4JMK66Wj4uLZTKbF-sT3LAxOsr6buig77PmOkJCRRxw,83 +idna/__pycache__/__init__.cpython-313.pyc,, +idna/__pycache__/__main__.cpython-313.pyc,, +idna/__pycache__/cli.cpython-313.pyc,, +idna/__pycache__/codec.cpython-313.pyc,, +idna/__pycache__/compat.cpython-313.pyc,, +idna/__pycache__/core.cpython-313.pyc,, +idna/__pycache__/idnadata.cpython-313.pyc,, +idna/__pycache__/intranges.cpython-313.pyc,, +idna/__pycache__/package_data.cpython-313.pyc,, +idna/__pycache__/uts46data.cpython-313.pyc,, +idna/cli.py,sha256=swqJLMNc8Uzs60KziNpbWnHuqlG3WRQwJSbo4n8xDAo,4139 +idna/codec.py,sha256=JRbo-f7pEkLdWeiH89Z72UR4VBYhvKDFrQBeNX6sRDE,5040 +idna/compat.py,sha256=AepA39ceRHxkfHP41-FvKW5Ki-f4PfUZ90RUMlCNdmo,1353 +idna/core.py,sha256=SfOr1xO3PoE0RDYx7bMciAnjiyjJPbPw_93AB5IUYOw,24685 +idna/idnadata.py,sha256=Af-mo8WBmkhAK6TyXKOQH88OX0mQNDKtdL7UWtQpppk,44862 +idna/intranges.py,sha256=g49scLSkqJtAhLmOODa7hVHriSjmb60tiTsEoocJdBI,1851 +idna/package_data.py,sha256=TeI94EqAFAFaXfBJwsOPUMLn2969uirPa-DaeaceAyU,21 +idna/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +idna/uts46data.py,sha256=jujNz5QqWMcJf-XYLv4X1jBvb5FlI0t6-e1mILsgbPk,234325 diff --git a/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/WHEEL b/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..d8b9936dad9ab2513fa6979f411560d3b6b57e37 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.12.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/entry_points.txt b/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/entry_points.txt new file mode 100644 index 0000000000000000000000000000000000000000..59ca7ac02ea0a40938ca867305e020981f52a077 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +idna=idna.cli:main + diff --git a/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/licenses/LICENSE.md b/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/licenses/LICENSE.md new file mode 100644 index 0000000000000000000000000000000000000000..f706835ab3a5dd709a6e1f57aee0a94ae1415df6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna-3.18.dist-info/licenses/LICENSE.md @@ -0,0 +1,31 @@ +BSD 3-Clause License + +Copyright (c) 2013-2026, Kim Davies and 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 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/python3.13/site-packages/idna/__init__.py b/.venv/lib/python3.13/site-packages/idna/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cfdc030a751b089fc7e38fc88093b791605d501d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna/__init__.py @@ -0,0 +1,45 @@ +from .core import ( + IDNABidiError, + IDNAError, + InvalidCodepoint, + InvalidCodepointContext, + alabel, + check_bidi, + check_hyphen_ok, + check_initial_combiner, + check_label, + check_nfc, + decode, + encode, + ulabel, + uts46_remap, + valid_contextj, + valid_contexto, + valid_label_length, + valid_string_length, +) +from .intranges import intranges_contain +from .package_data import __version__ + +__all__ = [ + "__version__", + "IDNABidiError", + "IDNAError", + "InvalidCodepoint", + "InvalidCodepointContext", + "alabel", + "check_bidi", + "check_hyphen_ok", + "check_initial_combiner", + "check_label", + "check_nfc", + "decode", + "encode", + "intranges_contain", + "ulabel", + "uts46_remap", + "valid_contextj", + "valid_contexto", + "valid_label_length", + "valid_string_length", +] diff --git a/.venv/lib/python3.13/site-packages/idna/__main__.py b/.venv/lib/python3.13/site-packages/idna/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..dbdd066172160ef2d47b29f0caa00e27c62ebc20 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna/__main__.py @@ -0,0 +1,6 @@ +import sys + +from .cli import main + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.venv/lib/python3.13/site-packages/idna/cli.py b/.venv/lib/python3.13/site-packages/idna/cli.py new file mode 100644 index 0000000000000000000000000000000000000000..4acda2c0f03561ee7e2a80611bdcb35900bb34e0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna/cli.py @@ -0,0 +1,128 @@ +"""Command-line interface for the :mod:`idna` package. + +Invoked via ``python -m idna``. See :func:`main` for the entry point. +""" + +import argparse +import sys +from collections.abc import Iterable +from itertools import chain +from typing import IO, Optional + +from . import IDNAError, decode, encode +from .core import _alabel_prefix, _unicode_dots_re +from .package_data import __version__ + + +def _looks_like_alabel(s: str) -> bool: + """Return True if any label in ``s`` carries the ``xn--`` ACE prefix.""" + prefix = _alabel_prefix.decode("ascii") + return any(label.lower().startswith(prefix) for label in _unicode_dots_re.split(s)) + + +def _build_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + prog="python -m idna", + description=( + "Convert a domain name between its Unicode (U-label) and " + "ASCII-compatible (A-label) forms. With no mode flag, the " + "direction is chosen from the first input — if it contains " + "an xn-- label the stream is decoded, otherwise it is " + "encoded — and the same mode is applied to every remaining " + "input. UTS #46 mapping is applied by default; pass " + "--strict to disable it. When no domains are given on the " + "command line and stdin is piped, one domain per line is " + "read from stdin." + ), + ) + mode = parser.add_mutually_exclusive_group() + mode.add_argument( + "-e", + "--encode", + dest="mode", + action="store_const", + const="encode", + help="Encode the input to its ASCII A-label form.", + ) + mode.add_argument( + "-d", + "--decode", + dest="mode", + action="store_const", + const="decode", + help="Decode the input from its ASCII A-label form.", + ) + parser.add_argument( + "--strict", + action="store_true", + help="Disable the default UTS #46 mapping and apply IDNA 2008 rules verbatim.", + ) + parser.add_argument( + "--version", + action="version", + version=f"idna {__version__}", + ) + parser.add_argument( + "domain", + nargs="*", + help="One or more domain names to convert. Omit to read from stdin.", + ) + return parser + + +def _iter_stdin(stream: IO[str]) -> Iterable[str]: + """Yield non-empty stripped lines from ``stream``, ignoring blanks.""" + for line in stream: + stripped = line.strip() + if stripped: + yield stripped + + +def _convert_one(domain: str, mode: str, uts46: bool) -> bool: + """Convert ``domain`` and write the result; return ``False`` on failure.""" + try: + if mode == "decode": + print(decode(domain, uts46=uts46)) + else: + print(encode(domain, uts46=uts46).decode("ascii")) + except IDNAError as err: + print(f"idna: {mode} failed for {domain!r}: {err}", file=sys.stderr) + return False + return True + + +def main(argv: Optional[list[str]] = None) -> int: + """Entry point for ``python -m idna``. + + When more than one domain is supplied (via positional arguments or + piped stdin) and no mode flag is given, the first input determines + the direction and that mode is applied uniformly to the rest. + + :param argv: Argument list excluding the program name. Defaults to + :data:`sys.argv` when ``None``. + :returns: ``0`` on success, ``1`` if any conversion fails. + """ + parser = _build_parser() + args = parser.parse_args(argv) + uts46 = not args.strict + + if args.domain: + domains: Iterable[str] = args.domain + elif not sys.stdin.isatty(): + domains = _iter_stdin(sys.stdin) + else: + parser.error("a domain argument is required when stdin is a terminal") + + iterator = iter(domains) + first = next(iterator, None) + if first is None: + return 0 + + mode = args.mode or ("decode" if _looks_like_alabel(first) else "encode") + + results = [_convert_one(domain, mode, uts46) for domain in chain([first], iterator)] + return 0 if all(results) else 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.venv/lib/python3.13/site-packages/idna/codec.py b/.venv/lib/python3.13/site-packages/idna/codec.py new file mode 100644 index 0000000000000000000000000000000000000000..83b42fe42b51adbe1cf9dbea79c4c8d8dbf8a0b9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna/codec.py @@ -0,0 +1,159 @@ +import codecs +from typing import Any, Optional + +from .core import IDNAError, _unicode_dots_re, alabel, decode, encode, ulabel + + +class Codec(codecs.Codec): + """Stateless IDNA 2008 codec. + + Implements the :class:`codecs.Codec` protocol so that the whole-domain + encoder (:func:`idna.encode`) and decoder (:func:`idna.decode`) are + accessible through the standard codec machinery as ``"idna2008"``. + + Only the ``"strict"`` error handler is supported; any other handler + raises :exc:`~idna.IDNAError`. + """ + + def encode(self, data: str, errors: str = "strict") -> tuple[bytes, int]: # ty: ignore[invalid-method-override] + if errors != "strict": + raise IDNAError(f'Unsupported error handling "{errors}"') + + if not data: + return b"", 0 + + return encode(data), len(data) + + def decode(self, data: bytes, errors: str = "strict") -> tuple[str, int]: # ty: ignore[invalid-method-override] + if errors != "strict": + raise IDNAError(f'Unsupported error handling "{errors}"') + + if not data: + return "", 0 + + return decode(data), len(data) + + +class IncrementalEncoder(codecs.BufferedIncrementalEncoder): + """Incremental IDNA 2008 encoder. + + Buffers a partial trailing label across calls until either the next + label separator is seen or ``final=True``, so that streamed input is + encoded one whole label at a time. Any of the four Unicode label + separators (``U+002E``, ``U+3002``, ``U+FF0E``, ``U+FF61``) ends a + label; the result always uses ``U+002E`` as the separator. + + Only the ``"strict"`` error handler is supported. + """ + + def _buffer_encode(self, data: str, errors: str, final: bool) -> tuple[bytes, int]: # ty: ignore[invalid-method-override] + if errors != "strict": + raise IDNAError(f'Unsupported error handling "{errors}"') + + if not data: + return b"", 0 + + labels = _unicode_dots_re.split(data) + trailing_dot = b"" + if labels: + if not labels[-1]: + trailing_dot = b"." + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = b"." + + result = [] + size = 0 + for label in labels: + result.append(alabel(label)) + if size: + size += 1 + size += len(label) + + # Join with U+002E + result_bytes = b".".join(result) + trailing_dot + size += len(trailing_dot) + return result_bytes, size + + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + """Incremental IDNA 2008 decoder. + + Buffers a partial trailing label across calls until either the next + label separator is seen or ``final=True``, so that streamed input is + decoded one whole label at a time. + + Only the ``"strict"`` error handler is supported. + """ + + def _buffer_decode(self, data: Any, errors: str, final: bool) -> tuple[str, int]: # ty: ignore[invalid-method-override] + if errors != "strict": + raise IDNAError(f'Unsupported error handling "{errors}"') + + if not data: + return ("", 0) + + if not isinstance(data, str): + data = str(data, "ascii") + + labels = _unicode_dots_re.split(data) + trailing_dot = "" + if labels: + if not labels[-1]: + trailing_dot = "." + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = "." + + result = [] + size = 0 + for label in labels: + result.append(ulabel(label)) + if size: + size += 1 + size += len(label) + + result_str = ".".join(result) + trailing_dot + size += len(trailing_dot) + return (result_str, size) + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + + +class StreamReader(Codec, codecs.StreamReader): + pass + + +def search_function(name: str) -> Optional[codecs.CodecInfo]: + """Codec search function registered with :mod:`codecs`. + + Returns a :class:`codecs.CodecInfo` for the ``"idna2008"`` codec name + so that ``str.encode("idna2008")`` and ``bytes.decode("idna2008")`` + invoke the IDNA 2008 codec defined in this module. + + :param name: The codec name being looked up. + :returns: A :class:`codecs.CodecInfo` instance if ``name`` is + ``"idna2008"``, otherwise ``None``. + """ + if name != "idna2008": + return None + return codecs.CodecInfo( + name=name, + encode=Codec().encode, + decode=Codec().decode, # type: ignore + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) + + +codecs.register(search_function) diff --git a/.venv/lib/python3.13/site-packages/idna/compat.py b/.venv/lib/python3.13/site-packages/idna/compat.py new file mode 100644 index 0000000000000000000000000000000000000000..1d01e3d9750860e6ec87fb7c0955cee6bcd9fcc1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna/compat.py @@ -0,0 +1,41 @@ +from typing import Any, Union + +from .core import decode, encode + + +def ToASCII(label: str) -> bytes: + """Compatibility shim for :rfc:`3490` ``ToASCII``. + + Delegates to :func:`idna.encode` (IDNA 2008). Provided to ease porting + of code written against the legacy :mod:`encodings.idna` API; new code + should call :func:`idna.encode` directly. + + :param label: The label or domain to encode. + :returns: The encoded form as ASCII :class:`bytes`. + """ + return encode(label) + + +def ToUnicode(label: Union[bytes, bytearray]) -> str: + """Compatibility shim for :rfc:`3490` ``ToUnicode``. + + Delegates to :func:`idna.decode` (IDNA 2008). Provided to ease porting + of code written against the legacy :mod:`encodings.idna` API; new code + should call :func:`idna.decode` directly. + + :param label: The label or domain to decode. + :returns: The decoded Unicode form. + """ + return decode(label) + + +def nameprep(s: Any) -> None: + """Stub for :rfc:`3491` Nameprep, which is not used by IDNA 2008. + + IDNA 2008 (:rfc:`5891`) replaces Nameprep with the per-codepoint + validity classes from :rfc:`5892`; this function exists only to + return a clear error if legacy code attempts to call it. + + :raises NotImplementedError: Always. + """ + raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol") diff --git a/.venv/lib/python3.13/site-packages/idna/core.py b/.venv/lib/python3.13/site-packages/idna/core.py new file mode 100644 index 0000000000000000000000000000000000000000..1ccbd1f3356e4b9f2aeb36b00fd5591d85459464 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna/core.py @@ -0,0 +1,648 @@ +import bisect +import re +import unicodedata +import warnings +from typing import Optional, Union + +from . import idnadata +from .intranges import intranges_contain + +_virama_combining_class = 9 +_alabel_prefix = b"xn--" +_max_input_length = 1024 +_unicode_dots_re = re.compile("[\u002e\u3002\uff0e\uff61]") + + +# Bidi category sets from RFC 5893, hoisted out of the per-codepoint loop +_bidi_rtl_first = frozenset({"R", "AL"}) +_bidi_rtl_categories = frozenset({"R", "AL", "AN"}) +_bidi_rtl_allowed = frozenset({"R", "AL", "AN", "EN", "ES", "CS", "ET", "ON", "BN", "NSM"}) +_bidi_rtl_valid_ending = frozenset({"R", "AL", "EN", "AN"}) +_bidi_rtl_numeric = frozenset({"AN", "EN"}) +_bidi_ltr_allowed = frozenset({"L", "EN", "ES", "CS", "ET", "ON", "BN", "NSM"}) +_bidi_ltr_valid_ending = frozenset({"L", "EN"}) +_bidi_joiner_l_or_d = frozenset({"L", "D"}) +_bidi_joiner_r_or_d = frozenset({"R", "D"}) + + +def _joining_type(cp: int) -> Optional[str]: + for jt, ranges in idnadata.joining_types.items(): + if intranges_contain(cp, ranges): + return jt + return None + + +class IDNAError(UnicodeError): + """Base exception for all IDNA-encoding related problems""" + + +class IDNABidiError(IDNAError): + """Exception when bidirectional requirements are not satisfied""" + + +class InvalidCodepoint(IDNAError): + """Exception when a disallowed or unallocated codepoint is used""" + + +class InvalidCodepointContext(IDNAError): + """Exception when the codepoint is not valid in the context it is used""" + + +def _combining_class(cp: int) -> int: + v = unicodedata.combining(chr(cp)) + if v == 0 and not unicodedata.name(chr(cp)): + raise ValueError("Unknown character in unicodedata") + return v + + +def _is_script(cp: str, script: str) -> bool: + return intranges_contain(ord(cp), idnadata.scripts[script]) + + +def _punycode(s: str) -> bytes: + return s.encode("punycode") + + +def _unot(s: int) -> str: + return f"U+{s:04X}" + + +def valid_label_length(label: Union[bytes, str]) -> bool: + """Check that a label does not exceed the maximum permitted length. + + Per :rfc:`1035` (and :rfc:`5891` §4.2.4) a DNS label must not exceed + 63 octets. The argument may be either a :class:`str` (a U-label, where + length is measured in characters) or :class:`bytes` (an A-label, where + length is measured in octets). + + :param label: The label to check. + :returns: ``True`` if the label is within the length limit, otherwise + ``False``. + """ + return len(label) <= 63 + + +def valid_string_length(domain: Union[bytes, str], trailing_dot: bool) -> bool: + """Check that a full domain name does not exceed the maximum length. + + Per :rfc:`1035`, a domain name is limited to 253 octets when no trailing + dot is present, or 254 octets when one is included. + + :param domain: The full (possibly multi-label) domain name. + :param trailing_dot: ``True`` if ``domain`` includes a trailing ``.``. + :returns: ``True`` if the domain is within the length limit, otherwise + ``False``. + """ + return len(domain) <= (254 if trailing_dot else 253) + + +def check_bidi(label: str, check_ltr: bool = False) -> bool: + """Validate the Bidi Rule from :rfc:`5893` for a single label. + + The Bidi Rule constrains how bidirectional characters (Hebrew, Arabic, + etc.) may appear within a label. By default the check is only applied + when the label contains at least one right-to-left character (Unicode + bidirectional categories ``R``, ``AL``, or ``AN``); set ``check_ltr`` + to ``True`` to apply it to LTR-only labels as well. + + :param label: The label to validate, as a Unicode string. + :param check_ltr: If ``True``, apply the rules even when the label + contains no RTL characters. + :returns: ``True`` if the label satisfies the Bidi Rule. + :raises IDNABidiError: If any of Bidi Rule conditions 1-6 are violated, + or if the directional category of a codepoint cannot be determined. + """ + if len(label) > _max_input_length: + raise IDNAError("Label too long") + # Bidi rules should only be applied if string contains RTL characters + bidi_label = False + for idx, cp in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + if direction == "": + # String likely comes from a newer version of Unicode + raise IDNABidiError(f"Unknown directionality in label {label!r} at position {idx}") + if direction in _bidi_rtl_categories: + bidi_label = True + if not bidi_label and not check_ltr: + return True + + # Bidi rule 1 + direction = unicodedata.bidirectional(label[0]) + if direction in _bidi_rtl_first: + rtl = True + elif direction == "L": + rtl = False + else: + raise IDNABidiError(f"First codepoint in label {label!r} must be directionality L, R or AL") + + valid_ending = False + number_type: Optional[str] = None + for idx, cp in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + + if rtl: + # Bidi rule 2 + if direction not in _bidi_rtl_allowed: + raise IDNABidiError(f"Invalid direction for codepoint at position {idx} in a right-to-left label") + # Bidi rule 3 + if direction in _bidi_rtl_valid_ending: + valid_ending = True + elif direction != "NSM": + valid_ending = False + # Bidi rule 4 + if direction in _bidi_rtl_numeric: + if not number_type: + number_type = direction + elif number_type != direction: + raise IDNABidiError("Can not mix numeral types in a right-to-left label") + else: + # Bidi rule 5 + if direction not in _bidi_ltr_allowed: + raise IDNABidiError(f"Invalid direction for codepoint at position {idx} in a left-to-right label") + # Bidi rule 6 + if direction in _bidi_ltr_valid_ending: + valid_ending = True + elif direction != "NSM": + valid_ending = False + + if not valid_ending: + raise IDNABidiError("Label ends with illegal codepoint directionality") + + return True + + +def check_initial_combiner(label: str) -> bool: + """Reject labels that begin with a combining mark. + + Per :rfc:`5891` §4.2.3.2 a label must not start with a character of + Unicode general category ``M`` (Mark). + + :param label: The label to check. + :returns: ``True`` if the first character is not a combining mark. + :raises IDNAError: If the label begins with a combining character. + """ + if unicodedata.category(label[0])[0] == "M": + raise IDNAError("Label begins with an illegal combining character") + return True + + +def check_hyphen_ok(label: str) -> bool: + """Validate the hyphen restrictions for a label. + + Per :rfc:`5891` §4.2.3.1 a label must not start or end with a hyphen + (``U+002D``), and must not have hyphens in both the third and fourth + positions (the prefix reserved for A-labels). + + :param label: The label to check. + :returns: ``True`` if the hyphen restrictions are satisfied. + :raises IDNAError: If any of the hyphen restrictions are violated. + """ + if label[2:4] == "--": + raise IDNAError("Label has disallowed hyphens in 3rd and 4th position") + if label[0] == "-" or label[-1] == "-": + raise IDNAError("Label must not start or end with a hyphen") + return True + + +def check_nfc(label: str) -> None: + """Require that a label is in Unicode Normalization Form C. + + :param label: The label to check. + :raises IDNAError: If ``label`` differs from its NFC normalisation. + """ + if len(label) > _max_input_length: + raise IDNAError("Label too long") + if unicodedata.normalize("NFC", label) != label: + raise IDNAError("Label must be in Normalization Form C") + + +def valid_contextj(label: str, pos: int) -> bool: + """Validate the CONTEXTJ rules from :rfc:`5892` Appendix A. + + These rules govern the contextual use of the joiner codepoints + ``U+200C`` (ZERO WIDTH NON-JOINER, Appendix A.1) and ``U+200D`` + (ZERO WIDTH JOINER, Appendix A.2) within a label. + + :param label: The label containing the codepoint. + :param pos: Index of the joiner codepoint within ``label``. + :returns: ``True`` if the codepoint at ``pos`` satisfies its CONTEXTJ + rule, ``False`` otherwise (including when the codepoint at + ``pos`` is not a recognised joiner). + :raises ValueError: If an adjacent codepoint has no Unicode name when + determining its combining class. + :raises IDNAError: If ``label`` exceeds the defensive input length limit. + """ + if len(label) > _max_input_length: + raise IDNAError("Label too long") + cp_value = ord(label[pos]) + + if cp_value == 0x200C: + if pos > 0 and _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + + ok = False + for i in range(pos - 1, -1, -1): + joining_type = _joining_type(ord(label[i])) + if joining_type == "T": + continue + if joining_type in _bidi_joiner_l_or_d: + ok = True + break + break + + if not ok: + return False + + ok = False + for i in range(pos + 1, len(label)): + joining_type = _joining_type(ord(label[i])) + if joining_type == "T": + continue + if joining_type in _bidi_joiner_r_or_d: + ok = True + break + break + return ok + + if cp_value == 0x200D: + return pos > 0 and _combining_class(ord(label[pos - 1])) == _virama_combining_class + + return False + + +def valid_contexto(label: str, pos: int, exception: bool = False) -> bool: + """Validate the CONTEXTO rules from :rfc:`5892` Appendix A. + + Covers the contextual rules for codepoints such as MIDDLE DOT + (``U+00B7``), Greek lower numeral sign, Hebrew punctuation, Katakana + middle dot, and the Arabic-Indic / Extended Arabic-Indic digit ranges. + + :param label: The label containing the codepoint. + :param pos: Index of the codepoint within ``label``. + :param exception: Reserved for forward compatibility; currently unused. + :returns: ``True`` if the codepoint at ``pos`` satisfies its CONTEXTO + rule, ``False`` otherwise (including when the codepoint is not a + recognised CONTEXTO codepoint). + :raises IDNAError: If ``label`` exceeds the defensive input length limit. + """ + if len(label) > _max_input_length: + raise IDNAError("Label too long") + cp_value = ord(label[pos]) + + if cp_value == 0x00B7: + return 0 < pos < len(label) - 1 and ord(label[pos - 1]) == 0x006C and ord(label[pos + 1]) == 0x006C + + if cp_value == 0x0375: + if pos < len(label) - 1 and len(label) > 1: + return _is_script(label[pos + 1], "Greek") + return False + + if cp_value in {0x05F3, 0x05F4}: + if pos > 0: + return _is_script(label[pos - 1], "Hebrew") + return False + + if cp_value == 0x30FB: + for cp in label: + if cp == "\u30fb": + continue + if _is_script(cp, "Hiragana") or _is_script(cp, "Katakana") or _is_script(cp, "Han"): + return True + return False + + if 0x660 <= cp_value <= 0x669: + return not any(0x6F0 <= ord(cp) <= 0x06F9 for cp in label) + + if 0x6F0 <= cp_value <= 0x6F9: + return not any(0x660 <= ord(cp) <= 0x0669 for cp in label) + + return False + + +def check_label(label: Union[str, bytes, bytearray]) -> None: + """Run the full set of IDNA 2008 validity checks on a single label. + + Applies, in order: NFC normalisation (:func:`check_nfc`), hyphen + restrictions (:func:`check_hyphen_ok`), the no-leading-combiner rule + (:func:`check_initial_combiner`), per-codepoint validity (PVALID, + CONTEXTJ, CONTEXTO classes from :rfc:`5892`), and the Bidi Rule + (:func:`check_bidi`). + + :param label: The label to validate. ``bytes`` or ``bytearray`` input + is decoded as UTF-8 first. + :raises IDNAError: If the label is empty or fails a structural rule. + :raises InvalidCodepoint: If the label contains a DISALLOWED or + UNASSIGNED codepoint. + :raises InvalidCodepointContext: If a CONTEXTJ or CONTEXTO codepoint + is not valid in its context. + :raises IDNABidiError: If the Bidi Rule is violated. + """ + if len(label) > _max_input_length: + raise IDNAError("Label too long") + if isinstance(label, (bytes, bytearray)): + label = label.decode("utf-8") + if len(label) == 0: + raise IDNAError("Empty Label") + + # Reject on domain length rather than label length so support some UTS 46 + # use cases, still reducing processing of label contextual rules + if not valid_string_length(label, trailing_dot=True): + raise IDNAError("Label too long") + + check_nfc(label) + check_hyphen_ok(label) + check_initial_combiner(label) + + for pos, cp in enumerate(label): + cp_value = ord(cp) + if intranges_contain(cp_value, idnadata.codepoint_classes["PVALID"]): + continue + if intranges_contain(cp_value, idnadata.codepoint_classes["CONTEXTJ"]): + try: + if not valid_contextj(label, pos): + raise InvalidCodepointContext(f"Joiner {_unot(cp_value)} not allowed at position {pos + 1} in {label!r}") + except ValueError as err: + raise IDNAError( + f"Unknown codepoint adjacent to joiner {_unot(cp_value)} at position {pos + 1} in {label!r}" + ) from err + elif intranges_contain(cp_value, idnadata.codepoint_classes["CONTEXTO"]): + if not valid_contexto(label, pos): + raise InvalidCodepointContext(f"Codepoint {_unot(cp_value)} not allowed at position {pos + 1} in {label!r}") + else: + raise InvalidCodepoint(f"Codepoint {_unot(cp_value)} at position {pos + 1} of {label!r} not allowed") + + check_bidi(label) + + +def alabel(label: str) -> bytes: + """Convert a single U-label into its A-label form. + + The result is the ASCII-Compatible Encoding (ACE) form per :rfc:`5891` + §4: the label is validated, Punycode-encoded, and prefixed with + ``xn--``. Pure ASCII labels that are already valid IDNA labels are + returned unchanged (as :class:`bytes`). + + :param label: The label to convert, as a Unicode string. + :returns: The A-label as ASCII-encoded :class:`bytes`. + :raises IDNAError: If the label is invalid or the resulting A-label + exceeds 63 octets. + """ + if len(label) > _max_input_length: + raise IDNAError("Label too long") + try: + label_bytes = label.encode("ascii") + except UnicodeEncodeError: + pass + else: + ulabel(label_bytes) + if not valid_label_length(label_bytes): + raise IDNAError("Label too long") + return label_bytes + + check_label(label) + label_bytes = _alabel_prefix + _punycode(label) + + if not valid_label_length(label_bytes): + raise IDNAError("Label too long") + + return label_bytes + + +def ulabel(label: Union[str, bytes, bytearray]) -> str: + """Convert a single A-label into its U-label form. + + Performs the inverse of :func:`alabel`: an ``xn--``-prefixed label is + Punycode-decoded and validated. Labels that are already Unicode (or + plain ASCII without the ACE prefix) are validated and returned as a + Unicode string. + + :param label: The label to convert. ``bytes`` or ``bytearray`` input + is treated as ASCII. + :returns: The U-label as a Unicode string. + :raises IDNAError: If the label is malformed or fails validation. + """ + if len(label) > _max_input_length: + raise IDNAError("Label too long") + if not isinstance(label, (bytes, bytearray)): + try: + label_bytes = label.encode("ascii") + except UnicodeEncodeError: + check_label(label) + return label + else: + label_bytes = bytes(label) + + label_bytes = label_bytes.lower() + if label_bytes.startswith(_alabel_prefix): + label_bytes = label_bytes[len(_alabel_prefix) :] + if not label_bytes: + raise IDNAError("Malformed A-label, no Punycode eligible content found") + if label_bytes.endswith(b"-"): + raise IDNAError("A-label must not end with a hyphen") + else: + check_label(label_bytes) + return label_bytes.decode("ascii") + + try: + label = label_bytes.decode("punycode") + except UnicodeError as err: + raise IDNAError("Invalid A-label") from err + check_label(label) + return label + + +def uts46_remap(domain: str, std3_rules: bool = True, transitional: bool = False) -> str: + """Apply the UTS #46 character mapping to a domain string. + + Implements the mapping table from `UTS #46 §4 + `_: each character is kept, + replaced, or rejected based on its status (``V``, ``M``, ``D``, ``3``, + ``I``). The result is returned in Normalisation Form C. + + :param domain: The full domain name to remap. + :param std3_rules: If ``True``, apply the stricter STD3 ASCII rules + (status ``3`` codepoints raise instead of being kept or mapped). + :param transitional: If ``True``, use transitional processing (status + ``D`` codepoints are mapped instead of kept). Transitional + processing has been removed from UTS #46 and this option is + retained only for backwards compatibility. + :returns: The remapped domain, in Normalisation Form C. + :raises InvalidCodepoint: If the domain contains a disallowed + codepoint under the chosen rules. + :raises IDNAError: If ``domain`` exceeds the defensive input length limit. + """ + if len(domain) > _max_input_length: + raise IDNAError("Domain too long") + from .uts46data import uts46_replacements, uts46_starts, uts46_statuses + + output = "" + + for pos, char in enumerate(domain): + code_point = ord(char) + i = code_point if code_point < 256 else bisect.bisect_right(uts46_starts, code_point) - 1 + status = chr(uts46_statuses[i]) + replacement: Optional[str] = uts46_replacements[i] + + # UTS #46 §4: V is always valid, D is deviation (kept unless transitional), + # 3 is disallowed-STD3 (kept unmapped if std3_rules is off and no mapping). + keep_as_is = ( + status == "V" or (status == "D" and not transitional) or (status == "3" and not std3_rules and replacement is None) + ) + # M is mapped, 3-with-replacement and transitional D fall through to the + # same replacement output path. + use_replacement = replacement is not None and ( + status == "M" or (status == "3" and not std3_rules) or (status == "D" and transitional) + ) + + if keep_as_is: + output += char + elif use_replacement: + assert replacement is not None # narrowed by use_replacement + output += replacement + elif status == "I": + continue + else: + raise InvalidCodepoint(f"Codepoint {_unot(code_point)} not allowed at position {pos + 1} in {domain!r}") + + return unicodedata.normalize("NFC", output) + + +def encode( + s: Union[str, bytes, bytearray], + strict: bool = False, + uts46: bool = False, + std3_rules: bool = False, + transitional: bool = False, +) -> bytes: + """Encode a Unicode domain name into its ASCII (A-label) form. + + Splits the input on label separators (only ``U+002E`` if ``strict`` is + set; otherwise also IDEOGRAPHIC FULL STOP ``U+3002``, FULLWIDTH FULL + STOP ``U+FF0E``, and HALFWIDTH IDEOGRAPHIC FULL STOP ``U+FF61``), + encodes each label with :func:`alabel`, and rejoins them with ``.``. + Optionally pre-processes the input through :func:`uts46_remap`. + + :param s: The domain name to encode. + :param strict: If ``True``, only ``U+002E`` is recognised as a label + separator. + :param uts46: If ``True``, apply UTS #46 mapping before encoding. + :param std3_rules: Forwarded to :func:`uts46_remap` when ``uts46`` is + ``True``. + :param transitional: Forwarded to :func:`uts46_remap` when ``uts46`` + is ``True``. Deprecated: emits a :class:`DeprecationWarning` and + will be removed in a future version. + :returns: The encoded domain as ASCII :class:`bytes`. + :raises IDNAError: If the domain is empty, contains an invalid label, + or exceeds the maximum domain length. + """ + if transitional: + warnings.warn( + "Transitional processing has been removed from UTS #46. " + "The transitional argument will be removed in a future version.", + DeprecationWarning, + stacklevel=2, + ) + if not isinstance(s, str): + try: + s = str(s, "ascii") + except (UnicodeDecodeError, TypeError) as err: + raise IDNAError("should pass a unicode string to the function rather than a byte string.") from err + if len(s) > _max_input_length: + raise IDNAError("Domain too long") + if uts46: + s = uts46_remap(s, std3_rules, transitional) + + # Reject inputs that exceed the maximum DNS domain length up-front + # to avoid expensive computation on long inputs. + if not valid_string_length(s, trailing_dot=True): + raise IDNAError("Domain too long") + + trailing_dot = False + result = [] + labels = s.split(".") if strict else _unicode_dots_re.split(s) + if not labels or labels == [""]: + raise IDNAError("Empty domain") + if labels[-1] == "": + del labels[-1] + trailing_dot = True + for label in labels: + s = alabel(label) + if s: + result.append(s) + else: + raise IDNAError("Empty label") + if trailing_dot: + result.append(b"") + s = b".".join(result) + if not valid_string_length(s, trailing_dot): + raise IDNAError("Domain too long") + return s + + +def decode( + s: Union[str, bytes, bytearray], + strict: bool = False, + uts46: bool = False, + std3_rules: bool = False, + display: bool = False, +) -> str: + """Decode an A-label-encoded domain name back to Unicode. + + Splits the input on label separators (see :func:`encode` for the + rules), decodes each label with :func:`ulabel`, and rejoins them + with ``.``. Optionally pre-processes the input through + :func:`uts46_remap`. + + :param s: The domain name to decode. + :param strict: If ``True``, only ``U+002E`` is recognised as a label + separator. + :param uts46: If ``True``, apply UTS #46 mapping before decoding. + :param std3_rules: Forwarded to :func:`uts46_remap` when ``uts46`` is + ``True``. + :param display: If ``True``, any ``xn--`` label that fails IDNA + validation is passed through unchanged (lowercased) rather than + aborting the whole call. Intended for "decode for display" + consumers (e.g. URL libraries, HTTP clients) that want to show + the user the label as it appears on the wire when it cannot be + rendered as Unicode. Matches the per-label recovery prescribed + by UTS #46 §4 and the WHATWG URL "domain to Unicode" algorithm. + :returns: The decoded domain as a Unicode string. + :raises IDNAError: If the input is not valid ASCII, contains an + invalid label, or is empty. + """ + if not isinstance(s, str): + try: + s = str(s, "ascii") + except (UnicodeDecodeError, TypeError) as err: + raise IDNAError("Invalid ASCII in A-label") from err + if len(s) > _max_input_length: + raise IDNAError("Domain too long") + if uts46: + s = uts46_remap(s, std3_rules, False) + # Reject inputs that exceed the maximum DNS domain length up-front + # to avoid expensive computation on long inputs. + if not valid_string_length(s, trailing_dot=True): + raise IDNAError("Domain too long") + trailing_dot = False + result = [] + labels = s.split(".") if strict else _unicode_dots_re.split(s) + if not labels or labels == [""]: + raise IDNAError("Empty domain") + if not labels[-1]: + del labels[-1] + trailing_dot = True + for label in labels: + try: + u = ulabel(label) + except IDNAError: + if display and label[:4].lower() == "xn--": + u = label.lower() + else: + raise + if u: + result.append(u) + else: + raise IDNAError("Empty label") + if trailing_dot: + result.append("") + return ".".join(result) diff --git a/.venv/lib/python3.13/site-packages/idna/idnadata.py b/.venv/lib/python3.13/site-packages/idna/idnadata.py new file mode 100644 index 0000000000000000000000000000000000000000..f2ab38897bf1f8fc6f0db50f237edec68ca89295 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna/idnadata.py @@ -0,0 +1,1897 @@ +# This file is automatically generated by tools/idna-data + +__version__ = "17.0.0" + +scripts = { + "Greek": ( + 0x37000000374, + 0x37500000378, + 0x37A0000037E, + 0x37F00000380, + 0x38400000385, + 0x38600000387, + 0x3880000038B, + 0x38C0000038D, + 0x38E000003A2, + 0x3A3000003E2, + 0x3F000000400, + 0x1D2600001D2B, + 0x1D5D00001D62, + 0x1D6600001D6B, + 0x1DBF00001DC0, + 0x1F0000001F16, + 0x1F1800001F1E, + 0x1F2000001F46, + 0x1F4800001F4E, + 0x1F5000001F58, + 0x1F5900001F5A, + 0x1F5B00001F5C, + 0x1F5D00001F5E, + 0x1F5F00001F7E, + 0x1F8000001FB5, + 0x1FB600001FC5, + 0x1FC600001FD4, + 0x1FD600001FDC, + 0x1FDD00001FF0, + 0x1FF200001FF5, + 0x1FF600001FFF, + 0x212600002127, + 0xAB650000AB66, + 0x101400001018F, + 0x101A0000101A1, + 0x1D2000001D246, + ), + "Han": ( + 0x2E8000002E9A, + 0x2E9B00002EF4, + 0x2F0000002FD6, + 0x300500003006, + 0x300700003008, + 0x30210000302A, + 0x30380000303C, + 0x340000004DC0, + 0x4E000000A000, + 0xF9000000FA6E, + 0xFA700000FADA, + 0x16FE200016FE4, + 0x16FF000016FF7, + 0x200000002A6E0, + 0x2A7000002B81E, + 0x2B8200002CEAE, + 0x2CEB00002EBE1, + 0x2EBF00002EE5E, + 0x2F8000002FA1E, + 0x300000003134B, + 0x313500003347A, + ), + "Hebrew": ( + 0x591000005C8, + 0x5D0000005EB, + 0x5EF000005F5, + 0xFB1D0000FB37, + 0xFB380000FB3D, + 0xFB3E0000FB3F, + 0xFB400000FB42, + 0xFB430000FB45, + 0xFB460000FB50, + ), + "Hiragana": ( + 0x304100003097, + 0x309D000030A0, + 0x1B0010001B120, + 0x1B1320001B133, + 0x1B1500001B153, + 0x1F2000001F201, + ), + "Katakana": ( + 0x30A1000030FB, + 0x30FD00003100, + 0x31F000003200, + 0x32D0000032FF, + 0x330000003358, + 0xFF660000FF70, + 0xFF710000FF9E, + 0x1AFF00001AFF4, + 0x1AFF50001AFFC, + 0x1AFFD0001AFFF, + 0x1B0000001B001, + 0x1B1200001B123, + 0x1B1550001B156, + 0x1B1640001B168, + ), +} + + +joining_types = { + "C": ( + 0x64000000641, + 0x7FA000007FB, + 0x88300000886, + 0x180A0000180B, + 0x200D0000200E, + ), + "D": ( + 0x62000000621, + 0x62600000627, + 0x62800000629, + 0x62A0000062F, + 0x63300000640, + 0x64100000648, + 0x6490000064B, + 0x66E00000670, + 0x67800000688, + 0x69A000006C0, + 0x6C1000006C3, + 0x6CC000006CD, + 0x6CE000006CF, + 0x6D0000006D2, + 0x6FA000006FD, + 0x6FF00000700, + 0x71200000715, + 0x71A0000071E, + 0x71F00000728, + 0x7290000072A, + 0x72B0000072C, + 0x72D0000072F, + 0x74E00000759, + 0x75C0000076B, + 0x76D00000771, + 0x77200000773, + 0x77500000778, + 0x77A00000780, + 0x7CA000007EB, + 0x84100000846, + 0x84800000849, + 0x84A00000854, + 0x85500000856, + 0x86000000861, + 0x86200000866, + 0x86800000869, + 0x88600000887, + 0x8890000088E, + 0x88F00000890, + 0x8A0000008AA, + 0x8AF000008B1, + 0x8B3000008B9, + 0x8BA000008C9, + 0x180700001808, + 0x182000001879, + 0x1887000018A9, + 0x18AA000018AB, + 0xA8400000A872, + 0x10AC000010AC5, + 0x10AD300010AD7, + 0x10AD800010ADD, + 0x10ADE00010AE1, + 0x10AEB00010AEF, + 0x10B8000010B81, + 0x10B8200010B83, + 0x10B8600010B89, + 0x10B8A00010B8C, + 0x10B8D00010B8E, + 0x10B9000010B91, + 0x10BAD00010BAF, + 0x10D0100010D22, + 0x10D2300010D24, + 0x10EC300010EC5, + 0x10EC600010EC8, + 0x10F3000010F33, + 0x10F3400010F45, + 0x10F5100010F54, + 0x10F7000010F74, + 0x10F7600010F82, + 0x10FB000010FB1, + 0x10FB200010FB4, + 0x10FB800010FB9, + 0x10FBB00010FBD, + 0x10FBE00010FC0, + 0x10FC100010FC2, + 0x10FC400010FC5, + 0x10FCA00010FCB, + 0x1E9000001E944, + ), + "L": ( + 0xA8720000A873, + 0x10ACD00010ACE, + 0x10AD700010AD8, + 0x10D0000010D01, + 0x10FCB00010FCC, + ), + "R": ( + 0x62200000626, + 0x62700000628, + 0x6290000062A, + 0x62F00000633, + 0x64800000649, + 0x67100000674, + 0x67500000678, + 0x6880000069A, + 0x6C0000006C1, + 0x6C3000006CC, + 0x6CD000006CE, + 0x6CF000006D0, + 0x6D2000006D4, + 0x6D5000006D6, + 0x6EE000006F0, + 0x71000000711, + 0x7150000071A, + 0x71E0000071F, + 0x72800000729, + 0x72A0000072B, + 0x72C0000072D, + 0x72F00000730, + 0x74D0000074E, + 0x7590000075C, + 0x76B0000076D, + 0x77100000772, + 0x77300000775, + 0x7780000077A, + 0x84000000841, + 0x84600000848, + 0x8490000084A, + 0x85400000855, + 0x85600000859, + 0x86700000868, + 0x8690000086B, + 0x87000000883, + 0x88E0000088F, + 0x8AA000008AD, + 0x8AE000008AF, + 0x8B1000008B3, + 0x8B9000008BA, + 0x10AC500010AC6, + 0x10AC700010AC8, + 0x10AC900010ACB, + 0x10ACE00010AD3, + 0x10ADD00010ADE, + 0x10AE100010AE2, + 0x10AE400010AE5, + 0x10AEF00010AF0, + 0x10B8100010B82, + 0x10B8300010B86, + 0x10B8900010B8A, + 0x10B8C00010B8D, + 0x10B8E00010B90, + 0x10B9100010B92, + 0x10BA900010BAD, + 0x10D2200010D23, + 0x10EC200010EC3, + 0x10F3300010F34, + 0x10F5400010F55, + 0x10F7400010F76, + 0x10FB400010FB7, + 0x10FB900010FBB, + 0x10FBD00010FBE, + 0x10FC200010FC4, + 0x10FC900010FCA, + ), + "T": ( + 0xAD000000AE, + 0x30000000370, + 0x4830000048A, + 0x591000005BE, + 0x5BF000005C0, + 0x5C1000005C3, + 0x5C4000005C6, + 0x5C7000005C8, + 0x6100000061B, + 0x61C0000061D, + 0x64B00000660, + 0x67000000671, + 0x6D6000006DD, + 0x6DF000006E5, + 0x6E7000006E9, + 0x6EA000006EE, + 0x70F00000710, + 0x71100000712, + 0x7300000074B, + 0x7A6000007B1, + 0x7EB000007F4, + 0x7FD000007FE, + 0x8160000081A, + 0x81B00000824, + 0x82500000828, + 0x8290000082E, + 0x8590000085C, + 0x897000008A0, + 0x8CA000008E2, + 0x8E300000903, + 0x93A0000093B, + 0x93C0000093D, + 0x94100000949, + 0x94D0000094E, + 0x95100000958, + 0x96200000964, + 0x98100000982, + 0x9BC000009BD, + 0x9C1000009C5, + 0x9CD000009CE, + 0x9E2000009E4, + 0x9FE000009FF, + 0xA0100000A03, + 0xA3C00000A3D, + 0xA4100000A43, + 0xA4700000A49, + 0xA4B00000A4E, + 0xA5100000A52, + 0xA7000000A72, + 0xA7500000A76, + 0xA8100000A83, + 0xABC00000ABD, + 0xAC100000AC6, + 0xAC700000AC9, + 0xACD00000ACE, + 0xAE200000AE4, + 0xAFA00000B00, + 0xB0100000B02, + 0xB3C00000B3D, + 0xB3F00000B40, + 0xB4100000B45, + 0xB4D00000B4E, + 0xB5500000B57, + 0xB6200000B64, + 0xB8200000B83, + 0xBC000000BC1, + 0xBCD00000BCE, + 0xC0000000C01, + 0xC0400000C05, + 0xC3C00000C3D, + 0xC3E00000C41, + 0xC4600000C49, + 0xC4A00000C4E, + 0xC5500000C57, + 0xC6200000C64, + 0xC8100000C82, + 0xCBC00000CBD, + 0xCBF00000CC0, + 0xCC600000CC7, + 0xCCC00000CCE, + 0xCE200000CE4, + 0xD0000000D02, + 0xD3B00000D3D, + 0xD4100000D45, + 0xD4D00000D4E, + 0xD6200000D64, + 0xD8100000D82, + 0xDCA00000DCB, + 0xDD200000DD5, + 0xDD600000DD7, + 0xE3100000E32, + 0xE3400000E3B, + 0xE4700000E4F, + 0xEB100000EB2, + 0xEB400000EBD, + 0xEC800000ECF, + 0xF1800000F1A, + 0xF3500000F36, + 0xF3700000F38, + 0xF3900000F3A, + 0xF7100000F7F, + 0xF8000000F85, + 0xF8600000F88, + 0xF8D00000F98, + 0xF9900000FBD, + 0xFC600000FC7, + 0x102D00001031, + 0x103200001038, + 0x10390000103B, + 0x103D0000103F, + 0x10580000105A, + 0x105E00001061, + 0x107100001075, + 0x108200001083, + 0x108500001087, + 0x108D0000108E, + 0x109D0000109E, + 0x135D00001360, + 0x171200001715, + 0x173200001734, + 0x175200001754, + 0x177200001774, + 0x17B4000017B6, + 0x17B7000017BE, + 0x17C6000017C7, + 0x17C9000017D4, + 0x17DD000017DE, + 0x180B0000180E, + 0x180F00001810, + 0x188500001887, + 0x18A9000018AA, + 0x192000001923, + 0x192700001929, + 0x193200001933, + 0x19390000193C, + 0x1A1700001A19, + 0x1A1B00001A1C, + 0x1A5600001A57, + 0x1A5800001A5F, + 0x1A6000001A61, + 0x1A6200001A63, + 0x1A6500001A6D, + 0x1A7300001A7D, + 0x1A7F00001A80, + 0x1AB000001ADE, + 0x1AE000001AEC, + 0x1B0000001B04, + 0x1B3400001B35, + 0x1B3600001B3B, + 0x1B3C00001B3D, + 0x1B4200001B43, + 0x1B6B00001B74, + 0x1B8000001B82, + 0x1BA200001BA6, + 0x1BA800001BAA, + 0x1BAB00001BAE, + 0x1BE600001BE7, + 0x1BE800001BEA, + 0x1BED00001BEE, + 0x1BEF00001BF2, + 0x1C2C00001C34, + 0x1C3600001C38, + 0x1CD000001CD3, + 0x1CD400001CE1, + 0x1CE200001CE9, + 0x1CED00001CEE, + 0x1CF400001CF5, + 0x1CF800001CFA, + 0x1DC000001E00, + 0x200B0000200C, + 0x200E00002010, + 0x202A0000202F, + 0x206000002065, + 0x206A00002070, + 0x20D0000020F1, + 0x2CEF00002CF2, + 0x2D7F00002D80, + 0x2DE000002E00, + 0x302A0000302E, + 0x30990000309B, + 0xA66F0000A673, + 0xA6740000A67E, + 0xA69E0000A6A0, + 0xA6F00000A6F2, + 0xA8020000A803, + 0xA8060000A807, + 0xA80B0000A80C, + 0xA8250000A827, + 0xA82C0000A82D, + 0xA8C40000A8C6, + 0xA8E00000A8F2, + 0xA8FF0000A900, + 0xA9260000A92E, + 0xA9470000A952, + 0xA9800000A983, + 0xA9B30000A9B4, + 0xA9B60000A9BA, + 0xA9BC0000A9BE, + 0xA9E50000A9E6, + 0xAA290000AA2F, + 0xAA310000AA33, + 0xAA350000AA37, + 0xAA430000AA44, + 0xAA4C0000AA4D, + 0xAA7C0000AA7D, + 0xAAB00000AAB1, + 0xAAB20000AAB5, + 0xAAB70000AAB9, + 0xAABE0000AAC0, + 0xAAC10000AAC2, + 0xAAEC0000AAEE, + 0xAAF60000AAF7, + 0xABE50000ABE6, + 0xABE80000ABE9, + 0xABED0000ABEE, + 0xFB1E0000FB1F, + 0xFE000000FE10, + 0xFE200000FE30, + 0xFEFF0000FF00, + 0xFFF90000FFFC, + 0x101FD000101FE, + 0x102E0000102E1, + 0x103760001037B, + 0x10A0100010A04, + 0x10A0500010A07, + 0x10A0C00010A10, + 0x10A3800010A3B, + 0x10A3F00010A40, + 0x10AE500010AE7, + 0x10D2400010D28, + 0x10D6900010D6E, + 0x10EAB00010EAD, + 0x10EFA00010F00, + 0x10F4600010F51, + 0x10F8200010F86, + 0x1100100011002, + 0x1103800011047, + 0x1107000011071, + 0x1107300011075, + 0x1107F00011082, + 0x110B3000110B7, + 0x110B9000110BB, + 0x110C2000110C3, + 0x1110000011103, + 0x111270001112C, + 0x1112D00011135, + 0x1117300011174, + 0x1118000011182, + 0x111B6000111BF, + 0x111C9000111CD, + 0x111CF000111D0, + 0x1122F00011232, + 0x1123400011235, + 0x1123600011238, + 0x1123E0001123F, + 0x1124100011242, + 0x112DF000112E0, + 0x112E3000112EB, + 0x1130000011302, + 0x1133B0001133D, + 0x1134000011341, + 0x113660001136D, + 0x1137000011375, + 0x113BB000113C1, + 0x113CE000113CF, + 0x113D0000113D1, + 0x113D2000113D3, + 0x113E1000113E3, + 0x1143800011440, + 0x1144200011445, + 0x1144600011447, + 0x1145E0001145F, + 0x114B3000114B9, + 0x114BA000114BB, + 0x114BF000114C1, + 0x114C2000114C4, + 0x115B2000115B6, + 0x115BC000115BE, + 0x115BF000115C1, + 0x115DC000115DE, + 0x116330001163B, + 0x1163D0001163E, + 0x1163F00011641, + 0x116AB000116AC, + 0x116AD000116AE, + 0x116B0000116B6, + 0x116B7000116B8, + 0x1171D0001171E, + 0x1171F00011720, + 0x1172200011726, + 0x117270001172C, + 0x1182F00011838, + 0x118390001183B, + 0x1193B0001193D, + 0x1193E0001193F, + 0x1194300011944, + 0x119D4000119D8, + 0x119DA000119DC, + 0x119E0000119E1, + 0x11A0100011A0B, + 0x11A3300011A39, + 0x11A3B00011A3F, + 0x11A4700011A48, + 0x11A5100011A57, + 0x11A5900011A5C, + 0x11A8A00011A97, + 0x11A9800011A9A, + 0x11B6000011B61, + 0x11B6200011B65, + 0x11B6600011B67, + 0x11C3000011C37, + 0x11C3800011C3E, + 0x11C3F00011C40, + 0x11C9200011CA8, + 0x11CAA00011CB1, + 0x11CB200011CB4, + 0x11CB500011CB7, + 0x11D3100011D37, + 0x11D3A00011D3B, + 0x11D3C00011D3E, + 0x11D3F00011D46, + 0x11D4700011D48, + 0x11D9000011D92, + 0x11D9500011D96, + 0x11D9700011D98, + 0x11EF300011EF5, + 0x11F0000011F02, + 0x11F3600011F3B, + 0x11F4000011F41, + 0x11F4200011F43, + 0x11F5A00011F5B, + 0x1343000013441, + 0x1344700013456, + 0x1611E0001612A, + 0x1612D00016130, + 0x16AF000016AF5, + 0x16B3000016B37, + 0x16F4F00016F50, + 0x16F8F00016F93, + 0x16FE400016FE5, + 0x1BC9D0001BC9F, + 0x1BCA00001BCA4, + 0x1CF000001CF2E, + 0x1CF300001CF47, + 0x1D1670001D16A, + 0x1D1730001D183, + 0x1D1850001D18C, + 0x1D1AA0001D1AE, + 0x1D2420001D245, + 0x1DA000001DA37, + 0x1DA3B0001DA6D, + 0x1DA750001DA76, + 0x1DA840001DA85, + 0x1DA9B0001DAA0, + 0x1DAA10001DAB0, + 0x1E0000001E007, + 0x1E0080001E019, + 0x1E01B0001E022, + 0x1E0230001E025, + 0x1E0260001E02B, + 0x1E08F0001E090, + 0x1E1300001E137, + 0x1E2AE0001E2AF, + 0x1E2EC0001E2F0, + 0x1E4EC0001E4F0, + 0x1E5EE0001E5F0, + 0x1E6E30001E6E4, + 0x1E6E60001E6E7, + 0x1E6EE0001E6F0, + 0x1E6F50001E6F6, + 0x1E8D00001E8D7, + 0x1E9440001E94C, + 0xE0001000E0002, + 0xE0020000E0080, + 0xE0100000E01F0, + ), +} + + +codepoint_classes = { + "PVALID": ( + 0x2D0000002E, + 0x300000003A, + 0x610000007B, + 0xDF000000F7, + 0xF800000100, + 0x10100000102, + 0x10300000104, + 0x10500000106, + 0x10700000108, + 0x1090000010A, + 0x10B0000010C, + 0x10D0000010E, + 0x10F00000110, + 0x11100000112, + 0x11300000114, + 0x11500000116, + 0x11700000118, + 0x1190000011A, + 0x11B0000011C, + 0x11D0000011E, + 0x11F00000120, + 0x12100000122, + 0x12300000124, + 0x12500000126, + 0x12700000128, + 0x1290000012A, + 0x12B0000012C, + 0x12D0000012E, + 0x12F00000130, + 0x13100000132, + 0x13500000136, + 0x13700000139, + 0x13A0000013B, + 0x13C0000013D, + 0x13E0000013F, + 0x14200000143, + 0x14400000145, + 0x14600000147, + 0x14800000149, + 0x14B0000014C, + 0x14D0000014E, + 0x14F00000150, + 0x15100000152, + 0x15300000154, + 0x15500000156, + 0x15700000158, + 0x1590000015A, + 0x15B0000015C, + 0x15D0000015E, + 0x15F00000160, + 0x16100000162, + 0x16300000164, + 0x16500000166, + 0x16700000168, + 0x1690000016A, + 0x16B0000016C, + 0x16D0000016E, + 0x16F00000170, + 0x17100000172, + 0x17300000174, + 0x17500000176, + 0x17700000178, + 0x17A0000017B, + 0x17C0000017D, + 0x17E0000017F, + 0x18000000181, + 0x18300000184, + 0x18500000186, + 0x18800000189, + 0x18C0000018E, + 0x19200000193, + 0x19500000196, + 0x1990000019C, + 0x19E0000019F, + 0x1A1000001A2, + 0x1A3000001A4, + 0x1A5000001A6, + 0x1A8000001A9, + 0x1AA000001AC, + 0x1AD000001AE, + 0x1B0000001B1, + 0x1B4000001B5, + 0x1B6000001B7, + 0x1B9000001BC, + 0x1BD000001C4, + 0x1CE000001CF, + 0x1D0000001D1, + 0x1D2000001D3, + 0x1D4000001D5, + 0x1D6000001D7, + 0x1D8000001D9, + 0x1DA000001DB, + 0x1DC000001DE, + 0x1DF000001E0, + 0x1E1000001E2, + 0x1E3000001E4, + 0x1E5000001E6, + 0x1E7000001E8, + 0x1E9000001EA, + 0x1EB000001EC, + 0x1ED000001EE, + 0x1EF000001F1, + 0x1F5000001F6, + 0x1F9000001FA, + 0x1FB000001FC, + 0x1FD000001FE, + 0x1FF00000200, + 0x20100000202, + 0x20300000204, + 0x20500000206, + 0x20700000208, + 0x2090000020A, + 0x20B0000020C, + 0x20D0000020E, + 0x20F00000210, + 0x21100000212, + 0x21300000214, + 0x21500000216, + 0x21700000218, + 0x2190000021A, + 0x21B0000021C, + 0x21D0000021E, + 0x21F00000220, + 0x22100000222, + 0x22300000224, + 0x22500000226, + 0x22700000228, + 0x2290000022A, + 0x22B0000022C, + 0x22D0000022E, + 0x22F00000230, + 0x23100000232, + 0x2330000023A, + 0x23C0000023D, + 0x23F00000241, + 0x24200000243, + 0x24700000248, + 0x2490000024A, + 0x24B0000024C, + 0x24D0000024E, + 0x24F000002B0, + 0x2B9000002C2, + 0x2C6000002D2, + 0x2EC000002ED, + 0x2EE000002EF, + 0x30000000340, + 0x34200000343, + 0x3460000034F, + 0x35000000370, + 0x37100000372, + 0x37300000374, + 0x37700000378, + 0x37B0000037E, + 0x39000000391, + 0x3AC000003CF, + 0x3D7000003D8, + 0x3D9000003DA, + 0x3DB000003DC, + 0x3DD000003DE, + 0x3DF000003E0, + 0x3E1000003E2, + 0x3E3000003E4, + 0x3E5000003E6, + 0x3E7000003E8, + 0x3E9000003EA, + 0x3EB000003EC, + 0x3ED000003EE, + 0x3EF000003F0, + 0x3F3000003F4, + 0x3F8000003F9, + 0x3FB000003FD, + 0x43000000460, + 0x46100000462, + 0x46300000464, + 0x46500000466, + 0x46700000468, + 0x4690000046A, + 0x46B0000046C, + 0x46D0000046E, + 0x46F00000470, + 0x47100000472, + 0x47300000474, + 0x47500000476, + 0x47700000478, + 0x4790000047A, + 0x47B0000047C, + 0x47D0000047E, + 0x47F00000480, + 0x48100000482, + 0x48300000488, + 0x48B0000048C, + 0x48D0000048E, + 0x48F00000490, + 0x49100000492, + 0x49300000494, + 0x49500000496, + 0x49700000498, + 0x4990000049A, + 0x49B0000049C, + 0x49D0000049E, + 0x49F000004A0, + 0x4A1000004A2, + 0x4A3000004A4, + 0x4A5000004A6, + 0x4A7000004A8, + 0x4A9000004AA, + 0x4AB000004AC, + 0x4AD000004AE, + 0x4AF000004B0, + 0x4B1000004B2, + 0x4B3000004B4, + 0x4B5000004B6, + 0x4B7000004B8, + 0x4B9000004BA, + 0x4BB000004BC, + 0x4BD000004BE, + 0x4BF000004C0, + 0x4C2000004C3, + 0x4C4000004C5, + 0x4C6000004C7, + 0x4C8000004C9, + 0x4CA000004CB, + 0x4CC000004CD, + 0x4CE000004D0, + 0x4D1000004D2, + 0x4D3000004D4, + 0x4D5000004D6, + 0x4D7000004D8, + 0x4D9000004DA, + 0x4DB000004DC, + 0x4DD000004DE, + 0x4DF000004E0, + 0x4E1000004E2, + 0x4E3000004E4, + 0x4E5000004E6, + 0x4E7000004E8, + 0x4E9000004EA, + 0x4EB000004EC, + 0x4ED000004EE, + 0x4EF000004F0, + 0x4F1000004F2, + 0x4F3000004F4, + 0x4F5000004F6, + 0x4F7000004F8, + 0x4F9000004FA, + 0x4FB000004FC, + 0x4FD000004FE, + 0x4FF00000500, + 0x50100000502, + 0x50300000504, + 0x50500000506, + 0x50700000508, + 0x5090000050A, + 0x50B0000050C, + 0x50D0000050E, + 0x50F00000510, + 0x51100000512, + 0x51300000514, + 0x51500000516, + 0x51700000518, + 0x5190000051A, + 0x51B0000051C, + 0x51D0000051E, + 0x51F00000520, + 0x52100000522, + 0x52300000524, + 0x52500000526, + 0x52700000528, + 0x5290000052A, + 0x52B0000052C, + 0x52D0000052E, + 0x52F00000530, + 0x5590000055A, + 0x56000000587, + 0x58800000589, + 0x591000005BE, + 0x5BF000005C0, + 0x5C1000005C3, + 0x5C4000005C6, + 0x5C7000005C8, + 0x5D0000005EB, + 0x5EF000005F3, + 0x6100000061B, + 0x62000000640, + 0x64100000660, + 0x66E00000675, + 0x679000006D4, + 0x6D5000006DD, + 0x6DF000006E9, + 0x6EA000006F0, + 0x6FA00000700, + 0x7100000074B, + 0x74D000007B2, + 0x7C0000007F6, + 0x7FD000007FE, + 0x8000000082E, + 0x8400000085C, + 0x8600000086B, + 0x87000000888, + 0x88900000890, + 0x897000008E2, + 0x8E300000958, + 0x96000000964, + 0x96600000970, + 0x97100000984, + 0x9850000098D, + 0x98F00000991, + 0x993000009A9, + 0x9AA000009B1, + 0x9B2000009B3, + 0x9B6000009BA, + 0x9BC000009C5, + 0x9C7000009C9, + 0x9CB000009CF, + 0x9D7000009D8, + 0x9E0000009E4, + 0x9E6000009F2, + 0x9FC000009FD, + 0x9FE000009FF, + 0xA0100000A04, + 0xA0500000A0B, + 0xA0F00000A11, + 0xA1300000A29, + 0xA2A00000A31, + 0xA3200000A33, + 0xA3500000A36, + 0xA3800000A3A, + 0xA3C00000A3D, + 0xA3E00000A43, + 0xA4700000A49, + 0xA4B00000A4E, + 0xA5100000A52, + 0xA5C00000A5D, + 0xA6600000A76, + 0xA8100000A84, + 0xA8500000A8E, + 0xA8F00000A92, + 0xA9300000AA9, + 0xAAA00000AB1, + 0xAB200000AB4, + 0xAB500000ABA, + 0xABC00000AC6, + 0xAC700000ACA, + 0xACB00000ACE, + 0xAD000000AD1, + 0xAE000000AE4, + 0xAE600000AF0, + 0xAF900000B00, + 0xB0100000B04, + 0xB0500000B0D, + 0xB0F00000B11, + 0xB1300000B29, + 0xB2A00000B31, + 0xB3200000B34, + 0xB3500000B3A, + 0xB3C00000B45, + 0xB4700000B49, + 0xB4B00000B4E, + 0xB5500000B58, + 0xB5F00000B64, + 0xB6600000B70, + 0xB7100000B72, + 0xB8200000B84, + 0xB8500000B8B, + 0xB8E00000B91, + 0xB9200000B96, + 0xB9900000B9B, + 0xB9C00000B9D, + 0xB9E00000BA0, + 0xBA300000BA5, + 0xBA800000BAB, + 0xBAE00000BBA, + 0xBBE00000BC3, + 0xBC600000BC9, + 0xBCA00000BCE, + 0xBD000000BD1, + 0xBD700000BD8, + 0xBE600000BF0, + 0xC0000000C0D, + 0xC0E00000C11, + 0xC1200000C29, + 0xC2A00000C3A, + 0xC3C00000C45, + 0xC4600000C49, + 0xC4A00000C4E, + 0xC5500000C57, + 0xC5800000C5B, + 0xC5C00000C5E, + 0xC6000000C64, + 0xC6600000C70, + 0xC8000000C84, + 0xC8500000C8D, + 0xC8E00000C91, + 0xC9200000CA9, + 0xCAA00000CB4, + 0xCB500000CBA, + 0xCBC00000CC5, + 0xCC600000CC9, + 0xCCA00000CCE, + 0xCD500000CD7, + 0xCDC00000CDF, + 0xCE000000CE4, + 0xCE600000CF0, + 0xCF100000CF4, + 0xD0000000D0D, + 0xD0E00000D11, + 0xD1200000D45, + 0xD4600000D49, + 0xD4A00000D4F, + 0xD5400000D58, + 0xD5F00000D64, + 0xD6600000D70, + 0xD7A00000D80, + 0xD8100000D84, + 0xD8500000D97, + 0xD9A00000DB2, + 0xDB300000DBC, + 0xDBD00000DBE, + 0xDC000000DC7, + 0xDCA00000DCB, + 0xDCF00000DD5, + 0xDD600000DD7, + 0xDD800000DE0, + 0xDE600000DF0, + 0xDF200000DF4, + 0xE0100000E33, + 0xE3400000E3B, + 0xE4000000E4F, + 0xE5000000E5A, + 0xE8100000E83, + 0xE8400000E85, + 0xE8600000E8B, + 0xE8C00000EA4, + 0xEA500000EA6, + 0xEA700000EB3, + 0xEB400000EBE, + 0xEC000000EC5, + 0xEC600000EC7, + 0xEC800000ECF, + 0xED000000EDA, + 0xEDE00000EE0, + 0xF0000000F01, + 0xF0B00000F0C, + 0xF1800000F1A, + 0xF2000000F2A, + 0xF3500000F36, + 0xF3700000F38, + 0xF3900000F3A, + 0xF3E00000F43, + 0xF4400000F48, + 0xF4900000F4D, + 0xF4E00000F52, + 0xF5300000F57, + 0xF5800000F5C, + 0xF5D00000F69, + 0xF6A00000F6D, + 0xF7100000F73, + 0xF7400000F75, + 0xF7A00000F81, + 0xF8200000F85, + 0xF8600000F93, + 0xF9400000F98, + 0xF9900000F9D, + 0xF9E00000FA2, + 0xFA300000FA7, + 0xFA800000FAC, + 0xFAD00000FB9, + 0xFBA00000FBD, + 0xFC600000FC7, + 0x10000000104A, + 0x10500000109E, + 0x10D0000010FB, + 0x10FD00001100, + 0x120000001249, + 0x124A0000124E, + 0x125000001257, + 0x125800001259, + 0x125A0000125E, + 0x126000001289, + 0x128A0000128E, + 0x1290000012B1, + 0x12B2000012B6, + 0x12B8000012BF, + 0x12C0000012C1, + 0x12C2000012C6, + 0x12C8000012D7, + 0x12D800001311, + 0x131200001316, + 0x13180000135B, + 0x135D00001360, + 0x138000001390, + 0x13A0000013F6, + 0x14010000166D, + 0x166F00001680, + 0x16810000169B, + 0x16A0000016EB, + 0x16F1000016F9, + 0x170000001716, + 0x171F00001735, + 0x174000001754, + 0x17600000176D, + 0x176E00001771, + 0x177200001774, + 0x1780000017B4, + 0x17B6000017D4, + 0x17D7000017D8, + 0x17DC000017DE, + 0x17E0000017EA, + 0x18100000181A, + 0x182000001879, + 0x1880000018AB, + 0x18B0000018F6, + 0x19000000191F, + 0x19200000192C, + 0x19300000193C, + 0x19460000196E, + 0x197000001975, + 0x1980000019AC, + 0x19B0000019CA, + 0x19D0000019DA, + 0x1A0000001A1C, + 0x1A2000001A5F, + 0x1A6000001A7D, + 0x1A7F00001A8A, + 0x1A9000001A9A, + 0x1AA700001AA8, + 0x1AB000001ABE, + 0x1ABF00001ADE, + 0x1AE000001AEC, + 0x1B0000001B4D, + 0x1B5000001B5A, + 0x1B6B00001B74, + 0x1B8000001BF4, + 0x1C0000001C38, + 0x1C4000001C4A, + 0x1C4D00001C7E, + 0x1C8A00001C8B, + 0x1CD000001CD3, + 0x1CD400001CFB, + 0x1D0000001D2C, + 0x1D2F00001D30, + 0x1D3B00001D3C, + 0x1D4E00001D4F, + 0x1D6B00001D78, + 0x1D7900001D9B, + 0x1DC000001E00, + 0x1E0100001E02, + 0x1E0300001E04, + 0x1E0500001E06, + 0x1E0700001E08, + 0x1E0900001E0A, + 0x1E0B00001E0C, + 0x1E0D00001E0E, + 0x1E0F00001E10, + 0x1E1100001E12, + 0x1E1300001E14, + 0x1E1500001E16, + 0x1E1700001E18, + 0x1E1900001E1A, + 0x1E1B00001E1C, + 0x1E1D00001E1E, + 0x1E1F00001E20, + 0x1E2100001E22, + 0x1E2300001E24, + 0x1E2500001E26, + 0x1E2700001E28, + 0x1E2900001E2A, + 0x1E2B00001E2C, + 0x1E2D00001E2E, + 0x1E2F00001E30, + 0x1E3100001E32, + 0x1E3300001E34, + 0x1E3500001E36, + 0x1E3700001E38, + 0x1E3900001E3A, + 0x1E3B00001E3C, + 0x1E3D00001E3E, + 0x1E3F00001E40, + 0x1E4100001E42, + 0x1E4300001E44, + 0x1E4500001E46, + 0x1E4700001E48, + 0x1E4900001E4A, + 0x1E4B00001E4C, + 0x1E4D00001E4E, + 0x1E4F00001E50, + 0x1E5100001E52, + 0x1E5300001E54, + 0x1E5500001E56, + 0x1E5700001E58, + 0x1E5900001E5A, + 0x1E5B00001E5C, + 0x1E5D00001E5E, + 0x1E5F00001E60, + 0x1E6100001E62, + 0x1E6300001E64, + 0x1E6500001E66, + 0x1E6700001E68, + 0x1E6900001E6A, + 0x1E6B00001E6C, + 0x1E6D00001E6E, + 0x1E6F00001E70, + 0x1E7100001E72, + 0x1E7300001E74, + 0x1E7500001E76, + 0x1E7700001E78, + 0x1E7900001E7A, + 0x1E7B00001E7C, + 0x1E7D00001E7E, + 0x1E7F00001E80, + 0x1E8100001E82, + 0x1E8300001E84, + 0x1E8500001E86, + 0x1E8700001E88, + 0x1E8900001E8A, + 0x1E8B00001E8C, + 0x1E8D00001E8E, + 0x1E8F00001E90, + 0x1E9100001E92, + 0x1E9300001E94, + 0x1E9500001E9A, + 0x1E9C00001E9E, + 0x1E9F00001EA0, + 0x1EA100001EA2, + 0x1EA300001EA4, + 0x1EA500001EA6, + 0x1EA700001EA8, + 0x1EA900001EAA, + 0x1EAB00001EAC, + 0x1EAD00001EAE, + 0x1EAF00001EB0, + 0x1EB100001EB2, + 0x1EB300001EB4, + 0x1EB500001EB6, + 0x1EB700001EB8, + 0x1EB900001EBA, + 0x1EBB00001EBC, + 0x1EBD00001EBE, + 0x1EBF00001EC0, + 0x1EC100001EC2, + 0x1EC300001EC4, + 0x1EC500001EC6, + 0x1EC700001EC8, + 0x1EC900001ECA, + 0x1ECB00001ECC, + 0x1ECD00001ECE, + 0x1ECF00001ED0, + 0x1ED100001ED2, + 0x1ED300001ED4, + 0x1ED500001ED6, + 0x1ED700001ED8, + 0x1ED900001EDA, + 0x1EDB00001EDC, + 0x1EDD00001EDE, + 0x1EDF00001EE0, + 0x1EE100001EE2, + 0x1EE300001EE4, + 0x1EE500001EE6, + 0x1EE700001EE8, + 0x1EE900001EEA, + 0x1EEB00001EEC, + 0x1EED00001EEE, + 0x1EEF00001EF0, + 0x1EF100001EF2, + 0x1EF300001EF4, + 0x1EF500001EF6, + 0x1EF700001EF8, + 0x1EF900001EFA, + 0x1EFB00001EFC, + 0x1EFD00001EFE, + 0x1EFF00001F08, + 0x1F1000001F16, + 0x1F2000001F28, + 0x1F3000001F38, + 0x1F4000001F46, + 0x1F5000001F58, + 0x1F6000001F68, + 0x1F7000001F71, + 0x1F7200001F73, + 0x1F7400001F75, + 0x1F7600001F77, + 0x1F7800001F79, + 0x1F7A00001F7B, + 0x1F7C00001F7D, + 0x1FB000001FB2, + 0x1FB600001FB7, + 0x1FC600001FC7, + 0x1FD000001FD3, + 0x1FD600001FD8, + 0x1FE000001FE3, + 0x1FE400001FE8, + 0x1FF600001FF7, + 0x214E0000214F, + 0x218400002185, + 0x2C3000002C60, + 0x2C6100002C62, + 0x2C6500002C67, + 0x2C6800002C69, + 0x2C6A00002C6B, + 0x2C6C00002C6D, + 0x2C7100002C72, + 0x2C7300002C75, + 0x2C7600002C7C, + 0x2C8100002C82, + 0x2C8300002C84, + 0x2C8500002C86, + 0x2C8700002C88, + 0x2C8900002C8A, + 0x2C8B00002C8C, + 0x2C8D00002C8E, + 0x2C8F00002C90, + 0x2C9100002C92, + 0x2C9300002C94, + 0x2C9500002C96, + 0x2C9700002C98, + 0x2C9900002C9A, + 0x2C9B00002C9C, + 0x2C9D00002C9E, + 0x2C9F00002CA0, + 0x2CA100002CA2, + 0x2CA300002CA4, + 0x2CA500002CA6, + 0x2CA700002CA8, + 0x2CA900002CAA, + 0x2CAB00002CAC, + 0x2CAD00002CAE, + 0x2CAF00002CB0, + 0x2CB100002CB2, + 0x2CB300002CB4, + 0x2CB500002CB6, + 0x2CB700002CB8, + 0x2CB900002CBA, + 0x2CBB00002CBC, + 0x2CBD00002CBE, + 0x2CBF00002CC0, + 0x2CC100002CC2, + 0x2CC300002CC4, + 0x2CC500002CC6, + 0x2CC700002CC8, + 0x2CC900002CCA, + 0x2CCB00002CCC, + 0x2CCD00002CCE, + 0x2CCF00002CD0, + 0x2CD100002CD2, + 0x2CD300002CD4, + 0x2CD500002CD6, + 0x2CD700002CD8, + 0x2CD900002CDA, + 0x2CDB00002CDC, + 0x2CDD00002CDE, + 0x2CDF00002CE0, + 0x2CE100002CE2, + 0x2CE300002CE5, + 0x2CEC00002CED, + 0x2CEE00002CF2, + 0x2CF300002CF4, + 0x2D0000002D26, + 0x2D2700002D28, + 0x2D2D00002D2E, + 0x2D3000002D68, + 0x2D7F00002D97, + 0x2DA000002DA7, + 0x2DA800002DAF, + 0x2DB000002DB7, + 0x2DB800002DBF, + 0x2DC000002DC7, + 0x2DC800002DCF, + 0x2DD000002DD7, + 0x2DD800002DDF, + 0x2DE000002E00, + 0x2E2F00002E30, + 0x300500003008, + 0x302A0000302E, + 0x303C0000303D, + 0x304100003097, + 0x30990000309B, + 0x309D0000309F, + 0x30A1000030FB, + 0x30FC000030FF, + 0x310500003130, + 0x31A0000031C0, + 0x31F000003200, + 0x340000004DC0, + 0x4E000000A48D, + 0xA4D00000A4FE, + 0xA5000000A60D, + 0xA6100000A62C, + 0xA6410000A642, + 0xA6430000A644, + 0xA6450000A646, + 0xA6470000A648, + 0xA6490000A64A, + 0xA64B0000A64C, + 0xA64D0000A64E, + 0xA64F0000A650, + 0xA6510000A652, + 0xA6530000A654, + 0xA6550000A656, + 0xA6570000A658, + 0xA6590000A65A, + 0xA65B0000A65C, + 0xA65D0000A65E, + 0xA65F0000A660, + 0xA6610000A662, + 0xA6630000A664, + 0xA6650000A666, + 0xA6670000A668, + 0xA6690000A66A, + 0xA66B0000A66C, + 0xA66D0000A670, + 0xA6740000A67E, + 0xA67F0000A680, + 0xA6810000A682, + 0xA6830000A684, + 0xA6850000A686, + 0xA6870000A688, + 0xA6890000A68A, + 0xA68B0000A68C, + 0xA68D0000A68E, + 0xA68F0000A690, + 0xA6910000A692, + 0xA6930000A694, + 0xA6950000A696, + 0xA6970000A698, + 0xA6990000A69A, + 0xA69B0000A69C, + 0xA69E0000A6E6, + 0xA6F00000A6F2, + 0xA7170000A720, + 0xA7230000A724, + 0xA7250000A726, + 0xA7270000A728, + 0xA7290000A72A, + 0xA72B0000A72C, + 0xA72D0000A72E, + 0xA72F0000A732, + 0xA7330000A734, + 0xA7350000A736, + 0xA7370000A738, + 0xA7390000A73A, + 0xA73B0000A73C, + 0xA73D0000A73E, + 0xA73F0000A740, + 0xA7410000A742, + 0xA7430000A744, + 0xA7450000A746, + 0xA7470000A748, + 0xA7490000A74A, + 0xA74B0000A74C, + 0xA74D0000A74E, + 0xA74F0000A750, + 0xA7510000A752, + 0xA7530000A754, + 0xA7550000A756, + 0xA7570000A758, + 0xA7590000A75A, + 0xA75B0000A75C, + 0xA75D0000A75E, + 0xA75F0000A760, + 0xA7610000A762, + 0xA7630000A764, + 0xA7650000A766, + 0xA7670000A768, + 0xA7690000A76A, + 0xA76B0000A76C, + 0xA76D0000A76E, + 0xA76F0000A770, + 0xA7710000A779, + 0xA77A0000A77B, + 0xA77C0000A77D, + 0xA77F0000A780, + 0xA7810000A782, + 0xA7830000A784, + 0xA7850000A786, + 0xA7870000A789, + 0xA78C0000A78D, + 0xA78E0000A790, + 0xA7910000A792, + 0xA7930000A796, + 0xA7970000A798, + 0xA7990000A79A, + 0xA79B0000A79C, + 0xA79D0000A79E, + 0xA79F0000A7A0, + 0xA7A10000A7A2, + 0xA7A30000A7A4, + 0xA7A50000A7A6, + 0xA7A70000A7A8, + 0xA7A90000A7AA, + 0xA7AF0000A7B0, + 0xA7B50000A7B6, + 0xA7B70000A7B8, + 0xA7B90000A7BA, + 0xA7BB0000A7BC, + 0xA7BD0000A7BE, + 0xA7BF0000A7C0, + 0xA7C10000A7C2, + 0xA7C30000A7C4, + 0xA7C80000A7C9, + 0xA7CA0000A7CB, + 0xA7CD0000A7CE, + 0xA7CF0000A7D0, + 0xA7D10000A7D2, + 0xA7D30000A7D4, + 0xA7D50000A7D6, + 0xA7D70000A7D8, + 0xA7D90000A7DA, + 0xA7DB0000A7DC, + 0xA7F60000A7F8, + 0xA7FA0000A828, + 0xA82C0000A82D, + 0xA8400000A874, + 0xA8800000A8C6, + 0xA8D00000A8DA, + 0xA8E00000A8F8, + 0xA8FB0000A8FC, + 0xA8FD0000A92E, + 0xA9300000A954, + 0xA9800000A9C1, + 0xA9CF0000A9DA, + 0xA9E00000A9FF, + 0xAA000000AA37, + 0xAA400000AA4E, + 0xAA500000AA5A, + 0xAA600000AA77, + 0xAA7A0000AAC3, + 0xAADB0000AADE, + 0xAAE00000AAF0, + 0xAAF20000AAF7, + 0xAB010000AB07, + 0xAB090000AB0F, + 0xAB110000AB17, + 0xAB200000AB27, + 0xAB280000AB2F, + 0xAB300000AB5B, + 0xAB600000AB69, + 0xABC00000ABEB, + 0xABEC0000ABEE, + 0xABF00000ABFA, + 0xAC000000D7A4, + 0xFA0E0000FA10, + 0xFA110000FA12, + 0xFA130000FA15, + 0xFA1F0000FA20, + 0xFA210000FA22, + 0xFA230000FA25, + 0xFA270000FA2A, + 0xFB1E0000FB1F, + 0xFE200000FE30, + 0xFE730000FE74, + 0x100000001000C, + 0x1000D00010027, + 0x100280001003B, + 0x1003C0001003E, + 0x1003F0001004E, + 0x100500001005E, + 0x10080000100FB, + 0x101FD000101FE, + 0x102800001029D, + 0x102A0000102D1, + 0x102E0000102E1, + 0x1030000010320, + 0x1032D00010341, + 0x103420001034A, + 0x103500001037B, + 0x103800001039E, + 0x103A0000103C4, + 0x103C8000103D0, + 0x104280001049E, + 0x104A0000104AA, + 0x104D8000104FC, + 0x1050000010528, + 0x1053000010564, + 0x10597000105A2, + 0x105A3000105B2, + 0x105B3000105BA, + 0x105BB000105BD, + 0x105C0000105F4, + 0x1060000010737, + 0x1074000010756, + 0x1076000010768, + 0x1078000010781, + 0x1080000010806, + 0x1080800010809, + 0x1080A00010836, + 0x1083700010839, + 0x1083C0001083D, + 0x1083F00010856, + 0x1086000010877, + 0x108800001089F, + 0x108E0000108F3, + 0x108F4000108F6, + 0x1090000010916, + 0x109200001093A, + 0x109400001095A, + 0x10980000109B8, + 0x109BE000109C0, + 0x10A0000010A04, + 0x10A0500010A07, + 0x10A0C00010A14, + 0x10A1500010A18, + 0x10A1900010A36, + 0x10A3800010A3B, + 0x10A3F00010A40, + 0x10A6000010A7D, + 0x10A8000010A9D, + 0x10AC000010AC8, + 0x10AC900010AE7, + 0x10B0000010B36, + 0x10B4000010B56, + 0x10B6000010B73, + 0x10B8000010B92, + 0x10C0000010C49, + 0x10CC000010CF3, + 0x10D0000010D28, + 0x10D3000010D3A, + 0x10D4000010D50, + 0x10D6900010D6E, + 0x10D6F00010D86, + 0x10E8000010EAA, + 0x10EAB00010EAD, + 0x10EB000010EB2, + 0x10EC200010EC8, + 0x10EFA00010F1D, + 0x10F2700010F28, + 0x10F3000010F51, + 0x10F7000010F86, + 0x10FB000010FC5, + 0x10FE000010FF7, + 0x1100000011047, + 0x1106600011076, + 0x1107F000110BB, + 0x110C2000110C3, + 0x110D0000110E9, + 0x110F0000110FA, + 0x1110000011135, + 0x1113600011140, + 0x1114400011148, + 0x1115000011174, + 0x1117600011177, + 0x11180000111C5, + 0x111C9000111CD, + 0x111CE000111DB, + 0x111DC000111DD, + 0x1120000011212, + 0x1121300011238, + 0x1123E00011242, + 0x1128000011287, + 0x1128800011289, + 0x1128A0001128E, + 0x1128F0001129E, + 0x1129F000112A9, + 0x112B0000112EB, + 0x112F0000112FA, + 0x1130000011304, + 0x113050001130D, + 0x1130F00011311, + 0x1131300011329, + 0x1132A00011331, + 0x1133200011334, + 0x113350001133A, + 0x1133B00011345, + 0x1134700011349, + 0x1134B0001134E, + 0x1135000011351, + 0x1135700011358, + 0x1135D00011364, + 0x113660001136D, + 0x1137000011375, + 0x113800001138A, + 0x1138B0001138C, + 0x1138E0001138F, + 0x11390000113B6, + 0x113B7000113C1, + 0x113C2000113C3, + 0x113C5000113C6, + 0x113C7000113CB, + 0x113CC000113D4, + 0x113E1000113E3, + 0x114000001144B, + 0x114500001145A, + 0x1145E00011462, + 0x11480000114C6, + 0x114C7000114C8, + 0x114D0000114DA, + 0x11580000115B6, + 0x115B8000115C1, + 0x115D8000115DE, + 0x1160000011641, + 0x1164400011645, + 0x116500001165A, + 0x11680000116B9, + 0x116C0000116CA, + 0x116D0000116E4, + 0x117000001171B, + 0x1171D0001172C, + 0x117300001173A, + 0x1174000011747, + 0x118000001183B, + 0x118C0000118EA, + 0x118FF00011907, + 0x119090001190A, + 0x1190C00011914, + 0x1191500011917, + 0x1191800011936, + 0x1193700011939, + 0x1193B00011944, + 0x119500001195A, + 0x119A0000119A8, + 0x119AA000119D8, + 0x119DA000119E2, + 0x119E3000119E5, + 0x11A0000011A3F, + 0x11A4700011A48, + 0x11A5000011A9A, + 0x11A9D00011A9E, + 0x11AB000011AF9, + 0x11B6000011B68, + 0x11BC000011BE1, + 0x11BF000011BFA, + 0x11C0000011C09, + 0x11C0A00011C37, + 0x11C3800011C41, + 0x11C5000011C5A, + 0x11C7200011C90, + 0x11C9200011CA8, + 0x11CA900011CB7, + 0x11D0000011D07, + 0x11D0800011D0A, + 0x11D0B00011D37, + 0x11D3A00011D3B, + 0x11D3C00011D3E, + 0x11D3F00011D48, + 0x11D5000011D5A, + 0x11D6000011D66, + 0x11D6700011D69, + 0x11D6A00011D8F, + 0x11D9000011D92, + 0x11D9300011D99, + 0x11DA000011DAA, + 0x11DB000011DDC, + 0x11DE000011DEA, + 0x11EE000011EF7, + 0x11F0000011F11, + 0x11F1200011F3B, + 0x11F3E00011F43, + 0x11F5000011F5B, + 0x11FB000011FB1, + 0x120000001239A, + 0x1248000012544, + 0x12F9000012FF1, + 0x1300000013430, + 0x1344000013456, + 0x13460000143FB, + 0x1440000014647, + 0x161000001613A, + 0x1680000016A39, + 0x16A4000016A5F, + 0x16A6000016A6A, + 0x16A7000016ABF, + 0x16AC000016ACA, + 0x16AD000016AEE, + 0x16AF000016AF5, + 0x16B0000016B37, + 0x16B4000016B44, + 0x16B5000016B5A, + 0x16B6300016B78, + 0x16B7D00016B90, + 0x16D4000016D6D, + 0x16D7000016D7A, + 0x16E6000016E80, + 0x16EBB00016ED4, + 0x16F0000016F4B, + 0x16F4F00016F88, + 0x16F8F00016FA0, + 0x16FE000016FE2, + 0x16FE300016FE5, + 0x16FF000016FF4, + 0x1700000018CD6, + 0x18CFF00018D1F, + 0x18D8000018DF3, + 0x1AFF00001AFF4, + 0x1AFF50001AFFC, + 0x1AFFD0001AFFF, + 0x1B0000001B123, + 0x1B1320001B133, + 0x1B1500001B153, + 0x1B1550001B156, + 0x1B1640001B168, + 0x1B1700001B2FC, + 0x1BC000001BC6B, + 0x1BC700001BC7D, + 0x1BC800001BC89, + 0x1BC900001BC9A, + 0x1BC9D0001BC9F, + 0x1CF000001CF2E, + 0x1CF300001CF47, + 0x1DA000001DA37, + 0x1DA3B0001DA6D, + 0x1DA750001DA76, + 0x1DA840001DA85, + 0x1DA9B0001DAA0, + 0x1DAA10001DAB0, + 0x1DF000001DF1F, + 0x1DF250001DF2B, + 0x1E0000001E007, + 0x1E0080001E019, + 0x1E01B0001E022, + 0x1E0230001E025, + 0x1E0260001E02B, + 0x1E08F0001E090, + 0x1E1000001E12D, + 0x1E1300001E13E, + 0x1E1400001E14A, + 0x1E14E0001E14F, + 0x1E2900001E2AF, + 0x1E2C00001E2FA, + 0x1E4D00001E4FA, + 0x1E5D00001E5FB, + 0x1E6C00001E6DF, + 0x1E6E00001E6F6, + 0x1E6FE0001E700, + 0x1E7E00001E7E7, + 0x1E7E80001E7EC, + 0x1E7ED0001E7EF, + 0x1E7F00001E7FF, + 0x1E8000001E8C5, + 0x1E8D00001E8D7, + 0x1E9220001E94C, + 0x1E9500001E95A, + 0x200000002A6E0, + 0x2A7000002B81E, + 0x2B8200002CEAE, + 0x2CEB00002EBE1, + 0x2EBF00002EE5E, + 0x300000003134B, + 0x313500003347A, + ), + "CONTEXTJ": (0x200C0000200E,), + "CONTEXTO": ( + 0xB7000000B8, + 0x37500000376, + 0x5F3000005F5, + 0x6600000066A, + 0x6F0000006FA, + 0x30FB000030FC, + ), +} diff --git a/.venv/lib/python3.13/site-packages/idna/intranges.py b/.venv/lib/python3.13/site-packages/idna/intranges.py new file mode 100644 index 0000000000000000000000000000000000000000..19d77810caf332a1f310bd3b734dab7bbd82f64c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna/intranges.py @@ -0,0 +1,55 @@ +""" +Given a list of integers, made up of (hopefully) a small number of long runs +of consecutive integers, compute a representation of the form +((start1, end1), (start2, end2) ...). Then answer the question "was x present +in the original list?" in time O(log(# runs)). +""" + +import bisect + + +def intranges_from_list(list_: list[int]) -> tuple[int, ...]: + """Represent a list of integers as a sequence of ranges: + ((start_0, end_0), (start_1, end_1), ...), such that the original + integers are exactly those x such that start_i <= x < end_i for some i. + + Ranges are encoded as single integers (start << 32 | end), not as tuples. + """ + + sorted_list = sorted(list_) + ranges = [] + last_write = -1 + for i in range(len(sorted_list)): + if i + 1 < len(sorted_list) and sorted_list[i] == sorted_list[i + 1] - 1: + continue + current_range = sorted_list[last_write + 1 : i + 1] + ranges.append(_encode_range(current_range[0], current_range[-1] + 1)) + last_write = i + + return tuple(ranges) + + +def _encode_range(start: int, end: int) -> int: + return (start << 32) | end + + +def _decode_range(r: int) -> tuple[int, int]: + return (r >> 32), (r & ((1 << 32) - 1)) + + +def intranges_contain(int_: int, ranges: tuple[int, ...]) -> bool: + """Determine if `int_` falls into one of the ranges in `ranges`.""" + tuple_ = _encode_range(int_, 0) + pos = bisect.bisect_left(ranges, tuple_) + # we could be immediately ahead of a tuple (start, end) + # with start < int_ <= end + if pos > 0: + left, right = _decode_range(ranges[pos - 1]) + if left <= int_ < right: + return True + # or we could be immediately behind a tuple (int_, end) + if pos < len(ranges): + left, _ = _decode_range(ranges[pos]) + if left == int_: + return True + return False diff --git a/.venv/lib/python3.13/site-packages/idna/package_data.py b/.venv/lib/python3.13/site-packages/idna/package_data.py new file mode 100644 index 0000000000000000000000000000000000000000..94e40398cda6322e7c348ce8c2c44b80a904e5c7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna/package_data.py @@ -0,0 +1 @@ +__version__ = "3.18" diff --git a/.venv/lib/python3.13/site-packages/idna/py.typed b/.venv/lib/python3.13/site-packages/idna/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/lib/python3.13/site-packages/idna/uts46data.py b/.venv/lib/python3.13/site-packages/idna/uts46data.py new file mode 100644 index 0000000000000000000000000000000000000000..f2d931fe5d23c043a47687c480cffffd069e7aa6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/idna/uts46data.py @@ -0,0 +1,16896 @@ +# This file is automatically generated by tools/idna-data + +from array import array +from typing import Optional + +"""IDNA Mapping Table from UTS46.""" + + +__version__ = "17.0.0" + +uts46_starts: "array[int]" = array( + "I", + ( + 0x0, + 0x1, + 0x2, + 0x3, + 0x4, + 0x5, + 0x6, + 0x7, + 0x8, + 0x9, + 0xA, + 0xB, + 0xC, + 0xD, + 0xE, + 0xF, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1A, + 0x1B, + 0x1C, + 0x1D, + 0x1E, + 0x1F, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + 0x29, + 0x2A, + 0x2B, + 0x2C, + 0x2D, + 0x2E, + 0x2F, + 0x30, + 0x31, + 0x32, + 0x33, + 0x34, + 0x35, + 0x36, + 0x37, + 0x38, + 0x39, + 0x3A, + 0x3B, + 0x3C, + 0x3D, + 0x3E, + 0x3F, + 0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x46, + 0x47, + 0x48, + 0x49, + 0x4A, + 0x4B, + 0x4C, + 0x4D, + 0x4E, + 0x4F, + 0x50, + 0x51, + 0x52, + 0x53, + 0x54, + 0x55, + 0x56, + 0x57, + 0x58, + 0x59, + 0x5A, + 0x5B, + 0x5C, + 0x5D, + 0x5E, + 0x5F, + 0x60, + 0x61, + 0x62, + 0x63, + 0x64, + 0x65, + 0x66, + 0x67, + 0x68, + 0x69, + 0x6A, + 0x6B, + 0x6C, + 0x6D, + 0x6E, + 0x6F, + 0x70, + 0x71, + 0x72, + 0x73, + 0x74, + 0x75, + 0x76, + 0x77, + 0x78, + 0x79, + 0x7A, + 0x7B, + 0x7C, + 0x7D, + 0x7E, + 0x7F, + 0x80, + 0x81, + 0x82, + 0x83, + 0x84, + 0x85, + 0x86, + 0x87, + 0x88, + 0x89, + 0x8A, + 0x8B, + 0x8C, + 0x8D, + 0x8E, + 0x8F, + 0x90, + 0x91, + 0x92, + 0x93, + 0x94, + 0x95, + 0x96, + 0x97, + 0x98, + 0x99, + 0x9A, + 0x9B, + 0x9C, + 0x9D, + 0x9E, + 0x9F, + 0xA0, + 0xA1, + 0xA2, + 0xA3, + 0xA4, + 0xA5, + 0xA6, + 0xA7, + 0xA8, + 0xA9, + 0xAA, + 0xAB, + 0xAC, + 0xAD, + 0xAE, + 0xAF, + 0xB0, + 0xB1, + 0xB2, + 0xB3, + 0xB4, + 0xB5, + 0xB6, + 0xB7, + 0xB8, + 0xB9, + 0xBA, + 0xBB, + 0xBC, + 0xBD, + 0xBE, + 0xBF, + 0xC0, + 0xC1, + 0xC2, + 0xC3, + 0xC4, + 0xC5, + 0xC6, + 0xC7, + 0xC8, + 0xC9, + 0xCA, + 0xCB, + 0xCC, + 0xCD, + 0xCE, + 0xCF, + 0xD0, + 0xD1, + 0xD2, + 0xD3, + 0xD4, + 0xD5, + 0xD6, + 0xD7, + 0xD8, + 0xD9, + 0xDA, + 0xDB, + 0xDC, + 0xDD, + 0xDE, + 0xDF, + 0xE0, + 0xE1, + 0xE2, + 0xE3, + 0xE4, + 0xE5, + 0xE6, + 0xE7, + 0xE8, + 0xE9, + 0xEA, + 0xEB, + 0xEC, + 0xED, + 0xEE, + 0xEF, + 0xF0, + 0xF1, + 0xF2, + 0xF3, + 0xF4, + 0xF5, + 0xF6, + 0xF7, + 0xF8, + 0xF9, + 0xFA, + 0xFB, + 0xFC, + 0xFD, + 0xFE, + 0xFF, + 0x100, + 0x101, + 0x102, + 0x103, + 0x104, + 0x105, + 0x106, + 0x107, + 0x108, + 0x109, + 0x10A, + 0x10B, + 0x10C, + 0x10D, + 0x10E, + 0x10F, + 0x110, + 0x111, + 0x112, + 0x113, + 0x114, + 0x115, + 0x116, + 0x117, + 0x118, + 0x119, + 0x11A, + 0x11B, + 0x11C, + 0x11D, + 0x11E, + 0x11F, + 0x120, + 0x121, + 0x122, + 0x123, + 0x124, + 0x125, + 0x126, + 0x127, + 0x128, + 0x129, + 0x12A, + 0x12B, + 0x12C, + 0x12D, + 0x12E, + 0x12F, + 0x130, + 0x131, + 0x132, + 0x134, + 0x135, + 0x136, + 0x137, + 0x139, + 0x13A, + 0x13B, + 0x13C, + 0x13D, + 0x13E, + 0x13F, + 0x141, + 0x142, + 0x143, + 0x144, + 0x145, + 0x146, + 0x147, + 0x148, + 0x149, + 0x14A, + 0x14B, + 0x14C, + 0x14D, + 0x14E, + 0x14F, + 0x150, + 0x151, + 0x152, + 0x153, + 0x154, + 0x155, + 0x156, + 0x157, + 0x158, + 0x159, + 0x15A, + 0x15B, + 0x15C, + 0x15D, + 0x15E, + 0x15F, + 0x160, + 0x161, + 0x162, + 0x163, + 0x164, + 0x165, + 0x166, + 0x167, + 0x168, + 0x169, + 0x16A, + 0x16B, + 0x16C, + 0x16D, + 0x16E, + 0x16F, + 0x170, + 0x171, + 0x172, + 0x173, + 0x174, + 0x175, + 0x176, + 0x177, + 0x178, + 0x179, + 0x17A, + 0x17B, + 0x17C, + 0x17D, + 0x17E, + 0x17F, + 0x180, + 0x181, + 0x182, + 0x183, + 0x184, + 0x185, + 0x186, + 0x187, + 0x188, + 0x189, + 0x18A, + 0x18B, + 0x18C, + 0x18E, + 0x18F, + 0x190, + 0x191, + 0x192, + 0x193, + 0x194, + 0x195, + 0x196, + 0x197, + 0x198, + 0x199, + 0x19C, + 0x19D, + 0x19E, + 0x19F, + 0x1A0, + 0x1A1, + 0x1A2, + 0x1A3, + 0x1A4, + 0x1A5, + 0x1A6, + 0x1A7, + 0x1A8, + 0x1A9, + 0x1AA, + 0x1AC, + 0x1AD, + 0x1AE, + 0x1AF, + 0x1B0, + 0x1B1, + 0x1B2, + 0x1B3, + 0x1B4, + 0x1B5, + 0x1B6, + 0x1B7, + 0x1B8, + 0x1B9, + 0x1BC, + 0x1BD, + 0x1C4, + 0x1C7, + 0x1CA, + 0x1CD, + 0x1CE, + 0x1CF, + 0x1D0, + 0x1D1, + 0x1D2, + 0x1D3, + 0x1D4, + 0x1D5, + 0x1D6, + 0x1D7, + 0x1D8, + 0x1D9, + 0x1DA, + 0x1DB, + 0x1DC, + 0x1DE, + 0x1DF, + 0x1E0, + 0x1E1, + 0x1E2, + 0x1E3, + 0x1E4, + 0x1E5, + 0x1E6, + 0x1E7, + 0x1E8, + 0x1E9, + 0x1EA, + 0x1EB, + 0x1EC, + 0x1ED, + 0x1EE, + 0x1EF, + 0x1F1, + 0x1F4, + 0x1F5, + 0x1F6, + 0x1F7, + 0x1F8, + 0x1F9, + 0x1FA, + 0x1FB, + 0x1FC, + 0x1FD, + 0x1FE, + 0x1FF, + 0x200, + 0x201, + 0x202, + 0x203, + 0x204, + 0x205, + 0x206, + 0x207, + 0x208, + 0x209, + 0x20A, + 0x20B, + 0x20C, + 0x20D, + 0x20E, + 0x20F, + 0x210, + 0x211, + 0x212, + 0x213, + 0x214, + 0x215, + 0x216, + 0x217, + 0x218, + 0x219, + 0x21A, + 0x21B, + 0x21C, + 0x21D, + 0x21E, + 0x21F, + 0x220, + 0x221, + 0x222, + 0x223, + 0x224, + 0x225, + 0x226, + 0x227, + 0x228, + 0x229, + 0x22A, + 0x22B, + 0x22C, + 0x22D, + 0x22E, + 0x22F, + 0x230, + 0x231, + 0x232, + 0x233, + 0x23A, + 0x23B, + 0x23C, + 0x23D, + 0x23E, + 0x23F, + 0x241, + 0x242, + 0x243, + 0x244, + 0x245, + 0x246, + 0x247, + 0x248, + 0x249, + 0x24A, + 0x24B, + 0x24C, + 0x24D, + 0x24E, + 0x24F, + 0x2B0, + 0x2B1, + 0x2B2, + 0x2B3, + 0x2B4, + 0x2B5, + 0x2B6, + 0x2B7, + 0x2B8, + 0x2B9, + 0x2D8, + 0x2D9, + 0x2DA, + 0x2DB, + 0x2DC, + 0x2DD, + 0x2DE, + 0x2E0, + 0x2E1, + 0x2E2, + 0x2E3, + 0x2E4, + 0x2E5, + 0x340, + 0x341, + 0x342, + 0x343, + 0x344, + 0x345, + 0x346, + 0x34F, + 0x350, + 0x370, + 0x371, + 0x372, + 0x373, + 0x374, + 0x375, + 0x376, + 0x377, + 0x378, + 0x37A, + 0x37B, + 0x37E, + 0x37F, + 0x380, + 0x384, + 0x385, + 0x386, + 0x387, + 0x388, + 0x389, + 0x38A, + 0x38B, + 0x38C, + 0x38D, + 0x38E, + 0x38F, + 0x390, + 0x391, + 0x392, + 0x393, + 0x394, + 0x395, + 0x396, + 0x397, + 0x398, + 0x399, + 0x39A, + 0x39B, + 0x39C, + 0x39D, + 0x39E, + 0x39F, + 0x3A0, + 0x3A1, + 0x3A2, + 0x3A3, + 0x3A4, + 0x3A5, + 0x3A6, + 0x3A7, + 0x3A8, + 0x3A9, + 0x3AA, + 0x3AB, + 0x3AC, + 0x3C2, + 0x3C3, + 0x3CF, + 0x3D0, + 0x3D1, + 0x3D2, + 0x3D3, + 0x3D4, + 0x3D5, + 0x3D6, + 0x3D7, + 0x3D8, + 0x3D9, + 0x3DA, + 0x3DB, + 0x3DC, + 0x3DD, + 0x3DE, + 0x3DF, + 0x3E0, + 0x3E1, + 0x3E2, + 0x3E3, + 0x3E4, + 0x3E5, + 0x3E6, + 0x3E7, + 0x3E8, + 0x3E9, + 0x3EA, + 0x3EB, + 0x3EC, + 0x3ED, + 0x3EE, + 0x3EF, + 0x3F0, + 0x3F1, + 0x3F2, + 0x3F3, + 0x3F4, + 0x3F5, + 0x3F6, + 0x3F7, + 0x3F8, + 0x3F9, + 0x3FA, + 0x3FB, + 0x3FD, + 0x3FE, + 0x3FF, + 0x400, + 0x401, + 0x402, + 0x403, + 0x404, + 0x405, + 0x406, + 0x407, + 0x408, + 0x409, + 0x40A, + 0x40B, + 0x40C, + 0x40D, + 0x40E, + 0x40F, + 0x410, + 0x411, + 0x412, + 0x413, + 0x414, + 0x415, + 0x416, + 0x417, + 0x418, + 0x419, + 0x41A, + 0x41B, + 0x41C, + 0x41D, + 0x41E, + 0x41F, + 0x420, + 0x421, + 0x422, + 0x423, + 0x424, + 0x425, + 0x426, + 0x427, + 0x428, + 0x429, + 0x42A, + 0x42B, + 0x42C, + 0x42D, + 0x42E, + 0x42F, + 0x430, + 0x460, + 0x461, + 0x462, + 0x463, + 0x464, + 0x465, + 0x466, + 0x467, + 0x468, + 0x469, + 0x46A, + 0x46B, + 0x46C, + 0x46D, + 0x46E, + 0x46F, + 0x470, + 0x471, + 0x472, + 0x473, + 0x474, + 0x475, + 0x476, + 0x477, + 0x478, + 0x479, + 0x47A, + 0x47B, + 0x47C, + 0x47D, + 0x47E, + 0x47F, + 0x480, + 0x481, + 0x48A, + 0x48B, + 0x48C, + 0x48D, + 0x48E, + 0x48F, + 0x490, + 0x491, + 0x492, + 0x493, + 0x494, + 0x495, + 0x496, + 0x497, + 0x498, + 0x499, + 0x49A, + 0x49B, + 0x49C, + 0x49D, + 0x49E, + 0x49F, + 0x4A0, + 0x4A1, + 0x4A2, + 0x4A3, + 0x4A4, + 0x4A5, + 0x4A6, + 0x4A7, + 0x4A8, + 0x4A9, + 0x4AA, + 0x4AB, + 0x4AC, + 0x4AD, + 0x4AE, + 0x4AF, + 0x4B0, + 0x4B1, + 0x4B2, + 0x4B3, + 0x4B4, + 0x4B5, + 0x4B6, + 0x4B7, + 0x4B8, + 0x4B9, + 0x4BA, + 0x4BB, + 0x4BC, + 0x4BD, + 0x4BE, + 0x4BF, + 0x4C0, + 0x4C1, + 0x4C2, + 0x4C3, + 0x4C4, + 0x4C5, + 0x4C6, + 0x4C7, + 0x4C8, + 0x4C9, + 0x4CA, + 0x4CB, + 0x4CC, + 0x4CD, + 0x4CE, + 0x4D0, + 0x4D1, + 0x4D2, + 0x4D3, + 0x4D4, + 0x4D5, + 0x4D6, + 0x4D7, + 0x4D8, + 0x4D9, + 0x4DA, + 0x4DB, + 0x4DC, + 0x4DD, + 0x4DE, + 0x4DF, + 0x4E0, + 0x4E1, + 0x4E2, + 0x4E3, + 0x4E4, + 0x4E5, + 0x4E6, + 0x4E7, + 0x4E8, + 0x4E9, + 0x4EA, + 0x4EB, + 0x4EC, + 0x4ED, + 0x4EE, + 0x4EF, + 0x4F0, + 0x4F1, + 0x4F2, + 0x4F3, + 0x4F4, + 0x4F5, + 0x4F6, + 0x4F7, + 0x4F8, + 0x4F9, + 0x4FA, + 0x4FB, + 0x4FC, + 0x4FD, + 0x4FE, + 0x4FF, + 0x500, + 0x501, + 0x502, + 0x503, + 0x504, + 0x505, + 0x506, + 0x507, + 0x508, + 0x509, + 0x50A, + 0x50B, + 0x50C, + 0x50D, + 0x50E, + 0x50F, + 0x510, + 0x511, + 0x512, + 0x513, + 0x514, + 0x515, + 0x516, + 0x517, + 0x518, + 0x519, + 0x51A, + 0x51B, + 0x51C, + 0x51D, + 0x51E, + 0x51F, + 0x520, + 0x521, + 0x522, + 0x523, + 0x524, + 0x525, + 0x526, + 0x527, + 0x528, + 0x529, + 0x52A, + 0x52B, + 0x52C, + 0x52D, + 0x52E, + 0x52F, + 0x530, + 0x531, + 0x532, + 0x533, + 0x534, + 0x535, + 0x536, + 0x537, + 0x538, + 0x539, + 0x53A, + 0x53B, + 0x53C, + 0x53D, + 0x53E, + 0x53F, + 0x540, + 0x541, + 0x542, + 0x543, + 0x544, + 0x545, + 0x546, + 0x547, + 0x548, + 0x549, + 0x54A, + 0x54B, + 0x54C, + 0x54D, + 0x54E, + 0x54F, + 0x550, + 0x551, + 0x552, + 0x553, + 0x554, + 0x555, + 0x556, + 0x557, + 0x559, + 0x587, + 0x588, + 0x58B, + 0x58D, + 0x590, + 0x591, + 0x5C8, + 0x5D0, + 0x5EB, + 0x5EF, + 0x5F5, + 0x606, + 0x61C, + 0x61D, + 0x675, + 0x676, + 0x677, + 0x678, + 0x679, + 0x6DD, + 0x6DE, + 0x70E, + 0x710, + 0x74B, + 0x74D, + 0x7B2, + 0x7C0, + 0x7FB, + 0x7FD, + 0x82E, + 0x830, + 0x83F, + 0x840, + 0x85C, + 0x85E, + 0x85F, + 0x860, + 0x86B, + 0x870, + 0x890, + 0x897, + 0x8E2, + 0x8E3, + 0x958, + 0x959, + 0x95A, + 0x95B, + 0x95C, + 0x95D, + 0x95E, + 0x95F, + 0x960, + 0x984, + 0x985, + 0x98D, + 0x98F, + 0x991, + 0x993, + 0x9A9, + 0x9AA, + 0x9B1, + 0x9B2, + 0x9B3, + 0x9B6, + 0x9BA, + 0x9BC, + 0x9C5, + 0x9C7, + 0x9C9, + 0x9CB, + 0x9CF, + 0x9D7, + 0x9D8, + 0x9DC, + 0x9DD, + 0x9DE, + 0x9DF, + 0x9E0, + 0x9E4, + 0x9E6, + 0x9FF, + 0xA01, + 0xA04, + 0xA05, + 0xA0B, + 0xA0F, + 0xA11, + 0xA13, + 0xA29, + 0xA2A, + 0xA31, + 0xA32, + 0xA33, + 0xA34, + 0xA35, + 0xA36, + 0xA37, + 0xA38, + 0xA3A, + 0xA3C, + 0xA3D, + 0xA3E, + 0xA43, + 0xA47, + 0xA49, + 0xA4B, + 0xA4E, + 0xA51, + 0xA52, + 0xA59, + 0xA5A, + 0xA5B, + 0xA5C, + 0xA5D, + 0xA5E, + 0xA5F, + 0xA66, + 0xA77, + 0xA81, + 0xA84, + 0xA85, + 0xA8E, + 0xA8F, + 0xA92, + 0xA93, + 0xAA9, + 0xAAA, + 0xAB1, + 0xAB2, + 0xAB4, + 0xAB5, + 0xABA, + 0xABC, + 0xAC6, + 0xAC7, + 0xACA, + 0xACB, + 0xACE, + 0xAD0, + 0xAD1, + 0xAE0, + 0xAE4, + 0xAE6, + 0xAF2, + 0xAF9, + 0xB00, + 0xB01, + 0xB04, + 0xB05, + 0xB0D, + 0xB0F, + 0xB11, + 0xB13, + 0xB29, + 0xB2A, + 0xB31, + 0xB32, + 0xB34, + 0xB35, + 0xB3A, + 0xB3C, + 0xB45, + 0xB47, + 0xB49, + 0xB4B, + 0xB4E, + 0xB55, + 0xB58, + 0xB5C, + 0xB5D, + 0xB5E, + 0xB5F, + 0xB64, + 0xB66, + 0xB78, + 0xB82, + 0xB84, + 0xB85, + 0xB8B, + 0xB8E, + 0xB91, + 0xB92, + 0xB96, + 0xB99, + 0xB9B, + 0xB9C, + 0xB9D, + 0xB9E, + 0xBA0, + 0xBA3, + 0xBA5, + 0xBA8, + 0xBAB, + 0xBAE, + 0xBBA, + 0xBBE, + 0xBC3, + 0xBC6, + 0xBC9, + 0xBCA, + 0xBCE, + 0xBD0, + 0xBD1, + 0xBD7, + 0xBD8, + 0xBE6, + 0xBFB, + 0xC00, + 0xC0D, + 0xC0E, + 0xC11, + 0xC12, + 0xC29, + 0xC2A, + 0xC3A, + 0xC3C, + 0xC45, + 0xC46, + 0xC49, + 0xC4A, + 0xC4E, + 0xC55, + 0xC57, + 0xC58, + 0xC5B, + 0xC5C, + 0xC5E, + 0xC60, + 0xC64, + 0xC66, + 0xC70, + 0xC77, + 0xC8D, + 0xC8E, + 0xC91, + 0xC92, + 0xCA9, + 0xCAA, + 0xCB4, + 0xCB5, + 0xCBA, + 0xCBC, + 0xCC5, + 0xCC6, + 0xCC9, + 0xCCA, + 0xCCE, + 0xCD5, + 0xCD7, + 0xCDC, + 0xCDF, + 0xCE0, + 0xCE4, + 0xCE6, + 0xCF0, + 0xCF1, + 0xCF4, + 0xD00, + 0xD0D, + 0xD0E, + 0xD11, + 0xD12, + 0xD45, + 0xD46, + 0xD49, + 0xD4A, + 0xD50, + 0xD54, + 0xD64, + 0xD66, + 0xD80, + 0xD81, + 0xD84, + 0xD85, + 0xD97, + 0xD9A, + 0xDB2, + 0xDB3, + 0xDBC, + 0xDBD, + 0xDBE, + 0xDC0, + 0xDC7, + 0xDCA, + 0xDCB, + 0xDCF, + 0xDD5, + 0xDD6, + 0xDD7, + 0xDD8, + 0xDE0, + 0xDE6, + 0xDF0, + 0xDF2, + 0xDF5, + 0xE01, + 0xE33, + 0xE34, + 0xE3B, + 0xE3F, + 0xE5C, + 0xE81, + 0xE83, + 0xE84, + 0xE85, + 0xE86, + 0xE8B, + 0xE8C, + 0xEA4, + 0xEA5, + 0xEA6, + 0xEA7, + 0xEB3, + 0xEB4, + 0xEBE, + 0xEC0, + 0xEC5, + 0xEC6, + 0xEC7, + 0xEC8, + 0xECF, + 0xED0, + 0xEDA, + 0xEDC, + 0xEDD, + 0xEDE, + 0xEE0, + 0xF00, + 0xF0C, + 0xF0D, + 0xF43, + 0xF44, + 0xF48, + 0xF49, + 0xF4D, + 0xF4E, + 0xF52, + 0xF53, + 0xF57, + 0xF58, + 0xF5C, + 0xF5D, + 0xF69, + 0xF6A, + 0xF6D, + 0xF71, + 0xF73, + 0xF74, + 0xF75, + 0xF76, + 0xF77, + 0xF78, + 0xF79, + 0xF7A, + 0xF81, + 0xF82, + 0xF93, + 0xF94, + 0xF98, + 0xF99, + 0xF9D, + 0xF9E, + 0xFA2, + 0xFA3, + 0xFA7, + 0xFA8, + 0xFAC, + 0xFAD, + 0xFB9, + 0xFBA, + 0xFBD, + 0xFBE, + 0xFCD, + 0xFCE, + 0xFDB, + 0x1000, + 0x10A0, + 0x10A1, + 0x10A2, + 0x10A3, + 0x10A4, + 0x10A5, + 0x10A6, + 0x10A7, + 0x10A8, + 0x10A9, + 0x10AA, + 0x10AB, + 0x10AC, + 0x10AD, + 0x10AE, + 0x10AF, + 0x10B0, + 0x10B1, + 0x10B2, + 0x10B3, + 0x10B4, + 0x10B5, + 0x10B6, + 0x10B7, + 0x10B8, + 0x10B9, + 0x10BA, + 0x10BB, + 0x10BC, + 0x10BD, + 0x10BE, + 0x10BF, + 0x10C0, + 0x10C1, + 0x10C2, + 0x10C3, + 0x10C4, + 0x10C5, + 0x10C6, + 0x10C7, + 0x10C8, + 0x10CD, + 0x10CE, + 0x10D0, + 0x10FC, + 0x10FD, + 0x115F, + 0x1161, + 0x1249, + 0x124A, + 0x124E, + 0x1250, + 0x1257, + 0x1258, + 0x1259, + 0x125A, + 0x125E, + 0x1260, + 0x1289, + 0x128A, + 0x128E, + 0x1290, + 0x12B1, + 0x12B2, + 0x12B6, + 0x12B8, + 0x12BF, + 0x12C0, + 0x12C1, + 0x12C2, + 0x12C6, + 0x12C8, + 0x12D7, + 0x12D8, + 0x1311, + 0x1312, + 0x1316, + 0x1318, + 0x135B, + 0x135D, + 0x137D, + 0x1380, + 0x139A, + 0x13A0, + 0x13F6, + 0x13F8, + 0x13F9, + 0x13FA, + 0x13FB, + 0x13FC, + 0x13FD, + 0x13FE, + 0x1400, + 0x1680, + 0x1681, + 0x169D, + 0x16A0, + 0x16F9, + 0x1700, + 0x1716, + 0x171F, + 0x1737, + 0x1740, + 0x1754, + 0x1760, + 0x176D, + 0x176E, + 0x1771, + 0x1772, + 0x1774, + 0x1780, + 0x17B4, + 0x17B6, + 0x17DE, + 0x17E0, + 0x17EA, + 0x17F0, + 0x17FA, + 0x1800, + 0x180B, + 0x1810, + 0x181A, + 0x1820, + 0x1879, + 0x1880, + 0x18AB, + 0x18B0, + 0x18F6, + 0x1900, + 0x191F, + 0x1920, + 0x192C, + 0x1930, + 0x193C, + 0x1940, + 0x1941, + 0x1944, + 0x196E, + 0x1970, + 0x1975, + 0x1980, + 0x19AC, + 0x19B0, + 0x19CA, + 0x19D0, + 0x19DB, + 0x19DE, + 0x1A1C, + 0x1A1E, + 0x1A5F, + 0x1A60, + 0x1A7D, + 0x1A7F, + 0x1A8A, + 0x1A90, + 0x1A9A, + 0x1AA0, + 0x1AAE, + 0x1AB0, + 0x1ADE, + 0x1AE0, + 0x1AEC, + 0x1B00, + 0x1B4D, + 0x1B4E, + 0x1BF4, + 0x1BFC, + 0x1C38, + 0x1C3B, + 0x1C4A, + 0x1C4D, + 0x1C80, + 0x1C81, + 0x1C82, + 0x1C83, + 0x1C84, + 0x1C86, + 0x1C87, + 0x1C88, + 0x1C89, + 0x1C8A, + 0x1C8B, + 0x1C90, + 0x1C91, + 0x1C92, + 0x1C93, + 0x1C94, + 0x1C95, + 0x1C96, + 0x1C97, + 0x1C98, + 0x1C99, + 0x1C9A, + 0x1C9B, + 0x1C9C, + 0x1C9D, + 0x1C9E, + 0x1C9F, + 0x1CA0, + 0x1CA1, + 0x1CA2, + 0x1CA3, + 0x1CA4, + 0x1CA5, + 0x1CA6, + 0x1CA7, + 0x1CA8, + 0x1CA9, + 0x1CAA, + 0x1CAB, + 0x1CAC, + 0x1CAD, + 0x1CAE, + 0x1CAF, + 0x1CB0, + 0x1CB1, + 0x1CB2, + 0x1CB3, + 0x1CB4, + 0x1CB5, + 0x1CB6, + 0x1CB7, + 0x1CB8, + 0x1CB9, + 0x1CBA, + 0x1CBB, + 0x1CBD, + 0x1CBE, + 0x1CBF, + 0x1CC0, + 0x1CC8, + 0x1CD0, + 0x1CFB, + 0x1D00, + 0x1D2C, + 0x1D2D, + 0x1D2E, + 0x1D2F, + 0x1D30, + 0x1D31, + 0x1D32, + 0x1D33, + 0x1D34, + 0x1D35, + 0x1D36, + 0x1D37, + 0x1D38, + 0x1D39, + 0x1D3A, + 0x1D3B, + 0x1D3C, + 0x1D3D, + 0x1D3E, + 0x1D3F, + 0x1D40, + 0x1D41, + 0x1D42, + 0x1D43, + 0x1D44, + 0x1D45, + 0x1D46, + 0x1D47, + 0x1D48, + 0x1D49, + 0x1D4A, + 0x1D4B, + 0x1D4C, + 0x1D4D, + 0x1D4E, + 0x1D4F, + 0x1D50, + 0x1D51, + 0x1D52, + 0x1D53, + 0x1D54, + 0x1D55, + 0x1D56, + 0x1D57, + 0x1D58, + 0x1D59, + 0x1D5A, + 0x1D5B, + 0x1D5C, + 0x1D5D, + 0x1D5E, + 0x1D5F, + 0x1D60, + 0x1D61, + 0x1D62, + 0x1D63, + 0x1D64, + 0x1D65, + 0x1D66, + 0x1D67, + 0x1D68, + 0x1D69, + 0x1D6A, + 0x1D6B, + 0x1D78, + 0x1D79, + 0x1D9B, + 0x1D9C, + 0x1D9D, + 0x1D9E, + 0x1D9F, + 0x1DA0, + 0x1DA1, + 0x1DA2, + 0x1DA3, + 0x1DA4, + 0x1DA5, + 0x1DA6, + 0x1DA7, + 0x1DA8, + 0x1DA9, + 0x1DAA, + 0x1DAB, + 0x1DAC, + 0x1DAD, + 0x1DAE, + 0x1DAF, + 0x1DB0, + 0x1DB1, + 0x1DB2, + 0x1DB3, + 0x1DB4, + 0x1DB5, + 0x1DB6, + 0x1DB7, + 0x1DB8, + 0x1DB9, + 0x1DBA, + 0x1DBB, + 0x1DBC, + 0x1DBD, + 0x1DBE, + 0x1DBF, + 0x1DC0, + 0x1E00, + 0x1E01, + 0x1E02, + 0x1E03, + 0x1E04, + 0x1E05, + 0x1E06, + 0x1E07, + 0x1E08, + 0x1E09, + 0x1E0A, + 0x1E0B, + 0x1E0C, + 0x1E0D, + 0x1E0E, + 0x1E0F, + 0x1E10, + 0x1E11, + 0x1E12, + 0x1E13, + 0x1E14, + 0x1E15, + 0x1E16, + 0x1E17, + 0x1E18, + 0x1E19, + 0x1E1A, + 0x1E1B, + 0x1E1C, + 0x1E1D, + 0x1E1E, + 0x1E1F, + 0x1E20, + 0x1E21, + 0x1E22, + 0x1E23, + 0x1E24, + 0x1E25, + 0x1E26, + 0x1E27, + 0x1E28, + 0x1E29, + 0x1E2A, + 0x1E2B, + 0x1E2C, + 0x1E2D, + 0x1E2E, + 0x1E2F, + 0x1E30, + 0x1E31, + 0x1E32, + 0x1E33, + 0x1E34, + 0x1E35, + 0x1E36, + 0x1E37, + 0x1E38, + 0x1E39, + 0x1E3A, + 0x1E3B, + 0x1E3C, + 0x1E3D, + 0x1E3E, + 0x1E3F, + 0x1E40, + 0x1E41, + 0x1E42, + 0x1E43, + 0x1E44, + 0x1E45, + 0x1E46, + 0x1E47, + 0x1E48, + 0x1E49, + 0x1E4A, + 0x1E4B, + 0x1E4C, + 0x1E4D, + 0x1E4E, + 0x1E4F, + 0x1E50, + 0x1E51, + 0x1E52, + 0x1E53, + 0x1E54, + 0x1E55, + 0x1E56, + 0x1E57, + 0x1E58, + 0x1E59, + 0x1E5A, + 0x1E5B, + 0x1E5C, + 0x1E5D, + 0x1E5E, + 0x1E5F, + 0x1E60, + 0x1E61, + 0x1E62, + 0x1E63, + 0x1E64, + 0x1E65, + 0x1E66, + 0x1E67, + 0x1E68, + 0x1E69, + 0x1E6A, + 0x1E6B, + 0x1E6C, + 0x1E6D, + 0x1E6E, + 0x1E6F, + 0x1E70, + 0x1E71, + 0x1E72, + 0x1E73, + 0x1E74, + 0x1E75, + 0x1E76, + 0x1E77, + 0x1E78, + 0x1E79, + 0x1E7A, + 0x1E7B, + 0x1E7C, + 0x1E7D, + 0x1E7E, + 0x1E7F, + 0x1E80, + 0x1E81, + 0x1E82, + 0x1E83, + 0x1E84, + 0x1E85, + 0x1E86, + 0x1E87, + 0x1E88, + 0x1E89, + 0x1E8A, + 0x1E8B, + 0x1E8C, + 0x1E8D, + 0x1E8E, + 0x1E8F, + 0x1E90, + 0x1E91, + 0x1E92, + 0x1E93, + 0x1E94, + 0x1E95, + 0x1E9A, + 0x1E9B, + 0x1E9C, + 0x1E9E, + 0x1E9F, + 0x1EA0, + 0x1EA1, + 0x1EA2, + 0x1EA3, + 0x1EA4, + 0x1EA5, + 0x1EA6, + 0x1EA7, + 0x1EA8, + 0x1EA9, + 0x1EAA, + 0x1EAB, + 0x1EAC, + 0x1EAD, + 0x1EAE, + 0x1EAF, + 0x1EB0, + 0x1EB1, + 0x1EB2, + 0x1EB3, + 0x1EB4, + 0x1EB5, + 0x1EB6, + 0x1EB7, + 0x1EB8, + 0x1EB9, + 0x1EBA, + 0x1EBB, + 0x1EBC, + 0x1EBD, + 0x1EBE, + 0x1EBF, + 0x1EC0, + 0x1EC1, + 0x1EC2, + 0x1EC3, + 0x1EC4, + 0x1EC5, + 0x1EC6, + 0x1EC7, + 0x1EC8, + 0x1EC9, + 0x1ECA, + 0x1ECB, + 0x1ECC, + 0x1ECD, + 0x1ECE, + 0x1ECF, + 0x1ED0, + 0x1ED1, + 0x1ED2, + 0x1ED3, + 0x1ED4, + 0x1ED5, + 0x1ED6, + 0x1ED7, + 0x1ED8, + 0x1ED9, + 0x1EDA, + 0x1EDB, + 0x1EDC, + 0x1EDD, + 0x1EDE, + 0x1EDF, + 0x1EE0, + 0x1EE1, + 0x1EE2, + 0x1EE3, + 0x1EE4, + 0x1EE5, + 0x1EE6, + 0x1EE7, + 0x1EE8, + 0x1EE9, + 0x1EEA, + 0x1EEB, + 0x1EEC, + 0x1EED, + 0x1EEE, + 0x1EEF, + 0x1EF0, + 0x1EF1, + 0x1EF2, + 0x1EF3, + 0x1EF4, + 0x1EF5, + 0x1EF6, + 0x1EF7, + 0x1EF8, + 0x1EF9, + 0x1EFA, + 0x1EFB, + 0x1EFC, + 0x1EFD, + 0x1EFE, + 0x1EFF, + 0x1F08, + 0x1F09, + 0x1F0A, + 0x1F0B, + 0x1F0C, + 0x1F0D, + 0x1F0E, + 0x1F0F, + 0x1F10, + 0x1F16, + 0x1F18, + 0x1F19, + 0x1F1A, + 0x1F1B, + 0x1F1C, + 0x1F1D, + 0x1F1E, + 0x1F20, + 0x1F28, + 0x1F29, + 0x1F2A, + 0x1F2B, + 0x1F2C, + 0x1F2D, + 0x1F2E, + 0x1F2F, + 0x1F30, + 0x1F38, + 0x1F39, + 0x1F3A, + 0x1F3B, + 0x1F3C, + 0x1F3D, + 0x1F3E, + 0x1F3F, + 0x1F40, + 0x1F46, + 0x1F48, + 0x1F49, + 0x1F4A, + 0x1F4B, + 0x1F4C, + 0x1F4D, + 0x1F4E, + 0x1F50, + 0x1F58, + 0x1F59, + 0x1F5A, + 0x1F5B, + 0x1F5C, + 0x1F5D, + 0x1F5E, + 0x1F5F, + 0x1F60, + 0x1F68, + 0x1F69, + 0x1F6A, + 0x1F6B, + 0x1F6C, + 0x1F6D, + 0x1F6E, + 0x1F6F, + 0x1F70, + 0x1F71, + 0x1F72, + 0x1F73, + 0x1F74, + 0x1F75, + 0x1F76, + 0x1F77, + 0x1F78, + 0x1F79, + 0x1F7A, + 0x1F7B, + 0x1F7C, + 0x1F7D, + 0x1F7E, + 0x1F80, + 0x1F81, + 0x1F82, + 0x1F83, + 0x1F84, + 0x1F85, + 0x1F86, + 0x1F87, + 0x1F88, + 0x1F89, + 0x1F8A, + 0x1F8B, + 0x1F8C, + 0x1F8D, + 0x1F8E, + 0x1F8F, + 0x1F90, + 0x1F91, + 0x1F92, + 0x1F93, + 0x1F94, + 0x1F95, + 0x1F96, + 0x1F97, + 0x1F98, + 0x1F99, + 0x1F9A, + 0x1F9B, + 0x1F9C, + 0x1F9D, + 0x1F9E, + 0x1F9F, + 0x1FA0, + 0x1FA1, + 0x1FA2, + 0x1FA3, + 0x1FA4, + 0x1FA5, + 0x1FA6, + 0x1FA7, + 0x1FA8, + 0x1FA9, + 0x1FAA, + 0x1FAB, + 0x1FAC, + 0x1FAD, + 0x1FAE, + 0x1FAF, + 0x1FB0, + 0x1FB2, + 0x1FB3, + 0x1FB4, + 0x1FB5, + 0x1FB6, + 0x1FB7, + 0x1FB8, + 0x1FB9, + 0x1FBA, + 0x1FBB, + 0x1FBC, + 0x1FBD, + 0x1FBE, + 0x1FBF, + 0x1FC0, + 0x1FC1, + 0x1FC2, + 0x1FC3, + 0x1FC4, + 0x1FC5, + 0x1FC6, + 0x1FC7, + 0x1FC8, + 0x1FC9, + 0x1FCA, + 0x1FCB, + 0x1FCC, + 0x1FCD, + 0x1FCE, + 0x1FCF, + 0x1FD0, + 0x1FD3, + 0x1FD4, + 0x1FD6, + 0x1FD8, + 0x1FD9, + 0x1FDA, + 0x1FDB, + 0x1FDC, + 0x1FDD, + 0x1FDE, + 0x1FDF, + 0x1FE0, + 0x1FE3, + 0x1FE4, + 0x1FE8, + 0x1FE9, + 0x1FEA, + 0x1FEB, + 0x1FEC, + 0x1FED, + 0x1FEE, + 0x1FEF, + 0x1FF0, + 0x1FF2, + 0x1FF3, + 0x1FF4, + 0x1FF5, + 0x1FF6, + 0x1FF7, + 0x1FF8, + 0x1FF9, + 0x1FFA, + 0x1FFB, + 0x1FFC, + 0x1FFD, + 0x1FFE, + 0x1FFF, + 0x2000, + 0x200B, + 0x200C, + 0x200E, + 0x2010, + 0x2011, + 0x2012, + 0x2017, + 0x2018, + 0x2024, + 0x2027, + 0x2028, + 0x202F, + 0x2030, + 0x2033, + 0x2034, + 0x2035, + 0x2036, + 0x2037, + 0x2038, + 0x203C, + 0x203D, + 0x203E, + 0x203F, + 0x2047, + 0x2048, + 0x2049, + 0x204A, + 0x2057, + 0x2058, + 0x205F, + 0x2060, + 0x2065, + 0x206A, + 0x2070, + 0x2071, + 0x2072, + 0x2074, + 0x2075, + 0x2076, + 0x2077, + 0x2078, + 0x2079, + 0x207A, + 0x207B, + 0x207C, + 0x207D, + 0x207E, + 0x207F, + 0x2080, + 0x2081, + 0x2082, + 0x2083, + 0x2084, + 0x2085, + 0x2086, + 0x2087, + 0x2088, + 0x2089, + 0x208A, + 0x208B, + 0x208C, + 0x208D, + 0x208E, + 0x208F, + 0x2090, + 0x2091, + 0x2092, + 0x2093, + 0x2094, + 0x2095, + 0x2096, + 0x2097, + 0x2098, + 0x2099, + 0x209A, + 0x209B, + 0x209C, + 0x209D, + 0x20A0, + 0x20A8, + 0x20A9, + 0x20C2, + 0x20D0, + 0x20F1, + 0x2100, + 0x2101, + 0x2102, + 0x2103, + 0x2104, + 0x2105, + 0x2106, + 0x2107, + 0x2108, + 0x2109, + 0x210A, + 0x210B, + 0x210F, + 0x2110, + 0x2112, + 0x2114, + 0x2115, + 0x2116, + 0x2117, + 0x2119, + 0x211A, + 0x211B, + 0x211E, + 0x2120, + 0x2121, + 0x2122, + 0x2123, + 0x2124, + 0x2125, + 0x2126, + 0x2127, + 0x2128, + 0x2129, + 0x212A, + 0x212B, + 0x212C, + 0x212D, + 0x212E, + 0x212F, + 0x2131, + 0x2132, + 0x2133, + 0x2134, + 0x2135, + 0x2136, + 0x2137, + 0x2138, + 0x2139, + 0x213A, + 0x213B, + 0x213C, + 0x213D, + 0x213F, + 0x2140, + 0x2141, + 0x2145, + 0x2147, + 0x2148, + 0x2149, + 0x214A, + 0x2150, + 0x2151, + 0x2152, + 0x2153, + 0x2154, + 0x2155, + 0x2156, + 0x2157, + 0x2158, + 0x2159, + 0x215A, + 0x215B, + 0x215C, + 0x215D, + 0x215E, + 0x215F, + 0x2160, + 0x2161, + 0x2162, + 0x2163, + 0x2164, + 0x2165, + 0x2166, + 0x2167, + 0x2168, + 0x2169, + 0x216A, + 0x216B, + 0x216C, + 0x216D, + 0x216E, + 0x216F, + 0x2170, + 0x2171, + 0x2172, + 0x2173, + 0x2174, + 0x2175, + 0x2176, + 0x2177, + 0x2178, + 0x2179, + 0x217A, + 0x217B, + 0x217C, + 0x217D, + 0x217E, + 0x217F, + 0x2180, + 0x2183, + 0x2184, + 0x2189, + 0x218A, + 0x218C, + 0x2190, + 0x222C, + 0x222D, + 0x222E, + 0x222F, + 0x2230, + 0x2231, + 0x2329, + 0x232A, + 0x232B, + 0x242A, + 0x2440, + 0x244B, + 0x2460, + 0x2461, + 0x2462, + 0x2463, + 0x2464, + 0x2465, + 0x2466, + 0x2467, + 0x2468, + 0x2469, + 0x246A, + 0x246B, + 0x246C, + 0x246D, + 0x246E, + 0x246F, + 0x2470, + 0x2471, + 0x2472, + 0x2473, + 0x2474, + 0x2475, + 0x2476, + 0x2477, + 0x2478, + 0x2479, + 0x247A, + 0x247B, + 0x247C, + 0x247D, + 0x247E, + 0x247F, + 0x2480, + 0x2481, + 0x2482, + 0x2483, + 0x2484, + 0x2485, + 0x2486, + 0x2487, + 0x2488, + 0x249C, + 0x249D, + 0x249E, + 0x249F, + 0x24A0, + 0x24A1, + 0x24A2, + 0x24A3, + 0x24A4, + 0x24A5, + 0x24A6, + 0x24A7, + 0x24A8, + 0x24A9, + 0x24AA, + 0x24AB, + 0x24AC, + 0x24AD, + 0x24AE, + 0x24AF, + 0x24B0, + 0x24B1, + 0x24B2, + 0x24B3, + 0x24B4, + 0x24B5, + 0x24B6, + 0x24B7, + 0x24B8, + 0x24B9, + 0x24BA, + 0x24BB, + 0x24BC, + 0x24BD, + 0x24BE, + 0x24BF, + 0x24C0, + 0x24C1, + 0x24C2, + 0x24C3, + 0x24C4, + 0x24C5, + 0x24C6, + 0x24C7, + 0x24C8, + 0x24C9, + 0x24CA, + 0x24CB, + 0x24CC, + 0x24CD, + 0x24CE, + 0x24CF, + 0x24D0, + 0x24D1, + 0x24D2, + 0x24D3, + 0x24D4, + 0x24D5, + 0x24D6, + 0x24D7, + 0x24D8, + 0x24D9, + 0x24DA, + 0x24DB, + 0x24DC, + 0x24DD, + 0x24DE, + 0x24DF, + 0x24E0, + 0x24E1, + 0x24E2, + 0x24E3, + 0x24E4, + 0x24E5, + 0x24E6, + 0x24E7, + 0x24E8, + 0x24E9, + 0x24EA, + 0x24EB, + 0x2A0C, + 0x2A0D, + 0x2A74, + 0x2A75, + 0x2A76, + 0x2A77, + 0x2ADC, + 0x2ADD, + 0x2B74, + 0x2B76, + 0x2C00, + 0x2C01, + 0x2C02, + 0x2C03, + 0x2C04, + 0x2C05, + 0x2C06, + 0x2C07, + 0x2C08, + 0x2C09, + 0x2C0A, + 0x2C0B, + 0x2C0C, + 0x2C0D, + 0x2C0E, + 0x2C0F, + 0x2C10, + 0x2C11, + 0x2C12, + 0x2C13, + 0x2C14, + 0x2C15, + 0x2C16, + 0x2C17, + 0x2C18, + 0x2C19, + 0x2C1A, + 0x2C1B, + 0x2C1C, + 0x2C1D, + 0x2C1E, + 0x2C1F, + 0x2C20, + 0x2C21, + 0x2C22, + 0x2C23, + 0x2C24, + 0x2C25, + 0x2C26, + 0x2C27, + 0x2C28, + 0x2C29, + 0x2C2A, + 0x2C2B, + 0x2C2C, + 0x2C2D, + 0x2C2E, + 0x2C2F, + 0x2C30, + 0x2C60, + 0x2C61, + 0x2C62, + 0x2C63, + 0x2C64, + 0x2C65, + 0x2C67, + 0x2C68, + 0x2C69, + 0x2C6A, + 0x2C6B, + 0x2C6C, + 0x2C6D, + 0x2C6E, + 0x2C6F, + 0x2C70, + 0x2C71, + 0x2C72, + 0x2C73, + 0x2C75, + 0x2C76, + 0x2C7C, + 0x2C7D, + 0x2C7E, + 0x2C7F, + 0x2C80, + 0x2C81, + 0x2C82, + 0x2C83, + 0x2C84, + 0x2C85, + 0x2C86, + 0x2C87, + 0x2C88, + 0x2C89, + 0x2C8A, + 0x2C8B, + 0x2C8C, + 0x2C8D, + 0x2C8E, + 0x2C8F, + 0x2C90, + 0x2C91, + 0x2C92, + 0x2C93, + 0x2C94, + 0x2C95, + 0x2C96, + 0x2C97, + 0x2C98, + 0x2C99, + 0x2C9A, + 0x2C9B, + 0x2C9C, + 0x2C9D, + 0x2C9E, + 0x2C9F, + 0x2CA0, + 0x2CA1, + 0x2CA2, + 0x2CA3, + 0x2CA4, + 0x2CA5, + 0x2CA6, + 0x2CA7, + 0x2CA8, + 0x2CA9, + 0x2CAA, + 0x2CAB, + 0x2CAC, + 0x2CAD, + 0x2CAE, + 0x2CAF, + 0x2CB0, + 0x2CB1, + 0x2CB2, + 0x2CB3, + 0x2CB4, + 0x2CB5, + 0x2CB6, + 0x2CB7, + 0x2CB8, + 0x2CB9, + 0x2CBA, + 0x2CBB, + 0x2CBC, + 0x2CBD, + 0x2CBE, + 0x2CBF, + 0x2CC0, + 0x2CC1, + 0x2CC2, + 0x2CC3, + 0x2CC4, + 0x2CC5, + 0x2CC6, + 0x2CC7, + 0x2CC8, + 0x2CC9, + 0x2CCA, + 0x2CCB, + 0x2CCC, + 0x2CCD, + 0x2CCE, + 0x2CCF, + 0x2CD0, + 0x2CD1, + 0x2CD2, + 0x2CD3, + 0x2CD4, + 0x2CD5, + 0x2CD6, + 0x2CD7, + 0x2CD8, + 0x2CD9, + 0x2CDA, + 0x2CDB, + 0x2CDC, + 0x2CDD, + 0x2CDE, + 0x2CDF, + 0x2CE0, + 0x2CE1, + 0x2CE2, + 0x2CE3, + 0x2CEB, + 0x2CEC, + 0x2CED, + 0x2CEE, + 0x2CF2, + 0x2CF3, + 0x2CF4, + 0x2CF9, + 0x2D26, + 0x2D27, + 0x2D28, + 0x2D2D, + 0x2D2E, + 0x2D30, + 0x2D68, + 0x2D6F, + 0x2D70, + 0x2D71, + 0x2D7F, + 0x2D97, + 0x2DA0, + 0x2DA7, + 0x2DA8, + 0x2DAF, + 0x2DB0, + 0x2DB7, + 0x2DB8, + 0x2DBF, + 0x2DC0, + 0x2DC7, + 0x2DC8, + 0x2DCF, + 0x2DD0, + 0x2DD7, + 0x2DD8, + 0x2DDF, + 0x2DE0, + 0x2E5E, + 0x2E80, + 0x2E9A, + 0x2E9B, + 0x2E9F, + 0x2EA0, + 0x2EF3, + 0x2EF4, + 0x2F00, + 0x2F01, + 0x2F02, + 0x2F03, + 0x2F04, + 0x2F05, + 0x2F06, + 0x2F07, + 0x2F08, + 0x2F09, + 0x2F0A, + 0x2F0B, + 0x2F0C, + 0x2F0D, + 0x2F0E, + 0x2F0F, + 0x2F10, + 0x2F11, + 0x2F12, + 0x2F13, + 0x2F14, + 0x2F15, + 0x2F16, + 0x2F17, + 0x2F18, + 0x2F19, + 0x2F1A, + 0x2F1B, + 0x2F1C, + 0x2F1D, + 0x2F1E, + 0x2F1F, + 0x2F20, + 0x2F21, + 0x2F22, + 0x2F23, + 0x2F24, + 0x2F25, + 0x2F26, + 0x2F27, + 0x2F28, + 0x2F29, + 0x2F2A, + 0x2F2B, + 0x2F2C, + 0x2F2D, + 0x2F2E, + 0x2F2F, + 0x2F30, + 0x2F31, + 0x2F32, + 0x2F33, + 0x2F34, + 0x2F35, + 0x2F36, + 0x2F37, + 0x2F38, + 0x2F39, + 0x2F3A, + 0x2F3B, + 0x2F3C, + 0x2F3D, + 0x2F3E, + 0x2F3F, + 0x2F40, + 0x2F41, + 0x2F42, + 0x2F43, + 0x2F44, + 0x2F45, + 0x2F46, + 0x2F47, + 0x2F48, + 0x2F49, + 0x2F4A, + 0x2F4B, + 0x2F4C, + 0x2F4D, + 0x2F4E, + 0x2F4F, + 0x2F50, + 0x2F51, + 0x2F52, + 0x2F53, + 0x2F54, + 0x2F55, + 0x2F56, + 0x2F57, + 0x2F58, + 0x2F59, + 0x2F5A, + 0x2F5B, + 0x2F5C, + 0x2F5D, + 0x2F5E, + 0x2F5F, + 0x2F60, + 0x2F61, + 0x2F62, + 0x2F63, + 0x2F64, + 0x2F65, + 0x2F66, + 0x2F67, + 0x2F68, + 0x2F69, + 0x2F6A, + 0x2F6B, + 0x2F6C, + 0x2F6D, + 0x2F6E, + 0x2F6F, + 0x2F70, + 0x2F71, + 0x2F72, + 0x2F73, + 0x2F74, + 0x2F75, + 0x2F76, + 0x2F77, + 0x2F78, + 0x2F79, + 0x2F7A, + 0x2F7B, + 0x2F7C, + 0x2F7D, + 0x2F7E, + 0x2F7F, + 0x2F80, + 0x2F81, + 0x2F82, + 0x2F83, + 0x2F84, + 0x2F85, + 0x2F86, + 0x2F87, + 0x2F88, + 0x2F89, + 0x2F8A, + 0x2F8B, + 0x2F8C, + 0x2F8D, + 0x2F8E, + 0x2F8F, + 0x2F90, + 0x2F91, + 0x2F92, + 0x2F93, + 0x2F94, + 0x2F95, + 0x2F96, + 0x2F97, + 0x2F98, + 0x2F99, + 0x2F9A, + 0x2F9B, + 0x2F9C, + 0x2F9D, + 0x2F9E, + 0x2F9F, + 0x2FA0, + 0x2FA1, + 0x2FA2, + 0x2FA3, + 0x2FA4, + 0x2FA5, + 0x2FA6, + 0x2FA7, + 0x2FA8, + 0x2FA9, + 0x2FAA, + 0x2FAB, + 0x2FAC, + 0x2FAD, + 0x2FAE, + 0x2FAF, + 0x2FB0, + 0x2FB1, + 0x2FB2, + 0x2FB3, + 0x2FB4, + 0x2FB5, + 0x2FB6, + 0x2FB7, + 0x2FB8, + 0x2FB9, + 0x2FBA, + 0x2FBB, + 0x2FBC, + 0x2FBD, + 0x2FBE, + 0x2FBF, + 0x2FC0, + 0x2FC1, + 0x2FC2, + 0x2FC3, + 0x2FC4, + 0x2FC5, + 0x2FC6, + 0x2FC7, + 0x2FC8, + 0x2FC9, + 0x2FCA, + 0x2FCB, + 0x2FCC, + 0x2FCD, + 0x2FCE, + 0x2FCF, + 0x2FD0, + 0x2FD1, + 0x2FD2, + 0x2FD3, + 0x2FD4, + 0x2FD5, + 0x2FD6, + 0x3000, + 0x3001, + 0x3002, + 0x3003, + 0x3036, + 0x3037, + 0x3038, + 0x3039, + 0x303A, + 0x303B, + 0x3040, + 0x3041, + 0x3097, + 0x3099, + 0x309B, + 0x309C, + 0x309D, + 0x309F, + 0x30A0, + 0x30FF, + 0x3100, + 0x3105, + 0x3130, + 0x3131, + 0x3132, + 0x3133, + 0x3134, + 0x3135, + 0x3136, + 0x3137, + 0x3138, + 0x3139, + 0x313A, + 0x313B, + 0x313C, + 0x313D, + 0x313E, + 0x313F, + 0x3140, + 0x3141, + 0x3142, + 0x3143, + 0x3144, + 0x3145, + 0x3146, + 0x3147, + 0x3148, + 0x3149, + 0x314A, + 0x314B, + 0x314C, + 0x314D, + 0x314E, + 0x314F, + 0x3150, + 0x3151, + 0x3152, + 0x3153, + 0x3154, + 0x3155, + 0x3156, + 0x3157, + 0x3158, + 0x3159, + 0x315A, + 0x315B, + 0x315C, + 0x315D, + 0x315E, + 0x315F, + 0x3160, + 0x3161, + 0x3162, + 0x3163, + 0x3164, + 0x3165, + 0x3166, + 0x3167, + 0x3168, + 0x3169, + 0x316A, + 0x316B, + 0x316C, + 0x316D, + 0x316E, + 0x316F, + 0x3170, + 0x3171, + 0x3172, + 0x3173, + 0x3174, + 0x3175, + 0x3176, + 0x3177, + 0x3178, + 0x3179, + 0x317A, + 0x317B, + 0x317C, + 0x317D, + 0x317E, + 0x317F, + 0x3180, + 0x3181, + 0x3182, + 0x3183, + 0x3184, + 0x3185, + 0x3186, + 0x3187, + 0x3188, + 0x3189, + 0x318A, + 0x318B, + 0x318C, + 0x318D, + 0x318E, + 0x318F, + 0x3190, + 0x3192, + 0x3193, + 0x3194, + 0x3195, + 0x3196, + 0x3197, + 0x3198, + 0x3199, + 0x319A, + 0x319B, + 0x319C, + 0x319D, + 0x319E, + 0x319F, + 0x31A0, + 0x31E6, + 0x31F0, + 0x3200, + 0x3201, + 0x3202, + 0x3203, + 0x3204, + 0x3205, + 0x3206, + 0x3207, + 0x3208, + 0x3209, + 0x320A, + 0x320B, + 0x320C, + 0x320D, + 0x320E, + 0x320F, + 0x3210, + 0x3211, + 0x3212, + 0x3213, + 0x3214, + 0x3215, + 0x3216, + 0x3217, + 0x3218, + 0x3219, + 0x321A, + 0x321B, + 0x321C, + 0x321D, + 0x321E, + 0x321F, + 0x3220, + 0x3221, + 0x3222, + 0x3223, + 0x3224, + 0x3225, + 0x3226, + 0x3227, + 0x3228, + 0x3229, + 0x322A, + 0x322B, + 0x322C, + 0x322D, + 0x322E, + 0x322F, + 0x3230, + 0x3231, + 0x3232, + 0x3233, + 0x3234, + 0x3235, + 0x3236, + 0x3237, + 0x3238, + 0x3239, + 0x323A, + 0x323B, + 0x323C, + 0x323D, + 0x323E, + 0x323F, + 0x3240, + 0x3241, + 0x3242, + 0x3243, + 0x3244, + 0x3245, + 0x3246, + 0x3247, + 0x3248, + 0x3250, + 0x3251, + 0x3252, + 0x3253, + 0x3254, + 0x3255, + 0x3256, + 0x3257, + 0x3258, + 0x3259, + 0x325A, + 0x325B, + 0x325C, + 0x325D, + 0x325E, + 0x325F, + 0x3260, + 0x3261, + 0x3262, + 0x3263, + 0x3264, + 0x3265, + 0x3266, + 0x3267, + 0x3268, + 0x3269, + 0x326A, + 0x326B, + 0x326C, + 0x326D, + 0x326E, + 0x326F, + 0x3270, + 0x3271, + 0x3272, + 0x3273, + 0x3274, + 0x3275, + 0x3276, + 0x3277, + 0x3278, + 0x3279, + 0x327A, + 0x327B, + 0x327C, + 0x327D, + 0x327E, + 0x327F, + 0x3280, + 0x3281, + 0x3282, + 0x3283, + 0x3284, + 0x3285, + 0x3286, + 0x3287, + 0x3288, + 0x3289, + 0x328A, + 0x328B, + 0x328C, + 0x328D, + 0x328E, + 0x328F, + 0x3290, + 0x3291, + 0x3292, + 0x3293, + 0x3294, + 0x3295, + 0x3296, + 0x3297, + 0x3298, + 0x3299, + 0x329A, + 0x329B, + 0x329C, + 0x329D, + 0x329E, + 0x329F, + 0x32A0, + 0x32A1, + 0x32A2, + 0x32A3, + 0x32A4, + 0x32A5, + 0x32A6, + 0x32A7, + 0x32A8, + 0x32A9, + 0x32AA, + 0x32AB, + 0x32AC, + 0x32AD, + 0x32AE, + 0x32AF, + 0x32B0, + 0x32B1, + 0x32B2, + 0x32B3, + 0x32B4, + 0x32B5, + 0x32B6, + 0x32B7, + 0x32B8, + 0x32B9, + 0x32BA, + 0x32BB, + 0x32BC, + 0x32BD, + 0x32BE, + 0x32BF, + 0x32C0, + 0x32C1, + 0x32C2, + 0x32C3, + 0x32C4, + 0x32C5, + 0x32C6, + 0x32C7, + 0x32C8, + 0x32C9, + 0x32CA, + 0x32CB, + 0x32CC, + 0x32CD, + 0x32CE, + 0x32CF, + 0x32D0, + 0x32D1, + 0x32D2, + 0x32D3, + 0x32D4, + 0x32D5, + 0x32D6, + 0x32D7, + 0x32D8, + 0x32D9, + 0x32DA, + 0x32DB, + 0x32DC, + 0x32DD, + 0x32DE, + 0x32DF, + 0x32E0, + 0x32E1, + 0x32E2, + 0x32E3, + 0x32E4, + 0x32E5, + 0x32E6, + 0x32E7, + 0x32E8, + 0x32E9, + 0x32EA, + 0x32EB, + 0x32EC, + 0x32ED, + 0x32EE, + 0x32EF, + 0x32F0, + 0x32F1, + 0x32F2, + 0x32F3, + 0x32F4, + 0x32F5, + 0x32F6, + 0x32F7, + 0x32F8, + 0x32F9, + 0x32FA, + 0x32FB, + 0x32FC, + 0x32FD, + 0x32FE, + 0x32FF, + 0x3300, + 0x3301, + 0x3302, + 0x3303, + 0x3304, + 0x3305, + 0x3306, + 0x3307, + 0x3308, + 0x3309, + 0x330A, + 0x330B, + 0x330C, + 0x330D, + 0x330E, + 0x330F, + 0x3310, + 0x3311, + 0x3312, + 0x3313, + 0x3314, + 0x3315, + 0x3316, + 0x3317, + 0x3318, + 0x3319, + 0x331A, + 0x331B, + 0x331C, + 0x331D, + 0x331E, + 0x331F, + 0x3320, + 0x3321, + 0x3322, + 0x3323, + 0x3324, + 0x3325, + 0x3326, + 0x3327, + 0x3328, + 0x3329, + 0x332A, + 0x332B, + 0x332C, + 0x332D, + 0x332E, + 0x332F, + 0x3330, + 0x3331, + 0x3332, + 0x3333, + 0x3334, + 0x3335, + 0x3336, + 0x3337, + 0x3338, + 0x3339, + 0x333A, + 0x333B, + 0x333C, + 0x333D, + 0x333E, + 0x333F, + 0x3340, + 0x3341, + 0x3342, + 0x3343, + 0x3344, + 0x3345, + 0x3346, + 0x3347, + 0x3348, + 0x3349, + 0x334A, + 0x334B, + 0x334C, + 0x334D, + 0x334E, + 0x334F, + 0x3350, + 0x3351, + 0x3352, + 0x3353, + 0x3354, + 0x3355, + 0x3356, + 0x3357, + 0x3358, + 0x3359, + 0x335A, + 0x335B, + 0x335C, + 0x335D, + 0x335E, + 0x335F, + 0x3360, + 0x3361, + 0x3362, + 0x3363, + 0x3364, + 0x3365, + 0x3366, + 0x3367, + 0x3368, + 0x3369, + 0x336A, + 0x336B, + 0x336C, + 0x336D, + 0x336E, + 0x336F, + 0x3370, + 0x3371, + 0x3372, + 0x3373, + 0x3374, + 0x3375, + 0x3376, + 0x3377, + 0x3378, + 0x3379, + 0x337A, + 0x337B, + 0x337C, + 0x337D, + 0x337E, + 0x337F, + 0x3380, + 0x3381, + 0x3382, + 0x3383, + 0x3384, + 0x3385, + 0x3386, + 0x3387, + 0x3388, + 0x3389, + 0x338A, + 0x338B, + 0x338C, + 0x338D, + 0x338E, + 0x338F, + 0x3390, + 0x3391, + 0x3392, + 0x3393, + 0x3394, + 0x3395, + 0x3396, + 0x3397, + 0x3398, + 0x3399, + 0x339A, + 0x339B, + 0x339C, + 0x339D, + 0x339E, + 0x339F, + 0x33A0, + 0x33A1, + 0x33A2, + 0x33A3, + 0x33A4, + 0x33A5, + 0x33A6, + 0x33A7, + 0x33A8, + 0x33A9, + 0x33AA, + 0x33AB, + 0x33AC, + 0x33AD, + 0x33AE, + 0x33AF, + 0x33B0, + 0x33B1, + 0x33B2, + 0x33B3, + 0x33B4, + 0x33B5, + 0x33B6, + 0x33B7, + 0x33B8, + 0x33B9, + 0x33BA, + 0x33BB, + 0x33BC, + 0x33BD, + 0x33BE, + 0x33BF, + 0x33C0, + 0x33C1, + 0x33C2, + 0x33C3, + 0x33C4, + 0x33C5, + 0x33C6, + 0x33C7, + 0x33C8, + 0x33C9, + 0x33CA, + 0x33CB, + 0x33CC, + 0x33CD, + 0x33CE, + 0x33CF, + 0x33D0, + 0x33D1, + 0x33D2, + 0x33D3, + 0x33D4, + 0x33D5, + 0x33D6, + 0x33D7, + 0x33D8, + 0x33D9, + 0x33DA, + 0x33DB, + 0x33DC, + 0x33DD, + 0x33DE, + 0x33DF, + 0x33E0, + 0x33E1, + 0x33E2, + 0x33E3, + 0x33E4, + 0x33E5, + 0x33E6, + 0x33E7, + 0x33E8, + 0x33E9, + 0x33EA, + 0x33EB, + 0x33EC, + 0x33ED, + 0x33EE, + 0x33EF, + 0x33F0, + 0x33F1, + 0x33F2, + 0x33F3, + 0x33F4, + 0x33F5, + 0x33F6, + 0x33F7, + 0x33F8, + 0x33F9, + 0x33FA, + 0x33FB, + 0x33FC, + 0x33FD, + 0x33FE, + 0x33FF, + 0x3400, + 0xA48D, + 0xA490, + 0xA4C7, + 0xA4D0, + 0xA62C, + 0xA640, + 0xA641, + 0xA642, + 0xA643, + 0xA644, + 0xA645, + 0xA646, + 0xA647, + 0xA648, + 0xA649, + 0xA64A, + 0xA64B, + 0xA64C, + 0xA64D, + 0xA64E, + 0xA64F, + 0xA650, + 0xA651, + 0xA652, + 0xA653, + 0xA654, + 0xA655, + 0xA656, + 0xA657, + 0xA658, + 0xA659, + 0xA65A, + 0xA65B, + 0xA65C, + 0xA65D, + 0xA65E, + 0xA65F, + 0xA660, + 0xA661, + 0xA662, + 0xA663, + 0xA664, + 0xA665, + 0xA666, + 0xA667, + 0xA668, + 0xA669, + 0xA66A, + 0xA66B, + 0xA66C, + 0xA66D, + 0xA680, + 0xA681, + 0xA682, + 0xA683, + 0xA684, + 0xA685, + 0xA686, + 0xA687, + 0xA688, + 0xA689, + 0xA68A, + 0xA68B, + 0xA68C, + 0xA68D, + 0xA68E, + 0xA68F, + 0xA690, + 0xA691, + 0xA692, + 0xA693, + 0xA694, + 0xA695, + 0xA696, + 0xA697, + 0xA698, + 0xA699, + 0xA69A, + 0xA69B, + 0xA69C, + 0xA69D, + 0xA69E, + 0xA6F8, + 0xA700, + 0xA722, + 0xA723, + 0xA724, + 0xA725, + 0xA726, + 0xA727, + 0xA728, + 0xA729, + 0xA72A, + 0xA72B, + 0xA72C, + 0xA72D, + 0xA72E, + 0xA72F, + 0xA732, + 0xA733, + 0xA734, + 0xA735, + 0xA736, + 0xA737, + 0xA738, + 0xA739, + 0xA73A, + 0xA73B, + 0xA73C, + 0xA73D, + 0xA73E, + 0xA73F, + 0xA740, + 0xA741, + 0xA742, + 0xA743, + 0xA744, + 0xA745, + 0xA746, + 0xA747, + 0xA748, + 0xA749, + 0xA74A, + 0xA74B, + 0xA74C, + 0xA74D, + 0xA74E, + 0xA74F, + 0xA750, + 0xA751, + 0xA752, + 0xA753, + 0xA754, + 0xA755, + 0xA756, + 0xA757, + 0xA758, + 0xA759, + 0xA75A, + 0xA75B, + 0xA75C, + 0xA75D, + 0xA75E, + 0xA75F, + 0xA760, + 0xA761, + 0xA762, + 0xA763, + 0xA764, + 0xA765, + 0xA766, + 0xA767, + 0xA768, + 0xA769, + 0xA76A, + 0xA76B, + 0xA76C, + 0xA76D, + 0xA76E, + 0xA76F, + 0xA770, + 0xA771, + 0xA779, + 0xA77A, + 0xA77B, + 0xA77C, + 0xA77D, + 0xA77E, + 0xA77F, + 0xA780, + 0xA781, + 0xA782, + 0xA783, + 0xA784, + 0xA785, + 0xA786, + 0xA787, + 0xA78B, + 0xA78C, + 0xA78D, + 0xA78E, + 0xA790, + 0xA791, + 0xA792, + 0xA793, + 0xA796, + 0xA797, + 0xA798, + 0xA799, + 0xA79A, + 0xA79B, + 0xA79C, + 0xA79D, + 0xA79E, + 0xA79F, + 0xA7A0, + 0xA7A1, + 0xA7A2, + 0xA7A3, + 0xA7A4, + 0xA7A5, + 0xA7A6, + 0xA7A7, + 0xA7A8, + 0xA7A9, + 0xA7AA, + 0xA7AB, + 0xA7AC, + 0xA7AD, + 0xA7AE, + 0xA7AF, + 0xA7B0, + 0xA7B1, + 0xA7B2, + 0xA7B3, + 0xA7B4, + 0xA7B5, + 0xA7B6, + 0xA7B7, + 0xA7B8, + 0xA7B9, + 0xA7BA, + 0xA7BB, + 0xA7BC, + 0xA7BD, + 0xA7BE, + 0xA7BF, + 0xA7C0, + 0xA7C1, + 0xA7C2, + 0xA7C3, + 0xA7C4, + 0xA7C5, + 0xA7C6, + 0xA7C7, + 0xA7C8, + 0xA7C9, + 0xA7CA, + 0xA7CB, + 0xA7CC, + 0xA7CD, + 0xA7CE, + 0xA7CF, + 0xA7D0, + 0xA7D1, + 0xA7D2, + 0xA7D3, + 0xA7D4, + 0xA7D5, + 0xA7D6, + 0xA7D7, + 0xA7D8, + 0xA7D9, + 0xA7DA, + 0xA7DB, + 0xA7DC, + 0xA7DD, + 0xA7F1, + 0xA7F2, + 0xA7F3, + 0xA7F4, + 0xA7F5, + 0xA7F6, + 0xA7F8, + 0xA7F9, + 0xA7FA, + 0xA82D, + 0xA830, + 0xA83A, + 0xA840, + 0xA878, + 0xA880, + 0xA8C6, + 0xA8CE, + 0xA8DA, + 0xA8E0, + 0xA954, + 0xA95F, + 0xA97D, + 0xA980, + 0xA9CE, + 0xA9CF, + 0xA9DA, + 0xA9DE, + 0xA9FF, + 0xAA00, + 0xAA37, + 0xAA40, + 0xAA4E, + 0xAA50, + 0xAA5A, + 0xAA5C, + 0xAAC3, + 0xAADB, + 0xAAF7, + 0xAB01, + 0xAB07, + 0xAB09, + 0xAB0F, + 0xAB11, + 0xAB17, + 0xAB20, + 0xAB27, + 0xAB28, + 0xAB2F, + 0xAB30, + 0xAB5C, + 0xAB5D, + 0xAB5E, + 0xAB5F, + 0xAB60, + 0xAB69, + 0xAB6A, + 0xAB6C, + 0xAB70, + 0xAB71, + 0xAB72, + 0xAB73, + 0xAB74, + 0xAB75, + 0xAB76, + 0xAB77, + 0xAB78, + 0xAB79, + 0xAB7A, + 0xAB7B, + 0xAB7C, + 0xAB7D, + 0xAB7E, + 0xAB7F, + 0xAB80, + 0xAB81, + 0xAB82, + 0xAB83, + 0xAB84, + 0xAB85, + 0xAB86, + 0xAB87, + 0xAB88, + 0xAB89, + 0xAB8A, + 0xAB8B, + 0xAB8C, + 0xAB8D, + 0xAB8E, + 0xAB8F, + 0xAB90, + 0xAB91, + 0xAB92, + 0xAB93, + 0xAB94, + 0xAB95, + 0xAB96, + 0xAB97, + 0xAB98, + 0xAB99, + 0xAB9A, + 0xAB9B, + 0xAB9C, + 0xAB9D, + 0xAB9E, + 0xAB9F, + 0xABA0, + 0xABA1, + 0xABA2, + 0xABA3, + 0xABA4, + 0xABA5, + 0xABA6, + 0xABA7, + 0xABA8, + 0xABA9, + 0xABAA, + 0xABAB, + 0xABAC, + 0xABAD, + 0xABAE, + 0xABAF, + 0xABB0, + 0xABB1, + 0xABB2, + 0xABB3, + 0xABB4, + 0xABB5, + 0xABB6, + 0xABB7, + 0xABB8, + 0xABB9, + 0xABBA, + 0xABBB, + 0xABBC, + 0xABBD, + 0xABBE, + 0xABBF, + 0xABC0, + 0xABEE, + 0xABF0, + 0xABFA, + 0xAC00, + 0xD7A4, + 0xD7B0, + 0xD7C7, + 0xD7CB, + 0xD7FC, + 0xF900, + 0xF901, + 0xF902, + 0xF903, + 0xF904, + 0xF905, + 0xF906, + 0xF907, + 0xF909, + 0xF90A, + 0xF90B, + 0xF90C, + 0xF90D, + 0xF90E, + 0xF90F, + 0xF910, + 0xF911, + 0xF912, + 0xF913, + 0xF914, + 0xF915, + 0xF916, + 0xF917, + 0xF918, + 0xF919, + 0xF91A, + 0xF91B, + 0xF91C, + 0xF91D, + 0xF91E, + 0xF91F, + 0xF920, + 0xF921, + 0xF922, + 0xF923, + 0xF924, + 0xF925, + 0xF926, + 0xF927, + 0xF928, + 0xF929, + 0xF92A, + 0xF92B, + 0xF92C, + 0xF92D, + 0xF92E, + 0xF92F, + 0xF930, + 0xF931, + 0xF932, + 0xF933, + 0xF934, + 0xF935, + 0xF936, + 0xF937, + 0xF938, + 0xF939, + 0xF93A, + 0xF93B, + 0xF93C, + 0xF93D, + 0xF93E, + 0xF93F, + 0xF940, + 0xF941, + 0xF942, + 0xF943, + 0xF944, + 0xF945, + 0xF946, + 0xF947, + 0xF948, + 0xF949, + 0xF94A, + 0xF94B, + 0xF94C, + 0xF94D, + 0xF94E, + 0xF94F, + 0xF950, + 0xF951, + 0xF952, + 0xF953, + 0xF954, + 0xF955, + 0xF956, + 0xF957, + 0xF958, + 0xF959, + 0xF95A, + 0xF95B, + 0xF95C, + 0xF95D, + 0xF95E, + 0xF95F, + 0xF960, + 0xF961, + 0xF962, + 0xF963, + 0xF964, + 0xF965, + 0xF966, + 0xF967, + 0xF968, + 0xF969, + 0xF96A, + 0xF96B, + 0xF96C, + 0xF96D, + 0xF96E, + 0xF96F, + 0xF970, + 0xF971, + 0xF972, + 0xF973, + 0xF974, + 0xF975, + 0xF976, + 0xF977, + 0xF978, + 0xF979, + 0xF97A, + 0xF97B, + 0xF97C, + 0xF97D, + 0xF97E, + 0xF97F, + 0xF980, + 0xF981, + 0xF982, + 0xF983, + 0xF984, + 0xF985, + 0xF986, + 0xF987, + 0xF988, + 0xF989, + 0xF98A, + 0xF98B, + 0xF98C, + 0xF98D, + 0xF98E, + 0xF98F, + 0xF990, + 0xF991, + 0xF992, + 0xF993, + 0xF994, + 0xF995, + 0xF996, + 0xF997, + 0xF998, + 0xF999, + 0xF99A, + 0xF99B, + 0xF99C, + 0xF99D, + 0xF99E, + 0xF99F, + 0xF9A0, + 0xF9A1, + 0xF9A2, + 0xF9A3, + 0xF9A4, + 0xF9A5, + 0xF9A6, + 0xF9A7, + 0xF9A8, + 0xF9A9, + 0xF9AA, + 0xF9AB, + 0xF9AC, + 0xF9AD, + 0xF9AE, + 0xF9AF, + 0xF9B0, + 0xF9B1, + 0xF9B2, + 0xF9B3, + 0xF9B4, + 0xF9B5, + 0xF9B6, + 0xF9B7, + 0xF9B8, + 0xF9B9, + 0xF9BA, + 0xF9BB, + 0xF9BC, + 0xF9BD, + 0xF9BE, + 0xF9BF, + 0xF9C0, + 0xF9C1, + 0xF9C2, + 0xF9C3, + 0xF9C4, + 0xF9C5, + 0xF9C6, + 0xF9C7, + 0xF9C8, + 0xF9C9, + 0xF9CA, + 0xF9CB, + 0xF9CC, + 0xF9CD, + 0xF9CE, + 0xF9CF, + 0xF9D0, + 0xF9D1, + 0xF9D2, + 0xF9D3, + 0xF9D4, + 0xF9D5, + 0xF9D6, + 0xF9D7, + 0xF9D8, + 0xF9D9, + 0xF9DA, + 0xF9DB, + 0xF9DC, + 0xF9DD, + 0xF9DE, + 0xF9DF, + 0xF9E0, + 0xF9E1, + 0xF9E2, + 0xF9E3, + 0xF9E4, + 0xF9E5, + 0xF9E6, + 0xF9E7, + 0xF9E8, + 0xF9E9, + 0xF9EA, + 0xF9EB, + 0xF9EC, + 0xF9ED, + 0xF9EE, + 0xF9EF, + 0xF9F0, + 0xF9F1, + 0xF9F2, + 0xF9F3, + 0xF9F4, + 0xF9F5, + 0xF9F6, + 0xF9F7, + 0xF9F8, + 0xF9F9, + 0xF9FA, + 0xF9FB, + 0xF9FC, + 0xF9FD, + 0xF9FE, + 0xF9FF, + 0xFA00, + 0xFA01, + 0xFA02, + 0xFA03, + 0xFA04, + 0xFA05, + 0xFA06, + 0xFA07, + 0xFA08, + 0xFA09, + 0xFA0A, + 0xFA0B, + 0xFA0C, + 0xFA0D, + 0xFA0E, + 0xFA10, + 0xFA11, + 0xFA12, + 0xFA13, + 0xFA15, + 0xFA16, + 0xFA17, + 0xFA18, + 0xFA19, + 0xFA1A, + 0xFA1B, + 0xFA1C, + 0xFA1D, + 0xFA1E, + 0xFA1F, + 0xFA20, + 0xFA21, + 0xFA22, + 0xFA23, + 0xFA25, + 0xFA26, + 0xFA27, + 0xFA2A, + 0xFA2B, + 0xFA2C, + 0xFA2D, + 0xFA2E, + 0xFA2F, + 0xFA30, + 0xFA31, + 0xFA32, + 0xFA33, + 0xFA34, + 0xFA35, + 0xFA36, + 0xFA37, + 0xFA38, + 0xFA39, + 0xFA3A, + 0xFA3B, + 0xFA3C, + 0xFA3D, + 0xFA3E, + 0xFA3F, + 0xFA40, + 0xFA41, + 0xFA42, + 0xFA43, + 0xFA44, + 0xFA45, + 0xFA46, + 0xFA47, + 0xFA48, + 0xFA49, + 0xFA4A, + 0xFA4B, + 0xFA4C, + 0xFA4D, + 0xFA4E, + 0xFA4F, + 0xFA50, + 0xFA51, + 0xFA52, + 0xFA53, + 0xFA54, + 0xFA55, + 0xFA56, + 0xFA57, + 0xFA58, + 0xFA59, + 0xFA5A, + 0xFA5B, + 0xFA5C, + 0xFA5D, + 0xFA5F, + 0xFA60, + 0xFA61, + 0xFA62, + 0xFA63, + 0xFA64, + 0xFA65, + 0xFA66, + 0xFA67, + 0xFA68, + 0xFA69, + 0xFA6A, + 0xFA6B, + 0xFA6C, + 0xFA6D, + 0xFA6E, + 0xFA70, + 0xFA71, + 0xFA72, + 0xFA73, + 0xFA74, + 0xFA75, + 0xFA76, + 0xFA77, + 0xFA78, + 0xFA79, + 0xFA7A, + 0xFA7B, + 0xFA7C, + 0xFA7D, + 0xFA7E, + 0xFA7F, + 0xFA80, + 0xFA81, + 0xFA82, + 0xFA83, + 0xFA84, + 0xFA85, + 0xFA86, + 0xFA87, + 0xFA88, + 0xFA89, + 0xFA8A, + 0xFA8B, + 0xFA8C, + 0xFA8D, + 0xFA8E, + 0xFA8F, + 0xFA90, + 0xFA91, + 0xFA92, + 0xFA93, + 0xFA94, + 0xFA95, + 0xFA96, + 0xFA97, + 0xFA98, + 0xFA99, + 0xFA9A, + 0xFA9B, + 0xFA9C, + 0xFA9D, + 0xFA9E, + 0xFA9F, + 0xFAA0, + 0xFAA1, + 0xFAA2, + 0xFAA3, + 0xFAA4, + 0xFAA5, + 0xFAA6, + 0xFAA7, + 0xFAA8, + 0xFAA9, + 0xFAAA, + 0xFAAB, + 0xFAAC, + 0xFAAD, + 0xFAAE, + 0xFAAF, + 0xFAB0, + 0xFAB1, + 0xFAB2, + 0xFAB3, + 0xFAB4, + 0xFAB5, + 0xFAB6, + 0xFAB7, + 0xFAB8, + 0xFAB9, + 0xFABA, + 0xFABB, + 0xFABC, + 0xFABD, + 0xFABE, + 0xFABF, + 0xFAC0, + 0xFAC1, + 0xFAC2, + 0xFAC3, + 0xFAC4, + 0xFAC5, + 0xFAC6, + 0xFAC7, + 0xFAC8, + 0xFAC9, + 0xFACA, + 0xFACB, + 0xFACC, + 0xFACD, + 0xFACE, + 0xFACF, + 0xFAD0, + 0xFAD1, + 0xFAD2, + 0xFAD3, + 0xFAD4, + 0xFAD5, + 0xFAD6, + 0xFAD7, + 0xFAD8, + 0xFAD9, + 0xFADA, + 0xFB00, + 0xFB01, + 0xFB02, + 0xFB03, + 0xFB04, + 0xFB05, + 0xFB07, + 0xFB13, + 0xFB14, + 0xFB15, + 0xFB16, + 0xFB17, + 0xFB18, + 0xFB1D, + 0xFB1E, + 0xFB1F, + 0xFB20, + 0xFB21, + 0xFB22, + 0xFB23, + 0xFB24, + 0xFB25, + 0xFB26, + 0xFB27, + 0xFB28, + 0xFB29, + 0xFB2A, + 0xFB2B, + 0xFB2C, + 0xFB2D, + 0xFB2E, + 0xFB2F, + 0xFB30, + 0xFB31, + 0xFB32, + 0xFB33, + 0xFB34, + 0xFB35, + 0xFB36, + 0xFB37, + 0xFB38, + 0xFB39, + 0xFB3A, + 0xFB3B, + 0xFB3C, + 0xFB3D, + 0xFB3E, + 0xFB3F, + 0xFB40, + 0xFB41, + 0xFB42, + 0xFB43, + 0xFB44, + 0xFB45, + 0xFB46, + 0xFB47, + 0xFB48, + 0xFB49, + 0xFB4A, + 0xFB4B, + 0xFB4C, + 0xFB4D, + 0xFB4E, + 0xFB4F, + 0xFB50, + 0xFB52, + 0xFB56, + 0xFB5A, + 0xFB5E, + 0xFB62, + 0xFB66, + 0xFB6A, + 0xFB6E, + 0xFB72, + 0xFB76, + 0xFB7A, + 0xFB7E, + 0xFB82, + 0xFB84, + 0xFB86, + 0xFB88, + 0xFB8A, + 0xFB8C, + 0xFB8E, + 0xFB92, + 0xFB96, + 0xFB9A, + 0xFB9E, + 0xFBA0, + 0xFBA4, + 0xFBA6, + 0xFBAA, + 0xFBAE, + 0xFBB0, + 0xFBB2, + 0xFBD3, + 0xFBD7, + 0xFBD9, + 0xFBDB, + 0xFBDD, + 0xFBDE, + 0xFBE0, + 0xFBE2, + 0xFBE4, + 0xFBE8, + 0xFBEA, + 0xFBEC, + 0xFBEE, + 0xFBF0, + 0xFBF2, + 0xFBF4, + 0xFBF6, + 0xFBF9, + 0xFBFC, + 0xFC00, + 0xFC01, + 0xFC02, + 0xFC03, + 0xFC04, + 0xFC05, + 0xFC06, + 0xFC07, + 0xFC08, + 0xFC09, + 0xFC0A, + 0xFC0B, + 0xFC0C, + 0xFC0D, + 0xFC0E, + 0xFC0F, + 0xFC10, + 0xFC11, + 0xFC12, + 0xFC13, + 0xFC14, + 0xFC15, + 0xFC16, + 0xFC17, + 0xFC18, + 0xFC19, + 0xFC1A, + 0xFC1B, + 0xFC1C, + 0xFC1D, + 0xFC1E, + 0xFC1F, + 0xFC20, + 0xFC21, + 0xFC22, + 0xFC23, + 0xFC24, + 0xFC25, + 0xFC26, + 0xFC27, + 0xFC28, + 0xFC29, + 0xFC2A, + 0xFC2B, + 0xFC2C, + 0xFC2D, + 0xFC2E, + 0xFC2F, + 0xFC30, + 0xFC31, + 0xFC32, + 0xFC33, + 0xFC34, + 0xFC35, + 0xFC36, + 0xFC37, + 0xFC38, + 0xFC39, + 0xFC3A, + 0xFC3B, + 0xFC3C, + 0xFC3D, + 0xFC3E, + 0xFC3F, + 0xFC40, + 0xFC41, + 0xFC42, + 0xFC43, + 0xFC44, + 0xFC45, + 0xFC46, + 0xFC47, + 0xFC48, + 0xFC49, + 0xFC4A, + 0xFC4B, + 0xFC4C, + 0xFC4D, + 0xFC4E, + 0xFC4F, + 0xFC50, + 0xFC51, + 0xFC52, + 0xFC53, + 0xFC54, + 0xFC55, + 0xFC56, + 0xFC57, + 0xFC58, + 0xFC59, + 0xFC5A, + 0xFC5B, + 0xFC5C, + 0xFC5D, + 0xFC5E, + 0xFC5F, + 0xFC60, + 0xFC61, + 0xFC62, + 0xFC63, + 0xFC64, + 0xFC65, + 0xFC66, + 0xFC67, + 0xFC68, + 0xFC69, + 0xFC6A, + 0xFC6B, + 0xFC6C, + 0xFC6D, + 0xFC6E, + 0xFC6F, + 0xFC70, + 0xFC71, + 0xFC72, + 0xFC73, + 0xFC74, + 0xFC75, + 0xFC76, + 0xFC77, + 0xFC78, + 0xFC79, + 0xFC7A, + 0xFC7B, + 0xFC7C, + 0xFC7D, + 0xFC7E, + 0xFC7F, + 0xFC80, + 0xFC81, + 0xFC82, + 0xFC83, + 0xFC84, + 0xFC85, + 0xFC86, + 0xFC87, + 0xFC88, + 0xFC89, + 0xFC8A, + 0xFC8B, + 0xFC8C, + 0xFC8D, + 0xFC8E, + 0xFC8F, + 0xFC90, + 0xFC91, + 0xFC92, + 0xFC93, + 0xFC94, + 0xFC95, + 0xFC96, + 0xFC97, + 0xFC98, + 0xFC99, + 0xFC9A, + 0xFC9B, + 0xFC9C, + 0xFC9D, + 0xFC9E, + 0xFC9F, + 0xFCA0, + 0xFCA1, + 0xFCA2, + 0xFCA3, + 0xFCA4, + 0xFCA5, + 0xFCA6, + 0xFCA7, + 0xFCA8, + 0xFCA9, + 0xFCAA, + 0xFCAB, + 0xFCAC, + 0xFCAD, + 0xFCAE, + 0xFCAF, + 0xFCB0, + 0xFCB1, + 0xFCB2, + 0xFCB3, + 0xFCB4, + 0xFCB5, + 0xFCB6, + 0xFCB7, + 0xFCB8, + 0xFCB9, + 0xFCBA, + 0xFCBB, + 0xFCBC, + 0xFCBD, + 0xFCBE, + 0xFCBF, + 0xFCC0, + 0xFCC1, + 0xFCC2, + 0xFCC3, + 0xFCC4, + 0xFCC5, + 0xFCC6, + 0xFCC7, + 0xFCC8, + 0xFCC9, + 0xFCCA, + 0xFCCB, + 0xFCCC, + 0xFCCD, + 0xFCCE, + 0xFCCF, + 0xFCD0, + 0xFCD1, + 0xFCD2, + 0xFCD3, + 0xFCD4, + 0xFCD5, + 0xFCD6, + 0xFCD7, + 0xFCD8, + 0xFCD9, + 0xFCDA, + 0xFCDB, + 0xFCDC, + 0xFCDD, + 0xFCDE, + 0xFCDF, + 0xFCE0, + 0xFCE1, + 0xFCE2, + 0xFCE3, + 0xFCE4, + 0xFCE5, + 0xFCE6, + 0xFCE7, + 0xFCE8, + 0xFCE9, + 0xFCEA, + 0xFCEB, + 0xFCEC, + 0xFCED, + 0xFCEE, + 0xFCEF, + 0xFCF0, + 0xFCF1, + 0xFCF2, + 0xFCF3, + 0xFCF4, + 0xFCF5, + 0xFCF6, + 0xFCF7, + 0xFCF8, + 0xFCF9, + 0xFCFA, + 0xFCFB, + 0xFCFC, + 0xFCFD, + 0xFCFE, + 0xFCFF, + 0xFD00, + 0xFD01, + 0xFD02, + 0xFD03, + 0xFD04, + 0xFD05, + 0xFD06, + 0xFD07, + 0xFD08, + 0xFD09, + 0xFD0A, + 0xFD0B, + 0xFD0C, + 0xFD0D, + 0xFD0E, + 0xFD0F, + 0xFD10, + 0xFD11, + 0xFD12, + 0xFD13, + 0xFD14, + 0xFD15, + 0xFD16, + 0xFD17, + 0xFD18, + 0xFD19, + 0xFD1A, + 0xFD1B, + 0xFD1C, + 0xFD1D, + 0xFD1E, + 0xFD1F, + 0xFD20, + 0xFD21, + 0xFD22, + 0xFD23, + 0xFD24, + 0xFD25, + 0xFD26, + 0xFD27, + 0xFD28, + 0xFD29, + 0xFD2A, + 0xFD2B, + 0xFD2C, + 0xFD2D, + 0xFD2E, + 0xFD2F, + 0xFD30, + 0xFD31, + 0xFD32, + 0xFD33, + 0xFD34, + 0xFD35, + 0xFD36, + 0xFD37, + 0xFD38, + 0xFD39, + 0xFD3A, + 0xFD3B, + 0xFD3C, + 0xFD3E, + 0xFD50, + 0xFD51, + 0xFD53, + 0xFD54, + 0xFD55, + 0xFD56, + 0xFD57, + 0xFD58, + 0xFD5A, + 0xFD5B, + 0xFD5C, + 0xFD5D, + 0xFD5E, + 0xFD5F, + 0xFD61, + 0xFD62, + 0xFD64, + 0xFD66, + 0xFD67, + 0xFD69, + 0xFD6A, + 0xFD6C, + 0xFD6E, + 0xFD6F, + 0xFD71, + 0xFD73, + 0xFD74, + 0xFD75, + 0xFD76, + 0xFD78, + 0xFD79, + 0xFD7A, + 0xFD7B, + 0xFD7C, + 0xFD7E, + 0xFD7F, + 0xFD80, + 0xFD81, + 0xFD82, + 0xFD83, + 0xFD85, + 0xFD87, + 0xFD89, + 0xFD8A, + 0xFD8B, + 0xFD8C, + 0xFD8D, + 0xFD8E, + 0xFD8F, + 0xFD90, + 0xFD92, + 0xFD93, + 0xFD94, + 0xFD95, + 0xFD96, + 0xFD97, + 0xFD99, + 0xFD9A, + 0xFD9B, + 0xFD9C, + 0xFD9E, + 0xFD9F, + 0xFDA0, + 0xFDA1, + 0xFDA2, + 0xFDA3, + 0xFDA4, + 0xFDA5, + 0xFDA6, + 0xFDA7, + 0xFDA8, + 0xFDA9, + 0xFDAA, + 0xFDAB, + 0xFDAC, + 0xFDAD, + 0xFDAE, + 0xFDAF, + 0xFDB0, + 0xFDB1, + 0xFDB2, + 0xFDB3, + 0xFDB4, + 0xFDB5, + 0xFDB6, + 0xFDB7, + 0xFDB8, + 0xFDB9, + 0xFDBA, + 0xFDBB, + 0xFDBC, + 0xFDBD, + 0xFDBE, + 0xFDBF, + 0xFDC0, + 0xFDC1, + 0xFDC2, + 0xFDC3, + 0xFDC4, + 0xFDC5, + 0xFDC6, + 0xFDC7, + 0xFDC8, + 0xFDD0, + 0xFDF0, + 0xFDF1, + 0xFDF2, + 0xFDF3, + 0xFDF4, + 0xFDF5, + 0xFDF6, + 0xFDF7, + 0xFDF8, + 0xFDF9, + 0xFDFA, + 0xFDFB, + 0xFDFC, + 0xFDFD, + 0xFE00, + 0xFE10, + 0xFE11, + 0xFE12, + 0xFE13, + 0xFE14, + 0xFE15, + 0xFE16, + 0xFE17, + 0xFE18, + 0xFE19, + 0xFE20, + 0xFE30, + 0xFE31, + 0xFE32, + 0xFE33, + 0xFE35, + 0xFE36, + 0xFE37, + 0xFE38, + 0xFE39, + 0xFE3A, + 0xFE3B, + 0xFE3C, + 0xFE3D, + 0xFE3E, + 0xFE3F, + 0xFE40, + 0xFE41, + 0xFE42, + 0xFE43, + 0xFE44, + 0xFE45, + 0xFE47, + 0xFE48, + 0xFE49, + 0xFE4D, + 0xFE50, + 0xFE51, + 0xFE52, + 0xFE54, + 0xFE55, + 0xFE56, + 0xFE57, + 0xFE58, + 0xFE59, + 0xFE5A, + 0xFE5B, + 0xFE5C, + 0xFE5D, + 0xFE5E, + 0xFE5F, + 0xFE60, + 0xFE61, + 0xFE62, + 0xFE63, + 0xFE64, + 0xFE65, + 0xFE66, + 0xFE67, + 0xFE68, + 0xFE69, + 0xFE6A, + 0xFE6B, + 0xFE6C, + 0xFE70, + 0xFE71, + 0xFE72, + 0xFE73, + 0xFE74, + 0xFE75, + 0xFE76, + 0xFE77, + 0xFE78, + 0xFE79, + 0xFE7A, + 0xFE7B, + 0xFE7C, + 0xFE7D, + 0xFE7E, + 0xFE7F, + 0xFE80, + 0xFE81, + 0xFE83, + 0xFE85, + 0xFE87, + 0xFE89, + 0xFE8D, + 0xFE8F, + 0xFE93, + 0xFE95, + 0xFE99, + 0xFE9D, + 0xFEA1, + 0xFEA5, + 0xFEA9, + 0xFEAB, + 0xFEAD, + 0xFEAF, + 0xFEB1, + 0xFEB5, + 0xFEB9, + 0xFEBD, + 0xFEC1, + 0xFEC5, + 0xFEC9, + 0xFECD, + 0xFED1, + 0xFED5, + 0xFED9, + 0xFEDD, + 0xFEE1, + 0xFEE5, + 0xFEE9, + 0xFEED, + 0xFEEF, + 0xFEF1, + 0xFEF5, + 0xFEF7, + 0xFEF9, + 0xFEFB, + 0xFEFD, + 0xFEFF, + 0xFF00, + 0xFF01, + 0xFF02, + 0xFF03, + 0xFF04, + 0xFF05, + 0xFF06, + 0xFF07, + 0xFF08, + 0xFF09, + 0xFF0A, + 0xFF0B, + 0xFF0C, + 0xFF0D, + 0xFF0E, + 0xFF0F, + 0xFF10, + 0xFF11, + 0xFF12, + 0xFF13, + 0xFF14, + 0xFF15, + 0xFF16, + 0xFF17, + 0xFF18, + 0xFF19, + 0xFF1A, + 0xFF1B, + 0xFF1C, + 0xFF1D, + 0xFF1E, + 0xFF1F, + 0xFF20, + 0xFF21, + 0xFF22, + 0xFF23, + 0xFF24, + 0xFF25, + 0xFF26, + 0xFF27, + 0xFF28, + 0xFF29, + 0xFF2A, + 0xFF2B, + 0xFF2C, + 0xFF2D, + 0xFF2E, + 0xFF2F, + 0xFF30, + 0xFF31, + 0xFF32, + 0xFF33, + 0xFF34, + 0xFF35, + 0xFF36, + 0xFF37, + 0xFF38, + 0xFF39, + 0xFF3A, + 0xFF3B, + 0xFF3C, + 0xFF3D, + 0xFF3E, + 0xFF3F, + 0xFF40, + 0xFF41, + 0xFF42, + 0xFF43, + 0xFF44, + 0xFF45, + 0xFF46, + 0xFF47, + 0xFF48, + 0xFF49, + 0xFF4A, + 0xFF4B, + 0xFF4C, + 0xFF4D, + 0xFF4E, + 0xFF4F, + 0xFF50, + 0xFF51, + 0xFF52, + 0xFF53, + 0xFF54, + 0xFF55, + 0xFF56, + 0xFF57, + 0xFF58, + 0xFF59, + 0xFF5A, + 0xFF5B, + 0xFF5C, + 0xFF5D, + 0xFF5E, + 0xFF5F, + 0xFF60, + 0xFF61, + 0xFF62, + 0xFF63, + 0xFF64, + 0xFF65, + 0xFF66, + 0xFF67, + 0xFF68, + 0xFF69, + 0xFF6A, + 0xFF6B, + 0xFF6C, + 0xFF6D, + 0xFF6E, + 0xFF6F, + 0xFF70, + 0xFF71, + 0xFF72, + 0xFF73, + 0xFF74, + 0xFF75, + 0xFF76, + 0xFF77, + 0xFF78, + 0xFF79, + 0xFF7A, + 0xFF7B, + 0xFF7C, + 0xFF7D, + 0xFF7E, + 0xFF7F, + 0xFF80, + 0xFF81, + 0xFF82, + 0xFF83, + 0xFF84, + 0xFF85, + 0xFF86, + 0xFF87, + 0xFF88, + 0xFF89, + 0xFF8A, + 0xFF8B, + 0xFF8C, + 0xFF8D, + 0xFF8E, + 0xFF8F, + 0xFF90, + 0xFF91, + 0xFF92, + 0xFF93, + 0xFF94, + 0xFF95, + 0xFF96, + 0xFF97, + 0xFF98, + 0xFF99, + 0xFF9A, + 0xFF9B, + 0xFF9C, + 0xFF9D, + 0xFF9E, + 0xFF9F, + 0xFFA0, + 0xFFA1, + 0xFFA2, + 0xFFA3, + 0xFFA4, + 0xFFA5, + 0xFFA6, + 0xFFA7, + 0xFFA8, + 0xFFA9, + 0xFFAA, + 0xFFAB, + 0xFFAC, + 0xFFAD, + 0xFFAE, + 0xFFAF, + 0xFFB0, + 0xFFB1, + 0xFFB2, + 0xFFB3, + 0xFFB4, + 0xFFB5, + 0xFFB6, + 0xFFB7, + 0xFFB8, + 0xFFB9, + 0xFFBA, + 0xFFBB, + 0xFFBC, + 0xFFBD, + 0xFFBE, + 0xFFBF, + 0xFFC2, + 0xFFC3, + 0xFFC4, + 0xFFC5, + 0xFFC6, + 0xFFC7, + 0xFFC8, + 0xFFCA, + 0xFFCB, + 0xFFCC, + 0xFFCD, + 0xFFCE, + 0xFFCF, + 0xFFD0, + 0xFFD2, + 0xFFD3, + 0xFFD4, + 0xFFD5, + 0xFFD6, + 0xFFD7, + 0xFFD8, + 0xFFDA, + 0xFFDB, + 0xFFDC, + 0xFFDD, + 0xFFE0, + 0xFFE1, + 0xFFE2, + 0xFFE3, + 0xFFE4, + 0xFFE5, + 0xFFE6, + 0xFFE7, + 0xFFE8, + 0xFFE9, + 0xFFEA, + 0xFFEB, + 0xFFEC, + 0xFFED, + 0xFFEE, + 0xFFEF, + 0x10000, + 0x1000C, + 0x1000D, + 0x10027, + 0x10028, + 0x1003B, + 0x1003C, + 0x1003E, + 0x1003F, + 0x1004E, + 0x10050, + 0x1005E, + 0x10080, + 0x100FB, + 0x10100, + 0x10103, + 0x10107, + 0x10134, + 0x10137, + 0x1018F, + 0x10190, + 0x1019D, + 0x101A0, + 0x101A1, + 0x101D0, + 0x101FE, + 0x10280, + 0x1029D, + 0x102A0, + 0x102D1, + 0x102E0, + 0x102FC, + 0x10300, + 0x10324, + 0x1032D, + 0x1034B, + 0x10350, + 0x1037B, + 0x10380, + 0x1039E, + 0x1039F, + 0x103C4, + 0x103C8, + 0x103D6, + 0x10400, + 0x10401, + 0x10402, + 0x10403, + 0x10404, + 0x10405, + 0x10406, + 0x10407, + 0x10408, + 0x10409, + 0x1040A, + 0x1040B, + 0x1040C, + 0x1040D, + 0x1040E, + 0x1040F, + 0x10410, + 0x10411, + 0x10412, + 0x10413, + 0x10414, + 0x10415, + 0x10416, + 0x10417, + 0x10418, + 0x10419, + 0x1041A, + 0x1041B, + 0x1041C, + 0x1041D, + 0x1041E, + 0x1041F, + 0x10420, + 0x10421, + 0x10422, + 0x10423, + 0x10424, + 0x10425, + 0x10426, + 0x10427, + 0x10428, + 0x1049E, + 0x104A0, + 0x104AA, + 0x104B0, + 0x104B1, + 0x104B2, + 0x104B3, + 0x104B4, + 0x104B5, + 0x104B6, + 0x104B7, + 0x104B8, + 0x104B9, + 0x104BA, + 0x104BB, + 0x104BC, + 0x104BD, + 0x104BE, + 0x104BF, + 0x104C0, + 0x104C1, + 0x104C2, + 0x104C3, + 0x104C4, + 0x104C5, + 0x104C6, + 0x104C7, + 0x104C8, + 0x104C9, + 0x104CA, + 0x104CB, + 0x104CC, + 0x104CD, + 0x104CE, + 0x104CF, + 0x104D0, + 0x104D1, + 0x104D2, + 0x104D3, + 0x104D4, + 0x104D8, + 0x104FC, + 0x10500, + 0x10528, + 0x10530, + 0x10564, + 0x1056F, + 0x10570, + 0x10571, + 0x10572, + 0x10573, + 0x10574, + 0x10575, + 0x10576, + 0x10577, + 0x10578, + 0x10579, + 0x1057A, + 0x1057B, + 0x1057C, + 0x1057D, + 0x1057E, + 0x1057F, + 0x10580, + 0x10581, + 0x10582, + 0x10583, + 0x10584, + 0x10585, + 0x10586, + 0x10587, + 0x10588, + 0x10589, + 0x1058A, + 0x1058B, + 0x1058C, + 0x1058D, + 0x1058E, + 0x1058F, + 0x10590, + 0x10591, + 0x10592, + 0x10593, + 0x10594, + 0x10595, + 0x10596, + 0x10597, + 0x105A2, + 0x105A3, + 0x105B2, + 0x105B3, + 0x105BA, + 0x105BB, + 0x105BD, + 0x105C0, + 0x105F4, + 0x10600, + 0x10737, + 0x10740, + 0x10756, + 0x10760, + 0x10768, + 0x10780, + 0x10781, + 0x10782, + 0x10783, + 0x10784, + 0x10785, + 0x10786, + 0x10787, + 0x10788, + 0x10789, + 0x1078A, + 0x1078B, + 0x1078C, + 0x1078D, + 0x1078E, + 0x1078F, + 0x10790, + 0x10791, + 0x10792, + 0x10793, + 0x10794, + 0x10795, + 0x10796, + 0x10797, + 0x10798, + 0x10799, + 0x1079A, + 0x1079B, + 0x1079C, + 0x1079D, + 0x1079E, + 0x1079F, + 0x107A0, + 0x107A1, + 0x107A2, + 0x107A3, + 0x107A4, + 0x107A5, + 0x107A6, + 0x107A7, + 0x107A8, + 0x107A9, + 0x107AA, + 0x107AB, + 0x107AC, + 0x107AD, + 0x107AE, + 0x107AF, + 0x107B0, + 0x107B1, + 0x107B2, + 0x107B3, + 0x107B4, + 0x107B5, + 0x107B6, + 0x107B7, + 0x107B8, + 0x107B9, + 0x107BA, + 0x107BB, + 0x10800, + 0x10806, + 0x10808, + 0x10809, + 0x1080A, + 0x10836, + 0x10837, + 0x10839, + 0x1083C, + 0x1083D, + 0x1083F, + 0x10856, + 0x10857, + 0x1089F, + 0x108A7, + 0x108B0, + 0x108E0, + 0x108F3, + 0x108F4, + 0x108F6, + 0x108FB, + 0x1091C, + 0x1091F, + 0x1093A, + 0x1093F, + 0x1095A, + 0x10980, + 0x109B8, + 0x109BC, + 0x109D0, + 0x109D2, + 0x10A04, + 0x10A05, + 0x10A07, + 0x10A0C, + 0x10A14, + 0x10A15, + 0x10A18, + 0x10A19, + 0x10A36, + 0x10A38, + 0x10A3B, + 0x10A3F, + 0x10A49, + 0x10A50, + 0x10A59, + 0x10A60, + 0x10AA0, + 0x10AC0, + 0x10AE7, + 0x10AEB, + 0x10AF7, + 0x10B00, + 0x10B36, + 0x10B39, + 0x10B56, + 0x10B58, + 0x10B73, + 0x10B78, + 0x10B92, + 0x10B99, + 0x10B9D, + 0x10BA9, + 0x10BB0, + 0x10C00, + 0x10C49, + 0x10C80, + 0x10C81, + 0x10C82, + 0x10C83, + 0x10C84, + 0x10C85, + 0x10C86, + 0x10C87, + 0x10C88, + 0x10C89, + 0x10C8A, + 0x10C8B, + 0x10C8C, + 0x10C8D, + 0x10C8E, + 0x10C8F, + 0x10C90, + 0x10C91, + 0x10C92, + 0x10C93, + 0x10C94, + 0x10C95, + 0x10C96, + 0x10C97, + 0x10C98, + 0x10C99, + 0x10C9A, + 0x10C9B, + 0x10C9C, + 0x10C9D, + 0x10C9E, + 0x10C9F, + 0x10CA0, + 0x10CA1, + 0x10CA2, + 0x10CA3, + 0x10CA4, + 0x10CA5, + 0x10CA6, + 0x10CA7, + 0x10CA8, + 0x10CA9, + 0x10CAA, + 0x10CAB, + 0x10CAC, + 0x10CAD, + 0x10CAE, + 0x10CAF, + 0x10CB0, + 0x10CB1, + 0x10CB2, + 0x10CB3, + 0x10CC0, + 0x10CF3, + 0x10CFA, + 0x10D28, + 0x10D30, + 0x10D3A, + 0x10D40, + 0x10D50, + 0x10D51, + 0x10D52, + 0x10D53, + 0x10D54, + 0x10D55, + 0x10D56, + 0x10D57, + 0x10D58, + 0x10D59, + 0x10D5A, + 0x10D5B, + 0x10D5C, + 0x10D5D, + 0x10D5E, + 0x10D5F, + 0x10D60, + 0x10D61, + 0x10D62, + 0x10D63, + 0x10D64, + 0x10D65, + 0x10D66, + 0x10D69, + 0x10D86, + 0x10D8E, + 0x10D90, + 0x10E60, + 0x10E7F, + 0x10E80, + 0x10EAA, + 0x10EAB, + 0x10EAE, + 0x10EB0, + 0x10EB2, + 0x10EC2, + 0x10EC8, + 0x10ED0, + 0x10ED9, + 0x10EFA, + 0x10F28, + 0x10F30, + 0x10F5A, + 0x10F70, + 0x10F8A, + 0x10FB0, + 0x10FCC, + 0x10FE0, + 0x10FF7, + 0x11000, + 0x1104E, + 0x11052, + 0x11076, + 0x1107F, + 0x110BD, + 0x110BE, + 0x110C3, + 0x110D0, + 0x110E9, + 0x110F0, + 0x110FA, + 0x11100, + 0x11135, + 0x11136, + 0x11148, + 0x11150, + 0x11177, + 0x11180, + 0x111E0, + 0x111E1, + 0x111F5, + 0x11200, + 0x11212, + 0x11213, + 0x11242, + 0x11280, + 0x11287, + 0x11288, + 0x11289, + 0x1128A, + 0x1128E, + 0x1128F, + 0x1129E, + 0x1129F, + 0x112AA, + 0x112B0, + 0x112EB, + 0x112F0, + 0x112FA, + 0x11300, + 0x11304, + 0x11305, + 0x1130D, + 0x1130F, + 0x11311, + 0x11313, + 0x11329, + 0x1132A, + 0x11331, + 0x11332, + 0x11334, + 0x11335, + 0x1133A, + 0x1133B, + 0x11345, + 0x11347, + 0x11349, + 0x1134B, + 0x1134E, + 0x11350, + 0x11351, + 0x11357, + 0x11358, + 0x1135D, + 0x11364, + 0x11366, + 0x1136D, + 0x11370, + 0x11375, + 0x11380, + 0x1138A, + 0x1138B, + 0x1138C, + 0x1138E, + 0x1138F, + 0x11390, + 0x113B6, + 0x113B7, + 0x113C1, + 0x113C2, + 0x113C3, + 0x113C5, + 0x113C6, + 0x113C7, + 0x113CB, + 0x113CC, + 0x113D6, + 0x113D7, + 0x113D9, + 0x113E1, + 0x113E3, + 0x11400, + 0x1145C, + 0x1145D, + 0x11462, + 0x11480, + 0x114C8, + 0x114D0, + 0x114DA, + 0x11580, + 0x115B6, + 0x115B8, + 0x115DE, + 0x11600, + 0x11645, + 0x11650, + 0x1165A, + 0x11660, + 0x1166D, + 0x11680, + 0x116BA, + 0x116C0, + 0x116CA, + 0x116D0, + 0x116E4, + 0x11700, + 0x1171B, + 0x1171D, + 0x1172C, + 0x11730, + 0x11747, + 0x11800, + 0x1183C, + 0x118A0, + 0x118A1, + 0x118A2, + 0x118A3, + 0x118A4, + 0x118A5, + 0x118A6, + 0x118A7, + 0x118A8, + 0x118A9, + 0x118AA, + 0x118AB, + 0x118AC, + 0x118AD, + 0x118AE, + 0x118AF, + 0x118B0, + 0x118B1, + 0x118B2, + 0x118B3, + 0x118B4, + 0x118B5, + 0x118B6, + 0x118B7, + 0x118B8, + 0x118B9, + 0x118BA, + 0x118BB, + 0x118BC, + 0x118BD, + 0x118BE, + 0x118BF, + 0x118C0, + 0x118F3, + 0x118FF, + 0x11907, + 0x11909, + 0x1190A, + 0x1190C, + 0x11914, + 0x11915, + 0x11917, + 0x11918, + 0x11936, + 0x11937, + 0x11939, + 0x1193B, + 0x11947, + 0x11950, + 0x1195A, + 0x119A0, + 0x119A8, + 0x119AA, + 0x119D8, + 0x119DA, + 0x119E5, + 0x11A00, + 0x11A48, + 0x11A50, + 0x11AA3, + 0x11AB0, + 0x11AF9, + 0x11B00, + 0x11B0A, + 0x11B60, + 0x11B68, + 0x11BC0, + 0x11BE2, + 0x11BF0, + 0x11BFA, + 0x11C00, + 0x11C09, + 0x11C0A, + 0x11C37, + 0x11C38, + 0x11C46, + 0x11C50, + 0x11C6D, + 0x11C70, + 0x11C90, + 0x11C92, + 0x11CA8, + 0x11CA9, + 0x11CB7, + 0x11D00, + 0x11D07, + 0x11D08, + 0x11D0A, + 0x11D0B, + 0x11D37, + 0x11D3A, + 0x11D3B, + 0x11D3C, + 0x11D3E, + 0x11D3F, + 0x11D48, + 0x11D50, + 0x11D5A, + 0x11D60, + 0x11D66, + 0x11D67, + 0x11D69, + 0x11D6A, + 0x11D8F, + 0x11D90, + 0x11D92, + 0x11D93, + 0x11D99, + 0x11DA0, + 0x11DAA, + 0x11DB0, + 0x11DDC, + 0x11DE0, + 0x11DEA, + 0x11EE0, + 0x11EF9, + 0x11F00, + 0x11F11, + 0x11F12, + 0x11F3B, + 0x11F3E, + 0x11F5B, + 0x11FB0, + 0x11FB1, + 0x11FC0, + 0x11FF2, + 0x11FFF, + 0x1239A, + 0x12400, + 0x1246F, + 0x12470, + 0x12475, + 0x12480, + 0x12544, + 0x12F90, + 0x12FF3, + 0x13000, + 0x13430, + 0x13440, + 0x13456, + 0x13460, + 0x143FB, + 0x14400, + 0x14647, + 0x16100, + 0x1613A, + 0x16800, + 0x16A39, + 0x16A40, + 0x16A5F, + 0x16A60, + 0x16A6A, + 0x16A6E, + 0x16ABF, + 0x16AC0, + 0x16ACA, + 0x16AD0, + 0x16AEE, + 0x16AF0, + 0x16AF6, + 0x16B00, + 0x16B46, + 0x16B50, + 0x16B5A, + 0x16B5B, + 0x16B62, + 0x16B63, + 0x16B78, + 0x16B7D, + 0x16B90, + 0x16D40, + 0x16D7A, + 0x16E40, + 0x16E41, + 0x16E42, + 0x16E43, + 0x16E44, + 0x16E45, + 0x16E46, + 0x16E47, + 0x16E48, + 0x16E49, + 0x16E4A, + 0x16E4B, + 0x16E4C, + 0x16E4D, + 0x16E4E, + 0x16E4F, + 0x16E50, + 0x16E51, + 0x16E52, + 0x16E53, + 0x16E54, + 0x16E55, + 0x16E56, + 0x16E57, + 0x16E58, + 0x16E59, + 0x16E5A, + 0x16E5B, + 0x16E5C, + 0x16E5D, + 0x16E5E, + 0x16E5F, + 0x16E60, + 0x16E9B, + 0x16EA0, + 0x16EA1, + 0x16EA2, + 0x16EA3, + 0x16EA4, + 0x16EA5, + 0x16EA6, + 0x16EA7, + 0x16EA8, + 0x16EA9, + 0x16EAA, + 0x16EAB, + 0x16EAC, + 0x16EAD, + 0x16EAE, + 0x16EAF, + 0x16EB0, + 0x16EB1, + 0x16EB2, + 0x16EB3, + 0x16EB4, + 0x16EB5, + 0x16EB6, + 0x16EB7, + 0x16EB8, + 0x16EB9, + 0x16EBB, + 0x16ED4, + 0x16F00, + 0x16F4B, + 0x16F4F, + 0x16F88, + 0x16F8F, + 0x16FA0, + 0x16FE0, + 0x16FE5, + 0x16FF0, + 0x16FF7, + 0x17000, + 0x18CD6, + 0x18CFF, + 0x18D1F, + 0x18D80, + 0x18DF3, + 0x1AFF0, + 0x1AFF4, + 0x1AFF5, + 0x1AFFC, + 0x1AFFD, + 0x1AFFF, + 0x1B000, + 0x1B123, + 0x1B132, + 0x1B133, + 0x1B150, + 0x1B153, + 0x1B155, + 0x1B156, + 0x1B164, + 0x1B168, + 0x1B170, + 0x1B2FC, + 0x1BC00, + 0x1BC6B, + 0x1BC70, + 0x1BC7D, + 0x1BC80, + 0x1BC89, + 0x1BC90, + 0x1BC9A, + 0x1BC9C, + 0x1BCA0, + 0x1BCA4, + 0x1CC00, + 0x1CCD6, + 0x1CCD7, + 0x1CCD8, + 0x1CCD9, + 0x1CCDA, + 0x1CCDB, + 0x1CCDC, + 0x1CCDD, + 0x1CCDE, + 0x1CCDF, + 0x1CCE0, + 0x1CCE1, + 0x1CCE2, + 0x1CCE3, + 0x1CCE4, + 0x1CCE5, + 0x1CCE6, + 0x1CCE7, + 0x1CCE8, + 0x1CCE9, + 0x1CCEA, + 0x1CCEB, + 0x1CCEC, + 0x1CCED, + 0x1CCEE, + 0x1CCEF, + 0x1CCF0, + 0x1CCF1, + 0x1CCF2, + 0x1CCF3, + 0x1CCF4, + 0x1CCF5, + 0x1CCF6, + 0x1CCF7, + 0x1CCF8, + 0x1CCF9, + 0x1CCFA, + 0x1CCFD, + 0x1CD00, + 0x1CEB4, + 0x1CEBA, + 0x1CED1, + 0x1CEE0, + 0x1CEF1, + 0x1CF00, + 0x1CF2E, + 0x1CF30, + 0x1CF47, + 0x1CF50, + 0x1CFC4, + 0x1D000, + 0x1D0F6, + 0x1D100, + 0x1D127, + 0x1D129, + 0x1D15E, + 0x1D15F, + 0x1D160, + 0x1D161, + 0x1D162, + 0x1D163, + 0x1D164, + 0x1D165, + 0x1D173, + 0x1D17B, + 0x1D1BB, + 0x1D1BC, + 0x1D1BD, + 0x1D1BE, + 0x1D1BF, + 0x1D1C0, + 0x1D1C1, + 0x1D1EB, + 0x1D200, + 0x1D246, + 0x1D2C0, + 0x1D2D4, + 0x1D2E0, + 0x1D2F4, + 0x1D300, + 0x1D357, + 0x1D360, + 0x1D379, + 0x1D400, + 0x1D401, + 0x1D402, + 0x1D403, + 0x1D404, + 0x1D405, + 0x1D406, + 0x1D407, + 0x1D408, + 0x1D409, + 0x1D40A, + 0x1D40B, + 0x1D40C, + 0x1D40D, + 0x1D40E, + 0x1D40F, + 0x1D410, + 0x1D411, + 0x1D412, + 0x1D413, + 0x1D414, + 0x1D415, + 0x1D416, + 0x1D417, + 0x1D418, + 0x1D419, + 0x1D41A, + 0x1D41B, + 0x1D41C, + 0x1D41D, + 0x1D41E, + 0x1D41F, + 0x1D420, + 0x1D421, + 0x1D422, + 0x1D423, + 0x1D424, + 0x1D425, + 0x1D426, + 0x1D427, + 0x1D428, + 0x1D429, + 0x1D42A, + 0x1D42B, + 0x1D42C, + 0x1D42D, + 0x1D42E, + 0x1D42F, + 0x1D430, + 0x1D431, + 0x1D432, + 0x1D433, + 0x1D434, + 0x1D435, + 0x1D436, + 0x1D437, + 0x1D438, + 0x1D439, + 0x1D43A, + 0x1D43B, + 0x1D43C, + 0x1D43D, + 0x1D43E, + 0x1D43F, + 0x1D440, + 0x1D441, + 0x1D442, + 0x1D443, + 0x1D444, + 0x1D445, + 0x1D446, + 0x1D447, + 0x1D448, + 0x1D449, + 0x1D44A, + 0x1D44B, + 0x1D44C, + 0x1D44D, + 0x1D44E, + 0x1D44F, + 0x1D450, + 0x1D451, + 0x1D452, + 0x1D453, + 0x1D454, + 0x1D455, + 0x1D456, + 0x1D457, + 0x1D458, + 0x1D459, + 0x1D45A, + 0x1D45B, + 0x1D45C, + 0x1D45D, + 0x1D45E, + 0x1D45F, + 0x1D460, + 0x1D461, + 0x1D462, + 0x1D463, + 0x1D464, + 0x1D465, + 0x1D466, + 0x1D467, + 0x1D468, + 0x1D469, + 0x1D46A, + 0x1D46B, + 0x1D46C, + 0x1D46D, + 0x1D46E, + 0x1D46F, + 0x1D470, + 0x1D471, + 0x1D472, + 0x1D473, + 0x1D474, + 0x1D475, + 0x1D476, + 0x1D477, + 0x1D478, + 0x1D479, + 0x1D47A, + 0x1D47B, + 0x1D47C, + 0x1D47D, + 0x1D47E, + 0x1D47F, + 0x1D480, + 0x1D481, + 0x1D482, + 0x1D483, + 0x1D484, + 0x1D485, + 0x1D486, + 0x1D487, + 0x1D488, + 0x1D489, + 0x1D48A, + 0x1D48B, + 0x1D48C, + 0x1D48D, + 0x1D48E, + 0x1D48F, + 0x1D490, + 0x1D491, + 0x1D492, + 0x1D493, + 0x1D494, + 0x1D495, + 0x1D496, + 0x1D497, + 0x1D498, + 0x1D499, + 0x1D49A, + 0x1D49B, + 0x1D49C, + 0x1D49D, + 0x1D49E, + 0x1D49F, + 0x1D4A0, + 0x1D4A2, + 0x1D4A3, + 0x1D4A5, + 0x1D4A6, + 0x1D4A7, + 0x1D4A9, + 0x1D4AA, + 0x1D4AB, + 0x1D4AC, + 0x1D4AD, + 0x1D4AE, + 0x1D4AF, + 0x1D4B0, + 0x1D4B1, + 0x1D4B2, + 0x1D4B3, + 0x1D4B4, + 0x1D4B5, + 0x1D4B6, + 0x1D4B7, + 0x1D4B8, + 0x1D4B9, + 0x1D4BA, + 0x1D4BB, + 0x1D4BC, + 0x1D4BD, + 0x1D4BE, + 0x1D4BF, + 0x1D4C0, + 0x1D4C1, + 0x1D4C2, + 0x1D4C3, + 0x1D4C4, + 0x1D4C5, + 0x1D4C6, + 0x1D4C7, + 0x1D4C8, + 0x1D4C9, + 0x1D4CA, + 0x1D4CB, + 0x1D4CC, + 0x1D4CD, + 0x1D4CE, + 0x1D4CF, + 0x1D4D0, + 0x1D4D1, + 0x1D4D2, + 0x1D4D3, + 0x1D4D4, + 0x1D4D5, + 0x1D4D6, + 0x1D4D7, + 0x1D4D8, + 0x1D4D9, + 0x1D4DA, + 0x1D4DB, + 0x1D4DC, + 0x1D4DD, + 0x1D4DE, + 0x1D4DF, + 0x1D4E0, + 0x1D4E1, + 0x1D4E2, + 0x1D4E3, + 0x1D4E4, + 0x1D4E5, + 0x1D4E6, + 0x1D4E7, + 0x1D4E8, + 0x1D4E9, + 0x1D4EA, + 0x1D4EB, + 0x1D4EC, + 0x1D4ED, + 0x1D4EE, + 0x1D4EF, + 0x1D4F0, + 0x1D4F1, + 0x1D4F2, + 0x1D4F3, + 0x1D4F4, + 0x1D4F5, + 0x1D4F6, + 0x1D4F7, + 0x1D4F8, + 0x1D4F9, + 0x1D4FA, + 0x1D4FB, + 0x1D4FC, + 0x1D4FD, + 0x1D4FE, + 0x1D4FF, + 0x1D500, + 0x1D501, + 0x1D502, + 0x1D503, + 0x1D504, + 0x1D505, + 0x1D506, + 0x1D507, + 0x1D508, + 0x1D509, + 0x1D50A, + 0x1D50B, + 0x1D50D, + 0x1D50E, + 0x1D50F, + 0x1D510, + 0x1D511, + 0x1D512, + 0x1D513, + 0x1D514, + 0x1D515, + 0x1D516, + 0x1D517, + 0x1D518, + 0x1D519, + 0x1D51A, + 0x1D51B, + 0x1D51C, + 0x1D51D, + 0x1D51E, + 0x1D51F, + 0x1D520, + 0x1D521, + 0x1D522, + 0x1D523, + 0x1D524, + 0x1D525, + 0x1D526, + 0x1D527, + 0x1D528, + 0x1D529, + 0x1D52A, + 0x1D52B, + 0x1D52C, + 0x1D52D, + 0x1D52E, + 0x1D52F, + 0x1D530, + 0x1D531, + 0x1D532, + 0x1D533, + 0x1D534, + 0x1D535, + 0x1D536, + 0x1D537, + 0x1D538, + 0x1D539, + 0x1D53A, + 0x1D53B, + 0x1D53C, + 0x1D53D, + 0x1D53E, + 0x1D53F, + 0x1D540, + 0x1D541, + 0x1D542, + 0x1D543, + 0x1D544, + 0x1D545, + 0x1D546, + 0x1D547, + 0x1D54A, + 0x1D54B, + 0x1D54C, + 0x1D54D, + 0x1D54E, + 0x1D54F, + 0x1D550, + 0x1D551, + 0x1D552, + 0x1D553, + 0x1D554, + 0x1D555, + 0x1D556, + 0x1D557, + 0x1D558, + 0x1D559, + 0x1D55A, + 0x1D55B, + 0x1D55C, + 0x1D55D, + 0x1D55E, + 0x1D55F, + 0x1D560, + 0x1D561, + 0x1D562, + 0x1D563, + 0x1D564, + 0x1D565, + 0x1D566, + 0x1D567, + 0x1D568, + 0x1D569, + 0x1D56A, + 0x1D56B, + 0x1D56C, + 0x1D56D, + 0x1D56E, + 0x1D56F, + 0x1D570, + 0x1D571, + 0x1D572, + 0x1D573, + 0x1D574, + 0x1D575, + 0x1D576, + 0x1D577, + 0x1D578, + 0x1D579, + 0x1D57A, + 0x1D57B, + 0x1D57C, + 0x1D57D, + 0x1D57E, + 0x1D57F, + 0x1D580, + 0x1D581, + 0x1D582, + 0x1D583, + 0x1D584, + 0x1D585, + 0x1D586, + 0x1D587, + 0x1D588, + 0x1D589, + 0x1D58A, + 0x1D58B, + 0x1D58C, + 0x1D58D, + 0x1D58E, + 0x1D58F, + 0x1D590, + 0x1D591, + 0x1D592, + 0x1D593, + 0x1D594, + 0x1D595, + 0x1D596, + 0x1D597, + 0x1D598, + 0x1D599, + 0x1D59A, + 0x1D59B, + 0x1D59C, + 0x1D59D, + 0x1D59E, + 0x1D59F, + 0x1D5A0, + 0x1D5A1, + 0x1D5A2, + 0x1D5A3, + 0x1D5A4, + 0x1D5A5, + 0x1D5A6, + 0x1D5A7, + 0x1D5A8, + 0x1D5A9, + 0x1D5AA, + 0x1D5AB, + 0x1D5AC, + 0x1D5AD, + 0x1D5AE, + 0x1D5AF, + 0x1D5B0, + 0x1D5B1, + 0x1D5B2, + 0x1D5B3, + 0x1D5B4, + 0x1D5B5, + 0x1D5B6, + 0x1D5B7, + 0x1D5B8, + 0x1D5B9, + 0x1D5BA, + 0x1D5BB, + 0x1D5BC, + 0x1D5BD, + 0x1D5BE, + 0x1D5BF, + 0x1D5C0, + 0x1D5C1, + 0x1D5C2, + 0x1D5C3, + 0x1D5C4, + 0x1D5C5, + 0x1D5C6, + 0x1D5C7, + 0x1D5C8, + 0x1D5C9, + 0x1D5CA, + 0x1D5CB, + 0x1D5CC, + 0x1D5CD, + 0x1D5CE, + 0x1D5CF, + 0x1D5D0, + 0x1D5D1, + 0x1D5D2, + 0x1D5D3, + 0x1D5D4, + 0x1D5D5, + 0x1D5D6, + 0x1D5D7, + 0x1D5D8, + 0x1D5D9, + 0x1D5DA, + 0x1D5DB, + 0x1D5DC, + 0x1D5DD, + 0x1D5DE, + 0x1D5DF, + 0x1D5E0, + 0x1D5E1, + 0x1D5E2, + 0x1D5E3, + 0x1D5E4, + 0x1D5E5, + 0x1D5E6, + 0x1D5E7, + 0x1D5E8, + 0x1D5E9, + 0x1D5EA, + 0x1D5EB, + 0x1D5EC, + 0x1D5ED, + 0x1D5EE, + 0x1D5EF, + 0x1D5F0, + 0x1D5F1, + 0x1D5F2, + 0x1D5F3, + 0x1D5F4, + 0x1D5F5, + 0x1D5F6, + 0x1D5F7, + 0x1D5F8, + 0x1D5F9, + 0x1D5FA, + 0x1D5FB, + 0x1D5FC, + 0x1D5FD, + 0x1D5FE, + 0x1D5FF, + 0x1D600, + 0x1D601, + 0x1D602, + 0x1D603, + 0x1D604, + 0x1D605, + 0x1D606, + 0x1D607, + 0x1D608, + 0x1D609, + 0x1D60A, + 0x1D60B, + 0x1D60C, + 0x1D60D, + 0x1D60E, + 0x1D60F, + 0x1D610, + 0x1D611, + 0x1D612, + 0x1D613, + 0x1D614, + 0x1D615, + 0x1D616, + 0x1D617, + 0x1D618, + 0x1D619, + 0x1D61A, + 0x1D61B, + 0x1D61C, + 0x1D61D, + 0x1D61E, + 0x1D61F, + 0x1D620, + 0x1D621, + 0x1D622, + 0x1D623, + 0x1D624, + 0x1D625, + 0x1D626, + 0x1D627, + 0x1D628, + 0x1D629, + 0x1D62A, + 0x1D62B, + 0x1D62C, + 0x1D62D, + 0x1D62E, + 0x1D62F, + 0x1D630, + 0x1D631, + 0x1D632, + 0x1D633, + 0x1D634, + 0x1D635, + 0x1D636, + 0x1D637, + 0x1D638, + 0x1D639, + 0x1D63A, + 0x1D63B, + 0x1D63C, + 0x1D63D, + 0x1D63E, + 0x1D63F, + 0x1D640, + 0x1D641, + 0x1D642, + 0x1D643, + 0x1D644, + 0x1D645, + 0x1D646, + 0x1D647, + 0x1D648, + 0x1D649, + 0x1D64A, + 0x1D64B, + 0x1D64C, + 0x1D64D, + 0x1D64E, + 0x1D64F, + 0x1D650, + 0x1D651, + 0x1D652, + 0x1D653, + 0x1D654, + 0x1D655, + 0x1D656, + 0x1D657, + 0x1D658, + 0x1D659, + 0x1D65A, + 0x1D65B, + 0x1D65C, + 0x1D65D, + 0x1D65E, + 0x1D65F, + 0x1D660, + 0x1D661, + 0x1D662, + 0x1D663, + 0x1D664, + 0x1D665, + 0x1D666, + 0x1D667, + 0x1D668, + 0x1D669, + 0x1D66A, + 0x1D66B, + 0x1D66C, + 0x1D66D, + 0x1D66E, + 0x1D66F, + 0x1D670, + 0x1D671, + 0x1D672, + 0x1D673, + 0x1D674, + 0x1D675, + 0x1D676, + 0x1D677, + 0x1D678, + 0x1D679, + 0x1D67A, + 0x1D67B, + 0x1D67C, + 0x1D67D, + 0x1D67E, + 0x1D67F, + 0x1D680, + 0x1D681, + 0x1D682, + 0x1D683, + 0x1D684, + 0x1D685, + 0x1D686, + 0x1D687, + 0x1D688, + 0x1D689, + 0x1D68A, + 0x1D68B, + 0x1D68C, + 0x1D68D, + 0x1D68E, + 0x1D68F, + 0x1D690, + 0x1D691, + 0x1D692, + 0x1D693, + 0x1D694, + 0x1D695, + 0x1D696, + 0x1D697, + 0x1D698, + 0x1D699, + 0x1D69A, + 0x1D69B, + 0x1D69C, + 0x1D69D, + 0x1D69E, + 0x1D69F, + 0x1D6A0, + 0x1D6A1, + 0x1D6A2, + 0x1D6A3, + 0x1D6A4, + 0x1D6A5, + 0x1D6A6, + 0x1D6A8, + 0x1D6A9, + 0x1D6AA, + 0x1D6AB, + 0x1D6AC, + 0x1D6AD, + 0x1D6AE, + 0x1D6AF, + 0x1D6B0, + 0x1D6B1, + 0x1D6B2, + 0x1D6B3, + 0x1D6B4, + 0x1D6B5, + 0x1D6B6, + 0x1D6B7, + 0x1D6B8, + 0x1D6B9, + 0x1D6BA, + 0x1D6BB, + 0x1D6BC, + 0x1D6BD, + 0x1D6BE, + 0x1D6BF, + 0x1D6C0, + 0x1D6C1, + 0x1D6C2, + 0x1D6C3, + 0x1D6C4, + 0x1D6C5, + 0x1D6C6, + 0x1D6C7, + 0x1D6C8, + 0x1D6C9, + 0x1D6CA, + 0x1D6CB, + 0x1D6CC, + 0x1D6CD, + 0x1D6CE, + 0x1D6CF, + 0x1D6D0, + 0x1D6D1, + 0x1D6D2, + 0x1D6D3, + 0x1D6D5, + 0x1D6D6, + 0x1D6D7, + 0x1D6D8, + 0x1D6D9, + 0x1D6DA, + 0x1D6DB, + 0x1D6DC, + 0x1D6DD, + 0x1D6DE, + 0x1D6DF, + 0x1D6E0, + 0x1D6E1, + 0x1D6E2, + 0x1D6E3, + 0x1D6E4, + 0x1D6E5, + 0x1D6E6, + 0x1D6E7, + 0x1D6E8, + 0x1D6E9, + 0x1D6EA, + 0x1D6EB, + 0x1D6EC, + 0x1D6ED, + 0x1D6EE, + 0x1D6EF, + 0x1D6F0, + 0x1D6F1, + 0x1D6F2, + 0x1D6F3, + 0x1D6F4, + 0x1D6F5, + 0x1D6F6, + 0x1D6F7, + 0x1D6F8, + 0x1D6F9, + 0x1D6FA, + 0x1D6FB, + 0x1D6FC, + 0x1D6FD, + 0x1D6FE, + 0x1D6FF, + 0x1D700, + 0x1D701, + 0x1D702, + 0x1D703, + 0x1D704, + 0x1D705, + 0x1D706, + 0x1D707, + 0x1D708, + 0x1D709, + 0x1D70A, + 0x1D70B, + 0x1D70C, + 0x1D70D, + 0x1D70F, + 0x1D710, + 0x1D711, + 0x1D712, + 0x1D713, + 0x1D714, + 0x1D715, + 0x1D716, + 0x1D717, + 0x1D718, + 0x1D719, + 0x1D71A, + 0x1D71B, + 0x1D71C, + 0x1D71D, + 0x1D71E, + 0x1D71F, + 0x1D720, + 0x1D721, + 0x1D722, + 0x1D723, + 0x1D724, + 0x1D725, + 0x1D726, + 0x1D727, + 0x1D728, + 0x1D729, + 0x1D72A, + 0x1D72B, + 0x1D72C, + 0x1D72D, + 0x1D72E, + 0x1D72F, + 0x1D730, + 0x1D731, + 0x1D732, + 0x1D733, + 0x1D734, + 0x1D735, + 0x1D736, + 0x1D737, + 0x1D738, + 0x1D739, + 0x1D73A, + 0x1D73B, + 0x1D73C, + 0x1D73D, + 0x1D73E, + 0x1D73F, + 0x1D740, + 0x1D741, + 0x1D742, + 0x1D743, + 0x1D744, + 0x1D745, + 0x1D746, + 0x1D747, + 0x1D749, + 0x1D74A, + 0x1D74B, + 0x1D74C, + 0x1D74D, + 0x1D74E, + 0x1D74F, + 0x1D750, + 0x1D751, + 0x1D752, + 0x1D753, + 0x1D754, + 0x1D755, + 0x1D756, + 0x1D757, + 0x1D758, + 0x1D759, + 0x1D75A, + 0x1D75B, + 0x1D75C, + 0x1D75D, + 0x1D75E, + 0x1D75F, + 0x1D760, + 0x1D761, + 0x1D762, + 0x1D763, + 0x1D764, + 0x1D765, + 0x1D766, + 0x1D767, + 0x1D768, + 0x1D769, + 0x1D76A, + 0x1D76B, + 0x1D76C, + 0x1D76D, + 0x1D76E, + 0x1D76F, + 0x1D770, + 0x1D771, + 0x1D772, + 0x1D773, + 0x1D774, + 0x1D775, + 0x1D776, + 0x1D777, + 0x1D778, + 0x1D779, + 0x1D77A, + 0x1D77B, + 0x1D77C, + 0x1D77D, + 0x1D77E, + 0x1D77F, + 0x1D780, + 0x1D781, + 0x1D783, + 0x1D784, + 0x1D785, + 0x1D786, + 0x1D787, + 0x1D788, + 0x1D789, + 0x1D78A, + 0x1D78B, + 0x1D78C, + 0x1D78D, + 0x1D78E, + 0x1D78F, + 0x1D790, + 0x1D791, + 0x1D792, + 0x1D793, + 0x1D794, + 0x1D795, + 0x1D796, + 0x1D797, + 0x1D798, + 0x1D799, + 0x1D79A, + 0x1D79B, + 0x1D79C, + 0x1D79D, + 0x1D79E, + 0x1D79F, + 0x1D7A0, + 0x1D7A1, + 0x1D7A2, + 0x1D7A3, + 0x1D7A4, + 0x1D7A5, + 0x1D7A6, + 0x1D7A7, + 0x1D7A8, + 0x1D7A9, + 0x1D7AA, + 0x1D7AB, + 0x1D7AC, + 0x1D7AD, + 0x1D7AE, + 0x1D7AF, + 0x1D7B0, + 0x1D7B1, + 0x1D7B2, + 0x1D7B3, + 0x1D7B4, + 0x1D7B5, + 0x1D7B6, + 0x1D7B7, + 0x1D7B8, + 0x1D7B9, + 0x1D7BA, + 0x1D7BB, + 0x1D7BD, + 0x1D7BE, + 0x1D7BF, + 0x1D7C0, + 0x1D7C1, + 0x1D7C2, + 0x1D7C3, + 0x1D7C4, + 0x1D7C5, + 0x1D7C6, + 0x1D7C7, + 0x1D7C8, + 0x1D7C9, + 0x1D7CA, + 0x1D7CC, + 0x1D7CE, + 0x1D7CF, + 0x1D7D0, + 0x1D7D1, + 0x1D7D2, + 0x1D7D3, + 0x1D7D4, + 0x1D7D5, + 0x1D7D6, + 0x1D7D7, + 0x1D7D8, + 0x1D7D9, + 0x1D7DA, + 0x1D7DB, + 0x1D7DC, + 0x1D7DD, + 0x1D7DE, + 0x1D7DF, + 0x1D7E0, + 0x1D7E1, + 0x1D7E2, + 0x1D7E3, + 0x1D7E4, + 0x1D7E5, + 0x1D7E6, + 0x1D7E7, + 0x1D7E8, + 0x1D7E9, + 0x1D7EA, + 0x1D7EB, + 0x1D7EC, + 0x1D7ED, + 0x1D7EE, + 0x1D7EF, + 0x1D7F0, + 0x1D7F1, + 0x1D7F2, + 0x1D7F3, + 0x1D7F4, + 0x1D7F5, + 0x1D7F6, + 0x1D7F7, + 0x1D7F8, + 0x1D7F9, + 0x1D7FA, + 0x1D7FB, + 0x1D7FC, + 0x1D7FD, + 0x1D7FE, + 0x1D7FF, + 0x1D800, + 0x1DA8C, + 0x1DA9B, + 0x1DAA0, + 0x1DAA1, + 0x1DAB0, + 0x1DF00, + 0x1DF1F, + 0x1DF25, + 0x1DF2B, + 0x1E000, + 0x1E007, + 0x1E008, + 0x1E019, + 0x1E01B, + 0x1E022, + 0x1E023, + 0x1E025, + 0x1E026, + 0x1E02B, + 0x1E030, + 0x1E031, + 0x1E032, + 0x1E033, + 0x1E034, + 0x1E035, + 0x1E036, + 0x1E037, + 0x1E038, + 0x1E039, + 0x1E03A, + 0x1E03B, + 0x1E03C, + 0x1E03D, + 0x1E03E, + 0x1E03F, + 0x1E040, + 0x1E041, + 0x1E042, + 0x1E043, + 0x1E044, + 0x1E045, + 0x1E046, + 0x1E047, + 0x1E048, + 0x1E049, + 0x1E04A, + 0x1E04B, + 0x1E04C, + 0x1E04D, + 0x1E04E, + 0x1E04F, + 0x1E050, + 0x1E051, + 0x1E052, + 0x1E053, + 0x1E054, + 0x1E055, + 0x1E056, + 0x1E057, + 0x1E058, + 0x1E059, + 0x1E05A, + 0x1E05B, + 0x1E05C, + 0x1E05D, + 0x1E05E, + 0x1E05F, + 0x1E060, + 0x1E061, + 0x1E062, + 0x1E063, + 0x1E064, + 0x1E065, + 0x1E066, + 0x1E067, + 0x1E068, + 0x1E069, + 0x1E06A, + 0x1E06B, + 0x1E06C, + 0x1E06D, + 0x1E06E, + 0x1E08F, + 0x1E090, + 0x1E100, + 0x1E12D, + 0x1E130, + 0x1E13E, + 0x1E140, + 0x1E14A, + 0x1E14E, + 0x1E150, + 0x1E290, + 0x1E2AF, + 0x1E2C0, + 0x1E2FA, + 0x1E2FF, + 0x1E300, + 0x1E4D0, + 0x1E4FA, + 0x1E5D0, + 0x1E5FB, + 0x1E5FF, + 0x1E600, + 0x1E6C0, + 0x1E6DF, + 0x1E6E0, + 0x1E6F6, + 0x1E6FE, + 0x1E700, + 0x1E7E0, + 0x1E7E7, + 0x1E7E8, + 0x1E7EC, + 0x1E7ED, + 0x1E7EF, + 0x1E7F0, + 0x1E7FF, + 0x1E800, + 0x1E8C5, + 0x1E8C7, + 0x1E8D7, + 0x1E900, + 0x1E901, + 0x1E902, + 0x1E903, + 0x1E904, + 0x1E905, + 0x1E906, + 0x1E907, + 0x1E908, + 0x1E909, + 0x1E90A, + 0x1E90B, + 0x1E90C, + 0x1E90D, + 0x1E90E, + 0x1E90F, + 0x1E910, + 0x1E911, + 0x1E912, + 0x1E913, + 0x1E914, + 0x1E915, + 0x1E916, + 0x1E917, + 0x1E918, + 0x1E919, + 0x1E91A, + 0x1E91B, + 0x1E91C, + 0x1E91D, + 0x1E91E, + 0x1E91F, + 0x1E920, + 0x1E921, + 0x1E922, + 0x1E94C, + 0x1E950, + 0x1E95A, + 0x1E95E, + 0x1E960, + 0x1EC71, + 0x1ECB5, + 0x1ED01, + 0x1ED3E, + 0x1EE00, + 0x1EE01, + 0x1EE02, + 0x1EE03, + 0x1EE04, + 0x1EE05, + 0x1EE06, + 0x1EE07, + 0x1EE08, + 0x1EE09, + 0x1EE0A, + 0x1EE0B, + 0x1EE0C, + 0x1EE0D, + 0x1EE0E, + 0x1EE0F, + 0x1EE10, + 0x1EE11, + 0x1EE12, + 0x1EE13, + 0x1EE14, + 0x1EE15, + 0x1EE16, + 0x1EE17, + 0x1EE18, + 0x1EE19, + 0x1EE1A, + 0x1EE1B, + 0x1EE1C, + 0x1EE1D, + 0x1EE1E, + 0x1EE1F, + 0x1EE20, + 0x1EE21, + 0x1EE22, + 0x1EE23, + 0x1EE24, + 0x1EE25, + 0x1EE27, + 0x1EE28, + 0x1EE29, + 0x1EE2A, + 0x1EE2B, + 0x1EE2C, + 0x1EE2D, + 0x1EE2E, + 0x1EE2F, + 0x1EE30, + 0x1EE31, + 0x1EE32, + 0x1EE33, + 0x1EE34, + 0x1EE35, + 0x1EE36, + 0x1EE37, + 0x1EE38, + 0x1EE39, + 0x1EE3A, + 0x1EE3B, + 0x1EE3C, + 0x1EE42, + 0x1EE43, + 0x1EE47, + 0x1EE48, + 0x1EE49, + 0x1EE4A, + 0x1EE4B, + 0x1EE4C, + 0x1EE4D, + 0x1EE4E, + 0x1EE4F, + 0x1EE50, + 0x1EE51, + 0x1EE52, + 0x1EE53, + 0x1EE54, + 0x1EE55, + 0x1EE57, + 0x1EE58, + 0x1EE59, + 0x1EE5A, + 0x1EE5B, + 0x1EE5C, + 0x1EE5D, + 0x1EE5E, + 0x1EE5F, + 0x1EE60, + 0x1EE61, + 0x1EE62, + 0x1EE63, + 0x1EE64, + 0x1EE65, + 0x1EE67, + 0x1EE68, + 0x1EE69, + 0x1EE6A, + 0x1EE6B, + 0x1EE6C, + 0x1EE6D, + 0x1EE6E, + 0x1EE6F, + 0x1EE70, + 0x1EE71, + 0x1EE72, + 0x1EE73, + 0x1EE74, + 0x1EE75, + 0x1EE76, + 0x1EE77, + 0x1EE78, + 0x1EE79, + 0x1EE7A, + 0x1EE7B, + 0x1EE7C, + 0x1EE7D, + 0x1EE7E, + 0x1EE7F, + 0x1EE80, + 0x1EE81, + 0x1EE82, + 0x1EE83, + 0x1EE84, + 0x1EE85, + 0x1EE86, + 0x1EE87, + 0x1EE88, + 0x1EE89, + 0x1EE8A, + 0x1EE8B, + 0x1EE8C, + 0x1EE8D, + 0x1EE8E, + 0x1EE8F, + 0x1EE90, + 0x1EE91, + 0x1EE92, + 0x1EE93, + 0x1EE94, + 0x1EE95, + 0x1EE96, + 0x1EE97, + 0x1EE98, + 0x1EE99, + 0x1EE9A, + 0x1EE9B, + 0x1EE9C, + 0x1EEA1, + 0x1EEA2, + 0x1EEA3, + 0x1EEA4, + 0x1EEA5, + 0x1EEA6, + 0x1EEA7, + 0x1EEA8, + 0x1EEA9, + 0x1EEAA, + 0x1EEAB, + 0x1EEAC, + 0x1EEAD, + 0x1EEAE, + 0x1EEAF, + 0x1EEB0, + 0x1EEB1, + 0x1EEB2, + 0x1EEB3, + 0x1EEB4, + 0x1EEB5, + 0x1EEB6, + 0x1EEB7, + 0x1EEB8, + 0x1EEB9, + 0x1EEBA, + 0x1EEBB, + 0x1EEBC, + 0x1EEF0, + 0x1EEF2, + 0x1F000, + 0x1F02C, + 0x1F030, + 0x1F094, + 0x1F0A0, + 0x1F0AF, + 0x1F0B1, + 0x1F0C0, + 0x1F0C1, + 0x1F0D0, + 0x1F0D1, + 0x1F0F6, + 0x1F101, + 0x1F102, + 0x1F103, + 0x1F104, + 0x1F105, + 0x1F106, + 0x1F107, + 0x1F108, + 0x1F109, + 0x1F10A, + 0x1F10B, + 0x1F110, + 0x1F111, + 0x1F112, + 0x1F113, + 0x1F114, + 0x1F115, + 0x1F116, + 0x1F117, + 0x1F118, + 0x1F119, + 0x1F11A, + 0x1F11B, + 0x1F11C, + 0x1F11D, + 0x1F11E, + 0x1F11F, + 0x1F120, + 0x1F121, + 0x1F122, + 0x1F123, + 0x1F124, + 0x1F125, + 0x1F126, + 0x1F127, + 0x1F128, + 0x1F129, + 0x1F12A, + 0x1F12B, + 0x1F12C, + 0x1F12D, + 0x1F12E, + 0x1F12F, + 0x1F130, + 0x1F131, + 0x1F132, + 0x1F133, + 0x1F134, + 0x1F135, + 0x1F136, + 0x1F137, + 0x1F138, + 0x1F139, + 0x1F13A, + 0x1F13B, + 0x1F13C, + 0x1F13D, + 0x1F13E, + 0x1F13F, + 0x1F140, + 0x1F141, + 0x1F142, + 0x1F143, + 0x1F144, + 0x1F145, + 0x1F146, + 0x1F147, + 0x1F148, + 0x1F149, + 0x1F14A, + 0x1F14B, + 0x1F14C, + 0x1F14D, + 0x1F14E, + 0x1F14F, + 0x1F150, + 0x1F16A, + 0x1F16B, + 0x1F16C, + 0x1F16D, + 0x1F190, + 0x1F191, + 0x1F1AE, + 0x1F1E6, + 0x1F200, + 0x1F201, + 0x1F202, + 0x1F203, + 0x1F210, + 0x1F211, + 0x1F212, + 0x1F213, + 0x1F214, + 0x1F215, + 0x1F216, + 0x1F217, + 0x1F218, + 0x1F219, + 0x1F21A, + 0x1F21B, + 0x1F21C, + 0x1F21D, + 0x1F21E, + 0x1F21F, + 0x1F220, + 0x1F221, + 0x1F222, + 0x1F223, + 0x1F224, + 0x1F225, + 0x1F226, + 0x1F227, + 0x1F228, + 0x1F229, + 0x1F22A, + 0x1F22B, + 0x1F22C, + 0x1F22D, + 0x1F22E, + 0x1F22F, + 0x1F230, + 0x1F231, + 0x1F232, + 0x1F233, + 0x1F234, + 0x1F235, + 0x1F236, + 0x1F237, + 0x1F238, + 0x1F239, + 0x1F23A, + 0x1F23B, + 0x1F23C, + 0x1F240, + 0x1F241, + 0x1F242, + 0x1F243, + 0x1F244, + 0x1F245, + 0x1F246, + 0x1F247, + 0x1F248, + 0x1F249, + 0x1F250, + 0x1F251, + 0x1F252, + 0x1F260, + 0x1F266, + 0x1F300, + 0x1F6D9, + 0x1F6DC, + 0x1F6ED, + 0x1F6F0, + 0x1F6FD, + 0x1F700, + 0x1F7DA, + 0x1F7E0, + 0x1F7EC, + 0x1F7F0, + 0x1F7F1, + 0x1F800, + 0x1F80C, + 0x1F810, + 0x1F848, + 0x1F850, + 0x1F85A, + 0x1F860, + 0x1F888, + 0x1F890, + 0x1F8AE, + 0x1F8B0, + 0x1F8BC, + 0x1F8C0, + 0x1F8C2, + 0x1F8D0, + 0x1F8D9, + 0x1F900, + 0x1FA58, + 0x1FA60, + 0x1FA6E, + 0x1FA70, + 0x1FA7D, + 0x1FA80, + 0x1FA8B, + 0x1FA8E, + 0x1FAC7, + 0x1FAC8, + 0x1FAC9, + 0x1FACD, + 0x1FADD, + 0x1FADF, + 0x1FAEB, + 0x1FAEF, + 0x1FAF9, + 0x1FB00, + 0x1FB93, + 0x1FB94, + 0x1FBF0, + 0x1FBF1, + 0x1FBF2, + 0x1FBF3, + 0x1FBF4, + 0x1FBF5, + 0x1FBF6, + 0x1FBF7, + 0x1FBF8, + 0x1FBF9, + 0x1FBFA, + 0x1FBFB, + 0x20000, + 0x2A6E0, + 0x2A700, + 0x2B81E, + 0x2B820, + 0x2CEAE, + 0x2CEB0, + 0x2EBE1, + 0x2EBF0, + 0x2EE5E, + 0x2F800, + 0x2F801, + 0x2F802, + 0x2F803, + 0x2F804, + 0x2F805, + 0x2F806, + 0x2F807, + 0x2F808, + 0x2F809, + 0x2F80A, + 0x2F80B, + 0x2F80C, + 0x2F80D, + 0x2F80E, + 0x2F80F, + 0x2F810, + 0x2F811, + 0x2F812, + 0x2F813, + 0x2F814, + 0x2F815, + 0x2F816, + 0x2F817, + 0x2F818, + 0x2F819, + 0x2F81A, + 0x2F81B, + 0x2F81C, + 0x2F81D, + 0x2F81E, + 0x2F81F, + 0x2F820, + 0x2F821, + 0x2F822, + 0x2F823, + 0x2F824, + 0x2F825, + 0x2F826, + 0x2F827, + 0x2F828, + 0x2F829, + 0x2F82A, + 0x2F82B, + 0x2F82C, + 0x2F82D, + 0x2F82E, + 0x2F82F, + 0x2F830, + 0x2F831, + 0x2F834, + 0x2F835, + 0x2F836, + 0x2F837, + 0x2F838, + 0x2F839, + 0x2F83A, + 0x2F83B, + 0x2F83C, + 0x2F83D, + 0x2F83E, + 0x2F83F, + 0x2F840, + 0x2F841, + 0x2F842, + 0x2F843, + 0x2F844, + 0x2F845, + 0x2F847, + 0x2F848, + 0x2F849, + 0x2F84A, + 0x2F84B, + 0x2F84C, + 0x2F84D, + 0x2F84E, + 0x2F84F, + 0x2F850, + 0x2F851, + 0x2F852, + 0x2F853, + 0x2F854, + 0x2F855, + 0x2F856, + 0x2F857, + 0x2F858, + 0x2F859, + 0x2F85A, + 0x2F85B, + 0x2F85C, + 0x2F85D, + 0x2F85E, + 0x2F85F, + 0x2F860, + 0x2F861, + 0x2F862, + 0x2F863, + 0x2F864, + 0x2F865, + 0x2F866, + 0x2F867, + 0x2F868, + 0x2F869, + 0x2F86A, + 0x2F86C, + 0x2F86D, + 0x2F86E, + 0x2F86F, + 0x2F870, + 0x2F871, + 0x2F872, + 0x2F873, + 0x2F874, + 0x2F875, + 0x2F876, + 0x2F877, + 0x2F878, + 0x2F879, + 0x2F87A, + 0x2F87B, + 0x2F87C, + 0x2F87D, + 0x2F87E, + 0x2F87F, + 0x2F880, + 0x2F881, + 0x2F882, + 0x2F883, + 0x2F884, + 0x2F885, + 0x2F886, + 0x2F887, + 0x2F888, + 0x2F889, + 0x2F88A, + 0x2F88B, + 0x2F88C, + 0x2F88D, + 0x2F88E, + 0x2F88F, + 0x2F890, + 0x2F891, + 0x2F893, + 0x2F894, + 0x2F896, + 0x2F897, + 0x2F898, + 0x2F899, + 0x2F89A, + 0x2F89B, + 0x2F89C, + 0x2F89D, + 0x2F89E, + 0x2F89F, + 0x2F8A0, + 0x2F8A1, + 0x2F8A2, + 0x2F8A3, + 0x2F8A4, + 0x2F8A5, + 0x2F8A6, + 0x2F8A7, + 0x2F8A8, + 0x2F8A9, + 0x2F8AA, + 0x2F8AB, + 0x2F8AC, + 0x2F8AD, + 0x2F8AE, + 0x2F8AF, + 0x2F8B0, + 0x2F8B1, + 0x2F8B2, + 0x2F8B3, + 0x2F8B4, + 0x2F8B5, + 0x2F8B6, + 0x2F8B7, + 0x2F8B8, + 0x2F8B9, + 0x2F8BA, + 0x2F8BB, + 0x2F8BC, + 0x2F8BD, + 0x2F8BE, + 0x2F8BF, + 0x2F8C0, + 0x2F8C1, + 0x2F8C2, + 0x2F8C3, + 0x2F8C4, + 0x2F8C5, + 0x2F8C6, + 0x2F8C7, + 0x2F8C8, + 0x2F8C9, + 0x2F8CA, + 0x2F8CB, + 0x2F8CC, + 0x2F8CD, + 0x2F8CE, + 0x2F8CF, + 0x2F8D0, + 0x2F8D1, + 0x2F8D2, + 0x2F8D3, + 0x2F8D4, + 0x2F8D5, + 0x2F8D6, + 0x2F8D7, + 0x2F8D8, + 0x2F8D9, + 0x2F8DA, + 0x2F8DB, + 0x2F8DC, + 0x2F8DD, + 0x2F8DE, + 0x2F8DF, + 0x2F8E0, + 0x2F8E1, + 0x2F8E2, + 0x2F8E3, + 0x2F8E4, + 0x2F8E5, + 0x2F8E6, + 0x2F8E7, + 0x2F8E8, + 0x2F8E9, + 0x2F8EA, + 0x2F8EB, + 0x2F8EC, + 0x2F8ED, + 0x2F8EE, + 0x2F8EF, + 0x2F8F0, + 0x2F8F1, + 0x2F8F2, + 0x2F8F3, + 0x2F8F4, + 0x2F8F5, + 0x2F8F6, + 0x2F8F7, + 0x2F8F8, + 0x2F8F9, + 0x2F8FA, + 0x2F8FB, + 0x2F8FC, + 0x2F8FD, + 0x2F8FE, + 0x2F8FF, + 0x2F900, + 0x2F901, + 0x2F902, + 0x2F903, + 0x2F904, + 0x2F905, + 0x2F906, + 0x2F907, + 0x2F908, + 0x2F909, + 0x2F90A, + 0x2F90B, + 0x2F90C, + 0x2F90D, + 0x2F90E, + 0x2F90F, + 0x2F910, + 0x2F911, + 0x2F912, + 0x2F913, + 0x2F914, + 0x2F915, + 0x2F916, + 0x2F917, + 0x2F918, + 0x2F919, + 0x2F91A, + 0x2F91B, + 0x2F91C, + 0x2F91D, + 0x2F91E, + 0x2F91F, + 0x2F920, + 0x2F921, + 0x2F922, + 0x2F923, + 0x2F924, + 0x2F925, + 0x2F926, + 0x2F927, + 0x2F928, + 0x2F929, + 0x2F92A, + 0x2F92B, + 0x2F92C, + 0x2F92E, + 0x2F92F, + 0x2F930, + 0x2F931, + 0x2F932, + 0x2F933, + 0x2F934, + 0x2F935, + 0x2F936, + 0x2F937, + 0x2F938, + 0x2F939, + 0x2F93A, + 0x2F93B, + 0x2F93C, + 0x2F93D, + 0x2F93E, + 0x2F93F, + 0x2F940, + 0x2F941, + 0x2F942, + 0x2F943, + 0x2F944, + 0x2F945, + 0x2F946, + 0x2F948, + 0x2F949, + 0x2F94A, + 0x2F94B, + 0x2F94C, + 0x2F94D, + 0x2F94E, + 0x2F94F, + 0x2F950, + 0x2F951, + 0x2F952, + 0x2F953, + 0x2F954, + 0x2F955, + 0x2F956, + 0x2F957, + 0x2F958, + 0x2F959, + 0x2F95A, + 0x2F95B, + 0x2F95C, + 0x2F95D, + 0x2F95F, + 0x2F960, + 0x2F961, + 0x2F962, + 0x2F963, + 0x2F964, + 0x2F965, + 0x2F966, + 0x2F967, + 0x2F968, + 0x2F969, + 0x2F96A, + 0x2F96B, + 0x2F96C, + 0x2F96D, + 0x2F96E, + 0x2F96F, + 0x2F970, + 0x2F971, + 0x2F972, + 0x2F973, + 0x2F974, + 0x2F975, + 0x2F976, + 0x2F977, + 0x2F978, + 0x2F979, + 0x2F97A, + 0x2F97B, + 0x2F97C, + 0x2F97D, + 0x2F97E, + 0x2F97F, + 0x2F980, + 0x2F981, + 0x2F982, + 0x2F983, + 0x2F984, + 0x2F985, + 0x2F986, + 0x2F987, + 0x2F988, + 0x2F989, + 0x2F98A, + 0x2F98B, + 0x2F98C, + 0x2F98D, + 0x2F98E, + 0x2F98F, + 0x2F990, + 0x2F991, + 0x2F992, + 0x2F993, + 0x2F994, + 0x2F995, + 0x2F996, + 0x2F997, + 0x2F998, + 0x2F999, + 0x2F99A, + 0x2F99B, + 0x2F99C, + 0x2F99D, + 0x2F99E, + 0x2F99F, + 0x2F9A0, + 0x2F9A1, + 0x2F9A2, + 0x2F9A3, + 0x2F9A4, + 0x2F9A5, + 0x2F9A6, + 0x2F9A7, + 0x2F9A8, + 0x2F9A9, + 0x2F9AA, + 0x2F9AB, + 0x2F9AC, + 0x2F9AD, + 0x2F9AE, + 0x2F9AF, + 0x2F9B0, + 0x2F9B1, + 0x2F9B2, + 0x2F9B3, + 0x2F9B4, + 0x2F9B5, + 0x2F9B6, + 0x2F9B7, + 0x2F9B8, + 0x2F9B9, + 0x2F9BA, + 0x2F9BB, + 0x2F9BC, + 0x2F9BD, + 0x2F9BE, + 0x2F9BF, + 0x2F9C0, + 0x2F9C1, + 0x2F9C2, + 0x2F9C3, + 0x2F9C4, + 0x2F9C5, + 0x2F9C6, + 0x2F9C7, + 0x2F9C8, + 0x2F9C9, + 0x2F9CA, + 0x2F9CB, + 0x2F9CC, + 0x2F9CD, + 0x2F9CE, + 0x2F9CF, + 0x2F9D0, + 0x2F9D1, + 0x2F9D2, + 0x2F9D3, + 0x2F9D4, + 0x2F9D5, + 0x2F9D6, + 0x2F9D7, + 0x2F9D8, + 0x2F9D9, + 0x2F9DA, + 0x2F9DB, + 0x2F9DC, + 0x2F9DD, + 0x2F9DE, + 0x2F9DF, + 0x2F9E0, + 0x2F9E1, + 0x2F9E2, + 0x2F9E3, + 0x2F9E4, + 0x2F9E5, + 0x2F9E6, + 0x2F9E7, + 0x2F9E8, + 0x2F9E9, + 0x2F9EA, + 0x2F9EB, + 0x2F9EC, + 0x2F9ED, + 0x2F9EE, + 0x2F9EF, + 0x2F9F0, + 0x2F9F1, + 0x2F9F2, + 0x2F9F3, + 0x2F9F4, + 0x2F9F5, + 0x2F9F6, + 0x2F9F7, + 0x2F9F8, + 0x2F9F9, + 0x2F9FA, + 0x2F9FB, + 0x2F9FC, + 0x2F9FD, + 0x2F9FE, + 0x2FA00, + 0x2FA01, + 0x2FA02, + 0x2FA03, + 0x2FA04, + 0x2FA05, + 0x2FA06, + 0x2FA07, + 0x2FA08, + 0x2FA09, + 0x2FA0A, + 0x2FA0B, + 0x2FA0C, + 0x2FA0D, + 0x2FA0E, + 0x2FA0F, + 0x2FA10, + 0x2FA11, + 0x2FA12, + 0x2FA13, + 0x2FA14, + 0x2FA15, + 0x2FA16, + 0x2FA17, + 0x2FA18, + 0x2FA19, + 0x2FA1A, + 0x2FA1B, + 0x2FA1C, + 0x2FA1D, + 0x2FA1E, + 0x30000, + 0x3134B, + 0x31350, + 0x3347A, + 0xE0100, + 0xE01F0, + ), +) + +uts46_statuses: bytes = ( + b"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" + b"VMMMMMMMMMMMMMMMMMMMMMMMMMMVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" + b"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMVVVVVVVMVMVVIVMVVMMMMVVMMMVMMMV" + b"MMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMDVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" + b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMVMVMVMVMMV" + b"MVMVMVMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMVMVMVMM" + b"VMVMMVMMMVMMMMVMMVMMMVMMVMMVMVMVMMVMVMVMMVMMMVMVMMVMVMMMMVMVMVMV" + b"MVMVMVMVMVMVMVMVMVMVMVMVMVMMVMMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVM" + b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMMVMVMMMMVMVMVMVMVMMMMMMMMMVMMMMMM" + b"VMMMMMVMMVMMMVIVMVMVMVMVXMVMMXMMMMMMMXMXMMVMMMMMMMMMMMMMMMMMXMMM" + b"MMMMMMVDVMMMMMMMMVMVMVMVMVMVMVMVMVMVMVMVMVMMMVMMVMVMMVMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMVMVMVMVMVMVMVMVMVMV" + b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" + b"MVMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVM" + b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVXMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMXVMVXVXVXVXVXVXVMMMMVXVXVXVXVXVXVXVXVXVX" + b"VXVXVMMMMMMMMVXVXVXVXVXVXVXVXVXVXVXMMXMVXVXVXVXVXVXVXVMXVMXVXVXV" + b"XVXVXVXMMMVXMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" + b"VXMMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXV" + b"XVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXV" + b"XVMVXVXVXVXVXVXVXVMVXVXVXVXVXMMVXVMVMVXVMVMVMVMVMVXVMVMMMMMVMVMV" + b"XVMVMVMVMVMVXVXVXVMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMXMXVMV" + b"IVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXMMMMMMXVXVXVXVXVXVXVXVXVX" + b"VIVXVXVXVIVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVMMM" + b"MMMMMMVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMVXVXVMMMV" + b"MMMMMMMMMMMVMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" + b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" + b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMVM" + b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVM" + b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMMMMMMMVXMMMMMMXVMMMMMMMMVMMMMMM" + b"MMVXMMMMMMXVXMXMXMXMVMMMMMMMMVMVMVMVMVMVMVMXMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMXVMMMMMMMMMMMMMMXVMMMMMMMMMVMXVM" + b"MMMXMMMVMVMMMMMMMMXMMMXVMMMMMMMMXMIDXVMVMVXVXMVMMVMMVMVMVMMMVMVM" + b"IXIMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMXVMVXVXMMMMVMMMVM" + b"MMMMMVMMVMMMVMMMVMVMVMVMMMMVMMMMMMMMMMVMMMMMVMMMMVMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMVXVMMVMMVMMVXVXMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMMMVMVXVMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMMMVMVMVMVMMMMVMVMVMM" + b"MMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" + b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVXVXVXVXVXMVXVXVXVXVX" + b"VXVXVXVXVXVXVXVMVMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMVMVMVMMMVXVXVMMVMVMXV" + b"XMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMIMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXVMMMMMMMMMMMMMMVXVMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMXMMMMMMMMMMMMM" + b"MMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXMVMVMVMVMVMVMVM" + b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMVXV" + b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" + b"MVMVMVMVMVMVMVMVMVMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMMMMVM" + b"MMMMVMVMVMVMVMVMVMVMMMMVMVMMVMVMVMVMVMVMVMVMXMMMMMVMMVXVXVXVXVXV" + b"XVXVXVXVXVXVXVXVXVXVXVXVXVXVXVMMMMVMVXMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXVXVX" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMVMVMVMMMMMMMMMMVMVMVMMVMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMXMMMMMMXMMMMMXMVMMMMMMMMMMMMMMMMMMMMMMMMXMMMMM" + b"XMXMMXMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMVMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXMMMMMMMMMMMMMVIMMXMMM" + b"MMMXVXMMMMMMMMMMMMMMMMMMMVMMMMMMXMMMMMMMMMMMMMMMMMMMXMMMMXMMMVMX" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXIXMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMIMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMXMMMMM" + b"MXMMMMMMXMMMXMMMMMMMXMMMMMMMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXV" + b"XVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVMMMMMMMMMMMXMMMMMMMMMMMMMMMXMMM" + b"MMMMXMMXVXVXVXVXVXVXVXVXVMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMXMMMMMMMMMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" + b"VXVXVXVXVXVXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMXVXVXVXVMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVXVXVXVXVXVXVXVXVX" + b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" + b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" + b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" + b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMVXMMMMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVXVXVXVXVXVXVXVXVXVX" + b"VXVXVXVXVXVXVXVXVXVIXVMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVX" + b"VXVXVXVXVXVXVMMMMMMMVIVMMMMMMVXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMXMMXMXMMXMMMMXMMMMMMMMMMMMXMXMMMMMMMXMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMXMMMMMMMMXMMMMM" + b"MMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMXMMMMMXMXMMMMMMMXMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXVXVXVXVXVXVXVXMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVXVXVXVXVXVX" + b"VXVXVXVXVXVXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXVX" + b"VXMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMXMXMXMMMMMMMMMMXMMMMXMXMXMX" + b"MXMXMXMMMXMMXMXMXMXMXMXMXMMXMXMMMMXMMMMMMMXMMMMXMMMMXMXMMMMMMMMM" + b"MXMMMMMMMMMMMMMMMMMXMMMXMMMMMXMMMMMMMMMMMMMMMMMXVXVXVXVXVXVXVXMM" + b"MMMMMMMMVMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMVMMMVMVXVMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMXMMMMMMMMMXMMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" + b"VXVMMMMMMMMMMVXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXVXVXIX" +) + +uts46_replacements: tuple[Optional[str], ...] = ( + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + " ", + None, + None, + None, + None, + None, + None, + None, + " ̈", + None, + "a", + None, + None, + None, + None, + " ̄", + None, + None, + "2", + "3", + " ́", + "μ", + None, + None, + " ̧", + "1", + "o", + None, + "1⁄4", + "1⁄2", + "3⁄4", + None, + "à", + "á", + "â", + "ã", + "ä", + "å", + "æ", + "ç", + "è", + "é", + "ê", + "ë", + "ì", + "í", + "î", + "ï", + "ð", + "ñ", + "ò", + "ó", + "ô", + "õ", + "ö", + None, + "ø", + "ù", + "ú", + "û", + "ü", + "ý", + "þ", + "ss", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ā", + None, + "ă", + None, + "ą", + None, + "ć", + None, + "ĉ", + None, + "ċ", + None, + "č", + None, + "ď", + None, + "đ", + None, + "ē", + None, + "ĕ", + None, + "ė", + None, + "ę", + None, + "ě", + None, + "ĝ", + None, + "ğ", + None, + "ġ", + None, + "ģ", + None, + "ĥ", + None, + "ħ", + None, + "ĩ", + None, + "ī", + None, + "ĭ", + None, + "į", + None, + "i̇", + None, + "ij", + "ĵ", + None, + "ķ", + None, + "ĺ", + None, + "ļ", + None, + "ľ", + None, + "l·", + "ł", + None, + "ń", + None, + "ņ", + None, + "ň", + None, + "ʼn", + "ŋ", + None, + "ō", + None, + "ŏ", + None, + "ő", + None, + "œ", + None, + "ŕ", + None, + "ŗ", + None, + "ř", + None, + "ś", + None, + "ŝ", + None, + "ş", + None, + "š", + None, + "ţ", + None, + "ť", + None, + "ŧ", + None, + "ũ", + None, + "ū", + None, + "ŭ", + None, + "ů", + None, + "ű", + None, + "ų", + None, + "ŵ", + None, + "ŷ", + None, + "ÿ", + "ź", + None, + "ż", + None, + "ž", + None, + "s", + None, + "ɓ", + "ƃ", + None, + "ƅ", + None, + "ɔ", + "ƈ", + None, + "ɖ", + "ɗ", + "ƌ", + None, + "ǝ", + "ə", + "ɛ", + "ƒ", + None, + "ɠ", + "ɣ", + None, + "ɩ", + "ɨ", + "ƙ", + None, + "ɯ", + "ɲ", + None, + "ɵ", + "ơ", + None, + "ƣ", + None, + "ƥ", + None, + "ʀ", + "ƨ", + None, + "ʃ", + None, + "ƭ", + None, + "ʈ", + "ư", + None, + "ʊ", + "ʋ", + "ƴ", + None, + "ƶ", + None, + "ʒ", + "ƹ", + None, + "ƽ", + None, + "dž", + "lj", + "nj", + "ǎ", + None, + "ǐ", + None, + "ǒ", + None, + "ǔ", + None, + "ǖ", + None, + "ǘ", + None, + "ǚ", + None, + "ǜ", + None, + "ǟ", + None, + "ǡ", + None, + "ǣ", + None, + "ǥ", + None, + "ǧ", + None, + "ǩ", + None, + "ǫ", + None, + "ǭ", + None, + "ǯ", + None, + "dz", + "ǵ", + None, + "ƕ", + "ƿ", + "ǹ", + None, + "ǻ", + None, + "ǽ", + None, + "ǿ", + None, + "ȁ", + None, + "ȃ", + None, + "ȅ", + None, + "ȇ", + None, + "ȉ", + None, + "ȋ", + None, + "ȍ", + None, + "ȏ", + None, + "ȑ", + None, + "ȓ", + None, + "ȕ", + None, + "ȗ", + None, + "ș", + None, + "ț", + None, + "ȝ", + None, + "ȟ", + None, + "ƞ", + None, + "ȣ", + None, + "ȥ", + None, + "ȧ", + None, + "ȩ", + None, + "ȫ", + None, + "ȭ", + None, + "ȯ", + None, + "ȱ", + None, + "ȳ", + None, + "ⱥ", + "ȼ", + None, + "ƚ", + "ⱦ", + None, + "ɂ", + None, + "ƀ", + "ʉ", + "ʌ", + "ɇ", + None, + "ɉ", + None, + "ɋ", + None, + "ɍ", + None, + "ɏ", + None, + "h", + "ɦ", + "j", + "r", + "ɹ", + "ɻ", + "ʁ", + "w", + "y", + None, + " ̆", + " ̇", + " ̊", + " ̨", + " ̃", + " ̋", + None, + "ɣ", + "l", + "s", + "x", + "ʕ", + None, + "̀", + "́", + None, + "̓", + "̈́", + "ι", + None, + None, + None, + "ͱ", + None, + "ͳ", + None, + "ʹ", + None, + "ͷ", + None, + None, + " ι", + None, + ";", + "ϳ", + None, + " ́", + " ̈́", + "ά", + "·", + "έ", + "ή", + "ί", + None, + "ό", + None, + "ύ", + "ώ", + None, + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + None, + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "ϊ", + "ϋ", + None, + "σ", + None, + "ϗ", + "β", + "θ", + "υ", + "ύ", + "ϋ", + "φ", + "π", + None, + "ϙ", + None, + "ϛ", + None, + "ϝ", + None, + "ϟ", + None, + "ϡ", + None, + "ϣ", + None, + "ϥ", + None, + "ϧ", + None, + "ϩ", + None, + "ϫ", + None, + "ϭ", + None, + "ϯ", + None, + "κ", + "ρ", + "σ", + None, + "θ", + "ε", + None, + "ϸ", + None, + "σ", + "ϻ", + None, + "ͻ", + "ͼ", + "ͽ", + "ѐ", + "ё", + "ђ", + "ѓ", + "є", + "ѕ", + "і", + "ї", + "ј", + "љ", + "њ", + "ћ", + "ќ", + "ѝ", + "ў", + "џ", + "а", + "б", + "в", + "г", + "д", + "е", + "ж", + "з", + "и", + "й", + "к", + "л", + "м", + "н", + "о", + "п", + "р", + "с", + "т", + "у", + "ф", + "х", + "ц", + "ч", + "ш", + "щ", + "ъ", + "ы", + "ь", + "э", + "ю", + "я", + None, + "ѡ", + None, + "ѣ", + None, + "ѥ", + None, + "ѧ", + None, + "ѩ", + None, + "ѫ", + None, + "ѭ", + None, + "ѯ", + None, + "ѱ", + None, + "ѳ", + None, + "ѵ", + None, + "ѷ", + None, + "ѹ", + None, + "ѻ", + None, + "ѽ", + None, + "ѿ", + None, + "ҁ", + None, + "ҋ", + None, + "ҍ", + None, + "ҏ", + None, + "ґ", + None, + "ғ", + None, + "ҕ", + None, + "җ", + None, + "ҙ", + None, + "қ", + None, + "ҝ", + None, + "ҟ", + None, + "ҡ", + None, + "ң", + None, + "ҥ", + None, + "ҧ", + None, + "ҩ", + None, + "ҫ", + None, + "ҭ", + None, + "ү", + None, + "ұ", + None, + "ҳ", + None, + "ҵ", + None, + "ҷ", + None, + "ҹ", + None, + "һ", + None, + "ҽ", + None, + "ҿ", + None, + "ӏ", + "ӂ", + None, + "ӄ", + None, + "ӆ", + None, + "ӈ", + None, + "ӊ", + None, + "ӌ", + None, + "ӎ", + None, + "ӑ", + None, + "ӓ", + None, + "ӕ", + None, + "ӗ", + None, + "ә", + None, + "ӛ", + None, + "ӝ", + None, + "ӟ", + None, + "ӡ", + None, + "ӣ", + None, + "ӥ", + None, + "ӧ", + None, + "ө", + None, + "ӫ", + None, + "ӭ", + None, + "ӯ", + None, + "ӱ", + None, + "ӳ", + None, + "ӵ", + None, + "ӷ", + None, + "ӹ", + None, + "ӻ", + None, + "ӽ", + None, + "ӿ", + None, + "ԁ", + None, + "ԃ", + None, + "ԅ", + None, + "ԇ", + None, + "ԉ", + None, + "ԋ", + None, + "ԍ", + None, + "ԏ", + None, + "ԑ", + None, + "ԓ", + None, + "ԕ", + None, + "ԗ", + None, + "ԙ", + None, + "ԛ", + None, + "ԝ", + None, + "ԟ", + None, + "ԡ", + None, + "ԣ", + None, + "ԥ", + None, + "ԧ", + None, + "ԩ", + None, + "ԫ", + None, + "ԭ", + None, + "ԯ", + None, + None, + "ա", + "բ", + "գ", + "դ", + "ե", + "զ", + "է", + "ը", + "թ", + "ժ", + "ի", + "լ", + "խ", + "ծ", + "կ", + "հ", + "ձ", + "ղ", + "ճ", + "մ", + "յ", + "ն", + "շ", + "ո", + "չ", + "պ", + "ջ", + "ռ", + "ս", + "վ", + "տ", + "ր", + "ց", + "ւ", + "փ", + "ք", + "օ", + "ֆ", + None, + None, + "եւ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "اٴ", + "وٴ", + "ۇٴ", + "يٴ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "क़", + "ख़", + "ग़", + "ज़", + "ड़", + "ढ़", + "फ़", + "य़", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ড়", + "ঢ়", + None, + "য়", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ਲ਼", + None, + None, + "ਸ਼", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ਖ਼", + "ਗ਼", + "ਜ਼", + None, + None, + "ਫ਼", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ଡ଼", + "ଢ଼", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ํา", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ໍາ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ຫນ", + "ຫມ", + None, + None, + None, + "་", + None, + "གྷ", + None, + None, + None, + "ཌྷ", + None, + "དྷ", + None, + "བྷ", + None, + "ཛྷ", + None, + "ཀྵ", + None, + None, + None, + "ཱི", + None, + "ཱུ", + "ྲྀ", + "ྲཱྀ", + "ླྀ", + "ླཱྀ", + None, + "ཱྀ", + None, + "ྒྷ", + None, + None, + None, + "ྜྷ", + None, + "ྡྷ", + None, + "ྦྷ", + None, + "ྫྷ", + None, + "ྐྵ", + None, + None, + None, + None, + None, + None, + None, + "ⴀ", + "ⴁ", + "ⴂ", + "ⴃ", + "ⴄ", + "ⴅ", + "ⴆ", + "ⴇ", + "ⴈ", + "ⴉ", + "ⴊ", + "ⴋ", + "ⴌ", + "ⴍ", + "ⴎ", + "ⴏ", + "ⴐ", + "ⴑ", + "ⴒ", + "ⴓ", + "ⴔ", + "ⴕ", + "ⴖ", + "ⴗ", + "ⴘ", + "ⴙ", + "ⴚ", + "ⴛ", + "ⴜ", + "ⴝ", + "ⴞ", + "ⴟ", + "ⴠ", + "ⴡ", + "ⴢ", + "ⴣ", + "ⴤ", + "ⴥ", + None, + "ⴧ", + None, + "ⴭ", + None, + None, + "ნ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "Ᏸ", + "Ᏹ", + "Ᏺ", + "Ᏻ", + "Ᏼ", + "Ᏽ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "в", + "д", + "о", + "с", + "т", + "ъ", + "ѣ", + "ꙋ", + "\u1c8a", + None, + None, + "ა", + "ბ", + "გ", + "დ", + "ე", + "ვ", + "ზ", + "თ", + "ი", + "კ", + "ლ", + "მ", + "ნ", + "ო", + "პ", + "ჟ", + "რ", + "ს", + "ტ", + "უ", + "ფ", + "ქ", + "ღ", + "ყ", + "შ", + "ჩ", + "ც", + "ძ", + "წ", + "ჭ", + "ხ", + "ჯ", + "ჰ", + "ჱ", + "ჲ", + "ჳ", + "ჴ", + "ჵ", + "ჶ", + "ჷ", + "ჸ", + "ჹ", + "ჺ", + None, + "ჽ", + "ჾ", + "ჿ", + None, + None, + None, + None, + None, + "a", + "æ", + "b", + None, + "d", + "e", + "ǝ", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + None, + "o", + "ȣ", + "p", + "r", + "t", + "u", + "w", + "a", + "ɐ", + "ɑ", + "ᴂ", + "b", + "d", + "e", + "ə", + "ɛ", + "ɜ", + "g", + None, + "k", + "m", + "ŋ", + "o", + "ɔ", + "ᴖ", + "ᴗ", + "p", + "t", + "u", + "ᴝ", + "ɯ", + "v", + "ᴥ", + "β", + "γ", + "δ", + "φ", + "χ", + "i", + "r", + "u", + "v", + "β", + "γ", + "ρ", + "φ", + "χ", + None, + "н", + None, + "ɒ", + "c", + "ɕ", + "ð", + "ɜ", + "f", + "ɟ", + "ɡ", + "ɥ", + "ɨ", + "ɩ", + "ɪ", + "ᵻ", + "ʝ", + "ɭ", + "ᶅ", + "ʟ", + "ɱ", + "ɰ", + "ɲ", + "ɳ", + "ɴ", + "ɵ", + "ɸ", + "ʂ", + "ʃ", + "ƫ", + "ʉ", + "ʊ", + "ᴜ", + "ʋ", + "ʌ", + "z", + "ʐ", + "ʑ", + "ʒ", + "θ", + None, + "ḁ", + None, + "ḃ", + None, + "ḅ", + None, + "ḇ", + None, + "ḉ", + None, + "ḋ", + None, + "ḍ", + None, + "ḏ", + None, + "ḑ", + None, + "ḓ", + None, + "ḕ", + None, + "ḗ", + None, + "ḙ", + None, + "ḛ", + None, + "ḝ", + None, + "ḟ", + None, + "ḡ", + None, + "ḣ", + None, + "ḥ", + None, + "ḧ", + None, + "ḩ", + None, + "ḫ", + None, + "ḭ", + None, + "ḯ", + None, + "ḱ", + None, + "ḳ", + None, + "ḵ", + None, + "ḷ", + None, + "ḹ", + None, + "ḻ", + None, + "ḽ", + None, + "ḿ", + None, + "ṁ", + None, + "ṃ", + None, + "ṅ", + None, + "ṇ", + None, + "ṉ", + None, + "ṋ", + None, + "ṍ", + None, + "ṏ", + None, + "ṑ", + None, + "ṓ", + None, + "ṕ", + None, + "ṗ", + None, + "ṙ", + None, + "ṛ", + None, + "ṝ", + None, + "ṟ", + None, + "ṡ", + None, + "ṣ", + None, + "ṥ", + None, + "ṧ", + None, + "ṩ", + None, + "ṫ", + None, + "ṭ", + None, + "ṯ", + None, + "ṱ", + None, + "ṳ", + None, + "ṵ", + None, + "ṷ", + None, + "ṹ", + None, + "ṻ", + None, + "ṽ", + None, + "ṿ", + None, + "ẁ", + None, + "ẃ", + None, + "ẅ", + None, + "ẇ", + None, + "ẉ", + None, + "ẋ", + None, + "ẍ", + None, + "ẏ", + None, + "ẑ", + None, + "ẓ", + None, + "ẕ", + None, + "aʾ", + "ṡ", + None, + "ß", + None, + "ạ", + None, + "ả", + None, + "ấ", + None, + "ầ", + None, + "ẩ", + None, + "ẫ", + None, + "ậ", + None, + "ắ", + None, + "ằ", + None, + "ẳ", + None, + "ẵ", + None, + "ặ", + None, + "ẹ", + None, + "ẻ", + None, + "ẽ", + None, + "ế", + None, + "ề", + None, + "ể", + None, + "ễ", + None, + "ệ", + None, + "ỉ", + None, + "ị", + None, + "ọ", + None, + "ỏ", + None, + "ố", + None, + "ồ", + None, + "ổ", + None, + "ỗ", + None, + "ộ", + None, + "ớ", + None, + "ờ", + None, + "ở", + None, + "ỡ", + None, + "ợ", + None, + "ụ", + None, + "ủ", + None, + "ứ", + None, + "ừ", + None, + "ử", + None, + "ữ", + None, + "ự", + None, + "ỳ", + None, + "ỵ", + None, + "ỷ", + None, + "ỹ", + None, + "ỻ", + None, + "ỽ", + None, + "ỿ", + None, + "ἀ", + "ἁ", + "ἂ", + "ἃ", + "ἄ", + "ἅ", + "ἆ", + "ἇ", + None, + None, + "ἐ", + "ἑ", + "ἒ", + "ἓ", + "ἔ", + "ἕ", + None, + None, + "ἠ", + "ἡ", + "ἢ", + "ἣ", + "ἤ", + "ἥ", + "ἦ", + "ἧ", + None, + "ἰ", + "ἱ", + "ἲ", + "ἳ", + "ἴ", + "ἵ", + "ἶ", + "ἷ", + None, + None, + "ὀ", + "ὁ", + "ὂ", + "ὃ", + "ὄ", + "ὅ", + None, + None, + None, + "ὑ", + None, + "ὓ", + None, + "ὕ", + None, + "ὗ", + None, + "ὠ", + "ὡ", + "ὢ", + "ὣ", + "ὤ", + "ὥ", + "ὦ", + "ὧ", + None, + "ά", + None, + "έ", + None, + "ή", + None, + "ί", + None, + "ό", + None, + "ύ", + None, + "ώ", + None, + "ἀι", + "ἁι", + "ἂι", + "ἃι", + "ἄι", + "ἅι", + "ἆι", + "ἇι", + "ἀι", + "ἁι", + "ἂι", + "ἃι", + "ἄι", + "ἅι", + "ἆι", + "ἇι", + "ἠι", + "ἡι", + "ἢι", + "ἣι", + "ἤι", + "ἥι", + "ἦι", + "ἧι", + "ἠι", + "ἡι", + "ἢι", + "ἣι", + "ἤι", + "ἥι", + "ἦι", + "ἧι", + "ὠι", + "ὡι", + "ὢι", + "ὣι", + "ὤι", + "ὥι", + "ὦι", + "ὧι", + "ὠι", + "ὡι", + "ὢι", + "ὣι", + "ὤι", + "ὥι", + "ὦι", + "ὧι", + None, + "ὰι", + "αι", + "άι", + None, + None, + "ᾶι", + "ᾰ", + "ᾱ", + "ὰ", + "ά", + "αι", + " ̓", + "ι", + " ̓", + " ͂", + " ̈͂", + "ὴι", + "ηι", + "ήι", + None, + None, + "ῆι", + "ὲ", + "έ", + "ὴ", + "ή", + "ηι", + " ̓̀", + " ̓́", + " ̓͂", + None, + "ΐ", + None, + None, + "ῐ", + "ῑ", + "ὶ", + "ί", + None, + " ̔̀", + " ̔́", + " ̔͂", + None, + "ΰ", + None, + "ῠ", + "ῡ", + "ὺ", + "ύ", + "ῥ", + " ̈̀", + " ̈́", + "`", + None, + "ὼι", + "ωι", + "ώι", + None, + None, + "ῶι", + "ὸ", + "ό", + "ὼ", + "ώ", + "ωι", + " ́", + " ̔", + None, + " ", + None, + "", + None, + None, + "‐", + None, + " ̳", + None, + None, + None, + None, + " ", + None, + "′′", + "′′′", + None, + "‵‵", + "‵‵‵", + None, + "!!", + None, + " ̅", + None, + "??", + "?!", + "!?", + None, + "′′′′", + None, + " ", + None, + None, + None, + "0", + "i", + None, + "4", + "5", + "6", + "7", + "8", + "9", + "+", + "−", + "=", + "(", + ")", + "n", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "+", + "−", + "=", + "(", + ")", + None, + "a", + "e", + "o", + "x", + "ə", + "h", + "k", + "l", + "m", + "n", + "p", + "s", + "t", + None, + None, + "rs", + None, + None, + None, + None, + "a/c", + "a/s", + "c", + "°c", + None, + "c/o", + "c/u", + "ɛ", + None, + "°f", + "g", + "h", + "ħ", + "i", + "l", + None, + "n", + "no", + None, + "p", + "q", + "r", + None, + "sm", + "tel", + "tm", + None, + "z", + None, + "ω", + None, + "z", + None, + "k", + "å", + "b", + "c", + None, + "e", + "f", + "ⅎ", + "m", + "o", + "א", + "ב", + "ג", + "ד", + "i", + None, + "fax", + "π", + "γ", + "π", + "∑", + None, + "d", + "e", + "i", + "j", + None, + "1⁄7", + "1⁄9", + "1⁄10", + "1⁄3", + "2⁄3", + "1⁄5", + "2⁄5", + "3⁄5", + "4⁄5", + "1⁄6", + "5⁄6", + "1⁄8", + "3⁄8", + "5⁄8", + "7⁄8", + "1⁄", + "i", + "ii", + "iii", + "iv", + "v", + "vi", + "vii", + "viii", + "ix", + "x", + "xi", + "xii", + "l", + "c", + "d", + "m", + "i", + "ii", + "iii", + "iv", + "v", + "vi", + "vii", + "viii", + "ix", + "x", + "xi", + "xii", + "l", + "c", + "d", + "m", + None, + "ↄ", + None, + "0⁄3", + None, + None, + None, + "∫∫", + "∫∫∫", + None, + "∮∮", + "∮∮∮", + None, + "〈", + "〉", + None, + None, + None, + None, + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "20", + "(1)", + "(2)", + "(3)", + "(4)", + "(5)", + "(6)", + "(7)", + "(8)", + "(9)", + "(10)", + "(11)", + "(12)", + "(13)", + "(14)", + "(15)", + "(16)", + "(17)", + "(18)", + "(19)", + "(20)", + None, + "(a)", + "(b)", + "(c)", + "(d)", + "(e)", + "(f)", + "(g)", + "(h)", + "(i)", + "(j)", + "(k)", + "(l)", + "(m)", + "(n)", + "(o)", + "(p)", + "(q)", + "(r)", + "(s)", + "(t)", + "(u)", + "(v)", + "(w)", + "(x)", + "(y)", + "(z)", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "0", + None, + "∫∫∫∫", + None, + "::=", + "==", + "===", + None, + "⫝̸", + None, + None, + None, + "ⰰ", + "ⰱ", + "ⰲ", + "ⰳ", + "ⰴ", + "ⰵ", + "ⰶ", + "ⰷ", + "ⰸ", + "ⰹ", + "ⰺ", + "ⰻ", + "ⰼ", + "ⰽ", + "ⰾ", + "ⰿ", + "ⱀ", + "ⱁ", + "ⱂ", + "ⱃ", + "ⱄ", + "ⱅ", + "ⱆ", + "ⱇ", + "ⱈ", + "ⱉ", + "ⱊ", + "ⱋ", + "ⱌ", + "ⱍ", + "ⱎ", + "ⱏ", + "ⱐ", + "ⱑ", + "ⱒ", + "ⱓ", + "ⱔ", + "ⱕ", + "ⱖ", + "ⱗ", + "ⱘ", + "ⱙ", + "ⱚ", + "ⱛ", + "ⱜ", + "ⱝ", + "ⱞ", + "ⱟ", + None, + "ⱡ", + None, + "ɫ", + "ᵽ", + "ɽ", + None, + "ⱨ", + None, + "ⱪ", + None, + "ⱬ", + None, + "ɑ", + "ɱ", + "ɐ", + "ɒ", + None, + "ⱳ", + None, + "ⱶ", + None, + "j", + "v", + "ȿ", + "ɀ", + "ⲁ", + None, + "ⲃ", + None, + "ⲅ", + None, + "ⲇ", + None, + "ⲉ", + None, + "ⲋ", + None, + "ⲍ", + None, + "ⲏ", + None, + "ⲑ", + None, + "ⲓ", + None, + "ⲕ", + None, + "ⲗ", + None, + "ⲙ", + None, + "ⲛ", + None, + "ⲝ", + None, + "ⲟ", + None, + "ⲡ", + None, + "ⲣ", + None, + "ⲥ", + None, + "ⲧ", + None, + "ⲩ", + None, + "ⲫ", + None, + "ⲭ", + None, + "ⲯ", + None, + "ⲱ", + None, + "ⲳ", + None, + "ⲵ", + None, + "ⲷ", + None, + "ⲹ", + None, + "ⲻ", + None, + "ⲽ", + None, + "ⲿ", + None, + "ⳁ", + None, + "ⳃ", + None, + "ⳅ", + None, + "ⳇ", + None, + "ⳉ", + None, + "ⳋ", + None, + "ⳍ", + None, + "ⳏ", + None, + "ⳑ", + None, + "ⳓ", + None, + "ⳕ", + None, + "ⳗ", + None, + "ⳙ", + None, + "ⳛ", + None, + "ⳝ", + None, + "ⳟ", + None, + "ⳡ", + None, + "ⳣ", + None, + "ⳬ", + None, + "ⳮ", + None, + "ⳳ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ⵡ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "母", + None, + "龟", + None, + "一", + "丨", + "丶", + "丿", + "乙", + "亅", + "二", + "亠", + "人", + "儿", + "入", + "八", + "冂", + "冖", + "冫", + "几", + "凵", + "刀", + "力", + "勹", + "匕", + "匚", + "匸", + "十", + "卜", + "卩", + "厂", + "厶", + "又", + "口", + "囗", + "土", + "士", + "夂", + "夊", + "夕", + "大", + "女", + "子", + "宀", + "寸", + "小", + "尢", + "尸", + "屮", + "山", + "巛", + "工", + "己", + "巾", + "干", + "幺", + "广", + "廴", + "廾", + "弋", + "弓", + "彐", + "彡", + "彳", + "心", + "戈", + "戶", + "手", + "支", + "攴", + "文", + "斗", + "斤", + "方", + "无", + "日", + "曰", + "月", + "木", + "欠", + "止", + "歹", + "殳", + "毋", + "比", + "毛", + "氏", + "气", + "水", + "火", + "爪", + "父", + "爻", + "爿", + "片", + "牙", + "牛", + "犬", + "玄", + "玉", + "瓜", + "瓦", + "甘", + "生", + "用", + "田", + "疋", + "疒", + "癶", + "白", + "皮", + "皿", + "目", + "矛", + "矢", + "石", + "示", + "禸", + "禾", + "穴", + "立", + "竹", + "米", + "糸", + "缶", + "网", + "羊", + "羽", + "老", + "而", + "耒", + "耳", + "聿", + "肉", + "臣", + "自", + "至", + "臼", + "舌", + "舛", + "舟", + "艮", + "色", + "艸", + "虍", + "虫", + "血", + "行", + "衣", + "襾", + "見", + "角", + "言", + "谷", + "豆", + "豕", + "豸", + "貝", + "赤", + "走", + "足", + "身", + "車", + "辛", + "辰", + "辵", + "邑", + "酉", + "釆", + "里", + "金", + "長", + "門", + "阜", + "隶", + "隹", + "雨", + "靑", + "非", + "面", + "革", + "韋", + "韭", + "音", + "頁", + "風", + "飛", + "食", + "首", + "香", + "馬", + "骨", + "高", + "髟", + "鬥", + "鬯", + "鬲", + "鬼", + "魚", + "鳥", + "鹵", + "鹿", + "麥", + "麻", + "黃", + "黍", + "黑", + "黹", + "黽", + "鼎", + "鼓", + "鼠", + "鼻", + "齊", + "齒", + "龍", + "龜", + "龠", + None, + " ", + None, + ".", + None, + "〒", + None, + "十", + "卄", + "卅", + None, + None, + None, + None, + None, + " ゙", + " ゚", + None, + "より", + None, + "コト", + None, + None, + None, + "ᄀ", + "ᄁ", + "ᆪ", + "ᄂ", + "ᆬ", + "ᆭ", + "ᄃ", + "ᄄ", + "ᄅ", + "ᆰ", + "ᆱ", + "ᆲ", + "ᆳ", + "ᆴ", + "ᆵ", + "ᄚ", + "ᄆ", + "ᄇ", + "ᄈ", + "ᄡ", + "ᄉ", + "ᄊ", + "ᄋ", + "ᄌ", + "ᄍ", + "ᄎ", + "ᄏ", + "ᄐ", + "ᄑ", + "ᄒ", + "ᅡ", + "ᅢ", + "ᅣ", + "ᅤ", + "ᅥ", + "ᅦ", + "ᅧ", + "ᅨ", + "ᅩ", + "ᅪ", + "ᅫ", + "ᅬ", + "ᅭ", + "ᅮ", + "ᅯ", + "ᅰ", + "ᅱ", + "ᅲ", + "ᅳ", + "ᅴ", + "ᅵ", + None, + "ᄔ", + "ᄕ", + "ᇇ", + "ᇈ", + "ᇌ", + "ᇎ", + "ᇓ", + "ᇗ", + "ᇙ", + "ᄜ", + "ᇝ", + "ᇟ", + "ᄝ", + "ᄞ", + "ᄠ", + "ᄢ", + "ᄣ", + "ᄧ", + "ᄩ", + "ᄫ", + "ᄬ", + "ᄭ", + "ᄮ", + "ᄯ", + "ᄲ", + "ᄶ", + "ᅀ", + "ᅇ", + "ᅌ", + "ᇱ", + "ᇲ", + "ᅗ", + "ᅘ", + "ᅙ", + "ᆄ", + "ᆅ", + "ᆈ", + "ᆑ", + "ᆒ", + "ᆔ", + "ᆞ", + "ᆡ", + None, + None, + "一", + "二", + "三", + "四", + "上", + "中", + "下", + "甲", + "乙", + "丙", + "丁", + "天", + "地", + "人", + None, + None, + None, + "(ᄀ)", + "(ᄂ)", + "(ᄃ)", + "(ᄅ)", + "(ᄆ)", + "(ᄇ)", + "(ᄉ)", + "(ᄋ)", + "(ᄌ)", + "(ᄎ)", + "(ᄏ)", + "(ᄐ)", + "(ᄑ)", + "(ᄒ)", + "(가)", + "(나)", + "(다)", + "(라)", + "(마)", + "(바)", + "(사)", + "(아)", + "(자)", + "(차)", + "(카)", + "(타)", + "(파)", + "(하)", + "(주)", + "(오전)", + "(오후)", + None, + "(一)", + "(二)", + "(三)", + "(四)", + "(五)", + "(六)", + "(七)", + "(八)", + "(九)", + "(十)", + "(月)", + "(火)", + "(水)", + "(木)", + "(金)", + "(土)", + "(日)", + "(株)", + "(有)", + "(社)", + "(名)", + "(特)", + "(財)", + "(祝)", + "(労)", + "(代)", + "(呼)", + "(学)", + "(監)", + "(企)", + "(資)", + "(協)", + "(祭)", + "(休)", + "(自)", + "(至)", + "問", + "幼", + "文", + "箏", + None, + "pte", + "21", + "22", + "23", + "24", + "25", + "26", + "27", + "28", + "29", + "30", + "31", + "32", + "33", + "34", + "35", + "ᄀ", + "ᄂ", + "ᄃ", + "ᄅ", + "ᄆ", + "ᄇ", + "ᄉ", + "ᄋ", + "ᄌ", + "ᄎ", + "ᄏ", + "ᄐ", + "ᄑ", + "ᄒ", + "가", + "나", + "다", + "라", + "마", + "바", + "사", + "아", + "자", + "차", + "카", + "타", + "파", + "하", + "참고", + "주의", + "우", + None, + "一", + "二", + "三", + "四", + "五", + "六", + "七", + "八", + "九", + "十", + "月", + "火", + "水", + "木", + "金", + "土", + "日", + "株", + "有", + "社", + "名", + "特", + "財", + "祝", + "労", + "秘", + "男", + "女", + "適", + "優", + "印", + "注", + "項", + "休", + "写", + "正", + "上", + "中", + "下", + "左", + "右", + "医", + "宗", + "学", + "監", + "企", + "資", + "協", + "夜", + "36", + "37", + "38", + "39", + "40", + "41", + "42", + "43", + "44", + "45", + "46", + "47", + "48", + "49", + "50", + "1月", + "2月", + "3月", + "4月", + "5月", + "6月", + "7月", + "8月", + "9月", + "10月", + "11月", + "12月", + "hg", + "erg", + "ev", + "ltd", + "ア", + "イ", + "ウ", + "エ", + "オ", + "カ", + "キ", + "ク", + "ケ", + "コ", + "サ", + "シ", + "ス", + "セ", + "ソ", + "タ", + "チ", + "ツ", + "テ", + "ト", + "ナ", + "ニ", + "ヌ", + "ネ", + "ノ", + "ハ", + "ヒ", + "フ", + "ヘ", + "ホ", + "マ", + "ミ", + "ム", + "メ", + "モ", + "ヤ", + "ユ", + "ヨ", + "ラ", + "リ", + "ル", + "レ", + "ロ", + "ワ", + "ヰ", + "ヱ", + "ヲ", + "令和", + "アパート", + "アルファ", + "アンペア", + "アール", + "イニング", + "インチ", + "ウォン", + "エスクード", + "エーカー", + "オンス", + "オーム", + "カイリ", + "カラット", + "カロリー", + "ガロン", + "ガンマ", + "ギガ", + "ギニー", + "キュリー", + "ギルダー", + "キロ", + "キログラム", + "キロメートル", + "キロワット", + "グラム", + "グラムトン", + "クルゼイロ", + "クローネ", + "ケース", + "コルナ", + "コーポ", + "サイクル", + "サンチーム", + "シリング", + "センチ", + "セント", + "ダース", + "デシ", + "ドル", + "トン", + "ナノ", + "ノット", + "ハイツ", + "パーセント", + "パーツ", + "バーレル", + "ピアストル", + "ピクル", + "ピコ", + "ビル", + "ファラッド", + "フィート", + "ブッシェル", + "フラン", + "ヘクタール", + "ペソ", + "ペニヒ", + "ヘルツ", + "ペンス", + "ページ", + "ベータ", + "ポイント", + "ボルト", + "ホン", + "ポンド", + "ホール", + "ホーン", + "マイクロ", + "マイル", + "マッハ", + "マルク", + "マンション", + "ミクロン", + "ミリ", + "ミリバール", + "メガ", + "メガトン", + "メートル", + "ヤード", + "ヤール", + "ユアン", + "リットル", + "リラ", + "ルピー", + "ルーブル", + "レム", + "レントゲン", + "ワット", + "0点", + "1点", + "2点", + "3点", + "4点", + "5点", + "6点", + "7点", + "8点", + "9点", + "10点", + "11点", + "12点", + "13点", + "14点", + "15点", + "16点", + "17点", + "18点", + "19点", + "20点", + "21点", + "22点", + "23点", + "24点", + "hpa", + "da", + "au", + "bar", + "ov", + "pc", + "dm", + "dm2", + "dm3", + "iu", + "平成", + "昭和", + "大正", + "明治", + "株式会社", + "pa", + "na", + "μa", + "ma", + "ka", + "kb", + "mb", + "gb", + "cal", + "kcal", + "pf", + "nf", + "μf", + "μg", + "mg", + "kg", + "hz", + "khz", + "mhz", + "ghz", + "thz", + "μl", + "ml", + "dl", + "kl", + "fm", + "nm", + "μm", + "mm", + "cm", + "km", + "mm2", + "cm2", + "m2", + "km2", + "mm3", + "cm3", + "m3", + "km3", + "m∕s", + "m∕s2", + "pa", + "kpa", + "mpa", + "gpa", + "rad", + "rad∕s", + "rad∕s2", + "ps", + "ns", + "μs", + "ms", + "pv", + "nv", + "μv", + "mv", + "kv", + "mv", + "pw", + "nw", + "μw", + "mw", + "kw", + "mw", + "kω", + "mω", + None, + "bq", + "cc", + "cd", + "c∕kg", + None, + "db", + "gy", + "ha", + "hp", + "in", + "kk", + "km", + "kt", + "lm", + "ln", + "log", + "lx", + "mb", + "mil", + "mol", + "ph", + None, + "ppm", + "pr", + "sr", + "sv", + "wb", + "v∕m", + "a∕m", + "1日", + "2日", + "3日", + "4日", + "5日", + "6日", + "7日", + "8日", + "9日", + "10日", + "11日", + "12日", + "13日", + "14日", + "15日", + "16日", + "17日", + "18日", + "19日", + "20日", + "21日", + "22日", + "23日", + "24日", + "25日", + "26日", + "27日", + "28日", + "29日", + "30日", + "31日", + "gal", + None, + None, + None, + None, + None, + None, + "ꙁ", + None, + "ꙃ", + None, + "ꙅ", + None, + "ꙇ", + None, + "ꙉ", + None, + "ꙋ", + None, + "ꙍ", + None, + "ꙏ", + None, + "ꙑ", + None, + "ꙓ", + None, + "ꙕ", + None, + "ꙗ", + None, + "ꙙ", + None, + "ꙛ", + None, + "ꙝ", + None, + "ꙟ", + None, + "ꙡ", + None, + "ꙣ", + None, + "ꙥ", + None, + "ꙧ", + None, + "ꙩ", + None, + "ꙫ", + None, + "ꙭ", + None, + "ꚁ", + None, + "ꚃ", + None, + "ꚅ", + None, + "ꚇ", + None, + "ꚉ", + None, + "ꚋ", + None, + "ꚍ", + None, + "ꚏ", + None, + "ꚑ", + None, + "ꚓ", + None, + "ꚕ", + None, + "ꚗ", + None, + "ꚙ", + None, + "ꚛ", + None, + "ъ", + "ь", + None, + None, + None, + "ꜣ", + None, + "ꜥ", + None, + "ꜧ", + None, + "ꜩ", + None, + "ꜫ", + None, + "ꜭ", + None, + "ꜯ", + None, + "ꜳ", + None, + "ꜵ", + None, + "ꜷ", + None, + "ꜹ", + None, + "ꜻ", + None, + "ꜽ", + None, + "ꜿ", + None, + "ꝁ", + None, + "ꝃ", + None, + "ꝅ", + None, + "ꝇ", + None, + "ꝉ", + None, + "ꝋ", + None, + "ꝍ", + None, + "ꝏ", + None, + "ꝑ", + None, + "ꝓ", + None, + "ꝕ", + None, + "ꝗ", + None, + "ꝙ", + None, + "ꝛ", + None, + "ꝝ", + None, + "ꝟ", + None, + "ꝡ", + None, + "ꝣ", + None, + "ꝥ", + None, + "ꝧ", + None, + "ꝩ", + None, + "ꝫ", + None, + "ꝭ", + None, + "ꝯ", + None, + "ꝯ", + None, + "ꝺ", + None, + "ꝼ", + None, + "ᵹ", + "ꝿ", + None, + "ꞁ", + None, + "ꞃ", + None, + "ꞅ", + None, + "ꞇ", + None, + "ꞌ", + None, + "ɥ", + None, + "ꞑ", + None, + "ꞓ", + None, + "ꞗ", + None, + "ꞙ", + None, + "ꞛ", + None, + "ꞝ", + None, + "ꞟ", + None, + "ꞡ", + None, + "ꞣ", + None, + "ꞥ", + None, + "ꞧ", + None, + "ꞩ", + None, + "ɦ", + "ɜ", + "ɡ", + "ɬ", + "ɪ", + None, + "ʞ", + "ʇ", + "ʝ", + "ꭓ", + "ꞵ", + None, + "ꞷ", + None, + "ꞹ", + None, + "ꞻ", + None, + "ꞽ", + None, + "ꞿ", + None, + "ꟁ", + None, + "ꟃ", + None, + "ꞔ", + "ʂ", + "ᶎ", + "ꟈ", + None, + "ꟊ", + None, + "ɤ", + "\ua7cd", + None, + "\ua7cf", + None, + "ꟑ", + None, + "ꟓ", + None, + "ꟕ", + None, + "ꟗ", + None, + "ꟙ", + None, + "\ua7db", + None, + "ƛ", + None, + "s", + "c", + "f", + "q", + "ꟶ", + None, + "ħ", + "œ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ꜧ", + "ꬷ", + "ɫ", + "ꭒ", + None, + "ʍ", + None, + None, + "Ꭰ", + "Ꭱ", + "Ꭲ", + "Ꭳ", + "Ꭴ", + "Ꭵ", + "Ꭶ", + "Ꭷ", + "Ꭸ", + "Ꭹ", + "Ꭺ", + "Ꭻ", + "Ꭼ", + "Ꭽ", + "Ꭾ", + "Ꭿ", + "Ꮀ", + "Ꮁ", + "Ꮂ", + "Ꮃ", + "Ꮄ", + "Ꮅ", + "Ꮆ", + "Ꮇ", + "Ꮈ", + "Ꮉ", + "Ꮊ", + "Ꮋ", + "Ꮌ", + "Ꮍ", + "Ꮎ", + "Ꮏ", + "Ꮐ", + "Ꮑ", + "Ꮒ", + "Ꮓ", + "Ꮔ", + "Ꮕ", + "Ꮖ", + "Ꮗ", + "Ꮘ", + "Ꮙ", + "Ꮚ", + "Ꮛ", + "Ꮜ", + "Ꮝ", + "Ꮞ", + "Ꮟ", + "Ꮠ", + "Ꮡ", + "Ꮢ", + "Ꮣ", + "Ꮤ", + "Ꮥ", + "Ꮦ", + "Ꮧ", + "Ꮨ", + "Ꮩ", + "Ꮪ", + "Ꮫ", + "Ꮬ", + "Ꮭ", + "Ꮮ", + "Ꮯ", + "Ꮰ", + "Ꮱ", + "Ꮲ", + "Ꮳ", + "Ꮴ", + "Ꮵ", + "Ꮶ", + "Ꮷ", + "Ꮸ", + "Ꮹ", + "Ꮺ", + "Ꮻ", + "Ꮼ", + "Ꮽ", + "Ꮾ", + "Ꮿ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "豈", + "更", + "車", + "賈", + "滑", + "串", + "句", + "龜", + "契", + "金", + "喇", + "奈", + "懶", + "癩", + "羅", + "蘿", + "螺", + "裸", + "邏", + "樂", + "洛", + "烙", + "珞", + "落", + "酪", + "駱", + "亂", + "卵", + "欄", + "爛", + "蘭", + "鸞", + "嵐", + "濫", + "藍", + "襤", + "拉", + "臘", + "蠟", + "廊", + "朗", + "浪", + "狼", + "郎", + "來", + "冷", + "勞", + "擄", + "櫓", + "爐", + "盧", + "老", + "蘆", + "虜", + "路", + "露", + "魯", + "鷺", + "碌", + "祿", + "綠", + "菉", + "錄", + "鹿", + "論", + "壟", + "弄", + "籠", + "聾", + "牢", + "磊", + "賂", + "雷", + "壘", + "屢", + "樓", + "淚", + "漏", + "累", + "縷", + "陋", + "勒", + "肋", + "凜", + "凌", + "稜", + "綾", + "菱", + "陵", + "讀", + "拏", + "樂", + "諾", + "丹", + "寧", + "怒", + "率", + "異", + "北", + "磻", + "便", + "復", + "不", + "泌", + "數", + "索", + "參", + "塞", + "省", + "葉", + "說", + "殺", + "辰", + "沈", + "拾", + "若", + "掠", + "略", + "亮", + "兩", + "凉", + "梁", + "糧", + "良", + "諒", + "量", + "勵", + "呂", + "女", + "廬", + "旅", + "濾", + "礪", + "閭", + "驪", + "麗", + "黎", + "力", + "曆", + "歷", + "轢", + "年", + "憐", + "戀", + "撚", + "漣", + "煉", + "璉", + "秊", + "練", + "聯", + "輦", + "蓮", + "連", + "鍊", + "列", + "劣", + "咽", + "烈", + "裂", + "說", + "廉", + "念", + "捻", + "殮", + "簾", + "獵", + "令", + "囹", + "寧", + "嶺", + "怜", + "玲", + "瑩", + "羚", + "聆", + "鈴", + "零", + "靈", + "領", + "例", + "禮", + "醴", + "隸", + "惡", + "了", + "僚", + "寮", + "尿", + "料", + "樂", + "燎", + "療", + "蓼", + "遼", + "龍", + "暈", + "阮", + "劉", + "杻", + "柳", + "流", + "溜", + "琉", + "留", + "硫", + "紐", + "類", + "六", + "戮", + "陸", + "倫", + "崙", + "淪", + "輪", + "律", + "慄", + "栗", + "率", + "隆", + "利", + "吏", + "履", + "易", + "李", + "梨", + "泥", + "理", + "痢", + "罹", + "裏", + "裡", + "里", + "離", + "匿", + "溺", + "吝", + "燐", + "璘", + "藺", + "隣", + "鱗", + "麟", + "林", + "淋", + "臨", + "立", + "笠", + "粒", + "狀", + "炙", + "識", + "什", + "茶", + "刺", + "切", + "度", + "拓", + "糖", + "宅", + "洞", + "暴", + "輻", + "行", + "降", + "見", + "廓", + "兀", + "嗀", + None, + "塚", + None, + "晴", + None, + "凞", + "猪", + "益", + "礼", + "神", + "祥", + "福", + "靖", + "精", + "羽", + None, + "蘒", + None, + "諸", + None, + "逸", + "都", + None, + "飯", + "飼", + "館", + "鶴", + "郞", + "隷", + "侮", + "僧", + "免", + "勉", + "勤", + "卑", + "喝", + "嘆", + "器", + "塀", + "墨", + "層", + "屮", + "悔", + "慨", + "憎", + "懲", + "敏", + "既", + "暑", + "梅", + "海", + "渚", + "漢", + "煮", + "爫", + "琢", + "碑", + "社", + "祉", + "祈", + "祐", + "祖", + "祝", + "禍", + "禎", + "穀", + "突", + "節", + "練", + "縉", + "繁", + "署", + "者", + "臭", + "艹", + "著", + "褐", + "視", + "謁", + "謹", + "賓", + "贈", + "辶", + "逸", + "難", + "響", + "頻", + "恵", + "𤋮", + "舘", + None, + "並", + "况", + "全", + "侀", + "充", + "冀", + "勇", + "勺", + "喝", + "啕", + "喙", + "嗢", + "塚", + "墳", + "奄", + "奔", + "婢", + "嬨", + "廒", + "廙", + "彩", + "徭", + "惘", + "慎", + "愈", + "憎", + "慠", + "懲", + "戴", + "揄", + "搜", + "摒", + "敖", + "晴", + "朗", + "望", + "杖", + "歹", + "殺", + "流", + "滛", + "滋", + "漢", + "瀞", + "煮", + "瞧", + "爵", + "犯", + "猪", + "瑱", + "甆", + "画", + "瘝", + "瘟", + "益", + "盛", + "直", + "睊", + "着", + "磌", + "窱", + "節", + "类", + "絛", + "練", + "缾", + "者", + "荒", + "華", + "蝹", + "襁", + "覆", + "視", + "調", + "諸", + "請", + "謁", + "諾", + "諭", + "謹", + "變", + "贈", + "輸", + "遲", + "醙", + "鉶", + "陼", + "難", + "靖", + "韛", + "響", + "頋", + "頻", + "鬒", + "龜", + "𢡊", + "𢡄", + "𣏕", + "㮝", + "䀘", + "䀹", + "𥉉", + "𥳐", + "𧻓", + "齃", + "龎", + None, + "ff", + "fi", + "fl", + "ffi", + "ffl", + "st", + None, + "մն", + "մե", + "մի", + "վն", + "մխ", + None, + "יִ", + None, + "ײַ", + "ע", + "א", + "ד", + "ה", + "כ", + "ל", + "ם", + "ר", + "ת", + "+", + "שׁ", + "שׂ", + "שּׁ", + "שּׂ", + "אַ", + "אָ", + "אּ", + "בּ", + "גּ", + "דּ", + "הּ", + "וּ", + "זּ", + None, + "טּ", + "יּ", + "ךּ", + "כּ", + "לּ", + None, + "מּ", + None, + "נּ", + "סּ", + None, + "ףּ", + "פּ", + None, + "צּ", + "קּ", + "רּ", + "שּ", + "תּ", + "וֹ", + "בֿ", + "כֿ", + "פֿ", + "אל", + "ٱ", + "ٻ", + "پ", + "ڀ", + "ٺ", + "ٿ", + "ٹ", + "ڤ", + "ڦ", + "ڄ", + "ڃ", + "چ", + "ڇ", + "ڍ", + "ڌ", + "ڎ", + "ڈ", + "ژ", + "ڑ", + "ک", + "گ", + "ڳ", + "ڱ", + "ں", + "ڻ", + "ۀ", + "ہ", + "ھ", + "ے", + "ۓ", + None, + "ڭ", + "ۇ", + "ۆ", + "ۈ", + "ۇٴ", + "ۋ", + "ۅ", + "ۉ", + "ې", + "ى", + "ئا", + "ئە", + "ئو", + "ئۇ", + "ئۆ", + "ئۈ", + "ئې", + "ئى", + "ی", + "ئج", + "ئح", + "ئم", + "ئى", + "ئي", + "بج", + "بح", + "بخ", + "بم", + "بى", + "بي", + "تج", + "تح", + "تخ", + "تم", + "تى", + "تي", + "ثج", + "ثم", + "ثى", + "ثي", + "جح", + "جم", + "حج", + "حم", + "خج", + "خح", + "خم", + "سج", + "سح", + "سخ", + "سم", + "صح", + "صم", + "ضج", + "ضح", + "ضخ", + "ضم", + "طح", + "طم", + "ظم", + "عج", + "عم", + "غج", + "غم", + "فج", + "فح", + "فخ", + "فم", + "فى", + "في", + "قح", + "قم", + "قى", + "قي", + "كا", + "كج", + "كح", + "كخ", + "كل", + "كم", + "كى", + "كي", + "لج", + "لح", + "لخ", + "لم", + "لى", + "لي", + "مج", + "مح", + "مخ", + "مم", + "مى", + "مي", + "نج", + "نح", + "نخ", + "نم", + "نى", + "ني", + "هج", + "هم", + "هى", + "هي", + "يج", + "يح", + "يخ", + "يم", + "يى", + "يي", + "ذٰ", + "رٰ", + "ىٰ", + " ٌّ", + " ٍّ", + " َّ", + " ُّ", + " ِّ", + " ّٰ", + "ئر", + "ئز", + "ئم", + "ئن", + "ئى", + "ئي", + "بر", + "بز", + "بم", + "بن", + "بى", + "بي", + "تر", + "تز", + "تم", + "تن", + "تى", + "تي", + "ثر", + "ثز", + "ثم", + "ثن", + "ثى", + "ثي", + "فى", + "في", + "قى", + "قي", + "كا", + "كل", + "كم", + "كى", + "كي", + "لم", + "لى", + "لي", + "ما", + "مم", + "نر", + "نز", + "نم", + "نن", + "نى", + "ني", + "ىٰ", + "ير", + "يز", + "يم", + "ين", + "يى", + "يي", + "ئج", + "ئح", + "ئخ", + "ئم", + "ئه", + "بج", + "بح", + "بخ", + "بم", + "به", + "تج", + "تح", + "تخ", + "تم", + "ته", + "ثم", + "جح", + "جم", + "حج", + "حم", + "خج", + "خم", + "سج", + "سح", + "سخ", + "سم", + "صح", + "صخ", + "صم", + "ضج", + "ضح", + "ضخ", + "ضم", + "طح", + "ظم", + "عج", + "عم", + "غج", + "غم", + "فج", + "فح", + "فخ", + "فم", + "قح", + "قم", + "كج", + "كح", + "كخ", + "كل", + "كم", + "لج", + "لح", + "لخ", + "لم", + "له", + "مج", + "مح", + "مخ", + "مم", + "نج", + "نح", + "نخ", + "نم", + "نه", + "هج", + "هم", + "هٰ", + "يج", + "يح", + "يخ", + "يم", + "يه", + "ئم", + "ئه", + "بم", + "به", + "تم", + "ته", + "ثم", + "ثه", + "سم", + "سه", + "شم", + "شه", + "كل", + "كم", + "لم", + "نم", + "نه", + "يم", + "يه", + "ـَّ", + "ـُّ", + "ـِّ", + "طى", + "طي", + "عى", + "عي", + "غى", + "غي", + "سى", + "سي", + "شى", + "شي", + "حى", + "حي", + "جى", + "جي", + "خى", + "خي", + "صى", + "صي", + "ضى", + "ضي", + "شج", + "شح", + "شخ", + "شم", + "شر", + "سر", + "صر", + "ضر", + "طى", + "طي", + "عى", + "عي", + "غى", + "غي", + "سى", + "سي", + "شى", + "شي", + "حى", + "حي", + "جى", + "جي", + "خى", + "خي", + "صى", + "صي", + "ضى", + "ضي", + "شج", + "شح", + "شخ", + "شم", + "شر", + "سر", + "صر", + "ضر", + "شج", + "شح", + "شخ", + "شم", + "سه", + "شه", + "طم", + "سج", + "سح", + "سخ", + "شج", + "شح", + "شخ", + "طم", + "ظم", + "اً", + None, + "تجم", + "تحج", + "تحم", + "تخم", + "تمج", + "تمح", + "تمخ", + "جمح", + "حمي", + "حمى", + "سحج", + "سجح", + "سجى", + "سمح", + "سمج", + "سمم", + "صحح", + "صمم", + "شحم", + "شجي", + "شمخ", + "شمم", + "ضحى", + "ضخم", + "طمح", + "طمم", + "طمي", + "عجم", + "عمم", + "عمى", + "غمم", + "غمي", + "غمى", + "فخم", + "قمح", + "قمم", + "لحم", + "لحي", + "لحى", + "لجج", + "لخم", + "لمح", + "محج", + "محم", + "محي", + "مجح", + "مجم", + "مخج", + "مخم", + None, + "مجخ", + "همج", + "همم", + "نحم", + "نحى", + "نجم", + "نجى", + "نمي", + "نمى", + "يمم", + "بخي", + "تجي", + "تجى", + "تخي", + "تخى", + "تمي", + "تمى", + "جمي", + "جحى", + "جمى", + "سخى", + "صحي", + "شحي", + "ضحي", + "لجي", + "لمي", + "يحي", + "يجي", + "يمي", + "ممي", + "قمي", + "نحي", + "قمح", + "لحم", + "عمي", + "كمي", + "نجح", + "مخي", + "لجم", + "كمم", + "لجم", + "نجح", + "جحي", + "حجي", + "مجي", + "فمي", + "بحي", + "كمم", + "عجم", + "صمم", + "سخي", + "نجي", + None, + None, + "صلے", + "قلے", + "الله", + "اكبر", + "محمد", + "صلعم", + "رسول", + "عليه", + "وسلم", + "صلى", + "صلى الله عليه وسلم", + "جل جلاله", + "ریال", + None, + None, + ",", + "、", + None, + ":", + ";", + "!", + "?", + "〖", + "〗", + None, + None, + None, + "—", + "–", + "_", + "(", + ")", + "{", + "}", + "〔", + "〕", + "【", + "】", + "《", + "》", + "〈", + "〉", + "「", + "」", + "『", + "』", + None, + "[", + "]", + " ̅", + "_", + ",", + "、", + None, + ";", + ":", + "?", + "!", + "—", + "(", + ")", + "{", + "}", + "〔", + "〕", + "#", + "&", + "*", + "+", + "-", + "<", + ">", + "=", + None, + "\\", + "$", + "%", + "@", + None, + " ً", + "ـً", + " ٌ", + None, + " ٍ", + None, + " َ", + "ـَ", + " ُ", + "ـُ", + " ِ", + "ـِ", + " ّ", + "ـّ", + " ْ", + "ـْ", + "ء", + "آ", + "أ", + "ؤ", + "إ", + "ئ", + "ا", + "ب", + "ة", + "ت", + "ث", + "ج", + "ح", + "خ", + "د", + "ذ", + "ر", + "ز", + "س", + "ش", + "ص", + "ض", + "ط", + "ظ", + "ع", + "غ", + "ف", + "ق", + "ك", + "ل", + "م", + "ن", + "ه", + "و", + "ى", + "ي", + "لآ", + "لأ", + "لإ", + "لا", + None, + None, + None, + "!", + '"', + "#", + "$", + "%", + "&", + "'", + "(", + ")", + "*", + "+", + ",", + "-", + ".", + "/", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + ":", + ";", + "<", + "=", + ">", + "?", + "@", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "[", + "\\", + "]", + "^", + "_", + "`", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "{", + "|", + "}", + "~", + "⦅", + "⦆", + ".", + "「", + "」", + "、", + "・", + "ヲ", + "ァ", + "ィ", + "ゥ", + "ェ", + "ォ", + "ャ", + "ュ", + "ョ", + "ッ", + "ー", + "ア", + "イ", + "ウ", + "エ", + "オ", + "カ", + "キ", + "ク", + "ケ", + "コ", + "サ", + "シ", + "ス", + "セ", + "ソ", + "タ", + "チ", + "ツ", + "テ", + "ト", + "ナ", + "ニ", + "ヌ", + "ネ", + "ノ", + "ハ", + "ヒ", + "フ", + "ヘ", + "ホ", + "マ", + "ミ", + "ム", + "メ", + "モ", + "ヤ", + "ユ", + "ヨ", + "ラ", + "リ", + "ル", + "レ", + "ロ", + "ワ", + "ン", + "゙", + "゚", + None, + "ᄀ", + "ᄁ", + "ᆪ", + "ᄂ", + "ᆬ", + "ᆭ", + "ᄃ", + "ᄄ", + "ᄅ", + "ᆰ", + "ᆱ", + "ᆲ", + "ᆳ", + "ᆴ", + "ᆵ", + "ᄚ", + "ᄆ", + "ᄇ", + "ᄈ", + "ᄡ", + "ᄉ", + "ᄊ", + "ᄋ", + "ᄌ", + "ᄍ", + "ᄎ", + "ᄏ", + "ᄐ", + "ᄑ", + "ᄒ", + None, + "ᅡ", + "ᅢ", + "ᅣ", + "ᅤ", + "ᅥ", + "ᅦ", + None, + "ᅧ", + "ᅨ", + "ᅩ", + "ᅪ", + "ᅫ", + "ᅬ", + None, + "ᅭ", + "ᅮ", + "ᅯ", + "ᅰ", + "ᅱ", + "ᅲ", + None, + "ᅳ", + "ᅴ", + "ᅵ", + None, + "¢", + "£", + "¬", + " ̄", + "¦", + "¥", + "₩", + None, + "│", + "←", + "↑", + "→", + "↓", + "■", + "○", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "𐐨", + "𐐩", + "𐐪", + "𐐫", + "𐐬", + "𐐭", + "𐐮", + "𐐯", + "𐐰", + "𐐱", + "𐐲", + "𐐳", + "𐐴", + "𐐵", + "𐐶", + "𐐷", + "𐐸", + "𐐹", + "𐐺", + "𐐻", + "𐐼", + "𐐽", + "𐐾", + "𐐿", + "𐑀", + "𐑁", + "𐑂", + "𐑃", + "𐑄", + "𐑅", + "𐑆", + "𐑇", + "𐑈", + "𐑉", + "𐑊", + "𐑋", + "𐑌", + "𐑍", + "𐑎", + "𐑏", + None, + None, + None, + None, + "𐓘", + "𐓙", + "𐓚", + "𐓛", + "𐓜", + "𐓝", + "𐓞", + "𐓟", + "𐓠", + "𐓡", + "𐓢", + "𐓣", + "𐓤", + "𐓥", + "𐓦", + "𐓧", + "𐓨", + "𐓩", + "𐓪", + "𐓫", + "𐓬", + "𐓭", + "𐓮", + "𐓯", + "𐓰", + "𐓱", + "𐓲", + "𐓳", + "𐓴", + "𐓵", + "𐓶", + "𐓷", + "𐓸", + "𐓹", + "𐓺", + "𐓻", + None, + None, + None, + None, + None, + None, + None, + None, + "𐖗", + "𐖘", + "𐖙", + "𐖚", + "𐖛", + "𐖜", + "𐖝", + "𐖞", + "𐖟", + "𐖠", + "𐖡", + None, + "𐖣", + "𐖤", + "𐖥", + "𐖦", + "𐖧", + "𐖨", + "𐖩", + "𐖪", + "𐖫", + "𐖬", + "𐖭", + "𐖮", + "𐖯", + "𐖰", + "𐖱", + None, + "𐖳", + "𐖴", + "𐖵", + "𐖶", + "𐖷", + "𐖸", + "𐖹", + None, + "𐖻", + "𐖼", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ː", + "ˑ", + "æ", + "ʙ", + "ɓ", + None, + "ʣ", + "ꭦ", + "ʥ", + "ʤ", + "ɖ", + "ɗ", + "ᶑ", + "ɘ", + "ɞ", + "ʩ", + "ɤ", + "ɢ", + "ɠ", + "ʛ", + "ħ", + "ʜ", + "ɧ", + "ʄ", + "ʪ", + "ʫ", + "ɬ", + "𝼄", + "ꞎ", + "ɮ", + "𝼅", + "ʎ", + "𝼆", + "ø", + "ɶ", + "ɷ", + "q", + "ɺ", + "𝼈", + "ɽ", + "ɾ", + "ʀ", + "ʨ", + "ʦ", + "ꭧ", + "ʧ", + "ʈ", + "ⱱ", + None, + "ʏ", + "ʡ", + "ʢ", + "ʘ", + "ǀ", + "ǁ", + "ǂ", + "𝼊", + "𝼞", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "𐳀", + "𐳁", + "𐳂", + "𐳃", + "𐳄", + "𐳅", + "𐳆", + "𐳇", + "𐳈", + "𐳉", + "𐳊", + "𐳋", + "𐳌", + "𐳍", + "𐳎", + "𐳏", + "𐳐", + "𐳑", + "𐳒", + "𐳓", + "𐳔", + "𐳕", + "𐳖", + "𐳗", + "𐳘", + "𐳙", + "𐳚", + "𐳛", + "𐳜", + "𐳝", + "𐳞", + "𐳟", + "𐳠", + "𐳡", + "𐳢", + "𐳣", + "𐳤", + "𐳥", + "𐳦", + "𐳧", + "𐳨", + "𐳩", + "𐳪", + "𐳫", + "𐳬", + "𐳭", + "𐳮", + "𐳯", + "𐳰", + "𐳱", + "𐳲", + None, + None, + None, + None, + None, + None, + None, + None, + "\U00010d70", + "\U00010d71", + "\U00010d72", + "\U00010d73", + "\U00010d74", + "\U00010d75", + "\U00010d76", + "\U00010d77", + "\U00010d78", + "\U00010d79", + "\U00010d7a", + "\U00010d7b", + "\U00010d7c", + "\U00010d7d", + "\U00010d7e", + "\U00010d7f", + "\U00010d80", + "\U00010d81", + "\U00010d82", + "\U00010d83", + "\U00010d84", + "\U00010d85", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "𑣀", + "𑣁", + "𑣂", + "𑣃", + "𑣄", + "𑣅", + "𑣆", + "𑣇", + "𑣈", + "𑣉", + "𑣊", + "𑣋", + "𑣌", + "𑣍", + "𑣎", + "𑣏", + "𑣐", + "𑣑", + "𑣒", + "𑣓", + "𑣔", + "𑣕", + "𑣖", + "𑣗", + "𑣘", + "𑣙", + "𑣚", + "𑣛", + "𑣜", + "𑣝", + "𑣞", + "𑣟", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "𖹠", + "𖹡", + "𖹢", + "𖹣", + "𖹤", + "𖹥", + "𖹦", + "𖹧", + "𖹨", + "𖹩", + "𖹪", + "𖹫", + "𖹬", + "𖹭", + "𖹮", + "𖹯", + "𖹰", + "𖹱", + "𖹲", + "𖹳", + "𖹴", + "𖹵", + "𖹶", + "𖹷", + "𖹸", + "𖹹", + "𖹺", + "𖹻", + "𖹼", + "𖹽", + "𖹾", + "𖹿", + None, + None, + "\U00016ebb", + "\U00016ebc", + "\U00016ebd", + "\U00016ebe", + "\U00016ebf", + "\U00016ec0", + "\U00016ec1", + "\U00016ec2", + "\U00016ec3", + "\U00016ec4", + "\U00016ec5", + "\U00016ec6", + "\U00016ec7", + "\U00016ec8", + "\U00016ec9", + "\U00016eca", + "\U00016ecb", + "\U00016ecc", + "\U00016ecd", + "\U00016ece", + "\U00016ecf", + "\U00016ed0", + "\U00016ed1", + "\U00016ed2", + "\U00016ed3", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "𝅗𝅥", + "𝅘𝅥", + "𝅘𝅥𝅮", + "𝅘𝅥𝅯", + "𝅘𝅥𝅰", + "𝅘𝅥𝅱", + "𝅘𝅥𝅲", + None, + None, + None, + "𝆹𝅥", + "𝆺𝅥", + "𝆹𝅥𝅮", + "𝆺𝅥𝅮", + "𝆹𝅥𝅯", + "𝆺𝅥𝅯", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + None, + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + None, + "c", + "d", + None, + "g", + None, + "j", + "k", + None, + "n", + "o", + "p", + "q", + None, + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + None, + "f", + None, + "h", + "i", + "j", + "k", + "l", + "m", + "n", + None, + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + None, + "d", + "e", + "f", + "g", + None, + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + None, + "s", + "t", + "u", + "v", + "w", + "x", + "y", + None, + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + None, + "d", + "e", + "f", + "g", + None, + "i", + "j", + "k", + "l", + "m", + None, + "o", + None, + "s", + "t", + "u", + "v", + "w", + "x", + "y", + None, + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "ı", + "ȷ", + None, + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "θ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∇", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∂", + "ε", + "θ", + "κ", + "φ", + "ρ", + "π", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "θ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∇", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∂", + "ε", + "θ", + "κ", + "φ", + "ρ", + "π", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "θ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∇", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∂", + "ε", + "θ", + "κ", + "φ", + "ρ", + "π", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "θ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∇", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∂", + "ε", + "θ", + "κ", + "φ", + "ρ", + "π", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "θ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∇", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∂", + "ε", + "θ", + "κ", + "φ", + "ρ", + "π", + "ϝ", + None, + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "а", + "б", + "в", + "г", + "д", + "е", + "ж", + "з", + "и", + "к", + "л", + "м", + "о", + "п", + "р", + "с", + "т", + "у", + "ф", + "х", + "ц", + "ч", + "ш", + "ы", + "э", + "ю", + "ꚉ", + "ә", + "і", + "ј", + "ө", + "ү", + "ӏ", + "а", + "б", + "в", + "г", + "д", + "е", + "ж", + "з", + "и", + "к", + "л", + "о", + "п", + "с", + "у", + "ф", + "х", + "ц", + "ч", + "ш", + "ъ", + "ы", + "ґ", + "і", + "ѕ", + "џ", + "ҫ", + "ꙑ", + "ұ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "𞤢", + "𞤣", + "𞤤", + "𞤥", + "𞤦", + "𞤧", + "𞤨", + "𞤩", + "𞤪", + "𞤫", + "𞤬", + "𞤭", + "𞤮", + "𞤯", + "𞤰", + "𞤱", + "𞤲", + "𞤳", + "𞤴", + "𞤵", + "𞤶", + "𞤷", + "𞤸", + "𞤹", + "𞤺", + "𞤻", + "𞤼", + "𞤽", + "𞤾", + "𞤿", + "𞥀", + "𞥁", + "𞥂", + "𞥃", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ا", + "ب", + "ج", + "د", + None, + "و", + "ز", + "ح", + "ط", + "ي", + "ك", + "ل", + "م", + "ن", + "س", + "ع", + "ف", + "ص", + "ق", + "ر", + "ش", + "ت", + "ث", + "خ", + "ذ", + "ض", + "ظ", + "غ", + "ٮ", + "ں", + "ڡ", + "ٯ", + None, + "ب", + "ج", + None, + "ه", + None, + "ح", + None, + "ي", + "ك", + "ل", + "م", + "ن", + "س", + "ع", + "ف", + "ص", + "ق", + None, + "ش", + "ت", + "ث", + "خ", + None, + "ض", + None, + "غ", + None, + "ج", + None, + "ح", + None, + "ي", + None, + "ل", + None, + "ن", + "س", + "ع", + None, + "ص", + "ق", + None, + "ش", + None, + "خ", + None, + "ض", + None, + "غ", + None, + "ں", + None, + "ٯ", + None, + "ب", + "ج", + None, + "ه", + None, + "ح", + "ط", + "ي", + "ك", + None, + "م", + "ن", + "س", + "ع", + "ف", + "ص", + "ق", + None, + "ش", + "ت", + "ث", + "خ", + None, + "ض", + "ظ", + "غ", + "ٮ", + None, + "ڡ", + None, + "ا", + "ب", + "ج", + "د", + "ه", + "و", + "ز", + "ح", + "ط", + "ي", + None, + "ل", + "م", + "ن", + "س", + "ع", + "ف", + "ص", + "ق", + "ر", + "ش", + "ت", + "ث", + "خ", + "ذ", + "ض", + "ظ", + "غ", + None, + "ب", + "ج", + "د", + None, + "و", + "ز", + "ح", + "ط", + "ي", + None, + "ل", + "م", + "ن", + "س", + "ع", + "ف", + "ص", + "ق", + "ر", + "ش", + "ت", + "ث", + "خ", + "ذ", + "ض", + "ظ", + "غ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "0,", + "1,", + "2,", + "3,", + "4,", + "5,", + "6,", + "7,", + "8,", + "9,", + None, + "(a)", + "(b)", + "(c)", + "(d)", + "(e)", + "(f)", + "(g)", + "(h)", + "(i)", + "(j)", + "(k)", + "(l)", + "(m)", + "(n)", + "(o)", + "(p)", + "(q)", + "(r)", + "(s)", + "(t)", + "(u)", + "(v)", + "(w)", + "(x)", + "(y)", + "(z)", + "〔s〕", + "c", + "r", + "cd", + "wz", + None, + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "hv", + "mv", + "sd", + "ss", + "ppv", + "wc", + None, + "mc", + "md", + "mr", + None, + "dj", + None, + None, + None, + "ほか", + "ココ", + "サ", + None, + "手", + "字", + "双", + "デ", + "二", + "多", + "解", + "天", + "交", + "映", + "無", + "料", + "前", + "後", + "再", + "新", + "初", + "終", + "生", + "販", + "声", + "吹", + "演", + "投", + "捕", + "一", + "三", + "遊", + "左", + "中", + "右", + "指", + "走", + "打", + "禁", + "空", + "合", + "満", + "有", + "月", + "申", + "割", + "営", + "配", + None, + "〔本〕", + "〔三〕", + "〔二〕", + "〔安〕", + "〔点〕", + "〔打〕", + "〔盗〕", + "〔勝〕", + "〔敗〕", + None, + "得", + "可", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "丽", + "丸", + "乁", + "𠄢", + "你", + "侮", + "侻", + "倂", + "偺", + "備", + "僧", + "像", + "㒞", + "𠘺", + "免", + "兔", + "兤", + "具", + "𠔜", + "㒹", + "內", + "再", + "𠕋", + "冗", + "冤", + "仌", + "冬", + "况", + "𩇟", + "凵", + "刃", + "㓟", + "刻", + "剆", + "割", + "剷", + "㔕", + "勇", + "勉", + "勤", + "勺", + "包", + "匆", + "北", + "卉", + "卑", + "博", + "即", + "卽", + "卿", + "𠨬", + "灰", + "及", + "叟", + "𠭣", + "叫", + "叱", + "吆", + "咞", + "吸", + "呈", + "周", + "咢", + "哶", + "唐", + "啓", + "啣", + "善", + "喙", + "喫", + "喳", + "嗂", + "圖", + "嘆", + "圗", + "噑", + "噴", + "切", + "壮", + "城", + "埴", + "堍", + "型", + "堲", + "報", + "墬", + "𡓤", + "売", + "壷", + "夆", + "多", + "夢", + "奢", + "𡚨", + "𡛪", + "姬", + "娛", + "娧", + "姘", + "婦", + "㛮", + "㛼", + "嬈", + "嬾", + "𡧈", + "寃", + "寘", + "寧", + "寳", + "𡬘", + "寿", + "将", + "当", + "尢", + "㞁", + "屠", + "屮", + "峀", + "岍", + "𡷤", + "嵃", + "𡷦", + "嵮", + "嵫", + "嵼", + "巡", + "巢", + "㠯", + "巽", + "帨", + "帽", + "幩", + "㡢", + "𢆃", + "㡼", + "庰", + "庳", + "庶", + "廊", + "𪎒", + "廾", + "𢌱", + "舁", + "弢", + "㣇", + "𣊸", + "𦇚", + "形", + "彫", + "㣣", + "徚", + "忍", + "志", + "忹", + "悁", + "㤺", + "㤜", + "悔", + "𢛔", + "惇", + "慈", + "慌", + "慎", + "慌", + "慺", + "憎", + "憲", + "憤", + "憯", + "懞", + "懲", + "懶", + "成", + "戛", + "扝", + "抱", + "拔", + "捐", + "𢬌", + "挽", + "拼", + "捨", + "掃", + "揤", + "𢯱", + "搢", + "揅", + "掩", + "㨮", + "摩", + "摾", + "撝", + "摷", + "㩬", + "敏", + "敬", + "𣀊", + "旣", + "書", + "晉", + "㬙", + "暑", + "㬈", + "㫤", + "冒", + "冕", + "最", + "暜", + "肭", + "䏙", + "朗", + "望", + "朡", + "杞", + "杓", + "𣏃", + "㭉", + "柺", + "枅", + "桒", + "梅", + "𣑭", + "梎", + "栟", + "椔", + "㮝", + "楂", + "榣", + "槪", + "檨", + "𣚣", + "櫛", + "㰘", + "次", + "𣢧", + "歔", + "㱎", + "歲", + "殟", + "殺", + "殻", + "𣪍", + "𡴋", + "𣫺", + "汎", + "𣲼", + "沿", + "泍", + "汧", + "洖", + "派", + "海", + "流", + "浩", + "浸", + "涅", + "𣴞", + "洴", + "港", + "湮", + "㴳", + "滋", + "滇", + "𣻑", + "淹", + "潮", + "𣽞", + "𣾎", + "濆", + "瀹", + "瀞", + "瀛", + "㶖", + "灊", + "災", + "灷", + "炭", + "𠔥", + "煅", + "𤉣", + "熜", + "𤎫", + "爨", + "爵", + "牐", + "𤘈", + "犀", + "犕", + "𤜵", + "𤠔", + "獺", + "王", + "㺬", + "玥", + "㺸", + "瑇", + "瑜", + "瑱", + "璅", + "瓊", + "㼛", + "甤", + "𤰶", + "甾", + "𤲒", + "異", + "𢆟", + "瘐", + "𤾡", + "𤾸", + "𥁄", + "㿼", + "䀈", + "直", + "𥃳", + "𥃲", + "𥄙", + "𥄳", + "眞", + "真", + "睊", + "䀹", + "瞋", + "䁆", + "䂖", + "𥐝", + "硎", + "碌", + "磌", + "䃣", + "𥘦", + "祖", + "𥚚", + "𥛅", + "福", + "秫", + "䄯", + "穀", + "穊", + "穏", + "𥥼", + "𥪧", + "竮", + "䈂", + "𥮫", + "篆", + "築", + "䈧", + "𥲀", + "糒", + "䊠", + "糨", + "糣", + "紀", + "𥾆", + "絣", + "䌁", + "緇", + "縂", + "繅", + "䌴", + "𦈨", + "𦉇", + "䍙", + "𦋙", + "罺", + "𦌾", + "羕", + "翺", + "者", + "𦓚", + "𦔣", + "聠", + "𦖨", + "聰", + "𣍟", + "䏕", + "育", + "脃", + "䐋", + "脾", + "媵", + "𦞧", + "𦞵", + "𣎓", + "𣎜", + "舁", + "舄", + "辞", + "䑫", + "芑", + "芋", + "芝", + "劳", + "花", + "芳", + "芽", + "苦", + "𦬼", + "若", + "茝", + "荣", + "莭", + "茣", + "莽", + "菧", + "著", + "荓", + "菊", + "菌", + "菜", + "𦰶", + "𦵫", + "𦳕", + "䔫", + "蓱", + "蓳", + "蔖", + "𧏊", + "蕤", + "𦼬", + "䕝", + "䕡", + "𦾱", + "𧃒", + "䕫", + "虐", + "虜", + "虧", + "虩", + "蚩", + "蚈", + "蜎", + "蛢", + "蝹", + "蜨", + "蝫", + "螆", + "䗗", + "蟡", + "蠁", + "䗹", + "衠", + "衣", + "𧙧", + "裗", + "裞", + "䘵", + "裺", + "㒻", + "𧢮", + "𧥦", + "䚾", + "䛇", + "誠", + "諭", + "變", + "豕", + "𧲨", + "貫", + "賁", + "贛", + "起", + "𧼯", + "𠠄", + "跋", + "趼", + "跰", + "𠣞", + "軔", + "輸", + "𨗒", + "𨗭", + "邔", + "郱", + "鄑", + "𨜮", + "鄛", + "鈸", + "鋗", + "鋘", + "鉼", + "鏹", + "鐕", + "𨯺", + "開", + "䦕", + "閷", + "𨵷", + "䧦", + "雃", + "嶲", + "霣", + "𩅅", + "𩈚", + "䩮", + "䩶", + "韠", + "𩐊", + "䪲", + "𩒖", + "頋", + "頩", + "𩖶", + "飢", + "䬳", + "餩", + "馧", + "駂", + "駾", + "䯎", + "𩬰", + "鬒", + "鱀", + "鳽", + "䳎", + "䳭", + "鵧", + "𪃎", + "䳸", + "𪄅", + "𪈎", + "𪊑", + "麻", + "䵖", + "黹", + "黾", + "鼅", + "鼏", + "鼖", + "鼻", + "𪘀", + None, + None, + None, + None, + None, + None, + None, +) diff --git a/.venv/lib/python3.13/site-packages/images/logo.gif b/.venv/lib/python3.13/site-packages/images/logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..7b051c8a4d909e020d21ec883e7edad954de09fb Binary files /dev/null and b/.venv/lib/python3.13/site-packages/images/logo.gif differ diff --git a/.venv/lib/python3.13/site-packages/images/tqdm.gif b/.venv/lib/python3.13/site-packages/images/tqdm.gif new file mode 100644 index 0000000000000000000000000000000000000000..f636741eb1ff1069bc6a31ba0cb68bab921991f8 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/images/tqdm.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03c79d5eed0b5334b2cbfdaed4fb32424e70b375ef29be510748f17c562e79f4 +size 592063 diff --git a/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/INSTALLER b/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/METADATA b/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..fc3c00df97bbf6e38be40ce7bec8e9d136d18214 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/METADATA @@ -0,0 +1,79 @@ +Metadata-Version: 2.4 +Name: iniconfig +Version: 2.3.0 +Summary: brain-dead simple config-ini parsing +Author-email: Ronny Pfannschmidt , Holger Krekel +License-Expression: MIT +Project-URL: Homepage, https://github.com/pytest-dev/iniconfig +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: POSIX +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: Topic :: Software Development :: Libraries +Classifier: Topic :: Utilities +Requires-Python: >=3.10 +Description-Content-Type: text/x-rst +License-File: LICENSE +Dynamic: license-file + +iniconfig: brain-dead simple parsing of ini files +======================================================= + +iniconfig is a small and simple INI-file parser module +having a unique set of features: + +* maintains order of sections and entries +* supports multi-line values with or without line-continuations +* supports "#" comments everywhere +* raises errors with proper line-numbers +* no bells and whistles like automatic substitutions +* iniconfig raises an Error if two sections have the same name. + +If you encounter issues or have feature wishes please report them to: + + https://github.com/RonnyPfannschmidt/iniconfig/issues + +Basic Example +=================================== + +If you have an ini file like this: + +.. code-block:: ini + + # content of example.ini + [section1] # comment + name1=value1 # comment + name1b=value1,value2 # comment + + [section2] + name2= + line1 + line2 + +then you can do: + +.. code-block:: pycon + + >>> import iniconfig + >>> ini = iniconfig.IniConfig("example.ini") + >>> ini['section1']['name1'] # raises KeyError if not exists + 'value1' + >>> ini.get('section1', 'name1b', [], lambda x: x.split(",")) + ['value1', 'value2'] + >>> ini.get('section1', 'notexist', [], lambda x: x.split(",")) + [] + >>> [x.name for x in list(ini)] + ['section1', 'section2'] + >>> list(list(ini)[0].items()) + [('name1', 'value1'), ('name1b', 'value1,value2')] + >>> 'section1' in ini + True + >>> 'inexistendsection' in ini + False diff --git a/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/RECORD b/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..fc3adfc029340e2c6033f9efd903fe3fef9d973d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/RECORD @@ -0,0 +1,15 @@ +iniconfig-2.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +iniconfig-2.3.0.dist-info/METADATA,sha256=QNdz-E5OES9JW79PG-nL0tRWwK6271MR910b8yLyFls,2526 +iniconfig-2.3.0.dist-info/RECORD,, +iniconfig-2.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91 +iniconfig-2.3.0.dist-info/licenses/LICENSE,sha256=NAn6kfes5VeJRjJnZlbjImT-XvdYFTVyXcmiN3RVG9Q,1098 +iniconfig-2.3.0.dist-info/top_level.txt,sha256=7KfM0fugdlToj9UW7enKXk2HYALQD8qHiyKtjhSzgN8,10 +iniconfig/__init__.py,sha256=XL5eqUYj4mskAOorZ5jfRAinJvJzTI-fJxpP4xfXtaw,7497 +iniconfig/__pycache__/__init__.cpython-313.pyc,, +iniconfig/__pycache__/_parse.cpython-313.pyc,, +iniconfig/__pycache__/_version.cpython-313.pyc,, +iniconfig/__pycache__/exceptions.cpython-313.pyc,, +iniconfig/_parse.py,sha256=5ncBl7MAQiaPNnpRrs9FR4t6G6DkgOUs458OY_1CR28,5223 +iniconfig/_version.py,sha256=KNFYe-Vtdt7Z-oHyl8jmDAQ9qXoCNMAEXigj6BR1QUI,704 +iniconfig/exceptions.py,sha256=mipQ_aMxD9CvSvFWN1oTXY4QuRnKAMZ1f3sCdmjDTU0,399 +iniconfig/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/WHEEL b/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..e7fa31b6f3f78deb1022c1f7927f07d4d16da822 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (80.9.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/licenses/LICENSE b/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/licenses/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..46f4b2846fd708ecb81b2d665434ce6379aa1101 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/licenses/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2010 - 2023 Holger Krekel and others + +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/python3.13/site-packages/iniconfig-2.3.0.dist-info/top_level.txt b/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..9dda53692d2f44a97392cae823f8163d55ad4549 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/top_level.txt @@ -0,0 +1 @@ +iniconfig diff --git a/.venv/lib/python3.13/site-packages/iniconfig/__init__.py b/.venv/lib/python3.13/site-packages/iniconfig/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b84809f8e9dc0db6fba3505fcc29ca26c3383cce --- /dev/null +++ b/.venv/lib/python3.13/site-packages/iniconfig/__init__.py @@ -0,0 +1,249 @@ +"""brain-dead simple parser for ini-style files. +(C) Ronny Pfannschmidt, Holger Krekel -- MIT licensed +""" + +import os +from collections.abc import Callable +from collections.abc import Iterator +from collections.abc import Mapping +from typing import Final +from typing import TypeVar +from typing import overload + +__all__ = ["IniConfig", "ParseError", "COMMENTCHARS", "iscommentline"] + +from . import _parse +from ._parse import COMMENTCHARS +from ._parse import iscommentline +from .exceptions import ParseError + +_D = TypeVar("_D") +_T = TypeVar("_T") + + +class SectionWrapper: + config: Final["IniConfig"] + name: Final[str] + + def __init__(self, config: "IniConfig", name: str) -> None: + self.config = config + self.name = name + + def lineof(self, name: str) -> int | None: + return self.config.lineof(self.name, name) + + @overload + def get(self, key: str) -> str | None: ... + + @overload + def get( + self, + key: str, + convert: Callable[[str], _T], + ) -> _T | None: ... + + @overload + def get( + self, + key: str, + default: None, + convert: Callable[[str], _T], + ) -> _T | None: ... + + @overload + def get(self, key: str, default: _D, convert: None = None) -> str | _D: ... + + @overload + def get( + self, + key: str, + default: _D, + convert: Callable[[str], _T], + ) -> _T | _D: ... + + # TODO: investigate possible mypy bug wrt matching the passed over data + def get( # type: ignore [misc] + self, + key: str, + default: _D | None = None, + convert: Callable[[str], _T] | None = None, + ) -> _D | _T | str | None: + return self.config.get(self.name, key, convert=convert, default=default) + + def __getitem__(self, key: str) -> str: + return self.config.sections[self.name][key] + + def __iter__(self) -> Iterator[str]: + section: Mapping[str, str] = self.config.sections.get(self.name, {}) + + def lineof(key: str) -> int: + return self.config.lineof(self.name, key) # type: ignore[return-value] + + yield from sorted(section, key=lineof) + + def items(self) -> Iterator[tuple[str, str]]: + for name in self: + yield name, self[name] + + +class IniConfig: + path: Final[str] + sections: Final[Mapping[str, Mapping[str, str]]] + _sources: Final[Mapping[tuple[str, str | None], int]] + + def __init__( + self, + path: str | os.PathLike[str], + data: str | None = None, + encoding: str = "utf-8", + *, + _sections: Mapping[str, Mapping[str, str]] | None = None, + _sources: Mapping[tuple[str, str | None], int] | None = None, + ) -> None: + self.path = os.fspath(path) + + # Determine sections and sources + if _sections is not None and _sources is not None: + # Use provided pre-parsed data (called from parse()) + sections_data = _sections + sources = _sources + else: + # Parse the data (backward compatible path) + if data is None: + with open(self.path, encoding=encoding) as fp: + data = fp.read() + + # Use old behavior (no stripping) for backward compatibility + sections_data, sources = _parse.parse_ini_data( + self.path, data, strip_inline_comments=False + ) + + # Assign once to Final attributes + self._sources = sources + self.sections = sections_data + + @classmethod + def parse( + cls, + path: str | os.PathLike[str], + data: str | None = None, + encoding: str = "utf-8", + *, + strip_inline_comments: bool = True, + strip_section_whitespace: bool = False, + ) -> "IniConfig": + """Parse an INI file. + + Args: + path: Path to the INI file (used for error messages) + data: Optional INI content as string. If None, reads from path. + encoding: Encoding to use when reading the file (default: utf-8) + strip_inline_comments: Whether to strip inline comments from values + (default: True). When True, comments starting with # or ; are + removed from values, matching the behavior for section comments. + strip_section_whitespace: Whether to strip whitespace from section and key names + (default: False). When True, strips Unicode whitespace from section and key names, + addressing issue #4. When False, preserves existing behavior for backward compatibility. + + Returns: + IniConfig instance with parsed configuration + + Example: + # With comment stripping (default): + config = IniConfig.parse("setup.cfg") + # value = "foo" instead of "foo # comment" + + # Without comment stripping (old behavior): + config = IniConfig.parse("setup.cfg", strip_inline_comments=False) + # value = "foo # comment" + + # With section name stripping (opt-in for issue #4): + config = IniConfig.parse("setup.cfg", strip_section_whitespace=True) + # section names and keys have Unicode whitespace stripped + """ + fspath = os.fspath(path) + + if data is None: + with open(fspath, encoding=encoding) as fp: + data = fp.read() + + sections_data, sources = _parse.parse_ini_data( + fspath, + data, + strip_inline_comments=strip_inline_comments, + strip_section_whitespace=strip_section_whitespace, + ) + + # Call constructor with pre-parsed sections and sources + return cls(path=fspath, _sections=sections_data, _sources=sources) + + def lineof(self, section: str, name: str | None = None) -> int | None: + lineno = self._sources.get((section, name)) + return None if lineno is None else lineno + 1 + + @overload + def get( + self, + section: str, + name: str, + ) -> str | None: ... + + @overload + def get( + self, + section: str, + name: str, + convert: Callable[[str], _T], + ) -> _T | None: ... + + @overload + def get( + self, + section: str, + name: str, + default: None, + convert: Callable[[str], _T], + ) -> _T | None: ... + + @overload + def get( + self, section: str, name: str, default: _D, convert: None = None + ) -> str | _D: ... + + @overload + def get( + self, + section: str, + name: str, + default: _D, + convert: Callable[[str], _T], + ) -> _T | _D: ... + + def get( # type: ignore + self, + section: str, + name: str, + default: _D | None = None, + convert: Callable[[str], _T] | None = None, + ) -> _D | _T | str | None: + try: + value: str = self.sections[section][name] + except KeyError: + return default + else: + if convert is not None: + return convert(value) + else: + return value + + def __getitem__(self, name: str) -> SectionWrapper: + if name not in self.sections: + raise KeyError(name) + return SectionWrapper(self, name) + + def __iter__(self) -> Iterator[SectionWrapper]: + for name in sorted(self.sections, key=self.lineof): # type: ignore + yield SectionWrapper(self, name) + + def __contains__(self, arg: str) -> bool: + return arg in self.sections diff --git a/.venv/lib/python3.13/site-packages/iniconfig/_parse.py b/.venv/lib/python3.13/site-packages/iniconfig/_parse.py new file mode 100644 index 0000000000000000000000000000000000000000..57b9b44e4cccca635651b8d4380aed1e2ab020a8 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/iniconfig/_parse.py @@ -0,0 +1,163 @@ +from collections.abc import Mapping +from typing import NamedTuple + +from .exceptions import ParseError + +COMMENTCHARS = "#;" + + +class ParsedLine(NamedTuple): + lineno: int + section: str | None + name: str | None + value: str | None + + +def parse_ini_data( + path: str, + data: str, + *, + strip_inline_comments: bool, + strip_section_whitespace: bool = False, +) -> tuple[Mapping[str, Mapping[str, str]], Mapping[tuple[str, str | None], int]]: + """Parse INI data and return sections and sources mappings. + + Args: + path: Path for error messages + data: INI content as string + strip_inline_comments: Whether to strip inline comments from values + strip_section_whitespace: Whether to strip whitespace from section and key names + (default: False). When True, addresses issue #4 by stripping Unicode whitespace. + + Returns: + Tuple of (sections_data, sources) where: + - sections_data: mapping of section -> {name -> value} + - sources: mapping of (section, name) -> line number + """ + tokens = parse_lines( + path, + data.splitlines(True), + strip_inline_comments=strip_inline_comments, + strip_section_whitespace=strip_section_whitespace, + ) + + sources: dict[tuple[str, str | None], int] = {} + sections_data: dict[str, dict[str, str]] = {} + + for lineno, section, name, value in tokens: + if section is None: + raise ParseError(path, lineno, "no section header defined") + sources[section, name] = lineno + if name is None: + if section in sections_data: + raise ParseError(path, lineno, f"duplicate section {section!r}") + sections_data[section] = {} + else: + if name in sections_data[section]: + raise ParseError(path, lineno, f"duplicate name {name!r}") + assert value is not None + sections_data[section][name] = value + + return sections_data, sources + + +def parse_lines( + path: str, + line_iter: list[str], + *, + strip_inline_comments: bool = False, + strip_section_whitespace: bool = False, +) -> list[ParsedLine]: + result: list[ParsedLine] = [] + section = None + for lineno, line in enumerate(line_iter): + name, data = _parseline( + path, line, lineno, strip_inline_comments, strip_section_whitespace + ) + # new value + if name is not None and data is not None: + result.append(ParsedLine(lineno, section, name, data)) + # new section + elif name is not None and data is None: + if not name: + raise ParseError(path, lineno, "empty section name") + section = name + result.append(ParsedLine(lineno, section, None, None)) + # continuation + elif name is None and data is not None: + if not result: + raise ParseError(path, lineno, "unexpected value continuation") + last = result.pop() + if last.name is None: + raise ParseError(path, lineno, "unexpected value continuation") + + if last.value: + last = last._replace(value=f"{last.value}\n{data}") + else: + last = last._replace(value=data) + result.append(last) + return result + + +def _parseline( + path: str, + line: str, + lineno: int, + strip_inline_comments: bool, + strip_section_whitespace: bool, +) -> tuple[str | None, str | None]: + # blank lines + if iscommentline(line): + line = "" + else: + line = line.rstrip() + if not line: + return None, None + # section + if line[0] == "[": + realline = line + for c in COMMENTCHARS: + line = line.split(c)[0].rstrip() + if line[-1] == "]": + section_name = line[1:-1] + # Optionally strip whitespace from section name (issue #4) + if strip_section_whitespace: + section_name = section_name.strip() + return section_name, None + return None, realline.strip() + # value + elif not line[0].isspace(): + try: + name, value = line.split("=", 1) + if ":" in name: + raise ValueError() + except ValueError: + try: + name, value = line.split(":", 1) + except ValueError: + raise ParseError(path, lineno, f"unexpected line: {line!r}") from None + + # Strip key name (always for backward compatibility, optionally with unicode awareness) + key_name = name.strip() + + # Strip value + value = value.strip() + # Strip inline comments from values if requested (issue #55) + if strip_inline_comments: + for c in COMMENTCHARS: + value = value.split(c)[0].rstrip() + + return key_name, value + # continuation + else: + line = line.strip() + # Strip inline comments from continuations if requested (issue #55) + if strip_inline_comments: + for c in COMMENTCHARS: + line = line.split(c)[0].rstrip() + return None, line + + +def iscommentline(line: str) -> bool: + c = line.lstrip()[:1] + return c in COMMENTCHARS diff --git a/.venv/lib/python3.13/site-packages/iniconfig/_version.py b/.venv/lib/python3.13/site-packages/iniconfig/_version.py new file mode 100644 index 0000000000000000000000000000000000000000..b982b024d8649c68b58ba29198fab080774ddf5f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/iniconfig/_version.py @@ -0,0 +1,34 @@ +# file generated by setuptools-scm +# don't change, don't track in version control + +__all__ = [ + "__version__", + "__version_tuple__", + "version", + "version_tuple", + "__commit_id__", + "commit_id", +] + +TYPE_CHECKING = False +if TYPE_CHECKING: + from typing import Tuple + from typing import Union + + VERSION_TUPLE = Tuple[Union[int, str], ...] + COMMIT_ID = Union[str, None] +else: + VERSION_TUPLE = object + COMMIT_ID = object + +version: str +__version__: str +__version_tuple__: VERSION_TUPLE +version_tuple: VERSION_TUPLE +commit_id: COMMIT_ID +__commit_id__: COMMIT_ID + +__version__ = version = '2.3.0' +__version_tuple__ = version_tuple = (2, 3, 0) + +__commit_id__ = commit_id = None diff --git a/.venv/lib/python3.13/site-packages/iniconfig/exceptions.py b/.venv/lib/python3.13/site-packages/iniconfig/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..d078bc659504cf79d3cedefe66dd828af9a9d9e0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/iniconfig/exceptions.py @@ -0,0 +1,16 @@ +from typing import Final + + +class ParseError(Exception): + path: Final[str] + lineno: Final[int] + msg: Final[str] + + def __init__(self, path: str, lineno: int, msg: str) -> None: + super().__init__(path, lineno, msg) + self.path = path + self.lineno = lineno + self.msg = msg + + def __str__(self) -> str: + return f"{self.path}:{self.lineno + 1}: {self.msg}" diff --git a/.venv/lib/python3.13/site-packages/iniconfig/py.typed b/.venv/lib/python3.13/site-packages/iniconfig/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/INSTALLER b/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/METADATA b/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..ffef2ff3bfa0c42b6e6e3eefda700391d181c9a0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/METADATA @@ -0,0 +1,84 @@ +Metadata-Version: 2.4 +Name: Jinja2 +Version: 3.1.6 +Summary: A very fast and expressive template engine. +Maintainer-email: Pallets +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Classifier: Typing :: Typed +License-File: LICENSE.txt +Requires-Dist: MarkupSafe>=2.0 +Requires-Dist: Babel>=2.7 ; extra == "i18n" +Project-URL: Changes, https://jinja.palletsprojects.com/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://jinja.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Source, https://github.com/pallets/jinja/ +Provides-Extra: i18n + +# Jinja + +Jinja is a fast, expressive, extensible templating engine. Special +placeholders in the template allow writing code similar to Python +syntax. Then the template is passed data to render the final document. + +It includes: + +- Template inheritance and inclusion. +- Define and import macros within templates. +- HTML templates can use autoescaping to prevent XSS from untrusted + user input. +- A sandboxed environment can safely render untrusted templates. +- AsyncIO support for generating templates and calling async + functions. +- I18N support with Babel. +- Templates are compiled to optimized Python code just-in-time and + cached, or can be compiled ahead-of-time. +- Exceptions point to the correct line in templates to make debugging + easier. +- Extensible filters, tests, functions, and even syntax. + +Jinja's philosophy is that while application logic belongs in Python if +possible, it shouldn't make the template designer's job difficult by +restricting functionality too much. + + +## In A Nutshell + +```jinja +{% extends "base.html" %} +{% block title %}Members{% endblock %} +{% block content %} + +{% endblock %} +``` + +## Donate + +The Pallets organization develops and supports Jinja and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, [please +donate today][]. + +[please donate today]: https://palletsprojects.com/donate + +## Contributing + +See our [detailed contributing documentation][contrib] for many ways to +contribute, including reporting issues, requesting features, asking or answering +questions, and making PRs. + +[contrib]: https://palletsprojects.com/contributing/ + diff --git a/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/RECORD b/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..62dcfa6252b54d23a8089f37c774fd480bfbdde5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/RECORD @@ -0,0 +1,57 @@ +jinja2-3.1.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +jinja2-3.1.6.dist-info/METADATA,sha256=aMVUj7Z8QTKhOJjZsx7FDGvqKr3ZFdkh8hQ1XDpkmcg,2871 +jinja2-3.1.6.dist-info/RECORD,, +jinja2-3.1.6.dist-info/WHEEL,sha256=_2ozNFCLWc93bK4WKHCO-eDUENDlo-dgc9cU3qokYO4,82 +jinja2-3.1.6.dist-info/entry_points.txt,sha256=OL85gYU1eD8cuPlikifFngXpeBjaxl6rIJ8KkC_3r-I,58 +jinja2-3.1.6.dist-info/licenses/LICENSE.txt,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +jinja2/__init__.py,sha256=xxepO9i7DHsqkQrgBEduLtfoz2QCuT6_gbL4XSN1hbU,1928 +jinja2/__pycache__/__init__.cpython-313.pyc,, +jinja2/__pycache__/_identifier.cpython-313.pyc,, +jinja2/__pycache__/async_utils.cpython-313.pyc,, +jinja2/__pycache__/bccache.cpython-313.pyc,, +jinja2/__pycache__/compiler.cpython-313.pyc,, +jinja2/__pycache__/constants.cpython-313.pyc,, +jinja2/__pycache__/debug.cpython-313.pyc,, +jinja2/__pycache__/defaults.cpython-313.pyc,, +jinja2/__pycache__/environment.cpython-313.pyc,, +jinja2/__pycache__/exceptions.cpython-313.pyc,, +jinja2/__pycache__/ext.cpython-313.pyc,, +jinja2/__pycache__/filters.cpython-313.pyc,, +jinja2/__pycache__/idtracking.cpython-313.pyc,, +jinja2/__pycache__/lexer.cpython-313.pyc,, +jinja2/__pycache__/loaders.cpython-313.pyc,, +jinja2/__pycache__/meta.cpython-313.pyc,, +jinja2/__pycache__/nativetypes.cpython-313.pyc,, +jinja2/__pycache__/nodes.cpython-313.pyc,, +jinja2/__pycache__/optimizer.cpython-313.pyc,, +jinja2/__pycache__/parser.cpython-313.pyc,, +jinja2/__pycache__/runtime.cpython-313.pyc,, +jinja2/__pycache__/sandbox.cpython-313.pyc,, +jinja2/__pycache__/tests.cpython-313.pyc,, +jinja2/__pycache__/utils.cpython-313.pyc,, +jinja2/__pycache__/visitor.cpython-313.pyc,, +jinja2/_identifier.py,sha256=_zYctNKzRqlk_murTNlzrju1FFJL7Va_Ijqqd7ii2lU,1958 +jinja2/async_utils.py,sha256=vK-PdsuorOMnWSnEkT3iUJRIkTnYgO2T6MnGxDgHI5o,2834 +jinja2/bccache.py,sha256=gh0qs9rulnXo0PhX5jTJy2UHzI8wFnQ63o_vw7nhzRg,14061 +jinja2/compiler.py,sha256=9RpCQl5X88BHllJiPsHPh295Hh0uApvwFJNQuutULeM,74131 +jinja2/constants.py,sha256=GMoFydBF_kdpaRKPoM5cl5MviquVRLVyZtfp5-16jg0,1433 +jinja2/debug.py,sha256=CnHqCDHd-BVGvti_8ZsTolnXNhA3ECsY-6n_2pwU8Hw,6297 +jinja2/defaults.py,sha256=boBcSw78h-lp20YbaXSJsqkAI2uN_mD_TtCydpeq5wU,1267 +jinja2/environment.py,sha256=9nhrP7Ch-NbGX00wvyr4yy-uhNHq2OCc60ggGrni_fk,61513 +jinja2/exceptions.py,sha256=ioHeHrWwCWNaXX1inHmHVblvc4haO7AXsjCp3GfWvx0,5071 +jinja2/ext.py,sha256=5PF5eHfh8mXAIxXHHRB2xXbXohi8pE3nHSOxa66uS7E,31875 +jinja2/filters.py,sha256=PQ_Egd9n9jSgtnGQYyF4K5j2nYwhUIulhPnyimkdr-k,55212 +jinja2/idtracking.py,sha256=-ll5lIp73pML3ErUYiIJj7tdmWxcH_IlDv3yA_hiZYo,10555 +jinja2/lexer.py,sha256=LYiYio6br-Tep9nPcupWXsPEtjluw3p1mU-lNBVRUfk,29786 +jinja2/loaders.py,sha256=wIrnxjvcbqh5VwW28NSkfotiDq8qNCxIOSFbGUiSLB4,24055 +jinja2/meta.py,sha256=OTDPkaFvU2Hgvx-6akz7154F8BIWaRmvJcBFvwopHww,4397 +jinja2/nativetypes.py,sha256=7GIGALVJgdyL80oZJdQUaUfwSt5q2lSSZbXt0dNf_M4,4210 +jinja2/nodes.py,sha256=m1Duzcr6qhZI8JQ6VyJgUNinjAf5bQzijSmDnMsvUx8,34579 +jinja2/optimizer.py,sha256=rJnCRlQ7pZsEEmMhsQDgC_pKyDHxP5TPS6zVPGsgcu8,1651 +jinja2/parser.py,sha256=lLOFy3sEmHc5IaEHRiH1sQVnId2moUQzhyeJZTtdY30,40383 +jinja2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jinja2/runtime.py,sha256=gDk-GvdriJXqgsGbHgrcKTP0Yp6zPXzhzrIpCFH3jAU,34249 +jinja2/sandbox.py,sha256=Mw2aitlY2I8la7FYhcX2YG9BtUYcLnD0Gh3d29cDWrY,15009 +jinja2/tests.py,sha256=VLsBhVFnWg-PxSBz1MhRnNWgP1ovXk3neO1FLQMeC9Q,5926 +jinja2/utils.py,sha256=rRp3o9e7ZKS4fyrWRbELyLcpuGVTFcnooaOa1qx_FIk,24129 +jinja2/visitor.py,sha256=EcnL1PIwf_4RVCOMxsRNuR8AXHbS1qfAdMOE2ngKJz4,3557 diff --git a/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/WHEEL b/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..23d2d7e9a5d381ef8a375db09f82052144d1fd96 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.11.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/entry_points.txt b/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/entry_points.txt new file mode 100644 index 0000000000000000000000000000000000000000..abc3eae3b3bc573957cf7401711948799b3465c0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[babel.extractors] +jinja2=jinja2.ext:babel_extract[i18n] + diff --git a/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/licenses/LICENSE.txt b/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/licenses/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..c37cae49ec77ad6ebb25568c1605f1fee5313cfb --- /dev/null +++ b/.venv/lib/python3.13/site-packages/jinja2-3.1.6.dist-info/licenses/LICENSE.txt @@ -0,0 +1,28 @@ +Copyright 2007 Pallets + +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 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/python3.13/site-packages/jinja2/__init__.py b/.venv/lib/python3.13/site-packages/jinja2/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1a423a3eac16ac550e8e4008d7f5d79401b50e0f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/jinja2/__init__.py @@ -0,0 +1,38 @@ +"""Jinja is a template engine written in pure Python. It provides a +non-XML syntax that supports inline expressions and an optional +sandboxed environment. +""" + +from .bccache import BytecodeCache as BytecodeCache +from .bccache import FileSystemBytecodeCache as FileSystemBytecodeCache +from .bccache import MemcachedBytecodeCache as MemcachedBytecodeCache +from .environment import Environment as Environment +from .environment import Template as Template +from .exceptions import TemplateAssertionError as TemplateAssertionError +from .exceptions import TemplateError as TemplateError +from .exceptions import TemplateNotFound as TemplateNotFound +from .exceptions import TemplateRuntimeError as TemplateRuntimeError +from .exceptions import TemplatesNotFound as TemplatesNotFound +from .exceptions import TemplateSyntaxError as TemplateSyntaxError +from .exceptions import UndefinedError as UndefinedError +from .loaders import BaseLoader as BaseLoader +from .loaders import ChoiceLoader as ChoiceLoader +from .loaders import DictLoader as DictLoader +from .loaders import FileSystemLoader as FileSystemLoader +from .loaders import FunctionLoader as FunctionLoader +from .loaders import ModuleLoader as ModuleLoader +from .loaders import PackageLoader as PackageLoader +from .loaders import PrefixLoader as PrefixLoader +from .runtime import ChainableUndefined as ChainableUndefined +from .runtime import DebugUndefined as DebugUndefined +from .runtime import make_logging_undefined as make_logging_undefined +from .runtime import StrictUndefined as StrictUndefined +from .runtime import Undefined as Undefined +from .utils import clear_caches as clear_caches +from .utils import is_undefined as is_undefined +from .utils import pass_context as pass_context +from .utils import pass_environment as pass_environment +from .utils import pass_eval_context as pass_eval_context +from .utils import select_autoescape as select_autoescape + +__version__ = "3.1.6" diff --git a/.venv/lib/python3.13/site-packages/jinja2/_identifier.py b/.venv/lib/python3.13/site-packages/jinja2/_identifier.py new file mode 100644 index 0000000000000000000000000000000000000000..928c1503c7d414a8a86bbf5a82c68d42cb089bd2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/jinja2/_identifier.py @@ -0,0 +1,6 @@ +import re + +# generated by scripts/generate_identifier_pattern.py +pattern = re.compile( + r"[\w·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߽߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛࣓-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣ৾ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣૺ-૿ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣஂா-ூெ-ைொ-்ௗఀ-ఄా-ౄె-ైొ-్ౕౖౢౣಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣഀ-ഃ഻഼ാ-ൄെ-ൈൊ-്ൗൢൣංඃ්ා-ුූෘ-ෟෲෳัิ-ฺ็-๎ັິ-ູົຼ່-ໍ༹༘༙༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏႚ-ႝ፝-፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝᠋-᠍ᢅᢆᢩᤠ-ᤫᤰ-᤻ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼᪰-᪽ᬀ-ᬄ᬴-᭄᭫-᭳ᮀ-ᮂᮡ-ᮭ᯦-᯳ᰤ-᰷᳐-᳔᳒-᳨᳭ᳲ-᳴᳷-᳹᷀-᷹᷻-᷿‿⁀⁔⃐-⃥⃜⃡-⃰℘℮⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣠-꣱ꣿꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀ꧥꨩ-ꨶꩃꩌꩍꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭ﬞ︀-️︠-︯︳︴﹍-﹏_𐇽𐋠𐍶-𐍺𐨁-𐨃𐨅𐨆𐨌-𐨏𐨸-𐨿𐨺𐫦𐫥𐴤-𐽆𐴧-𐽐𑀀-𑀂𑀸-𑁆𑁿-𑂂𑂰-𑂺𑄀-𑄂𑄧-𑄴𑅅𑅆𑅳𑆀-𑆂𑆳-𑇀𑇉-𑇌𑈬-𑈷𑈾𑋟-𑋪𑌀-𑌃𑌻𑌼𑌾-𑍄𑍇𑍈𑍋-𑍍𑍗𑍢𑍣𑍦-𑍬𑍰-𑍴𑐵-𑑆𑑞𑒰-𑓃𑖯-𑖵𑖸-𑗀𑗜𑗝𑘰-𑙀𑚫-𑚷𑜝-𑜫𑠬-𑠺𑨁-𑨊𑨳-𑨹𑨻-𑨾𑩇𑩑-𑩛𑪊-𑪙𑰯-𑰶𑰸-𑰿𑲒-𑲧𑲩-𑲶𑴱-𑴶𑴺𑴼𑴽𑴿-𑵅𑵇𑶊-𑶎𑶐𑶑𑶓-𑶗𑻳-𑻶𖫰-𖫴𖬰-𖬶𖽑-𖽾𖾏-𖾒𛲝𛲞𝅥-𝅩𝅭-𝅲𝅻-𝆂𝆅-𝆋𝆪-𝆭𝉂-𝉄𝨀-𝨶𝨻-𝩬𝩵𝪄𝪛-𝪟𝪡-𝪯𞀀-𞀆𞀈-𞀘𞀛-𞀡𞀣𞀤𞀦-𞣐𞀪-𞣖𞥄-𞥊󠄀-󠇯]+" # noqa: B950 +) diff --git a/.venv/lib/python3.13/site-packages/jinja2/async_utils.py b/.venv/lib/python3.13/site-packages/jinja2/async_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..f0c140205c50a3df9863ce1ab610b0c62a483f1b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/jinja2/async_utils.py @@ -0,0 +1,99 @@ +import inspect +import typing as t +from functools import WRAPPER_ASSIGNMENTS +from functools import wraps + +from .utils import _PassArg +from .utils import pass_eval_context + +if t.TYPE_CHECKING: + import typing_extensions as te + +V = t.TypeVar("V") + + +def async_variant(normal_func): # type: ignore + def decorator(async_func): # type: ignore + pass_arg = _PassArg.from_obj(normal_func) + need_eval_context = pass_arg is None + + if pass_arg is _PassArg.environment: + + def is_async(args: t.Any) -> bool: + return t.cast(bool, args[0].is_async) + + else: + + def is_async(args: t.Any) -> bool: + return t.cast(bool, args[0].environment.is_async) + + # Take the doc and annotations from the sync function, but the + # name from the async function. Pallets-Sphinx-Themes + # build_function_directive expects __wrapped__ to point to the + # sync function. + async_func_attrs = ("__module__", "__name__", "__qualname__") + normal_func_attrs = tuple(set(WRAPPER_ASSIGNMENTS).difference(async_func_attrs)) + + @wraps(normal_func, assigned=normal_func_attrs) + @wraps(async_func, assigned=async_func_attrs, updated=()) + def wrapper(*args, **kwargs): # type: ignore + b = is_async(args) + + if need_eval_context: + args = args[1:] + + if b: + return async_func(*args, **kwargs) + + return normal_func(*args, **kwargs) + + if need_eval_context: + wrapper = pass_eval_context(wrapper) + + wrapper.jinja_async_variant = True # type: ignore[attr-defined] + return wrapper + + return decorator + + +_common_primitives = {int, float, bool, str, list, dict, tuple, type(None)} + + +async def auto_await(value: t.Union[t.Awaitable["V"], "V"]) -> "V": + # Avoid a costly call to isawaitable + if type(value) in _common_primitives: + return t.cast("V", value) + + if inspect.isawaitable(value): + return await t.cast("t.Awaitable[V]", value) + + return value + + +class _IteratorToAsyncIterator(t.Generic[V]): + def __init__(self, iterator: "t.Iterator[V]"): + self._iterator = iterator + + def __aiter__(self) -> "te.Self": + return self + + async def __anext__(self) -> V: + try: + return next(self._iterator) + except StopIteration as e: + raise StopAsyncIteration(e.value) from e + + +def auto_aiter( + iterable: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> "t.AsyncIterator[V]": + if hasattr(iterable, "__aiter__"): + return iterable.__aiter__() + else: + return _IteratorToAsyncIterator(iter(iterable)) + + +async def auto_to_list( + value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> t.List["V"]: + return [x async for x in auto_aiter(value)] diff --git a/.venv/lib/python3.13/site-packages/jinja2/bccache.py b/.venv/lib/python3.13/site-packages/jinja2/bccache.py new file mode 100644 index 0000000000000000000000000000000000000000..ada8b099ff251ea9c6da4c42e1383f37e359f06a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/jinja2/bccache.py @@ -0,0 +1,408 @@ +"""The optional bytecode cache system. This is useful if you have very +complex template situations and the compilation of all those templates +slows down your application too much. + +Situations where this is useful are often forking web applications that +are initialized on the first request. +""" + +import errno +import fnmatch +import marshal +import os +import pickle +import stat +import sys +import tempfile +import typing as t +from hashlib import sha1 +from io import BytesIO +from types import CodeType + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .environment import Environment + + class _MemcachedClient(te.Protocol): + def get(self, key: str) -> bytes: ... + + def set( + self, key: str, value: bytes, timeout: t.Optional[int] = None + ) -> None: ... + + +bc_version = 5 +# Magic bytes to identify Jinja bytecode cache files. Contains the +# Python major and minor version to avoid loading incompatible bytecode +# if a project upgrades its Python version. +bc_magic = ( + b"j2" + + pickle.dumps(bc_version, 2) + + pickle.dumps((sys.version_info[0] << 24) | sys.version_info[1], 2) +) + + +class Bucket: + """Buckets are used to store the bytecode for one template. It's created + and initialized by the bytecode cache and passed to the loading functions. + + The buckets get an internal checksum from the cache assigned and use this + to automatically reject outdated cache material. Individual bytecode + cache subclasses don't have to care about cache invalidation. + """ + + def __init__(self, environment: "Environment", key: str, checksum: str) -> None: + self.environment = environment + self.key = key + self.checksum = checksum + self.reset() + + def reset(self) -> None: + """Resets the bucket (unloads the bytecode).""" + self.code: t.Optional[CodeType] = None + + def load_bytecode(self, f: t.BinaryIO) -> None: + """Loads bytecode from a file or file like object.""" + # make sure the magic header is correct + magic = f.read(len(bc_magic)) + if magic != bc_magic: + self.reset() + return + # the source code of the file changed, we need to reload + checksum = pickle.load(f) + if self.checksum != checksum: + self.reset() + return + # if marshal_load fails then we need to reload + try: + self.code = marshal.load(f) + except (EOFError, ValueError, TypeError): + self.reset() + return + + def write_bytecode(self, f: t.IO[bytes]) -> None: + """Dump the bytecode into the file or file like object passed.""" + if self.code is None: + raise TypeError("can't write empty bucket") + f.write(bc_magic) + pickle.dump(self.checksum, f, 2) + marshal.dump(self.code, f) + + def bytecode_from_string(self, string: bytes) -> None: + """Load bytecode from bytes.""" + self.load_bytecode(BytesIO(string)) + + def bytecode_to_string(self) -> bytes: + """Return the bytecode as bytes.""" + out = BytesIO() + self.write_bytecode(out) + return out.getvalue() + + +class BytecodeCache: + """To implement your own bytecode cache you have to subclass this class + and override :meth:`load_bytecode` and :meth:`dump_bytecode`. Both of + these methods are passed a :class:`~jinja2.bccache.Bucket`. + + A very basic bytecode cache that saves the bytecode on the file system:: + + from os import path + + class MyCache(BytecodeCache): + + def __init__(self, directory): + self.directory = directory + + def load_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + if path.exists(filename): + with open(filename, 'rb') as f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + with open(filename, 'wb') as f: + bucket.write_bytecode(f) + + A more advanced version of a filesystem based bytecode cache is part of + Jinja. + """ + + def load_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to load bytecode into a + bucket. If they are not able to find code in the cache for the + bucket, it must not do anything. + """ + raise NotImplementedError() + + def dump_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to write the bytecode + from a bucket back to the cache. If it unable to do so it must not + fail silently but raise an exception. + """ + raise NotImplementedError() + + def clear(self) -> None: + """Clears the cache. This method is not used by Jinja but should be + implemented to allow applications to clear the bytecode cache used + by a particular environment. + """ + + def get_cache_key( + self, name: str, filename: t.Optional[t.Union[str]] = None + ) -> str: + """Returns the unique hash key for this template name.""" + hash = sha1(name.encode("utf-8")) + + if filename is not None: + hash.update(f"|{filename}".encode()) + + return hash.hexdigest() + + def get_source_checksum(self, source: str) -> str: + """Returns a checksum for the source.""" + return sha1(source.encode("utf-8")).hexdigest() + + def get_bucket( + self, + environment: "Environment", + name: str, + filename: t.Optional[str], + source: str, + ) -> Bucket: + """Return a cache bucket for the given template. All arguments are + mandatory but filename may be `None`. + """ + key = self.get_cache_key(name, filename) + checksum = self.get_source_checksum(source) + bucket = Bucket(environment, key, checksum) + self.load_bytecode(bucket) + return bucket + + def set_bucket(self, bucket: Bucket) -> None: + """Put the bucket into the cache.""" + self.dump_bytecode(bucket) + + +class FileSystemBytecodeCache(BytecodeCache): + """A bytecode cache that stores bytecode on the filesystem. It accepts + two arguments: The directory where the cache items are stored and a + pattern string that is used to build the filename. + + If no directory is specified a default cache directory is selected. On + Windows the user's temp directory is used, on UNIX systems a directory + is created for the user in the system temp directory. + + The pattern can be used to have multiple separate caches operate on the + same directory. The default pattern is ``'__jinja2_%s.cache'``. ``%s`` + is replaced with the cache key. + + >>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache') + + This bytecode cache supports clearing of the cache using the clear method. + """ + + def __init__( + self, directory: t.Optional[str] = None, pattern: str = "__jinja2_%s.cache" + ) -> None: + if directory is None: + directory = self._get_default_cache_dir() + self.directory = directory + self.pattern = pattern + + def _get_default_cache_dir(self) -> str: + def _unsafe_dir() -> "te.NoReturn": + raise RuntimeError( + "Cannot determine safe temp directory. You " + "need to explicitly provide one." + ) + + tmpdir = tempfile.gettempdir() + + # On windows the temporary directory is used specific unless + # explicitly forced otherwise. We can just use that. + if os.name == "nt": + return tmpdir + if not hasattr(os, "getuid"): + _unsafe_dir() + + dirname = f"_jinja2-cache-{os.getuid()}" + actual_dir = os.path.join(tmpdir, dirname) + + try: + os.mkdir(actual_dir, stat.S_IRWXU) + except OSError as e: + if e.errno != errno.EEXIST: + raise + try: + os.chmod(actual_dir, stat.S_IRWXU) + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + except OSError as e: + if e.errno != errno.EEXIST: + raise + + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + + return actual_dir + + def _get_cache_filename(self, bucket: Bucket) -> str: + return os.path.join(self.directory, self.pattern % (bucket.key,)) + + def load_bytecode(self, bucket: Bucket) -> None: + filename = self._get_cache_filename(bucket) + + # Don't test for existence before opening the file, since the + # file could disappear after the test before the open. + try: + f = open(filename, "rb") + except (FileNotFoundError, IsADirectoryError, PermissionError): + # PermissionError can occur on Windows when an operation is + # in progress, such as calling clear(). + return + + with f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket: Bucket) -> None: + # Write to a temporary file, then rename to the real name after + # writing. This avoids another process reading the file before + # it is fully written. + name = self._get_cache_filename(bucket) + f = tempfile.NamedTemporaryFile( + mode="wb", + dir=os.path.dirname(name), + prefix=os.path.basename(name), + suffix=".tmp", + delete=False, + ) + + def remove_silent() -> None: + try: + os.remove(f.name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + pass + + try: + with f: + bucket.write_bytecode(f) + except BaseException: + remove_silent() + raise + + try: + os.replace(f.name, name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + remove_silent() + except BaseException: + remove_silent() + raise + + def clear(self) -> None: + # imported lazily here because google app-engine doesn't support + # write access on the file system and the function does not exist + # normally. + from os import remove + + files = fnmatch.filter(os.listdir(self.directory), self.pattern % ("*",)) + for filename in files: + try: + remove(os.path.join(self.directory, filename)) + except OSError: + pass + + +class MemcachedBytecodeCache(BytecodeCache): + """This class implements a bytecode cache that uses a memcache cache for + storing the information. It does not enforce a specific memcache library + (tummy's memcache or cmemcache) but will accept any class that provides + the minimal interface required. + + Libraries compatible with this class: + + - `cachelib `_ + - `python-memcached `_ + + (Unfortunately the django cache interface is not compatible because it + does not support storing binary data, only text. You can however pass + the underlying cache client to the bytecode cache which is available + as `django.core.cache.cache._client`.) + + The minimal interface for the client passed to the constructor is this: + + .. class:: MinimalClientInterface + + .. method:: set(key, value[, timeout]) + + Stores the bytecode in the cache. `value` is a string and + `timeout` the timeout of the key. If timeout is not provided + a default timeout or no timeout should be assumed, if it's + provided it's an integer with the number of seconds the cache + item should exist. + + .. method:: get(key) + + Returns the value for the cache key. If the item does not + exist in the cache the return value must be `None`. + + The other arguments to the constructor are the prefix for all keys that + is added before the actual cache key and the timeout for the bytecode in + the cache system. We recommend a high (or no) timeout. + + This bytecode cache does not support clearing of used items in the cache. + The clear method is a no-operation function. + + .. versionadded:: 2.7 + Added support for ignoring memcache errors through the + `ignore_memcache_errors` parameter. + """ + + def __init__( + self, + client: "_MemcachedClient", + prefix: str = "jinja2/bytecode/", + timeout: t.Optional[int] = None, + ignore_memcache_errors: bool = True, + ): + self.client = client + self.prefix = prefix + self.timeout = timeout + self.ignore_memcache_errors = ignore_memcache_errors + + def load_bytecode(self, bucket: Bucket) -> None: + try: + code = self.client.get(self.prefix + bucket.key) + except Exception: + if not self.ignore_memcache_errors: + raise + else: + bucket.bytecode_from_string(code) + + def dump_bytecode(self, bucket: Bucket) -> None: + key = self.prefix + bucket.key + value = bucket.bytecode_to_string() + + try: + if self.timeout is not None: + self.client.set(key, value, self.timeout) + else: + self.client.set(key, value) + except Exception: + if not self.ignore_memcache_errors: + raise diff --git a/.venv/lib/python3.13/site-packages/jinja2/compiler.py b/.venv/lib/python3.13/site-packages/jinja2/compiler.py new file mode 100644 index 0000000000000000000000000000000000000000..a4ff6a1b11af3e1a868d1a74c48d842390259b43 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/jinja2/compiler.py @@ -0,0 +1,1998 @@ +"""Compiles nodes from the parser into Python code.""" + +import typing as t +from contextlib import contextmanager +from functools import update_wrapper +from io import StringIO +from itertools import chain +from keyword import iskeyword as is_python_keyword + +from markupsafe import escape +from markupsafe import Markup + +from . import nodes +from .exceptions import TemplateAssertionError +from .idtracking import Symbols +from .idtracking import VAR_LOAD_ALIAS +from .idtracking import VAR_LOAD_PARAMETER +from .idtracking import VAR_LOAD_RESOLVE +from .idtracking import VAR_LOAD_UNDEFINED +from .nodes import EvalContext +from .optimizer import Optimizer +from .utils import _PassArg +from .utils import concat +from .visitor import NodeVisitor + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .environment import Environment + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + +operators = { + "eq": "==", + "ne": "!=", + "gt": ">", + "gteq": ">=", + "lt": "<", + "lteq": "<=", + "in": "in", + "notin": "not in", +} + + +def optimizeconst(f: F) -> F: + def new_func( + self: "CodeGenerator", node: nodes.Expr, frame: "Frame", **kwargs: t.Any + ) -> t.Any: + # Only optimize if the frame is not volatile + if self.optimizer is not None and not frame.eval_ctx.volatile: + new_node = self.optimizer.visit(node, frame.eval_ctx) + + if new_node != node: + return self.visit(new_node, frame) + + return f(self, node, frame, **kwargs) + + return update_wrapper(new_func, f) # type: ignore[return-value] + + +def _make_binop(op: str) -> t.Callable[["CodeGenerator", nodes.BinExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.BinExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed and op in self.environment.intercepted_binops # type: ignore + ): + self.write(f"environment.call_binop(context, {op!r}, ") + self.visit(node.left, frame) + self.write(", ") + self.visit(node.right, frame) + else: + self.write("(") + self.visit(node.left, frame) + self.write(f" {op} ") + self.visit(node.right, frame) + + self.write(")") + + return visitor + + +def _make_unop( + op: str, +) -> t.Callable[["CodeGenerator", nodes.UnaryExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.UnaryExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed and op in self.environment.intercepted_unops # type: ignore + ): + self.write(f"environment.call_unop(context, {op!r}, ") + self.visit(node.node, frame) + else: + self.write("(" + op) + self.visit(node.node, frame) + + self.write(")") + + return visitor + + +def generate( + node: nodes.Template, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, +) -> t.Optional[str]: + """Generate the python source for a node tree.""" + if not isinstance(node, nodes.Template): + raise TypeError("Can't compile non template nodes") + + generator = environment.code_generator_class( + environment, name, filename, stream, defer_init, optimized + ) + generator.visit(node) + + if stream is None: + return generator.stream.getvalue() # type: ignore + + return None + + +def has_safe_repr(value: t.Any) -> bool: + """Does the node have a safe representation?""" + if value is None or value is NotImplemented or value is Ellipsis: + return True + + if type(value) in {bool, int, float, complex, range, str, Markup}: + return True + + if type(value) in {tuple, list, set, frozenset}: + return all(has_safe_repr(v) for v in value) + + if type(value) is dict: # noqa E721 + return all(has_safe_repr(k) and has_safe_repr(v) for k, v in value.items()) + + return False + + +def find_undeclared( + nodes: t.Iterable[nodes.Node], names: t.Iterable[str] +) -> t.Set[str]: + """Check if the names passed are accessed undeclared. The return value + is a set of all the undeclared names from the sequence of names found. + """ + visitor = UndeclaredNameVisitor(names) + try: + for node in nodes: + visitor.visit(node) + except VisitorExit: + pass + return visitor.undeclared + + +class MacroRef: + def __init__(self, node: t.Union[nodes.Macro, nodes.CallBlock]) -> None: + self.node = node + self.accesses_caller = False + self.accesses_kwargs = False + self.accesses_varargs = False + + +class Frame: + """Holds compile time information for us.""" + + def __init__( + self, + eval_ctx: EvalContext, + parent: t.Optional["Frame"] = None, + level: t.Optional[int] = None, + ) -> None: + self.eval_ctx = eval_ctx + + # the parent of this frame + self.parent = parent + + if parent is None: + self.symbols = Symbols(level=level) + + # in some dynamic inheritance situations the compiler needs to add + # write tests around output statements. + self.require_output_check = False + + # inside some tags we are using a buffer rather than yield statements. + # this for example affects {% filter %} or {% macro %}. If a frame + # is buffered this variable points to the name of the list used as + # buffer. + self.buffer: t.Optional[str] = None + + # the name of the block we're in, otherwise None. + self.block: t.Optional[str] = None + + else: + self.symbols = Symbols(parent.symbols, level=level) + self.require_output_check = parent.require_output_check + self.buffer = parent.buffer + self.block = parent.block + + # a toplevel frame is the root + soft frames such as if conditions. + self.toplevel = False + + # the root frame is basically just the outermost frame, so no if + # conditions. This information is used to optimize inheritance + # situations. + self.rootlevel = False + + # variables set inside of loops and blocks should not affect outer frames, + # but they still needs to be kept track of as part of the active context. + self.loop_frame = False + self.block_frame = False + + # track whether the frame is being used in an if-statement or conditional + # expression as it determines which errors should be raised during runtime + # or compile time. + self.soft_frame = False + + def copy(self) -> "te.Self": + """Create a copy of the current one.""" + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.symbols = self.symbols.copy() + return rv + + def inner(self, isolated: bool = False) -> "Frame": + """Return an inner frame.""" + if isolated: + return Frame(self.eval_ctx, level=self.symbols.level + 1) + return Frame(self.eval_ctx, self) + + def soft(self) -> "te.Self": + """Return a soft frame. A soft frame may not be modified as + standalone thing as it shares the resources with the frame it + was created of, but it's not a rootlevel frame any longer. + + This is only used to implement if-statements and conditional + expressions. + """ + rv = self.copy() + rv.rootlevel = False + rv.soft_frame = True + return rv + + __copy__ = copy + + +class VisitorExit(RuntimeError): + """Exception used by the `UndeclaredNameVisitor` to signal a stop.""" + + +class DependencyFinderVisitor(NodeVisitor): + """A visitor that collects filter and test calls.""" + + def __init__(self) -> None: + self.filters: t.Set[str] = set() + self.tests: t.Set[str] = set() + + def visit_Filter(self, node: nodes.Filter) -> None: + self.generic_visit(node) + self.filters.add(node.name) + + def visit_Test(self, node: nodes.Test) -> None: + self.generic_visit(node) + self.tests.add(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting at blocks.""" + + +class UndeclaredNameVisitor(NodeVisitor): + """A visitor that checks if a name is accessed without being + declared. This is different from the frame visitor as it will + not stop at closure frames. + """ + + def __init__(self, names: t.Iterable[str]) -> None: + self.names = set(names) + self.undeclared: t.Set[str] = set() + + def visit_Name(self, node: nodes.Name) -> None: + if node.ctx == "load" and node.name in self.names: + self.undeclared.add(node.name) + if self.undeclared == self.names: + raise VisitorExit() + else: + self.names.discard(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting a blocks.""" + + +class CompilerExit(Exception): + """Raised if the compiler encountered a situation where it just + doesn't make sense to further process the code. Any block that + raises such an exception is not further processed. + """ + + +class CodeGenerator(NodeVisitor): + def __init__( + self, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, + ) -> None: + if stream is None: + stream = StringIO() + self.environment = environment + self.name = name + self.filename = filename + self.stream = stream + self.created_block_context = False + self.defer_init = defer_init + self.optimizer: t.Optional[Optimizer] = None + + if optimized: + self.optimizer = Optimizer(environment) + + # aliases for imports + self.import_aliases: t.Dict[str, str] = {} + + # a registry for all blocks. Because blocks are moved out + # into the global python scope they are registered here + self.blocks: t.Dict[str, nodes.Block] = {} + + # the number of extends statements so far + self.extends_so_far = 0 + + # some templates have a rootlevel extends. In this case we + # can safely assume that we're a child template and do some + # more optimizations. + self.has_known_extends = False + + # the current line number + self.code_lineno = 1 + + # registry of all filters and tests (global, not block local) + self.tests: t.Dict[str, str] = {} + self.filters: t.Dict[str, str] = {} + + # the debug information + self.debug_info: t.List[t.Tuple[int, int]] = [] + self._write_debug_info: t.Optional[int] = None + + # the number of new lines before the next write() + self._new_lines = 0 + + # the line number of the last written statement + self._last_line = 0 + + # true if nothing was written so far. + self._first_write = True + + # used by the `temporary_identifier` method to get new + # unique, temporary identifier + self._last_identifier = 0 + + # the current indentation + self._indentation = 0 + + # Tracks toplevel assignments + self._assign_stack: t.List[t.Set[str]] = [] + + # Tracks parameter definition blocks + self._param_def_block: t.List[t.Set[str]] = [] + + # Tracks the current context. + self._context_reference_stack = ["context"] + + @property + def optimized(self) -> bool: + return self.optimizer is not None + + # -- Various compilation helpers + + def fail(self, msg: str, lineno: int) -> "te.NoReturn": + """Fail with a :exc:`TemplateAssertionError`.""" + raise TemplateAssertionError(msg, lineno, self.name, self.filename) + + def temporary_identifier(self) -> str: + """Get a new unique identifier.""" + self._last_identifier += 1 + return f"t_{self._last_identifier}" + + def buffer(self, frame: Frame) -> None: + """Enable buffering for the frame from that point onwards.""" + frame.buffer = self.temporary_identifier() + self.writeline(f"{frame.buffer} = []") + + def return_buffer_contents( + self, frame: Frame, force_unescaped: bool = False + ) -> None: + """Return the buffer contents of the frame.""" + if not force_unescaped: + if frame.eval_ctx.volatile: + self.writeline("if context.eval_ctx.autoescape:") + self.indent() + self.writeline(f"return Markup(concat({frame.buffer}))") + self.outdent() + self.writeline("else:") + self.indent() + self.writeline(f"return concat({frame.buffer})") + self.outdent() + return + elif frame.eval_ctx.autoescape: + self.writeline(f"return Markup(concat({frame.buffer}))") + return + self.writeline(f"return concat({frame.buffer})") + + def indent(self) -> None: + """Indent by one.""" + self._indentation += 1 + + def outdent(self, step: int = 1) -> None: + """Outdent by step.""" + self._indentation -= step + + def start_write(self, frame: Frame, node: t.Optional[nodes.Node] = None) -> None: + """Yield or write into the frame buffer.""" + if frame.buffer is None: + self.writeline("yield ", node) + else: + self.writeline(f"{frame.buffer}.append(", node) + + def end_write(self, frame: Frame) -> None: + """End the writing process started by `start_write`.""" + if frame.buffer is not None: + self.write(")") + + def simple_write( + self, s: str, frame: Frame, node: t.Optional[nodes.Node] = None + ) -> None: + """Simple shortcut for start_write + write + end_write.""" + self.start_write(frame, node) + self.write(s) + self.end_write(frame) + + def blockvisit(self, nodes: t.Iterable[nodes.Node], frame: Frame) -> None: + """Visit a list of nodes as block in a frame. If the current frame + is no buffer a dummy ``if 0: yield None`` is written automatically. + """ + try: + self.writeline("pass") + for node in nodes: + self.visit(node, frame) + except CompilerExit: + pass + + def write(self, x: str) -> None: + """Write a string into the output stream.""" + if self._new_lines: + if not self._first_write: + self.stream.write("\n" * self._new_lines) + self.code_lineno += self._new_lines + if self._write_debug_info is not None: + self.debug_info.append((self._write_debug_info, self.code_lineno)) + self._write_debug_info = None + self._first_write = False + self.stream.write(" " * self._indentation) + self._new_lines = 0 + self.stream.write(x) + + def writeline( + self, x: str, node: t.Optional[nodes.Node] = None, extra: int = 0 + ) -> None: + """Combination of newline and write.""" + self.newline(node, extra) + self.write(x) + + def newline(self, node: t.Optional[nodes.Node] = None, extra: int = 0) -> None: + """Add one or more newlines before the next write.""" + self._new_lines = max(self._new_lines, 1 + extra) + if node is not None and node.lineno != self._last_line: + self._write_debug_info = node.lineno + self._last_line = node.lineno + + def signature( + self, + node: t.Union[nodes.Call, nodes.Filter, nodes.Test], + frame: Frame, + extra_kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + ) -> None: + """Writes a function call to the stream for the current node. + A leading comma is added automatically. The extra keyword + arguments may not include python keywords otherwise a syntax + error could occur. The extra keyword arguments should be given + as python dict. + """ + # if any of the given keyword arguments is a python keyword + # we have to make sure that no invalid call is created. + kwarg_workaround = any( + is_python_keyword(t.cast(str, k)) + for k in chain((x.key for x in node.kwargs), extra_kwargs or ()) + ) + + for arg in node.args: + self.write(", ") + self.visit(arg, frame) + + if not kwarg_workaround: + for kwarg in node.kwargs: + self.write(", ") + self.visit(kwarg, frame) + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f", {key}={value}") + if node.dyn_args: + self.write(", *") + self.visit(node.dyn_args, frame) + + if kwarg_workaround: + if node.dyn_kwargs is not None: + self.write(", **dict({") + else: + self.write(", **{") + for kwarg in node.kwargs: + self.write(f"{kwarg.key!r}: ") + self.visit(kwarg.value, frame) + self.write(", ") + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f"{key!r}: {value}, ") + if node.dyn_kwargs is not None: + self.write("}, **") + self.visit(node.dyn_kwargs, frame) + self.write(")") + else: + self.write("}") + + elif node.dyn_kwargs is not None: + self.write(", **") + self.visit(node.dyn_kwargs, frame) + + def pull_dependencies(self, nodes: t.Iterable[nodes.Node]) -> None: + """Find all filter and test names used in the template and + assign them to variables in the compiled namespace. Checking + that the names are registered with the environment is done when + compiling the Filter and Test nodes. If the node is in an If or + CondExpr node, the check is done at runtime instead. + + .. versionchanged:: 3.0 + Filters and tests in If and CondExpr nodes are checked at + runtime instead of compile time. + """ + visitor = DependencyFinderVisitor() + + for node in nodes: + visitor.visit(node) + + for id_map, names, dependency in ( + (self.filters, visitor.filters, "filters"), + ( + self.tests, + visitor.tests, + "tests", + ), + ): + for name in sorted(names): + if name not in id_map: + id_map[name] = self.temporary_identifier() + + # add check during runtime that dependencies used inside of executed + # blocks are defined, as this step may be skipped during compile time + self.writeline("try:") + self.indent() + self.writeline(f"{id_map[name]} = environment.{dependency}[{name!r}]") + self.outdent() + self.writeline("except KeyError:") + self.indent() + self.writeline("@internalcode") + self.writeline(f"def {id_map[name]}(*unused):") + self.indent() + self.writeline( + f'raise TemplateRuntimeError("No {dependency[:-1]}' + f' named {name!r} found.")' + ) + self.outdent() + self.outdent() + + def enter_frame(self, frame: Frame) -> None: + undefs = [] + for target, (action, param) in frame.symbols.loads.items(): + if action == VAR_LOAD_PARAMETER: + pass + elif action == VAR_LOAD_RESOLVE: + self.writeline(f"{target} = {self.get_resolve_func()}({param!r})") + elif action == VAR_LOAD_ALIAS: + self.writeline(f"{target} = {param}") + elif action == VAR_LOAD_UNDEFINED: + undefs.append(target) + else: + raise NotImplementedError("unknown load instruction") + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def leave_frame(self, frame: Frame, with_python_scope: bool = False) -> None: + if not with_python_scope: + undefs = [] + for target in frame.symbols.loads: + undefs.append(target) + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def choose_async(self, async_value: str = "async ", sync_value: str = "") -> str: + return async_value if self.environment.is_async else sync_value + + def func(self, name: str) -> str: + return f"{self.choose_async()}def {name}" + + def macro_body( + self, node: t.Union[nodes.Macro, nodes.CallBlock], frame: Frame + ) -> t.Tuple[Frame, MacroRef]: + """Dump the function def of a macro or call block.""" + frame = frame.inner() + frame.symbols.analyze_node(node) + macro_ref = MacroRef(node) + + explicit_caller = None + skip_special_params = set() + args = [] + + for idx, arg in enumerate(node.args): + if arg.name == "caller": + explicit_caller = idx + if arg.name in ("kwargs", "varargs"): + skip_special_params.add(arg.name) + args.append(frame.symbols.ref(arg.name)) + + undeclared = find_undeclared(node.body, ("caller", "kwargs", "varargs")) + + if "caller" in undeclared: + # In older Jinja versions there was a bug that allowed caller + # to retain the special behavior even if it was mentioned in + # the argument list. However thankfully this was only really + # working if it was the last argument. So we are explicitly + # checking this now and error out if it is anywhere else in + # the argument list. + if explicit_caller is not None: + try: + node.defaults[explicit_caller - len(node.args)] + except IndexError: + self.fail( + "When defining macros or call blocks the " + 'special "caller" argument must be omitted ' + "or be given a default.", + node.lineno, + ) + else: + args.append(frame.symbols.declare_parameter("caller")) + macro_ref.accesses_caller = True + if "kwargs" in undeclared and "kwargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("kwargs")) + macro_ref.accesses_kwargs = True + if "varargs" in undeclared and "varargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("varargs")) + macro_ref.accesses_varargs = True + + # macros are delayed, they never require output checks + frame.require_output_check = False + frame.symbols.analyze_node(node) + self.writeline(f"{self.func('macro')}({', '.join(args)}):", node) + self.indent() + + self.buffer(frame) + self.enter_frame(frame) + + self.push_parameter_definitions(frame) + for idx, arg in enumerate(node.args): + ref = frame.symbols.ref(arg.name) + self.writeline(f"if {ref} is missing:") + self.indent() + try: + default = node.defaults[idx - len(node.args)] + except IndexError: + self.writeline( + f'{ref} = undefined("parameter {arg.name!r} was not provided",' + f" name={arg.name!r})" + ) + else: + self.writeline(f"{ref} = ") + self.visit(default, frame) + self.mark_parameter_stored(ref) + self.outdent() + self.pop_parameter_definitions() + + self.blockvisit(node.body, frame) + self.return_buffer_contents(frame, force_unescaped=True) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + return frame, macro_ref + + def macro_def(self, macro_ref: MacroRef, frame: Frame) -> None: + """Dump the macro definition for the def created by macro_body.""" + arg_tuple = ", ".join(repr(x.name) for x in macro_ref.node.args) + name = getattr(macro_ref.node, "name", None) + if len(macro_ref.node.args) == 1: + arg_tuple += "," + self.write( + f"Macro(environment, macro, {name!r}, ({arg_tuple})," + f" {macro_ref.accesses_kwargs!r}, {macro_ref.accesses_varargs!r}," + f" {macro_ref.accesses_caller!r}, context.eval_ctx.autoescape)" + ) + + def position(self, node: nodes.Node) -> str: + """Return a human readable position for the node.""" + rv = f"line {node.lineno}" + if self.name is not None: + rv = f"{rv} in {self.name!r}" + return rv + + def dump_local_context(self, frame: Frame) -> str: + items_kv = ", ".join( + f"{name!r}: {target}" + for name, target in frame.symbols.dump_stores().items() + ) + return f"{{{items_kv}}}" + + def write_commons(self) -> None: + """Writes a common preamble that is used by root and block functions. + Primarily this sets up common local helpers and enforces a generator + through a dead branch. + """ + self.writeline("resolve = context.resolve_or_missing") + self.writeline("undefined = environment.undefined") + self.writeline("concat = environment.concat") + # always use the standard Undefined class for the implicit else of + # conditional expressions + self.writeline("cond_expr_undefined = Undefined") + self.writeline("if 0: yield None") + + def push_parameter_definitions(self, frame: Frame) -> None: + """Pushes all parameter targets from the given frame into a local + stack that permits tracking of yet to be assigned parameters. In + particular this enables the optimization from `visit_Name` to skip + undefined expressions for parameters in macros as macros can reference + otherwise unbound parameters. + """ + self._param_def_block.append(frame.symbols.dump_param_targets()) + + def pop_parameter_definitions(self) -> None: + """Pops the current parameter definitions set.""" + self._param_def_block.pop() + + def mark_parameter_stored(self, target: str) -> None: + """Marks a parameter in the current parameter definitions as stored. + This will skip the enforced undefined checks. + """ + if self._param_def_block: + self._param_def_block[-1].discard(target) + + def push_context_reference(self, target: str) -> None: + self._context_reference_stack.append(target) + + def pop_context_reference(self) -> None: + self._context_reference_stack.pop() + + def get_context_ref(self) -> str: + return self._context_reference_stack[-1] + + def get_resolve_func(self) -> str: + target = self._context_reference_stack[-1] + if target == "context": + return "resolve" + return f"{target}.resolve" + + def derive_context(self, frame: Frame) -> str: + return f"{self.get_context_ref()}.derived({self.dump_local_context(frame)})" + + def parameter_is_undeclared(self, target: str) -> bool: + """Checks if a given target is an undeclared parameter.""" + if not self._param_def_block: + return False + return target in self._param_def_block[-1] + + def push_assign_tracking(self) -> None: + """Pushes a new layer for assignment tracking.""" + self._assign_stack.append(set()) + + def pop_assign_tracking(self, frame: Frame) -> None: + """Pops the topmost level for assignment tracking and updates the + context variables if necessary. + """ + vars = self._assign_stack.pop() + if ( + not frame.block_frame + and not frame.loop_frame + and not frame.toplevel + or not vars + ): + return + public_names = [x for x in vars if x[:1] != "_"] + if len(vars) == 1: + name = next(iter(vars)) + ref = frame.symbols.ref(name) + if frame.loop_frame: + self.writeline(f"_loop_vars[{name!r}] = {ref}") + return + if frame.block_frame: + self.writeline(f"_block_vars[{name!r}] = {ref}") + return + self.writeline(f"context.vars[{name!r}] = {ref}") + else: + if frame.loop_frame: + self.writeline("_loop_vars.update({") + elif frame.block_frame: + self.writeline("_block_vars.update({") + else: + self.writeline("context.vars.update({") + for idx, name in enumerate(sorted(vars)): + if idx: + self.write(", ") + ref = frame.symbols.ref(name) + self.write(f"{name!r}: {ref}") + self.write("})") + if not frame.block_frame and not frame.loop_frame and public_names: + if len(public_names) == 1: + self.writeline(f"context.exported_vars.add({public_names[0]!r})") + else: + names_str = ", ".join(map(repr, sorted(public_names))) + self.writeline(f"context.exported_vars.update(({names_str}))") + + # -- Statement Visitors + + def visit_Template( + self, node: nodes.Template, frame: t.Optional[Frame] = None + ) -> None: + assert frame is None, "no root frame allowed" + eval_ctx = EvalContext(self.environment, self.name) + + from .runtime import async_exported + from .runtime import exported + + if self.environment.is_async: + exported_names = sorted(exported + async_exported) + else: + exported_names = sorted(exported) + + self.writeline("from jinja2.runtime import " + ", ".join(exported_names)) + + # if we want a deferred initialization we cannot move the + # environment into a local name + envenv = "" if self.defer_init else ", environment=environment" + + # do we have an extends tag at all? If not, we can save some + # overhead by just not processing any inheritance code. + have_extends = node.find(nodes.Extends) is not None + + # find all blocks + for block in node.find_all(nodes.Block): + if block.name in self.blocks: + self.fail(f"block {block.name!r} defined twice", block.lineno) + self.blocks[block.name] = block + + # find all imports and import them + for import_ in node.find_all(nodes.ImportedName): + if import_.importname not in self.import_aliases: + imp = import_.importname + self.import_aliases[imp] = alias = self.temporary_identifier() + if "." in imp: + module, obj = imp.rsplit(".", 1) + self.writeline(f"from {module} import {obj} as {alias}") + else: + self.writeline(f"import {imp} as {alias}") + + # add the load name + self.writeline(f"name = {self.name!r}") + + # generate the root render function. + self.writeline( + f"{self.func('root')}(context, missing=missing{envenv}):", extra=1 + ) + self.indent() + self.write_commons() + + # process the root + frame = Frame(eval_ctx) + if "self" in find_undeclared(node.body, ("self",)): + ref = frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + frame.symbols.analyze_node(node) + frame.toplevel = frame.rootlevel = True + frame.require_output_check = have_extends and not self.has_known_extends + if have_extends: + self.writeline("parent_template = None") + self.enter_frame(frame) + self.pull_dependencies(node.body) + self.blockvisit(node.body, frame) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + # make sure that the parent root is called. + if have_extends: + if not self.has_known_extends: + self.indent() + self.writeline("if parent_template is not None:") + self.indent() + if not self.environment.is_async: + self.writeline("yield from parent_template.root_render_func(context)") + else: + self.writeline("agen = parent_template.root_render_func(context)") + self.writeline("try:") + self.indent() + self.writeline("async for event in agen:") + self.indent() + self.writeline("yield event") + self.outdent() + self.outdent() + self.writeline("finally: await agen.aclose()") + self.outdent(1 + (not self.has_known_extends)) + + # at this point we now have the blocks collected and can visit them too. + for name, block in self.blocks.items(): + self.writeline( + f"{self.func('block_' + name)}(context, missing=missing{envenv}):", + block, + 1, + ) + self.indent() + self.write_commons() + # It's important that we do not make this frame a child of the + # toplevel template. This would cause a variety of + # interesting issues with identifier tracking. + block_frame = Frame(eval_ctx) + block_frame.block_frame = True + undeclared = find_undeclared(block.body, ("self", "super")) + if "self" in undeclared: + ref = block_frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + if "super" in undeclared: + ref = block_frame.symbols.declare_parameter("super") + self.writeline(f"{ref} = context.super({name!r}, block_{name})") + block_frame.symbols.analyze_node(block) + block_frame.block = name + self.writeline("_block_vars = {}") + self.enter_frame(block_frame) + self.pull_dependencies(block.body) + self.blockvisit(block.body, block_frame) + self.leave_frame(block_frame, with_python_scope=True) + self.outdent() + + blocks_kv_str = ", ".join(f"{x!r}: block_{x}" for x in self.blocks) + self.writeline(f"blocks = {{{blocks_kv_str}}}", extra=1) + debug_kv_str = "&".join(f"{k}={v}" for k, v in self.debug_info) + self.writeline(f"debug_info = {debug_kv_str!r}") + + def visit_Block(self, node: nodes.Block, frame: Frame) -> None: + """Call a block and register it for the template.""" + level = 0 + if frame.toplevel: + # if we know that we are a child template, there is no need to + # check if we are one + if self.has_known_extends: + return + if self.extends_so_far > 0: + self.writeline("if parent_template is None:") + self.indent() + level += 1 + + if node.scoped: + context = self.derive_context(frame) + else: + context = self.get_context_ref() + + if node.required: + self.writeline(f"if len(context.blocks[{node.name!r}]) <= 1:", node) + self.indent() + self.writeline( + f'raise TemplateRuntimeError("Required block {node.name!r} not found")', + node, + ) + self.outdent() + + if not self.environment.is_async and frame.buffer is None: + self.writeline( + f"yield from context.blocks[{node.name!r}][0]({context})", node + ) + else: + self.writeline(f"gen = context.blocks[{node.name!r}][0]({context})") + self.writeline("try:") + self.indent() + self.writeline( + f"{self.choose_async()}for event in gen:", + node, + ) + self.indent() + self.simple_write("event", frame) + self.outdent() + self.outdent() + self.writeline( + f"finally: {self.choose_async('await gen.aclose()', 'gen.close()')}" + ) + + self.outdent(level) + + def visit_Extends(self, node: nodes.Extends, frame: Frame) -> None: + """Calls the extender.""" + if not frame.toplevel: + self.fail("cannot use extend from a non top-level scope", node.lineno) + + # if the number of extends statements in general is zero so + # far, we don't have to add a check if something extended + # the template before this one. + if self.extends_so_far > 0: + # if we have a known extends we just add a template runtime + # error into the generated code. We could catch that at compile + # time too, but i welcome it not to confuse users by throwing the + # same error at different times just "because we can". + if not self.has_known_extends: + self.writeline("if parent_template is not None:") + self.indent() + self.writeline('raise TemplateRuntimeError("extended multiple times")') + + # if we have a known extends already we don't need that code here + # as we know that the template execution will end here. + if self.has_known_extends: + raise CompilerExit() + else: + self.outdent() + + self.writeline("parent_template = environment.get_template(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + self.writeline("for name, parent_block in parent_template.blocks.items():") + self.indent() + self.writeline("context.blocks.setdefault(name, []).append(parent_block)") + self.outdent() + + # if this extends statement was in the root level we can take + # advantage of that information and simplify the generated code + # in the top level from this point onwards + if frame.rootlevel: + self.has_known_extends = True + + # and now we have one more + self.extends_so_far += 1 + + def visit_Include(self, node: nodes.Include, frame: Frame) -> None: + """Handles includes.""" + if node.ignore_missing: + self.writeline("try:") + self.indent() + + func_name = "get_or_select_template" + if isinstance(node.template, nodes.Const): + if isinstance(node.template.value, str): + func_name = "get_template" + elif isinstance(node.template.value, (tuple, list)): + func_name = "select_template" + elif isinstance(node.template, (nodes.Tuple, nodes.List)): + func_name = "select_template" + + self.writeline(f"template = environment.{func_name}(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + if node.ignore_missing: + self.outdent() + self.writeline("except TemplateNotFound:") + self.indent() + self.writeline("pass") + self.outdent() + self.writeline("else:") + self.indent() + + def loop_body() -> None: + self.indent() + self.simple_write("event", frame) + self.outdent() + + if node.with_context: + self.writeline( + f"gen = template.root_render_func(" + "template.new_context(context.get_all(), True," + f" {self.dump_local_context(frame)}))" + ) + self.writeline("try:") + self.indent() + self.writeline(f"{self.choose_async()}for event in gen:") + loop_body() + self.outdent() + self.writeline( + f"finally: {self.choose_async('await gen.aclose()', 'gen.close()')}" + ) + elif self.environment.is_async: + self.writeline( + "for event in (await template._get_default_module_async())" + "._body_stream:" + ) + loop_body() + else: + self.writeline("yield from template._get_default_module()._body_stream") + + if node.ignore_missing: + self.outdent() + + def _import_common( + self, node: t.Union[nodes.Import, nodes.FromImport], frame: Frame + ) -> None: + self.write(f"{self.choose_async('await ')}environment.get_template(") + self.visit(node.template, frame) + self.write(f", {self.name!r}).") + + if node.with_context: + f_name = f"make_module{self.choose_async('_async')}" + self.write( + f"{f_name}(context.get_all(), True, {self.dump_local_context(frame)})" + ) + else: + self.write(f"_get_default_module{self.choose_async('_async')}(context)") + + def visit_Import(self, node: nodes.Import, frame: Frame) -> None: + """Visit regular imports.""" + self.writeline(f"{frame.symbols.ref(node.target)} = ", node) + if frame.toplevel: + self.write(f"context.vars[{node.target!r}] = ") + + self._import_common(node, frame) + + if frame.toplevel and not node.target.startswith("_"): + self.writeline(f"context.exported_vars.discard({node.target!r})") + + def visit_FromImport(self, node: nodes.FromImport, frame: Frame) -> None: + """Visit named imports.""" + self.newline(node) + self.write("included_template = ") + self._import_common(node, frame) + var_names = [] + discarded_names = [] + for name in node.names: + if isinstance(name, tuple): + name, alias = name + else: + alias = name + self.writeline( + f"{frame.symbols.ref(alias)} =" + f" getattr(included_template, {name!r}, missing)" + ) + self.writeline(f"if {frame.symbols.ref(alias)} is missing:") + self.indent() + # The position will contain the template name, and will be formatted + # into a string that will be compiled into an f-string. Curly braces + # in the name must be replaced with escapes so that they will not be + # executed as part of the f-string. + position = self.position(node).replace("{", "{{").replace("}", "}}") + message = ( + "the template {included_template.__name__!r}" + f" (imported on {position})" + f" does not export the requested name {name!r}" + ) + self.writeline( + f"{frame.symbols.ref(alias)} = undefined(f{message!r}, name={name!r})" + ) + self.outdent() + if frame.toplevel: + var_names.append(alias) + if not alias.startswith("_"): + discarded_names.append(alias) + + if var_names: + if len(var_names) == 1: + name = var_names[0] + self.writeline(f"context.vars[{name!r}] = {frame.symbols.ref(name)}") + else: + names_kv = ", ".join( + f"{name!r}: {frame.symbols.ref(name)}" for name in var_names + ) + self.writeline(f"context.vars.update({{{names_kv}}})") + if discarded_names: + if len(discarded_names) == 1: + self.writeline(f"context.exported_vars.discard({discarded_names[0]!r})") + else: + names_str = ", ".join(map(repr, discarded_names)) + self.writeline( + f"context.exported_vars.difference_update(({names_str}))" + ) + + def visit_For(self, node: nodes.For, frame: Frame) -> None: + loop_frame = frame.inner() + loop_frame.loop_frame = True + test_frame = frame.inner() + else_frame = frame.inner() + + # try to figure out if we have an extended loop. An extended loop + # is necessary if the loop is in recursive mode if the special loop + # variable is accessed in the body if the body is a scoped block. + extended_loop = ( + node.recursive + or "loop" + in find_undeclared(node.iter_child_nodes(only=("body",)), ("loop",)) + or any(block.scoped for block in node.find_all(nodes.Block)) + ) + + loop_ref = None + if extended_loop: + loop_ref = loop_frame.symbols.declare_parameter("loop") + + loop_frame.symbols.analyze_node(node, for_branch="body") + if node.else_: + else_frame.symbols.analyze_node(node, for_branch="else") + + if node.test: + loop_filter_func = self.temporary_identifier() + test_frame.symbols.analyze_node(node, for_branch="test") + self.writeline(f"{self.func(loop_filter_func)}(fiter):", node.test) + self.indent() + self.enter_frame(test_frame) + self.writeline(self.choose_async("async for ", "for ")) + self.visit(node.target, loop_frame) + self.write(" in ") + self.write(self.choose_async("auto_aiter(fiter)", "fiter")) + self.write(":") + self.indent() + self.writeline("if ", node.test) + self.visit(node.test, test_frame) + self.write(":") + self.indent() + self.writeline("yield ") + self.visit(node.target, loop_frame) + self.outdent(3) + self.leave_frame(test_frame, with_python_scope=True) + + # if we don't have an recursive loop we have to find the shadowed + # variables at that point. Because loops can be nested but the loop + # variable is a special one we have to enforce aliasing for it. + if node.recursive: + self.writeline( + f"{self.func('loop')}(reciter, loop_render_func, depth=0):", node + ) + self.indent() + self.buffer(loop_frame) + + # Use the same buffer for the else frame + else_frame.buffer = loop_frame.buffer + + # make sure the loop variable is a special one and raise a template + # assertion error if a loop tries to write to loop + if extended_loop: + self.writeline(f"{loop_ref} = missing") + + for name in node.find_all(nodes.Name): + if name.ctx == "store" and name.name == "loop": + self.fail( + "Can't assign to special loop variable in for-loop target", + name.lineno, + ) + + if node.else_: + iteration_indicator = self.temporary_identifier() + self.writeline(f"{iteration_indicator} = 1") + + self.writeline(self.choose_async("async for ", "for "), node) + self.visit(node.target, loop_frame) + if extended_loop: + self.write(f", {loop_ref} in {self.choose_async('Async')}LoopContext(") + else: + self.write(" in ") + + if node.test: + self.write(f"{loop_filter_func}(") + if node.recursive: + self.write("reciter") + else: + if self.environment.is_async and not extended_loop: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async and not extended_loop: + self.write(")") + if node.test: + self.write(")") + + if node.recursive: + self.write(", undefined, loop_render_func, depth):") + else: + self.write(", undefined):" if extended_loop else ":") + + self.indent() + self.enter_frame(loop_frame) + + self.writeline("_loop_vars = {}") + self.blockvisit(node.body, loop_frame) + if node.else_: + self.writeline(f"{iteration_indicator} = 0") + self.outdent() + self.leave_frame( + loop_frame, with_python_scope=node.recursive and not node.else_ + ) + + if node.else_: + self.writeline(f"if {iteration_indicator}:") + self.indent() + self.enter_frame(else_frame) + self.blockvisit(node.else_, else_frame) + self.leave_frame(else_frame) + self.outdent() + + # if the node was recursive we have to return the buffer contents + # and start the iteration code + if node.recursive: + self.return_buffer_contents(loop_frame) + self.outdent() + self.start_write(frame, node) + self.write(f"{self.choose_async('await ')}loop(") + if self.environment.is_async: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async: + self.write(")") + self.write(", loop)") + self.end_write(frame) + + # at the end of the iteration, clear any assignments made in the + # loop from the top level + if self._assign_stack: + self._assign_stack[-1].difference_update(loop_frame.symbols.stores) + + def visit_If(self, node: nodes.If, frame: Frame) -> None: + if_frame = frame.soft() + self.writeline("if ", node) + self.visit(node.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(node.body, if_frame) + self.outdent() + for elif_ in node.elif_: + self.writeline("elif ", elif_) + self.visit(elif_.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(elif_.body, if_frame) + self.outdent() + if node.else_: + self.writeline("else:") + self.indent() + self.blockvisit(node.else_, if_frame) + self.outdent() + + def visit_Macro(self, node: nodes.Macro, frame: Frame) -> None: + macro_frame, macro_ref = self.macro_body(node, frame) + self.newline() + if frame.toplevel: + if not node.name.startswith("_"): + self.write(f"context.exported_vars.add({node.name!r})") + self.writeline(f"context.vars[{node.name!r}] = ") + self.write(f"{frame.symbols.ref(node.name)} = ") + self.macro_def(macro_ref, macro_frame) + + def visit_CallBlock(self, node: nodes.CallBlock, frame: Frame) -> None: + call_frame, macro_ref = self.macro_body(node, frame) + self.writeline("caller = ") + self.macro_def(macro_ref, call_frame) + self.start_write(frame, node) + self.visit_Call(node.call, frame, forward_caller=True) + self.end_write(frame) + + def visit_FilterBlock(self, node: nodes.FilterBlock, frame: Frame) -> None: + filter_frame = frame.inner() + filter_frame.symbols.analyze_node(node) + self.enter_frame(filter_frame) + self.buffer(filter_frame) + self.blockvisit(node.body, filter_frame) + self.start_write(frame, node) + self.visit_Filter(node.filter, filter_frame) + self.end_write(frame) + self.leave_frame(filter_frame) + + def visit_With(self, node: nodes.With, frame: Frame) -> None: + with_frame = frame.inner() + with_frame.symbols.analyze_node(node) + self.enter_frame(with_frame) + for target, expr in zip(node.targets, node.values): + self.newline() + self.visit(target, with_frame) + self.write(" = ") + self.visit(expr, frame) + self.blockvisit(node.body, with_frame) + self.leave_frame(with_frame) + + def visit_ExprStmt(self, node: nodes.ExprStmt, frame: Frame) -> None: + self.newline(node) + self.visit(node.node, frame) + + class _FinalizeInfo(t.NamedTuple): + const: t.Optional[t.Callable[..., str]] + src: t.Optional[str] + + @staticmethod + def _default_finalize(value: t.Any) -> t.Any: + """The default finalize function if the environment isn't + configured with one. Or, if the environment has one, this is + called on that function's output for constants. + """ + return str(value) + + _finalize: t.Optional[_FinalizeInfo] = None + + def _make_finalize(self) -> _FinalizeInfo: + """Build the finalize function to be used on constants and at + runtime. Cached so it's only created once for all output nodes. + + Returns a ``namedtuple`` with the following attributes: + + ``const`` + A function to finalize constant data at compile time. + + ``src`` + Source code to output around nodes to be evaluated at + runtime. + """ + if self._finalize is not None: + return self._finalize + + finalize: t.Optional[t.Callable[..., t.Any]] + finalize = default = self._default_finalize + src = None + + if self.environment.finalize: + src = "environment.finalize(" + env_finalize = self.environment.finalize + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(env_finalize) # type: ignore + ) + finalize = None + + if pass_arg is None: + + def finalize(value: t.Any) -> t.Any: # noqa: F811 + return default(env_finalize(value)) + + else: + src = f"{src}{pass_arg}, " + + if pass_arg == "environment": + + def finalize(value: t.Any) -> t.Any: # noqa: F811 + return default(env_finalize(self.environment, value)) + + self._finalize = self._FinalizeInfo(finalize, src) + return self._finalize + + def _output_const_repr(self, group: t.Iterable[t.Any]) -> str: + """Given a group of constant values converted from ``Output`` + child nodes, produce a string to write to the template module + source. + """ + return repr(concat(group)) + + def _output_child_to_const( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> str: + """Try to optimize a child of an ``Output`` node by trying to + convert it to constant, finalized data at compile time. + + If :exc:`Impossible` is raised, the node is not constant and + will be evaluated at runtime. Any other exception will also be + evaluated at runtime for easier debugging. + """ + const = node.as_const(frame.eval_ctx) + + if frame.eval_ctx.autoescape: + const = escape(const) + + # Template data doesn't go through finalize. + if isinstance(node, nodes.TemplateData): + return str(const) + + return finalize.const(const) # type: ignore + + def _output_child_pre( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code before visiting a child of an + ``Output`` node. + """ + if frame.eval_ctx.volatile: + self.write("(escape if context.eval_ctx.autoescape else str)(") + elif frame.eval_ctx.autoescape: + self.write("escape(") + else: + self.write("str(") + + if finalize.src is not None: + self.write(finalize.src) + + def _output_child_post( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code after visiting a child of an + ``Output`` node. + """ + self.write(")") + + if finalize.src is not None: + self.write(")") + + def visit_Output(self, node: nodes.Output, frame: Frame) -> None: + # If an extends is active, don't render outside a block. + if frame.require_output_check: + # A top-level extends is known to exist at compile time. + if self.has_known_extends: + return + + self.writeline("if parent_template is None:") + self.indent() + + finalize = self._make_finalize() + body: t.List[t.Union[t.List[t.Any], nodes.Expr]] = [] + + # Evaluate constants at compile time if possible. Each item in + # body will be either a list of static data or a node to be + # evaluated at runtime. + for child in node.nodes: + try: + if not ( + # If the finalize function requires runtime context, + # constants can't be evaluated at compile time. + finalize.const + # Unless it's basic template data that won't be + # finalized anyway. + or isinstance(child, nodes.TemplateData) + ): + raise nodes.Impossible() + + const = self._output_child_to_const(child, frame, finalize) + except (nodes.Impossible, Exception): + # The node was not constant and needs to be evaluated at + # runtime. Or another error was raised, which is easier + # to debug at runtime. + body.append(child) + continue + + if body and isinstance(body[-1], list): + body[-1].append(const) + else: + body.append([const]) + + if frame.buffer is not None: + if len(body) == 1: + self.writeline(f"{frame.buffer}.append(") + else: + self.writeline(f"{frame.buffer}.extend((") + + self.indent() + + for item in body: + if isinstance(item, list): + # A group of constant data to join and output. + val = self._output_const_repr(item) + + if frame.buffer is None: + self.writeline("yield " + val) + else: + self.writeline(val + ",") + else: + if frame.buffer is None: + self.writeline("yield ", item) + else: + self.newline(item) + + # A node to be evaluated at runtime. + self._output_child_pre(item, frame, finalize) + self.visit(item, frame) + self._output_child_post(item, frame, finalize) + + if frame.buffer is not None: + self.write(",") + + if frame.buffer is not None: + self.outdent() + self.writeline(")" if len(body) == 1 else "))") + + if frame.require_output_check: + self.outdent() + + def visit_Assign(self, node: nodes.Assign, frame: Frame) -> None: + self.push_assign_tracking() + + # ``a.b`` is allowed for assignment, and is parsed as an NSRef. However, + # it is only valid if it references a Namespace object. Emit a check for + # that for each ref here, before assignment code is emitted. This can't + # be done in visit_NSRef as the ref could be in the middle of a tuple. + seen_refs: t.Set[str] = set() + + for nsref in node.find_all(nodes.NSRef): + if nsref.name in seen_refs: + # Only emit the check for each reference once, in case the same + # ref is used multiple times in a tuple, `ns.a, ns.b = c, d`. + continue + + seen_refs.add(nsref.name) + ref = frame.symbols.ref(nsref.name) + self.writeline(f"if not isinstance({ref}, Namespace):") + self.indent() + self.writeline( + "raise TemplateRuntimeError" + '("cannot assign attribute on non-namespace object")' + ) + self.outdent() + + self.newline(node) + self.visit(node.target, frame) + self.write(" = ") + self.visit(node.node, frame) + self.pop_assign_tracking(frame) + + def visit_AssignBlock(self, node: nodes.AssignBlock, frame: Frame) -> None: + self.push_assign_tracking() + block_frame = frame.inner() + # This is a special case. Since a set block always captures we + # will disable output checks. This way one can use set blocks + # toplevel even in extended templates. + block_frame.require_output_check = False + block_frame.symbols.analyze_node(node) + self.enter_frame(block_frame) + self.buffer(block_frame) + self.blockvisit(node.body, block_frame) + self.newline(node) + self.visit(node.target, frame) + self.write(" = (Markup if context.eval_ctx.autoescape else identity)(") + if node.filter is not None: + self.visit_Filter(node.filter, block_frame) + else: + self.write(f"concat({block_frame.buffer})") + self.write(")") + self.pop_assign_tracking(frame) + self.leave_frame(block_frame) + + # -- Expression Visitors + + def visit_Name(self, node: nodes.Name, frame: Frame) -> None: + if node.ctx == "store" and ( + frame.toplevel or frame.loop_frame or frame.block_frame + ): + if self._assign_stack: + self._assign_stack[-1].add(node.name) + ref = frame.symbols.ref(node.name) + + # If we are looking up a variable we might have to deal with the + # case where it's undefined. We can skip that case if the load + # instruction indicates a parameter which are always defined. + if node.ctx == "load": + load = frame.symbols.find_load(ref) + if not ( + load is not None + and load[0] == VAR_LOAD_PARAMETER + and not self.parameter_is_undeclared(ref) + ): + self.write( + f"(undefined(name={node.name!r}) if {ref} is missing else {ref})" + ) + return + + self.write(ref) + + def visit_NSRef(self, node: nodes.NSRef, frame: Frame) -> None: + # NSRef is a dotted assignment target a.b=c, but uses a[b]=c internally. + # visit_Assign emits code to validate that each ref is to a Namespace + # object only. That can't be emitted here as the ref could be in the + # middle of a tuple assignment. + ref = frame.symbols.ref(node.name) + self.writeline(f"{ref}[{node.attr!r}]") + + def visit_Const(self, node: nodes.Const, frame: Frame) -> None: + val = node.as_const(frame.eval_ctx) + if isinstance(val, float): + self.write(str(val)) + else: + self.write(repr(val)) + + def visit_TemplateData(self, node: nodes.TemplateData, frame: Frame) -> None: + try: + self.write(repr(node.as_const(frame.eval_ctx))) + except nodes.Impossible: + self.write( + f"(Markup if context.eval_ctx.autoescape else identity)({node.data!r})" + ) + + def visit_Tuple(self, node: nodes.Tuple, frame: Frame) -> None: + self.write("(") + idx = -1 + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write(",)" if idx == 0 else ")") + + def visit_List(self, node: nodes.List, frame: Frame) -> None: + self.write("[") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write("]") + + def visit_Dict(self, node: nodes.Dict, frame: Frame) -> None: + self.write("{") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item.key, frame) + self.write(": ") + self.visit(item.value, frame) + self.write("}") + + visit_Add = _make_binop("+") + visit_Sub = _make_binop("-") + visit_Mul = _make_binop("*") + visit_Div = _make_binop("/") + visit_FloorDiv = _make_binop("//") + visit_Pow = _make_binop("**") + visit_Mod = _make_binop("%") + visit_And = _make_binop("and") + visit_Or = _make_binop("or") + visit_Pos = _make_unop("+") + visit_Neg = _make_unop("-") + visit_Not = _make_unop("not ") + + @optimizeconst + def visit_Concat(self, node: nodes.Concat, frame: Frame) -> None: + if frame.eval_ctx.volatile: + func_name = "(markup_join if context.eval_ctx.volatile else str_join)" + elif frame.eval_ctx.autoescape: + func_name = "markup_join" + else: + func_name = "str_join" + self.write(f"{func_name}((") + for arg in node.nodes: + self.visit(arg, frame) + self.write(", ") + self.write("))") + + @optimizeconst + def visit_Compare(self, node: nodes.Compare, frame: Frame) -> None: + self.write("(") + self.visit(node.expr, frame) + for op in node.ops: + self.visit(op, frame) + self.write(")") + + def visit_Operand(self, node: nodes.Operand, frame: Frame) -> None: + self.write(f" {operators[node.op]} ") + self.visit(node.expr, frame) + + @optimizeconst + def visit_Getattr(self, node: nodes.Getattr, frame: Frame) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getattr(") + self.visit(node.node, frame) + self.write(f", {node.attr!r})") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Getitem(self, node: nodes.Getitem, frame: Frame) -> None: + # slices bypass the environment getitem method. + if isinstance(node.arg, nodes.Slice): + self.visit(node.node, frame) + self.write("[") + self.visit(node.arg, frame) + self.write("]") + else: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getitem(") + self.visit(node.node, frame) + self.write(", ") + self.visit(node.arg, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + def visit_Slice(self, node: nodes.Slice, frame: Frame) -> None: + if node.start is not None: + self.visit(node.start, frame) + self.write(":") + if node.stop is not None: + self.visit(node.stop, frame) + if node.step is not None: + self.write(":") + self.visit(node.step, frame) + + @contextmanager + def _filter_test_common( + self, node: t.Union[nodes.Filter, nodes.Test], frame: Frame, is_filter: bool + ) -> t.Iterator[None]: + if self.environment.is_async: + self.write("(await auto_await(") + + if is_filter: + self.write(f"{self.filters[node.name]}(") + func = self.environment.filters.get(node.name) + else: + self.write(f"{self.tests[node.name]}(") + func = self.environment.tests.get(node.name) + + # When inside an If or CondExpr frame, allow the filter to be + # undefined at compile time and only raise an error if it's + # actually called at runtime. See pull_dependencies. + if func is None and not frame.soft_frame: + type_name = "filter" if is_filter else "test" + self.fail(f"No {type_name} named {node.name!r}.", node.lineno) + + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(func) # type: ignore + ) + + if pass_arg is not None: + self.write(f"{pass_arg}, ") + + # Back to the visitor function to handle visiting the target of + # the filter or test. + yield + + self.signature(node, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Filter(self, node: nodes.Filter, frame: Frame) -> None: + with self._filter_test_common(node, frame, True): + # if the filter node is None we are inside a filter block + # and want to write to the current buffer + if node.node is not None: + self.visit(node.node, frame) + elif frame.eval_ctx.volatile: + self.write( + f"(Markup(concat({frame.buffer}))" + f" if context.eval_ctx.autoescape else concat({frame.buffer}))" + ) + elif frame.eval_ctx.autoescape: + self.write(f"Markup(concat({frame.buffer}))") + else: + self.write(f"concat({frame.buffer})") + + @optimizeconst + def visit_Test(self, node: nodes.Test, frame: Frame) -> None: + with self._filter_test_common(node, frame, False): + self.visit(node.node, frame) + + @optimizeconst + def visit_CondExpr(self, node: nodes.CondExpr, frame: Frame) -> None: + frame = frame.soft() + + def write_expr2() -> None: + if node.expr2 is not None: + self.visit(node.expr2, frame) + return + + self.write( + f'cond_expr_undefined("the inline if-expression on' + f" {self.position(node)} evaluated to false and no else" + f' section was defined.")' + ) + + self.write("(") + self.visit(node.expr1, frame) + self.write(" if ") + self.visit(node.test, frame) + self.write(" else ") + write_expr2() + self.write(")") + + @optimizeconst + def visit_Call( + self, node: nodes.Call, frame: Frame, forward_caller: bool = False + ) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + if self.environment.sandboxed: + self.write("environment.call(context, ") + else: + self.write("context.call(") + self.visit(node.node, frame) + extra_kwargs = {"caller": "caller"} if forward_caller else None + loop_kwargs = {"_loop_vars": "_loop_vars"} if frame.loop_frame else {} + block_kwargs = {"_block_vars": "_block_vars"} if frame.block_frame else {} + if extra_kwargs: + extra_kwargs.update(loop_kwargs, **block_kwargs) + elif loop_kwargs or block_kwargs: + extra_kwargs = dict(loop_kwargs, **block_kwargs) + self.signature(node, frame, extra_kwargs) + self.write(")") + if self.environment.is_async: + self.write("))") + + def visit_Keyword(self, node: nodes.Keyword, frame: Frame) -> None: + self.write(node.key + "=") + self.visit(node.value, frame) + + # -- Unused nodes for extensions + + def visit_MarkSafe(self, node: nodes.MarkSafe, frame: Frame) -> None: + self.write("Markup(") + self.visit(node.expr, frame) + self.write(")") + + def visit_MarkSafeIfAutoescape( + self, node: nodes.MarkSafeIfAutoescape, frame: Frame + ) -> None: + self.write("(Markup if context.eval_ctx.autoescape else identity)(") + self.visit(node.expr, frame) + self.write(")") + + def visit_EnvironmentAttribute( + self, node: nodes.EnvironmentAttribute, frame: Frame + ) -> None: + self.write("environment." + node.name) + + def visit_ExtensionAttribute( + self, node: nodes.ExtensionAttribute, frame: Frame + ) -> None: + self.write(f"environment.extensions[{node.identifier!r}].{node.name}") + + def visit_ImportedName(self, node: nodes.ImportedName, frame: Frame) -> None: + self.write(self.import_aliases[node.importname]) + + def visit_InternalName(self, node: nodes.InternalName, frame: Frame) -> None: + self.write(node.name) + + def visit_ContextReference( + self, node: nodes.ContextReference, frame: Frame + ) -> None: + self.write("context") + + def visit_DerivedContextReference( + self, node: nodes.DerivedContextReference, frame: Frame + ) -> None: + self.write(self.derive_context(frame)) + + def visit_Continue(self, node: nodes.Continue, frame: Frame) -> None: + self.writeline("continue", node) + + def visit_Break(self, node: nodes.Break, frame: Frame) -> None: + self.writeline("break", node) + + def visit_Scope(self, node: nodes.Scope, frame: Frame) -> None: + scope_frame = frame.inner() + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + + def visit_OverlayScope(self, node: nodes.OverlayScope, frame: Frame) -> None: + ctx = self.temporary_identifier() + self.writeline(f"{ctx} = {self.derive_context(frame)}") + self.writeline(f"{ctx}.vars = ") + self.visit(node.context, frame) + self.push_context_reference(ctx) + + scope_frame = frame.inner(isolated=True) + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + self.pop_context_reference() + + def visit_EvalContextModifier( + self, node: nodes.EvalContextModifier, frame: Frame + ) -> None: + for keyword in node.options: + self.writeline(f"context.eval_ctx.{keyword.key} = ") + self.visit(keyword.value, frame) + try: + val = keyword.value.as_const(frame.eval_ctx) + except nodes.Impossible: + frame.eval_ctx.volatile = True + else: + setattr(frame.eval_ctx, keyword.key, val) + + def visit_ScopedEvalContextModifier( + self, node: nodes.ScopedEvalContextModifier, frame: Frame + ) -> None: + old_ctx_name = self.temporary_identifier() + saved_ctx = frame.eval_ctx.save() + self.writeline(f"{old_ctx_name} = context.eval_ctx.save()") + self.visit_EvalContextModifier(node, frame) + for child in node.body: + self.visit(child, frame) + frame.eval_ctx.revert(saved_ctx) + self.writeline(f"context.eval_ctx.revert({old_ctx_name})") diff --git a/.venv/lib/python3.13/site-packages/jinja2/constants.py b/.venv/lib/python3.13/site-packages/jinja2/constants.py new file mode 100644 index 0000000000000000000000000000000000000000..41a1c23b0a7fe134b1f662545876eb65b31b071e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/jinja2/constants.py @@ -0,0 +1,20 @@ +#: list of lorem ipsum words used by the lipsum() helper function +LOREM_IPSUM_WORDS = """\ +a ac accumsan ad adipiscing aenean aliquam aliquet amet ante aptent arcu at +auctor augue bibendum blandit class commodo condimentum congue consectetuer +consequat conubia convallis cras cubilia cum curabitur curae cursus dapibus +diam dictum dictumst dignissim dis dolor donec dui duis egestas eget eleifend +elementum elit enim erat eros est et etiam eu euismod facilisi facilisis fames +faucibus felis fermentum feugiat fringilla fusce gravida habitant habitasse hac +hendrerit hymenaeos iaculis id imperdiet in inceptos integer interdum ipsum +justo lacinia lacus laoreet lectus leo libero ligula litora lobortis lorem +luctus maecenas magna magnis malesuada massa mattis mauris metus mi molestie +mollis montes morbi mus nam nascetur natoque nec neque netus nibh nisi nisl non +nonummy nostra nulla nullam nunc odio orci ornare parturient pede pellentesque +penatibus per pharetra phasellus placerat platea porta porttitor posuere +potenti praesent pretium primis proin pulvinar purus quam quis quisque rhoncus +ridiculus risus rutrum sagittis sapien scelerisque sed sem semper senectus sit +sociis sociosqu sodales sollicitudin suscipit suspendisse taciti tellus tempor +tempus tincidunt torquent tortor tristique turpis ullamcorper ultrices +ultricies urna ut varius vehicula vel velit venenatis vestibulum vitae vivamus +viverra volutpat vulputate""" diff --git a/.venv/lib/python3.13/site-packages/jinja2/debug.py b/.venv/lib/python3.13/site-packages/jinja2/debug.py new file mode 100644 index 0000000000000000000000000000000000000000..eeeeee78b620f5d0745133b4629647973cd7af87 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/jinja2/debug.py @@ -0,0 +1,191 @@ +import sys +import typing as t +from types import CodeType +from types import TracebackType + +from .exceptions import TemplateSyntaxError +from .utils import internal_code +from .utils import missing + +if t.TYPE_CHECKING: + from .runtime import Context + + +def rewrite_traceback_stack(source: t.Optional[str] = None) -> BaseException: + """Rewrite the current exception to replace any tracebacks from + within compiled template code with tracebacks that look like they + came from the template source. + + This must be called within an ``except`` block. + + :param source: For ``TemplateSyntaxError``, the original source if + known. + :return: The original exception with the rewritten traceback. + """ + _, exc_value, tb = sys.exc_info() + exc_value = t.cast(BaseException, exc_value) + tb = t.cast(TracebackType, tb) + + if isinstance(exc_value, TemplateSyntaxError) and not exc_value.translated: + exc_value.translated = True + exc_value.source = source + # Remove the old traceback, otherwise the frames from the + # compiler still show up. + exc_value.with_traceback(None) + # Outside of runtime, so the frame isn't executing template + # code, but it still needs to point at the template. + tb = fake_traceback( + exc_value, None, exc_value.filename or "", exc_value.lineno + ) + else: + # Skip the frame for the render function. + tb = tb.tb_next + + stack = [] + + # Build the stack of traceback object, replacing any in template + # code with the source file and line information. + while tb is not None: + # Skip frames decorated with @internalcode. These are internal + # calls that aren't useful in template debugging output. + if tb.tb_frame.f_code in internal_code: + tb = tb.tb_next + continue + + template = tb.tb_frame.f_globals.get("__jinja_template__") + + if template is not None: + lineno = template.get_corresponding_lineno(tb.tb_lineno) + fake_tb = fake_traceback(exc_value, tb, template.filename, lineno) + stack.append(fake_tb) + else: + stack.append(tb) + + tb = tb.tb_next + + tb_next = None + + # Assign tb_next in reverse to avoid circular references. + for tb in reversed(stack): + tb.tb_next = tb_next + tb_next = tb + + return exc_value.with_traceback(tb_next) + + +def fake_traceback( # type: ignore + exc_value: BaseException, tb: t.Optional[TracebackType], filename: str, lineno: int +) -> TracebackType: + """Produce a new traceback object that looks like it came from the + template source instead of the compiled code. The filename, line + number, and location name will point to the template, and the local + variables will be the current template context. + + :param exc_value: The original exception to be re-raised to create + the new traceback. + :param tb: The original traceback to get the local variables and + code info from. + :param filename: The template filename. + :param lineno: The line number in the template source. + """ + if tb is not None: + # Replace the real locals with the context that would be + # available at that point in the template. + locals = get_template_locals(tb.tb_frame.f_locals) + locals.pop("__jinja_exception__", None) + else: + locals = {} + + globals = { + "__name__": filename, + "__file__": filename, + "__jinja_exception__": exc_value, + } + # Raise an exception at the correct line number. + code: CodeType = compile( + "\n" * (lineno - 1) + "raise __jinja_exception__", filename, "exec" + ) + + # Build a new code object that points to the template file and + # replaces the location with a block name. + location = "template" + + if tb is not None: + function = tb.tb_frame.f_code.co_name + + if function == "root": + location = "top-level template code" + elif function.startswith("block_"): + location = f"block {function[6:]!r}" + + if sys.version_info >= (3, 8): + code = code.replace(co_name=location) + else: + code = CodeType( + code.co_argcount, + code.co_kwonlyargcount, + code.co_nlocals, + code.co_stacksize, + code.co_flags, + code.co_code, + code.co_consts, + code.co_names, + code.co_varnames, + code.co_filename, + location, + code.co_firstlineno, + code.co_lnotab, + code.co_freevars, + code.co_cellvars, + ) + + # Execute the new code, which is guaranteed to raise, and return + # the new traceback without this frame. + try: + exec(code, globals, locals) + except BaseException: + return sys.exc_info()[2].tb_next # type: ignore + + +def get_template_locals(real_locals: t.Mapping[str, t.Any]) -> t.Dict[str, t.Any]: + """Based on the runtime locals, get the context that would be + available at that point in the template. + """ + # Start with the current template context. + ctx: t.Optional[Context] = real_locals.get("context") + + if ctx is not None: + data: t.Dict[str, t.Any] = ctx.get_all().copy() + else: + data = {} + + # Might be in a derived context that only sets local variables + # rather than pushing a context. Local variables follow the scheme + # l_depth_name. Find the highest-depth local that has a value for + # each name. + local_overrides: t.Dict[str, t.Tuple[int, t.Any]] = {} + + for name, value in real_locals.items(): + if not name.startswith("l_") or value is missing: + # Not a template variable, or no longer relevant. + continue + + try: + _, depth_str, name = name.split("_", 2) + depth = int(depth_str) + except ValueError: + continue + + cur_depth = local_overrides.get(name, (-1,))[0] + + if cur_depth < depth: + local_overrides[name] = (depth, value) + + # Modify the context with any derived context. + for name, (_, value) in local_overrides.items(): + if value is missing: + data.pop(name, None) + else: + data[name] = value + + return data diff --git a/.venv/lib/python3.13/site-packages/jinja2/defaults.py b/.venv/lib/python3.13/site-packages/jinja2/defaults.py new file mode 100644 index 0000000000000000000000000000000000000000..638cad3d2d8907330bde56e2b76c9b185c523b45 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/jinja2/defaults.py @@ -0,0 +1,48 @@ +import typing as t + +from .filters import FILTERS as DEFAULT_FILTERS # noqa: F401 +from .tests import TESTS as DEFAULT_TESTS # noqa: F401 +from .utils import Cycler +from .utils import generate_lorem_ipsum +from .utils import Joiner +from .utils import Namespace + +if t.TYPE_CHECKING: + import typing_extensions as te + +# defaults for the parser / lexer +BLOCK_START_STRING = "{%" +BLOCK_END_STRING = "%}" +VARIABLE_START_STRING = "{{" +VARIABLE_END_STRING = "}}" +COMMENT_START_STRING = "{#" +COMMENT_END_STRING = "#}" +LINE_STATEMENT_PREFIX: t.Optional[str] = None +LINE_COMMENT_PREFIX: t.Optional[str] = None +TRIM_BLOCKS = False +LSTRIP_BLOCKS = False +NEWLINE_SEQUENCE: "te.Literal['\\n', '\\r\\n', '\\r']" = "\n" +KEEP_TRAILING_NEWLINE = False + +# default filters, tests and namespace + +DEFAULT_NAMESPACE = { + "range": range, + "dict": dict, + "lipsum": generate_lorem_ipsum, + "cycler": Cycler, + "joiner": Joiner, + "namespace": Namespace, +} + +# default policies +DEFAULT_POLICIES: t.Dict[str, t.Any] = { + "compiler.ascii_str": True, + "urlize.rel": "noopener", + "urlize.target": None, + "urlize.extra_schemes": None, + "truncate.leeway": 5, + "json.dumps_function": None, + "json.dumps_kwargs": {"sort_keys": True}, + "ext.i18n.trimmed": False, +} diff --git a/.venv/lib/python3.13/site-packages/jinja2/environment.py b/.venv/lib/python3.13/site-packages/jinja2/environment.py new file mode 100644 index 0000000000000000000000000000000000000000..0fc6e5be87ab8273f6056ddfede07e1be28f1495 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/jinja2/environment.py @@ -0,0 +1,1672 @@ +"""Classes for managing templates and their runtime and compile time +options. +""" + +import os +import typing +import typing as t +import weakref +from collections import ChainMap +from functools import lru_cache +from functools import partial +from functools import reduce +from types import CodeType + +from markupsafe import Markup + +from . import nodes +from .compiler import CodeGenerator +from .compiler import generate +from .defaults import BLOCK_END_STRING +from .defaults import BLOCK_START_STRING +from .defaults import COMMENT_END_STRING +from .defaults import COMMENT_START_STRING +from .defaults import DEFAULT_FILTERS # type: ignore[attr-defined] +from .defaults import DEFAULT_NAMESPACE +from .defaults import DEFAULT_POLICIES +from .defaults import DEFAULT_TESTS # type: ignore[attr-defined] +from .defaults import KEEP_TRAILING_NEWLINE +from .defaults import LINE_COMMENT_PREFIX +from .defaults import LINE_STATEMENT_PREFIX +from .defaults import LSTRIP_BLOCKS +from .defaults import NEWLINE_SEQUENCE +from .defaults import TRIM_BLOCKS +from .defaults import VARIABLE_END_STRING +from .defaults import VARIABLE_START_STRING +from .exceptions import TemplateNotFound +from .exceptions import TemplateRuntimeError +from .exceptions import TemplatesNotFound +from .exceptions import TemplateSyntaxError +from .exceptions import UndefinedError +from .lexer import get_lexer +from .lexer import Lexer +from .lexer import TokenStream +from .nodes import EvalContext +from .parser import Parser +from .runtime import Context +from .runtime import new_context +from .runtime import Undefined +from .utils import _PassArg +from .utils import concat +from .utils import consume +from .utils import import_string +from .utils import internalcode +from .utils import LRUCache +from .utils import missing + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .bccache import BytecodeCache + from .ext import Extension + from .loaders import BaseLoader + +_env_bound = t.TypeVar("_env_bound", bound="Environment") + + +# for direct template usage we have up to ten living environments +@lru_cache(maxsize=10) +def get_spontaneous_environment(cls: t.Type[_env_bound], *args: t.Any) -> _env_bound: + """Return a new spontaneous environment. A spontaneous environment + is used for templates created directly rather than through an + existing environment. + + :param cls: Environment class to create. + :param args: Positional arguments passed to environment. + """ + env = cls(*args) + env.shared = True + return env + + +def create_cache( + size: int, +) -> t.Optional[t.MutableMapping[t.Tuple["weakref.ref[t.Any]", str], "Template"]]: + """Return the cache class for the given size.""" + if size == 0: + return None + + if size < 0: + return {} + + return LRUCache(size) # type: ignore + + +def copy_cache( + cache: t.Optional[t.MutableMapping[t.Any, t.Any]], +) -> t.Optional[t.MutableMapping[t.Tuple["weakref.ref[t.Any]", str], "Template"]]: + """Create an empty copy of the given cache.""" + if cache is None: + return None + + if type(cache) is dict: # noqa E721 + return {} + + return LRUCache(cache.capacity) # type: ignore + + +def load_extensions( + environment: "Environment", + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]], +) -> t.Dict[str, "Extension"]: + """Load the extensions from the list and bind it to the environment. + Returns a dict of instantiated extensions. + """ + result = {} + + for extension in extensions: + if isinstance(extension, str): + extension = t.cast(t.Type["Extension"], import_string(extension)) + + result[extension.identifier] = extension(environment) + + return result + + +def _environment_config_check(environment: _env_bound) -> _env_bound: + """Perform a sanity check on the environment.""" + assert issubclass( + environment.undefined, Undefined + ), "'undefined' must be a subclass of 'jinja2.Undefined'." + assert ( + environment.block_start_string + != environment.variable_start_string + != environment.comment_start_string + ), "block, variable and comment start strings must be different." + assert environment.newline_sequence in { + "\r", + "\r\n", + "\n", + }, "'newline_sequence' must be one of '\\n', '\\r\\n', or '\\r'." + return environment + + +class Environment: + r"""The core component of Jinja is the `Environment`. It contains + important shared variables like configuration, filters, tests, + globals and others. Instances of this class may be modified if + they are not shared and if no template was loaded so far. + Modifications on environments after the first template was loaded + will lead to surprising effects and undefined behavior. + + Here are the possible initialization parameters: + + `block_start_string` + The string marking the beginning of a block. Defaults to ``'{%'``. + + `block_end_string` + The string marking the end of a block. Defaults to ``'%}'``. + + `variable_start_string` + The string marking the beginning of a print statement. + Defaults to ``'{{'``. + + `variable_end_string` + The string marking the end of a print statement. Defaults to + ``'}}'``. + + `comment_start_string` + The string marking the beginning of a comment. Defaults to ``'{#'``. + + `comment_end_string` + The string marking the end of a comment. Defaults to ``'#}'``. + + `line_statement_prefix` + If given and a string, this will be used as prefix for line based + statements. See also :ref:`line-statements`. + + `line_comment_prefix` + If given and a string, this will be used as prefix for line based + comments. See also :ref:`line-statements`. + + .. versionadded:: 2.2 + + `trim_blocks` + If this is set to ``True`` the first newline after a block is + removed (block, not variable tag!). Defaults to `False`. + + `lstrip_blocks` + If this is set to ``True`` leading spaces and tabs are stripped + from the start of a line to a block. Defaults to `False`. + + `newline_sequence` + The sequence that starts a newline. Must be one of ``'\r'``, + ``'\n'`` or ``'\r\n'``. The default is ``'\n'`` which is a + useful default for Linux and OS X systems as well as web + applications. + + `keep_trailing_newline` + Preserve the trailing newline when rendering templates. + The default is ``False``, which causes a single newline, + if present, to be stripped from the end of the template. + + .. versionadded:: 2.7 + + `extensions` + List of Jinja extensions to use. This can either be import paths + as strings or extension classes. For more information have a + look at :ref:`the extensions documentation `. + + `optimized` + should the optimizer be enabled? Default is ``True``. + + `undefined` + :class:`Undefined` or a subclass of it that is used to represent + undefined values in the template. + + `finalize` + A callable that can be used to process the result of a variable + expression before it is output. For example one can convert + ``None`` implicitly into an empty string here. + + `autoescape` + If set to ``True`` the XML/HTML autoescaping feature is enabled by + default. For more details about autoescaping see + :class:`~markupsafe.Markup`. As of Jinja 2.4 this can also + be a callable that is passed the template name and has to + return ``True`` or ``False`` depending on autoescape should be + enabled by default. + + .. versionchanged:: 2.4 + `autoescape` can now be a function + + `loader` + The template loader for this environment. + + `cache_size` + The size of the cache. Per default this is ``400`` which means + that if more than 400 templates are loaded the loader will clean + out the least recently used template. If the cache size is set to + ``0`` templates are recompiled all the time, if the cache size is + ``-1`` the cache will not be cleaned. + + .. versionchanged:: 2.8 + The cache size was increased to 400 from a low 50. + + `auto_reload` + Some loaders load templates from locations where the template + sources may change (ie: file system or database). If + ``auto_reload`` is set to ``True`` (default) every time a template is + requested the loader checks if the source changed and if yes, it + will reload the template. For higher performance it's possible to + disable that. + + `bytecode_cache` + If set to a bytecode cache object, this object will provide a + cache for the internal Jinja bytecode so that templates don't + have to be parsed if they were not changed. + + See :ref:`bytecode-cache` for more information. + + `enable_async` + If set to true this enables async template execution which + allows using async functions and generators. + """ + + #: if this environment is sandboxed. Modifying this variable won't make + #: the environment sandboxed though. For a real sandboxed environment + #: have a look at jinja2.sandbox. This flag alone controls the code + #: generation by the compiler. + sandboxed = False + + #: True if the environment is just an overlay + overlayed = False + + #: the environment this environment is linked to if it is an overlay + linked_to: t.Optional["Environment"] = None + + #: shared environments have this set to `True`. A shared environment + #: must not be modified + shared = False + + #: the class that is used for code generation. See + #: :class:`~jinja2.compiler.CodeGenerator` for more information. + code_generator_class: t.Type["CodeGenerator"] = CodeGenerator + + concat = "".join + + #: the context class that is used for templates. See + #: :class:`~jinja2.runtime.Context` for more information. + context_class: t.Type[Context] = Context + + template_class: t.Type["Template"] + + def __init__( + self, + block_start_string: str = BLOCK_START_STRING, + block_end_string: str = BLOCK_END_STRING, + variable_start_string: str = VARIABLE_START_STRING, + variable_end_string: str = VARIABLE_END_STRING, + comment_start_string: str = COMMENT_START_STRING, + comment_end_string: str = COMMENT_END_STRING, + line_statement_prefix: t.Optional[str] = LINE_STATEMENT_PREFIX, + line_comment_prefix: t.Optional[str] = LINE_COMMENT_PREFIX, + trim_blocks: bool = TRIM_BLOCKS, + lstrip_blocks: bool = LSTRIP_BLOCKS, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = NEWLINE_SEQUENCE, + keep_trailing_newline: bool = KEEP_TRAILING_NEWLINE, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = (), + optimized: bool = True, + undefined: t.Type[Undefined] = Undefined, + finalize: t.Optional[t.Callable[..., t.Any]] = None, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = False, + loader: t.Optional["BaseLoader"] = None, + cache_size: int = 400, + auto_reload: bool = True, + bytecode_cache: t.Optional["BytecodeCache"] = None, + enable_async: bool = False, + ): + # !!Important notice!! + # The constructor accepts quite a few arguments that should be + # passed by keyword rather than position. However it's important to + # not change the order of arguments because it's used at least + # internally in those cases: + # - spontaneous environments (i18n extension and Template) + # - unittests + # If parameter changes are required only add parameters at the end + # and don't change the arguments (or the defaults!) of the arguments + # existing already. + + # lexer / parser information + self.block_start_string = block_start_string + self.block_end_string = block_end_string + self.variable_start_string = variable_start_string + self.variable_end_string = variable_end_string + self.comment_start_string = comment_start_string + self.comment_end_string = comment_end_string + self.line_statement_prefix = line_statement_prefix + self.line_comment_prefix = line_comment_prefix + self.trim_blocks = trim_blocks + self.lstrip_blocks = lstrip_blocks + self.newline_sequence = newline_sequence + self.keep_trailing_newline = keep_trailing_newline + + # runtime information + self.undefined: t.Type[Undefined] = undefined + self.optimized = optimized + self.finalize = finalize + self.autoescape = autoescape + + # defaults + self.filters = DEFAULT_FILTERS.copy() + self.tests = DEFAULT_TESTS.copy() + self.globals = DEFAULT_NAMESPACE.copy() + + # set the loader provided + self.loader = loader + self.cache = create_cache(cache_size) + self.bytecode_cache = bytecode_cache + self.auto_reload = auto_reload + + # configurable policies + self.policies = DEFAULT_POLICIES.copy() + + # load extensions + self.extensions = load_extensions(self, extensions) + + self.is_async = enable_async + _environment_config_check(self) + + def add_extension(self, extension: t.Union[str, t.Type["Extension"]]) -> None: + """Adds an extension after the environment was created. + + .. versionadded:: 2.5 + """ + self.extensions.update(load_extensions(self, [extension])) + + def extend(self, **attributes: t.Any) -> None: + """Add the items to the instance of the environment if they do not exist + yet. This is used by :ref:`extensions ` to register + callbacks and configuration values without breaking inheritance. + """ + for key, value in attributes.items(): + if not hasattr(self, key): + setattr(self, key, value) + + def overlay( + self, + block_start_string: str = missing, + block_end_string: str = missing, + variable_start_string: str = missing, + variable_end_string: str = missing, + comment_start_string: str = missing, + comment_end_string: str = missing, + line_statement_prefix: t.Optional[str] = missing, + line_comment_prefix: t.Optional[str] = missing, + trim_blocks: bool = missing, + lstrip_blocks: bool = missing, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = missing, + keep_trailing_newline: bool = missing, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = missing, + optimized: bool = missing, + undefined: t.Type[Undefined] = missing, + finalize: t.Optional[t.Callable[..., t.Any]] = missing, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = missing, + loader: t.Optional["BaseLoader"] = missing, + cache_size: int = missing, + auto_reload: bool = missing, + bytecode_cache: t.Optional["BytecodeCache"] = missing, + enable_async: bool = missing, + ) -> "te.Self": + """Create a new overlay environment that shares all the data with the + current environment except for cache and the overridden attributes. + Extensions cannot be removed for an overlayed environment. An overlayed + environment automatically gets all the extensions of the environment it + is linked to plus optional extra extensions. + + Creating overlays should happen after the initial environment was set + up completely. Not all attributes are truly linked, some are just + copied over so modifications on the original environment may not shine + through. + + .. versionchanged:: 3.1.5 + ``enable_async`` is applied correctly. + + .. versionchanged:: 3.1.2 + Added the ``newline_sequence``, ``keep_trailing_newline``, + and ``enable_async`` parameters to match ``__init__``. + """ + args = dict(locals()) + del args["self"], args["cache_size"], args["extensions"], args["enable_async"] + + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.overlayed = True + rv.linked_to = self + + for key, value in args.items(): + if value is not missing: + setattr(rv, key, value) + + if cache_size is not missing: + rv.cache = create_cache(cache_size) + else: + rv.cache = copy_cache(self.cache) + + rv.extensions = {} + for key, value in self.extensions.items(): + rv.extensions[key] = value.bind(rv) + if extensions is not missing: + rv.extensions.update(load_extensions(rv, extensions)) + + if enable_async is not missing: + rv.is_async = enable_async + + return _environment_config_check(rv) + + @property + def lexer(self) -> Lexer: + """The lexer for this environment.""" + return get_lexer(self) + + def iter_extensions(self) -> t.Iterator["Extension"]: + """Iterates over the extensions by priority.""" + return iter(sorted(self.extensions.values(), key=lambda x: x.priority)) + + def getitem( + self, obj: t.Any, argument: t.Union[str, t.Any] + ) -> t.Union[t.Any, Undefined]: + """Get an item or attribute of an object but prefer the item.""" + try: + return obj[argument] + except (AttributeError, TypeError, LookupError): + if isinstance(argument, str): + try: + attr = str(argument) + except Exception: + pass + else: + try: + return getattr(obj, attr) + except AttributeError: + pass + return self.undefined(obj=obj, name=argument) + + def getattr(self, obj: t.Any, attribute: str) -> t.Any: + """Get an item or attribute of an object but prefer the attribute. + Unlike :meth:`getitem` the attribute *must* be a string. + """ + try: + return getattr(obj, attribute) + except AttributeError: + pass + try: + return obj[attribute] + except (TypeError, LookupError, AttributeError): + return self.undefined(obj=obj, name=attribute) + + def _filter_test_common( + self, + name: t.Union[str, Undefined], + value: t.Any, + args: t.Optional[t.Sequence[t.Any]], + kwargs: t.Optional[t.Mapping[str, t.Any]], + context: t.Optional[Context], + eval_ctx: t.Optional[EvalContext], + is_filter: bool, + ) -> t.Any: + if is_filter: + env_map = self.filters + type_name = "filter" + else: + env_map = self.tests + type_name = "test" + + func = env_map.get(name) # type: ignore + + if func is None: + msg = f"No {type_name} named {name!r}." + + if isinstance(name, Undefined): + try: + name._fail_with_undefined_error() + except Exception as e: + msg = f"{msg} ({e}; did you forget to quote the callable name?)" + + raise TemplateRuntimeError(msg) + + args = [value, *(args if args is not None else ())] + kwargs = kwargs if kwargs is not None else {} + pass_arg = _PassArg.from_obj(func) + + if pass_arg is _PassArg.context: + if context is None: + raise TemplateRuntimeError( + f"Attempted to invoke a context {type_name} without context." + ) + + args.insert(0, context) + elif pass_arg is _PassArg.eval_context: + if eval_ctx is None: + if context is not None: + eval_ctx = context.eval_ctx + else: + eval_ctx = EvalContext(self) + + args.insert(0, eval_ctx) + elif pass_arg is _PassArg.environment: + args.insert(0, self) + + return func(*args, **kwargs) + + def call_filter( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a filter on a value the same way the compiler does. + + This might return a coroutine if the filter is running from an + environment in async mode and the filter supports async + execution. It's your responsibility to await this if needed. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, True + ) + + def call_test( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a test on a value the same way the compiler does. + + This might return a coroutine if the test is running from an + environment in async mode and the test supports async execution. + It's your responsibility to await this if needed. + + .. versionchanged:: 3.0 + Tests support ``@pass_context``, etc. decorators. Added + the ``context`` and ``eval_ctx`` parameters. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, False + ) + + @internalcode + def parse( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> nodes.Template: + """Parse the sourcecode and return the abstract syntax tree. This + tree of nodes is used by the compiler to convert the template into + executable source- or bytecode. This is useful for debugging or to + extract information from templates. + + If you are :ref:`developing Jinja extensions ` + this gives you a good overview of the node tree generated. + """ + try: + return self._parse(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def _parse( + self, source: str, name: t.Optional[str], filename: t.Optional[str] + ) -> nodes.Template: + """Internal parsing function used by `parse` and `compile`.""" + return Parser(self, source, name, filename).parse() + + def lex( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> t.Iterator[t.Tuple[int, str, str]]: + """Lex the given sourcecode and return a generator that yields + tokens as tuples in the form ``(lineno, token_type, value)``. + This can be useful for :ref:`extension development ` + and debugging templates. + + This does not perform preprocessing. If you want the preprocessing + of the extensions to be applied you have to filter source through + the :meth:`preprocess` method. + """ + source = str(source) + try: + return self.lexer.tokeniter(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def preprocess( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> str: + """Preprocesses the source with all extensions. This is automatically + called for all parsing and compiling methods but *not* for :meth:`lex` + because there you usually only want the actual source tokenized. + """ + return reduce( + lambda s, e: e.preprocess(s, name, filename), + self.iter_extensions(), + str(source), + ) + + def _tokenize( + self, + source: str, + name: t.Optional[str], + filename: t.Optional[str] = None, + state: t.Optional[str] = None, + ) -> TokenStream: + """Called by the parser to do the preprocessing and filtering + for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`. + """ + source = self.preprocess(source, name, filename) + stream = self.lexer.tokenize(source, name, filename, state) + + for ext in self.iter_extensions(): + stream = ext.filter_stream(stream) # type: ignore + + if not isinstance(stream, TokenStream): + stream = TokenStream(stream, name, filename) + + return stream + + def _generate( + self, + source: nodes.Template, + name: t.Optional[str], + filename: t.Optional[str], + defer_init: bool = False, + ) -> str: + """Internal hook that can be overridden to hook a different generate + method in. + + .. versionadded:: 2.5 + """ + return generate( # type: ignore + source, + self, + name, + filename, + defer_init=defer_init, + optimized=self.optimized, + ) + + def _compile(self, source: str, filename: str) -> CodeType: + """Internal hook that can be overridden to hook a different compile + method in. + + .. versionadded:: 2.5 + """ + return compile(source, filename, "exec") + + @typing.overload + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[False]" = False, + defer_init: bool = False, + ) -> CodeType: ... + + @typing.overload + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[True]" = ..., + defer_init: bool = False, + ) -> str: ... + + @internalcode + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: bool = False, + defer_init: bool = False, + ) -> t.Union[str, CodeType]: + """Compile a node or template source code. The `name` parameter is + the load name of the template after it was joined using + :meth:`join_path` if necessary, not the filename on the file system. + the `filename` parameter is the estimated filename of the template on + the file system. If the template came from a database or memory this + can be omitted. + + The return value of this method is a python code object. If the `raw` + parameter is `True` the return value will be a string with python + code equivalent to the bytecode returned otherwise. This method is + mainly used internally. + + `defer_init` is use internally to aid the module code generator. This + causes the generated code to be able to import without the global + environment variable to be set. + + .. versionadded:: 2.4 + `defer_init` parameter added. + """ + source_hint = None + try: + if isinstance(source, str): + source_hint = source + source = self._parse(source, name, filename) + source = self._generate(source, name, filename, defer_init=defer_init) + if raw: + return source + if filename is None: + filename = "